tag.py
127 lines
| 3.1 KiB
| text/x-python
|
PythonLexer
neko259
|
r599 | from boards.models import Thread, Post | ||
neko259
|
r386 | from django.db import models | ||
neko259
|
r607 | from django.db.models import Count, Sum | ||
neko259
|
r385 | |||
__author__ = 'neko259' | ||||
neko259
|
r598 | MAX_TAG_FONT = 1 | ||
MIN_TAG_FONT = 0.2 | ||||
neko259
|
r509 | |||
neko259
|
r601 | TAG_POPULARITY_MULTIPLIER = 20 | ||
neko259
|
r600 | |||
neko259
|
r601 | ARCHIVE_POPULARITY_MODIFIER = 0.5 | ||
neko259
|
r385 | |||
class TagManager(models.Manager): | ||||
def get_not_empty_tags(self): | ||||
neko259
|
r623 | """ | ||
Gets tags that have non-archived threads. | ||||
""" | ||||
neko259
|
r385 | tags = self.annotate(Count('threads')) \ | ||
neko259
|
r610 | .filter(threads__count__gt=0).filter(threads__archived=False) \ | ||
.order_by('name') | ||||
neko259
|
r385 | |||
return tags | ||||
class Tag(models.Model): | ||||
""" | ||||
neko259
|
r398 | A tag is a text node assigned to the thread. The tag serves as a board | ||
section. There can be multiple tags for each thread | ||||
neko259
|
r385 | """ | ||
objects = TagManager() | ||||
class Meta: | ||||
app_label = 'boards' | ||||
neko259
|
r609 | name = models.CharField(max_length=100, db_index=True) | ||
neko259
|
r398 | threads = models.ManyToManyField(Thread, null=True, | ||
neko259
|
r385 | blank=True, related_name='tag+') | ||
linked = models.ForeignKey('Tag', null=True, blank=True) | ||||
def __unicode__(self): | ||||
return self.name | ||||
def is_empty(self): | ||||
neko259
|
r623 | """ | ||
Checks if the tag has some threads. | ||||
""" | ||||
neko259
|
r606 | return self.get_thread_count() == 0 | ||
neko259
|
r385 | |||
neko259
|
r606 | def get_thread_count(self): | ||
neko259
|
r385 | return self.threads.count() | ||
neko259
|
r509 | def get_popularity(self): | ||
neko259
|
r623 | """ | ||
Gets tag's popularity value as a percentage of overall board post | ||||
count. | ||||
""" | ||||
all_post_count = Post.objects.count() | ||||
neko259
|
r599 | |||
tag_reply_count = 0.0 | ||||
neko259
|
r509 | |||
neko259
|
r606 | tag_reply_count += self.get_post_count() | ||
tag_reply_count +=\ | ||||
self.get_post_count(archived=True) * ARCHIVE_POPULARITY_MODIFIER | ||||
neko259
|
r509 | |||
neko259
|
r603 | popularity = tag_reply_count / all_post_count | ||
neko259
|
r509 | |||
return popularity | ||||
neko259
|
r385 | |||
def get_linked_tags(self): | ||||
neko259
|
r623 | """ | ||
Gets tags linked to the current one. | ||||
""" | ||||
neko259
|
r385 | tag_list = [] | ||
self.get_linked_tags_list(tag_list) | ||||
return tag_list | ||||
def get_linked_tags_list(self, tag_list=[]): | ||||
""" | ||||
Returns the list of tags linked to current. The list can be got | ||||
through returned value or tag_list parameter | ||||
""" | ||||
linked_tag = self.linked | ||||
if linked_tag and not (linked_tag in tag_list): | ||||
tag_list.append(linked_tag) | ||||
linked_tag.get_linked_tags_list(tag_list) | ||||
def get_font_value(self): | ||||
neko259
|
r623 | """ | ||
Gets tag font value to differ most popular tags in the list | ||||
""" | ||||
neko259
|
r385 | |||
neko259
|
r509 | popularity = self.get_popularity() | ||
neko259
|
r385 | |||
neko259
|
r602 | font_value = popularity * Tag.objects.get_not_empty_tags().count() | ||
neko259
|
r601 | font_value = max(font_value, MIN_TAG_FONT) | ||
neko259
|
r519 | font_value = min(font_value, MAX_TAG_FONT) | ||
neko259
|
r385 | |||
neko259
|
r519 | return str(font_value) | ||
neko259
|
r606 | |||
def get_post_count(self, archived=False): | ||||
neko259
|
r623 | """ | ||
Gets posts count for the tag's threads. | ||||
""" | ||||
neko259
|
r606 | posts_count = 0 | ||
neko259
|
r607 | threads = self.threads.filter(archived=archived) | ||
if threads.exists(): | ||||
posts_count = threads.annotate(posts_count=Count('replies')).aggregate( | ||||
posts_sum=Sum('posts_count'))['posts_sum'] | ||||
if not posts_count: | ||||
posts_count = 0 | ||||
neko259
|
r606 | |||
return posts_count | ||||