tag.py
138 lines
| 3.5 KiB
| text/x-python
|
PythonLexer
neko259
|
r692 | from django.template.loader import render_to_string | |
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
|
r692 | from django.core.urlresolvers import reverse | |
from boards.models.base import Viewable | |||
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 | |||
neko259
|
r692 | class Tag(models.Model, Viewable): | |
neko259
|
r385 | """ | |
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
|
r649 | ordering = ('name',) | |
neko259
|
r385 | ||
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 | |||
neko259
|
r692 | ||
def get_url(self): | |||
return reverse('tag', kwargs={'tag_name': self.name}) | |||
def get_view(self, *args, **kwargs): | |||
return render_to_string('boards/tag.html', { | |||
'tag': self, | |||
}) |