Show More
@@ -122,7 +122,7 b' class PostManager(models.Manager):' | |||||
122 | for post in posts: |
|
122 | for post in posts: | |
123 | post.delete() |
|
123 | post.delete() | |
124 |
|
124 | |||
125 | @cached_result |
|
125 | @cached_result() | |
126 | def get_posts_per_day(self) -> float: |
|
126 | def get_posts_per_day(self) -> float: | |
127 | """ |
|
127 | """ | |
128 | Gets average count of posts per day for the last 7 days |
|
128 | Gets average count of posts per day for the last 7 days | |
@@ -209,7 +209,7 b' class Post(models.Model, Viewable):' | |||||
209 |
|
209 | |||
210 | return self.get_thread().get_opening_post_id() == self.id |
|
210 | return self.get_thread().get_opening_post_id() == self.id | |
211 |
|
211 | |||
212 | @cached_result |
|
212 | @cached_result() | |
213 | def get_url(self): |
|
213 | def get_url(self): | |
214 | """ |
|
214 | """ | |
215 | Gets full url to the post. |
|
215 | Gets full url to the post. |
@@ -7,7 +7,7 b' from django.db import models' | |||||
7 |
|
7 | |||
8 | from boards import settings |
|
8 | from boards import settings | |
9 | import boards |
|
9 | import boards | |
10 | from boards.utils import cached_result |
|
10 | from boards.utils import cached_result, datetime_to_epoch | |
11 | from boards.models.post import Post |
|
11 | from boards.models.post import Post | |
12 | from boards.models.tag import Tag |
|
12 | from boards.models.tag import Tag | |
13 |
|
13 | |||
@@ -94,9 +94,14 b' class Thread(models.Model):' | |||||
94 | self.bumpable = False |
|
94 | self.bumpable = False | |
95 | self.update_posts_time() |
|
95 | self.update_posts_time() | |
96 |
|
96 | |||
|
97 | def _get_cache_key(self): | |||
|
98 | return [datetime_to_epoch(self.last_edit_time)] | |||
|
99 | ||||
|
100 | @cached_result(key_method=_get_cache_key) | |||
97 | def get_reply_count(self) -> int: |
|
101 | def get_reply_count(self) -> int: | |
98 | return self.get_replies().count() |
|
102 | return self.get_replies().count() | |
99 |
|
103 | |||
|
104 | @cached_result(key_method=_get_cache_key) | |||
100 | def get_images_count(self) -> int: |
|
105 | def get_images_count(self) -> int: | |
101 | return self.get_replies().annotate(images_count=Count( |
|
106 | return self.get_replies().annotate(images_count=Count( | |
102 | 'images')).aggregate(Sum('images_count'))['images_count__sum'] |
|
107 | 'images')).aggregate(Sum('images_count'))['images_count__sum'] | |
@@ -152,6 +157,7 b' class Thread(models.Model):' | |||||
152 | return self.get_replies(view_fields_only).annotate(images_count=Count( |
|
157 | return self.get_replies(view_fields_only).annotate(images_count=Count( | |
153 | 'images')).filter(images_count__gt=0) |
|
158 | 'images')).filter(images_count__gt=0) | |
154 |
|
159 | |||
|
160 | # TODO Do we still need this? | |||
155 | def add_tag(self, tag: Tag): |
|
161 | def add_tag(self, tag: Tag): | |
156 | """ |
|
162 | """ | |
157 | Connects thread to a tag and tag to a thread |
|
163 | Connects thread to a tag and tag to a thread | |
@@ -171,7 +177,7 b' class Thread(models.Model):' | |||||
171 |
|
177 | |||
172 | return opening_post |
|
178 | return opening_post | |
173 |
|
179 | |||
174 | @cached_result |
|
180 | @cached_result() | |
175 | def get_opening_post_id(self) -> int: |
|
181 | def get_opening_post_id(self) -> int: | |
176 | """ |
|
182 | """ | |
177 | Gets ID of the first thread post. |
|
183 | Gets ID of the first thread post. | |
@@ -217,4 +223,4 b' class Thread(models.Model):' | |||||
217 | client.publish(channel_name, { |
|
223 | client.publish(channel_name, { | |
218 | WS_NOTIFICATION_TYPE: WS_NOTIFICATION_TYPE_NEW_POST, |
|
224 | WS_NOTIFICATION_TYPE: WS_NOTIFICATION_TYPE_NEW_POST, | |
219 | }) |
|
225 | }) | |
220 | client.send() No newline at end of file |
|
226 | client.send() |
@@ -1,7 +1,6 b'' | |||||
1 | {% extends "boards/base.html" %} |
|
1 | {% extends "boards/base.html" %} | |
2 |
|
2 | |||
3 | {% load i18n %} |
|
3 | {% load i18n %} | |
4 | {% load cache %} |
|
|||
5 | {% load static from staticfiles %} |
|
4 | {% load static from staticfiles %} | |
6 | {% load board %} |
|
5 | {% load board %} | |
7 | {% load tz %} |
|
6 | {% load tz %} | |
@@ -13,9 +12,6 b'' | |||||
13 |
|
12 | |||
14 | {% block metapanel %} |
|
13 | {% block metapanel %} | |
15 |
|
14 | |||
16 | {% get_current_language as LANGUAGE_CODE %} |
|
|||
17 | {% get_current_timezone as TIME_ZONE %} |
|
|||
18 |
|
||||
19 | <span class="metapanel" |
|
15 | <span class="metapanel" | |
20 | data-last-update="{{ last_update }}" |
|
16 | data-last-update="{{ last_update }}" | |
21 | data-ws-token-time="{{ ws_token_time }}" |
|
17 | data-ws-token-time="{{ ws_token_time }}" | |
@@ -27,12 +23,10 b'' | |||||
27 | {% block thread_meta_panel %} |
|
23 | {% block thread_meta_panel %} | |
28 | {% endblock %} |
|
24 | {% endblock %} | |
29 |
|
25 | |||
30 | {% cache 600 thread_meta thread.last_edit_time moderator LANGUAGE_CODE TIME_ZONE %} |
|
|||
31 | <span id="reply-count">{{ thread.get_reply_count }}</span>{% if thread.has_post_limit %}/{{ thread.max_posts }}{% endif %} {% trans 'messages' %}, |
|
26 | <span id="reply-count">{{ thread.get_reply_count }}</span>{% if thread.has_post_limit %}/{{ thread.max_posts }}{% endif %} {% trans 'messages' %}, | |
32 | <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}. |
|
27 | <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}. | |
33 | {% trans 'Last update: ' %}<span id="last-update"><time datetime="{{ thread.last_edit_time|date:'c' }}">{{ thread.last_edit_time }}</time></span> |
|
28 | {% trans 'Last update: ' %}<span id="last-update"><time datetime="{{ thread.last_edit_time|date:'c' }}">{{ thread.last_edit_time }}</time></span> | |
34 | [<a href="rss/">RSS</a>] |
|
29 | [<a href="rss/">RSS</a>] | |
35 | {% endcache %} |
|
|||
36 | </span> |
|
30 | </span> | |
37 |
|
31 | |||
38 | {% endblock %} |
|
32 | {% endblock %} |
@@ -3,6 +3,8 b' This module contains helper functions an' | |||||
3 | """ |
|
3 | """ | |
4 | import time |
|
4 | import time | |
5 | import hmac |
|
5 | import hmac | |
|
6 | import functools | |||
|
7 | ||||
6 | from django.core.cache import cache |
|
8 | from django.core.cache import cache | |
7 | from django.db.models import Model |
|
9 | from django.db.models import Model | |
8 |
|
10 | |||
@@ -11,9 +13,7 b' from django.utils import timezone' | |||||
11 | from neboard import settings |
|
13 | from neboard import settings | |
12 |
|
14 | |||
13 |
|
15 | |||
14 | KEY_CAPTCHA_FAILS = 'key_captcha_fails' |
|
16 | CACHE_KEY_DELIMITER = '_' | |
15 | KEY_CAPTCHA_DELAY_TIME = 'key_captcha_delay_time' |
|
|||
16 | KEY_CAPTCHA_LAST_ACTIVITY = 'key_captcha_last_activity' |
|
|||
17 |
|
17 | |||
18 |
|
18 | |||
19 | def get_client_ip(request): |
|
19 | def get_client_ip(request): | |
@@ -46,24 +46,31 b" def get_websocket_token(user_id='', time" | |||||
46 | return token |
|
46 | return token | |
47 |
|
47 | |||
48 |
|
48 | |||
49 |
def cached_result( |
|
49 | def cached_result(key_method=None): | |
50 | """ |
|
50 | """ | |
51 | Caches method result in the Django's cache system, persisted by object name, |
|
51 | Caches method result in the Django's cache system, persisted by object name, | |
52 | object name and model id if object is a Django model. |
|
52 | object name and model id if object is a Django model. | |
53 | """ |
|
53 | """ | |
54 | def inner_func(obj, *args, **kwargs): |
|
54 | def _cached_result(function): | |
55 | # TODO Include method arguments to the cache key |
|
55 | def inner_func(obj, *args, **kwargs): | |
56 | cache_key = obj.__class__.__name__ + '_' + function.__name__ |
|
56 | # TODO Include method arguments to the cache key | |
57 | if isinstance(obj, Model): |
|
57 | cache_key_params = [obj.__class__.__name__, function.__name__] | |
58 | cache_key += '_' + str(obj.id) |
|
58 | if isinstance(obj, Model): | |
|
59 | cache_key_params.append(str(obj.id)) | |||
|
60 | ||||
|
61 | if key_method is not None: | |||
|
62 | cache_key_params += [str(arg) for arg in key_method(obj)] | |||
|
63 | ||||
|
64 | cache_key = CACHE_KEY_DELIMITER.join(cache_key_params) | |||
59 |
|
65 | |||
60 | persisted_result = cache.get(cache_key) |
|
66 | persisted_result = cache.get(cache_key) | |
61 | if persisted_result: |
|
67 | if persisted_result is not None: | |
62 | result = persisted_result |
|
68 | result = persisted_result | |
63 | else: |
|
69 | else: | |
64 | result = function(obj, *args, **kwargs) |
|
70 | result = function(obj, *args, **kwargs) | |
65 | cache.set(cache_key, result) |
|
71 | cache.set(cache_key, result) | |
66 |
|
72 | |||
67 | return result |
|
73 | return result | |
68 |
|
74 | |||
69 | return inner_func |
|
75 | return inner_func | |
|
76 | return _cached_result |
General Comments 0
You need to be logged in to leave comments.
Login now