##// END OF EJS Templates
Cache tag localized names
neko259 -
r1888:832beb99 default
parent child Browse files
Show More
@@ -1,194 +1,196 b''
1 1 import hashlib
2 2 import re
3 3
4 4 from boards.models.attachment import FILE_TYPES_IMAGE
5 5 from django.template.loader import render_to_string
6 6 from django.db import models
7 7 from django.db.models import Count
8 8 from django.core.urlresolvers import reverse
9 9 from django.utils.translation import get_language
10 10
11 11 from boards.models import Attachment
12 12 from boards.models.base import Viewable
13 13 from boards.models.thread import STATUS_ACTIVE, STATUS_BUMPLIMIT, STATUS_ARCHIVE
14 14 from boards.utils import cached_result
15 15 import boards
16 16
17 17 __author__ = 'neko259'
18 18
19 19
20 20 RELATED_TAGS_COUNT = 5
21 21 DEFAULT_LOCALE = 'default'
22 22
23 23
24 24 class TagAlias(models.Model, Viewable):
25 25 class Meta:
26 26 app_label = 'boards'
27 27 ordering = ('name',)
28 28
29 29 name = models.CharField(max_length=100, db_index=True)
30 30 locale = models.CharField(max_length=10, db_index=True)
31 31
32 32 parent = models.ForeignKey('Tag', null=True, blank=True,
33 33 related_name='aliases')
34 34
35 35
36 36 class TagManager(models.Manager):
37 37 def get_not_empty_tags(self):
38 38 """
39 39 Gets tags that have non-archived threads.
40 40 """
41 41
42 42 return self.annotate(num_threads=Count('thread_tags'))\
43 43 .filter(num_threads__gt=0)\
44 44 .filter(aliases__locale=DEFAULT_LOCALE)\
45 45 .order_by('aliases__name')
46 46
47 47 def get_tag_url_list(self, tags: list) -> str:
48 48 """
49 49 Gets a comma-separated list of tag links.
50 50 """
51 51
52 52 return ', '.join([tag.get_view() for tag in tags])
53 53
54 54 def get_by_alias(self, alias):
55 55 tag = None
56 56 aliases = TagAlias.objects.filter(name=alias).all()
57 57 if aliases:
58 58 tag = aliases[0].parent
59 59
60 60 return tag
61 61
62 62 def get_or_create_with_alias(self, name, required=False):
63 63 tag = self.get_by_alias(name)
64 64 created = False
65 65 if not tag:
66 66 tag = self.create(required=required)
67 67 TagAlias.objects.create(name=name, locale=DEFAULT_LOCALE, parent=tag)
68 68 created = True
69 69 return tag, created
70 70
71 71
72 72 class Tag(models.Model, Viewable):
73 73 """
74 74 A tag is a text node assigned to the thread. The tag serves as a board
75 75 section. There can be multiple tags for each thread
76 76 """
77 77
78 78 objects = TagManager()
79 79
80 80 class Meta:
81 81 app_label = 'boards'
82 82
83 83 required = models.BooleanField(default=False, db_index=True)
84 84 description = models.TextField(blank=True)
85 85
86 86 parent = models.ForeignKey('Tag', null=True, blank=True,
87 87 related_name='children')
88 88
89 @cached_result()
90 89 def get_name(self):
91 90 return self.aliases.get(locale=DEFAULT_LOCALE).name
92 91
93 92 def __str__(self):
94 93 return self.get_name()
95 94
96 95 def is_empty(self) -> bool:
97 96 """
98 97 Checks if the tag has some threads.
99 98 """
100 99
101 100 return self.get_thread_count() == 0
102 101
103 102 def get_thread_count(self, status=None) -> int:
104 103 threads = self.get_threads()
105 104 if status is not None:
106 105 threads = threads.filter(status=status)
107 106 return threads.count()
108 107
109 108 def get_active_thread_count(self) -> int:
110 109 return self.get_thread_count(status=STATUS_ACTIVE)
111 110
112 111 def get_bumplimit_thread_count(self) -> int:
113 112 return self.get_thread_count(status=STATUS_BUMPLIMIT)
114 113
115 114 def get_archived_thread_count(self) -> int:
116 115 return self.get_thread_count(status=STATUS_ARCHIVE)
117 116
118 117 def get_absolute_url(self):
119 118 return reverse('tag', kwargs={'tag_name': self.get_name()})
120 119
121 120 def get_threads(self):
122 121 return self.thread_tags.order_by('-bump_time')
123 122
124 123 def is_required(self):
125 124 return self.required
126 125
126 def _get_locale_cache_key(self):
127 return '{}_{}'.format(self.id, get_language())
128
129 @cached_result(key_method=_get_locale_cache_key)
127 130 def get_view(self):
128 131 locale = get_language()
129 132
130 133 try:
131 134 localized_tag_name = self.aliases.get(locale=locale).name
132 135 except TagAlias.DoesNotExist:
133 136 localized_tag_name = ''
134 137
135 138 default_name = self.get_name()
136 139
137 140 name = '{} ({})'.format(default_name, localized_tag_name) if localized_tag_name else default_name
138 141 link = '<a class="tag" href="{}">{}</a>'.format(
139 142 self.get_absolute_url(), name)
140 143 if self.is_required():
141 144 link = '<b>{}</b>'.format(link)
142 145 return link
143 146
144 147 @cached_result()
145 148 def get_post_count(self):
146 149 return self.get_threads().aggregate(num_posts=Count('replies'))['num_posts']
147 150
148 151 def get_description(self):
149 152 return self.description
150 153
151 154 def get_random_image_post(self, status=[STATUS_ACTIVE, STATUS_BUMPLIMIT]):
152 155 posts = boards.models.Post.objects.filter(attachments__mimetype__in=FILE_TYPES_IMAGE)\
153 156 .annotate(images_count=Count(
154 157 'attachments')).filter(images_count__gt=0, thread__tags__in=[self])
155 158 if status is not None:
156 159 posts = posts.filter(thread__status__in=status)
157 160 return posts.order_by('?').first()
158 161
159 162 def get_first_letter(self):
160 163 name = self.get_name()
161 164 return name and name[0] or ''
162 165
163 166 def get_related_tags(self):
164 167 return set(Tag.objects.filter(thread_tags__in=self.get_threads()).exclude(
165 168 id=self.id).order_by('?')[:RELATED_TAGS_COUNT])
166 169
167 170 @cached_result()
168 171 def get_color(self):
169 172 """
170 173 Gets color hashed from the tag name.
171 174 """
172 175 return hashlib.md5(self.get_name().encode()).hexdigest()[:6]
173 176
174 177 def get_parent(self):
175 178 return self.parent
176 179
177 180 def get_all_parents(self):
178 181 parents = list()
179 182 parent = self.get_parent()
180 183 if parent and parent not in parents:
181 184 parents.insert(0, parent)
182 185 parents = parent.get_all_parents() + parents
183 186
184 187 return parents
185 188
186 189 def get_children(self):
187 190 return self.children
188 191
189 192 def get_images(self):
190 193 return Attachment.objects.filter(
191 194 attachment_posts__thread__tags__in=[self]).filter(
192 195 mimetype__in=FILE_TYPES_IMAGE).order_by('-attachment_posts__pub_time')
193 196
194
General Comments 0
You need to be logged in to leave comments. Login now