-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathservices.py
More file actions
163 lines (123 loc) · 4.93 KB
/
services.py
File metadata and controls
163 lines (123 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.core.cache import cache
from django.db.models import Count
from core.constants import VIEWS_CACHING_TIMEOUT
from core.models import Like, View, Link
User = get_user_model()
def add_like(obj, user):
obj_type = ContentType.objects.get_for_model(obj)
like, is_created = Like.objects.get_or_create(
content_type=obj_type, object_id=obj.id, user=user
)
return like
def remove_like(obj, user):
obj_type = ContentType.objects.get_for_model(obj)
Like.objects.filter(content_type=obj_type, object_id=obj.id, user=user).delete()
def is_fan(obj, user) -> bool:
if not user.is_authenticated:
return False
obj_type = ContentType.objects.get_for_model(obj)
likes = Like.objects.filter(content_type=obj_type, object_id=obj.id, user=user)
return likes.exists()
def get_fans(obj):
obj_type = ContentType.objects.get_for_model(obj)
return User.objects.filter(likes__content_type=obj_type, likes__object_id=obj.id)
def get_likes_count(obj):
obj_type = ContentType.objects.get_for_model(obj)
# todo: temp comment
# likes_count = cache.get(f"likes_count_{obj_type}_{obj.id}")
# if likes_count is None:
# likes_count = User.objects.filter(
# likes__content_type=obj_type, likes__object_id=obj.id
# ).count()
# # cache for LIKES_CACHING_TIMEOUT seconds
# cache.set(f"likes_count_{obj_type}_{obj.id}", likes_count, LIKES_CACHING_TIMEOUT)
return User.objects.filter(
likes__content_type=obj_type, likes__object_id=obj.id
).count()
# return likes_count
def set_like(obj, user, is_liked):
if is_liked:
add_like(obj, user)
else:
remove_like(obj, user)
def add_view(obj, user):
# TODO: add docstring
# TODO: add caching
obj_type = ContentType.objects.get_for_model(obj)
view, is_created = View.objects.get_or_create(
content_type=obj_type, object_id=obj.id, user=user
)
views_count = cache.get(f"views_count_{obj_type}_{obj.id}", None)
if views_count is not None:
cache.set(
f"views_count_{obj_type}_{obj.id}", views_count + 1, VIEWS_CACHING_TIMEOUT
)
return view
def remove_view(obj, user):
obj_type = ContentType.objects.get_for_model(obj)
View.objects.filter(content_type=obj_type, object_id=obj.id, user=user).delete()
views_count = cache.get(f"views_count_{obj_type}_{obj.id}", None)
if views_count is not None:
cache.set(
f"views_count_{obj_type}_{obj.id}", views_count - 1, VIEWS_CACHING_TIMEOUT
)
def is_viewer(obj, user) -> bool:
if not user.is_authenticated:
return False
obj_type = ContentType.objects.get_for_model(obj)
views = View.objects.filter(content_type=obj_type, object_id=obj.id, user=user)
return views.exists()
def get_viewers(obj):
obj_type = ContentType.objects.get_for_model(obj)
return User.objects.filter(views__content_type=obj_type, views__object_id=obj.id)
def cache_views_for_many_objects(objs):
"""
Set cached views count for many objects in 1 SQL query
Args:
objs:
List of objects that need their views retrieved
Returns: QuerySet[dict[object_id, count]]
"""
obj_type = ContentType.objects.get_for_model(objs[0])
ids = [obj.id for obj in objs]
data = (
View.objects.filter(content_type=obj_type, object_id__in=ids)
.values("object_id")
.annotate(count=Count("object_id"))
)
for i in data:
cache.set(f"views_count_{obj_type}_{i.object_id}", i.count, VIEWS_CACHING_TIMEOUT)
return data
def get_views_count_cached(obj):
obj_type = ContentType.objects.get_for_model(obj)
return cache.get(f"views_count_{obj_type}_{obj.id}", None)
def get_views_count(obj):
obj_type = ContentType.objects.get_for_model(obj)
# cache this
views_count = cache.get(f"views_count_{obj_type}_{obj.id}", None)
if views_count is None:
views_count = User.objects.filter(
views__content_type=obj_type, views__object_id=obj.id
).count()
# cache for VIEWS_CACHING_TIMEOUT seconds
cache.set(f"views_count_{obj_type}_{obj.id}", views_count, VIEWS_CACHING_TIMEOUT)
return views_count
def set_viewed(obj, user, is_viewed):
if is_viewed:
add_view(obj, user)
else:
remove_view(obj, user)
def add_link(obj, link: str):
obj_type = ContentType.objects.get_for_model(obj)
like, is_created = Link.objects.get_or_create(
content_type=obj_type, object_id=obj.id, link=link
)
return like
def remove_link(obj, link):
obj_type = ContentType.objects.get_for_model(obj)
Like.objects.filter(content_type=obj_type, object_id=obj.id, link=link).delete()
def get_links(obj):
obj_type = ContentType.objects.get_for_model(obj)
return Link.objects.filter(content_type=obj_type, object_id=obj.id)