##// END OF EJS Templates
Some more marochkas (neboard und nedoschechko)
Some more marochkas (neboard und nedoschechko)

File last commit:

r2033:77184386 default
r2106:27591518 mirrors_stamps
Show More
tag.py
211 lines | 6.3 KiB | text/x-python | PythonLexer
neko259
Tag colors
r1338 import hashlib
neko259
Adapt to django-2.0
r1986 from django.urls import reverse
neko259
Split up user models
r386 from django.db import models
neko259
Speed up tag localization
r1889 from django.db.models import Count, Q
neko259
Tags localization
r1860 from django.utils.translation import get_language
neko259
Removed obsolete import
r732
neko259
Removed unused imports
r1946 import boards
neko259
Store images as regular attachments instead of separate model
r1590 from boards.models import Attachment
neko259
Removed unused imports
r1946 from boards.models.attachment import FILE_TYPES_IMAGE
neko259
Added tag search. Refactored search to show any model results in a list.
r692 from boards.models.base import Viewable
neko259
Thread status field instead of bumpable and archived fields (per BB-73)
r1414 from boards.models.thread import STATUS_ACTIVE, STATUS_BUMPLIMIT, STATUS_ARCHIVE
neko259
Cache tag post count
r973 from boards.utils import cached_result
neko259
Removed obsolete import
r732
neko259
Simplify some expressions
r2022
neko259
Split up tag module from post module
r385 __author__ = 'neko259'
neko259
Simplify some expressions
r2022 TAG_DELIMITER = ', '
neko259
Add up to 5 random related tags instead of all related list
r1270 RELATED_TAGS_COUNT = 5
neko259
Tag name is now stored in the alias with default locale
r1874 DEFAULT_LOCALE = 'default'
neko259
Add up to 5 random related tags instead of all related list
r1270
neko259
Fixed thread creation
r1862
neko259
Show only localized tags
r1891 class TagAliasManager(models.Manager):
def filter_localized(self, *args, **kwargs):
locale = get_language()
tag_aliases = (self.filter(locale=locale)
| self.filter(Q(locale=DEFAULT_LOCALE)
& ~Q(parent__aliases__locale=locale)))
return tag_aliases.filter(**kwargs)
neko259
Fixed thread creation
r1862 class TagAlias(models.Model, Viewable):
class Meta:
app_label = 'boards'
ordering = ('name',)
neko259
Added constraint on a tag. Fixed creation of new tags
r2023 unique_together = ('name', 'locale')
neko259
Fixed thread creation
r1862
neko259
Show only localized tags
r1891 objects = TagAliasManager()
neko259
Allow using the same tag alias for different locales
r1873 name = models.CharField(max_length=100, db_index=True)
neko259
Fixed thread creation
r1862 locale = models.CharField(max_length=10, db_index=True)
neko259
Adapt to django-2.0
r1986 parent = models.ForeignKey('Tag', on_delete=models.CASCADE, null=True,
blank=True, related_name='aliases')
neko259
Tags localization
r1860
neko259
Added constraint on a tag. Fixed creation of new tags
r2023 def __str__(self):
return self.name
neko259
Add up to 5 random related tags instead of all related list
r1270
neko259
Split up tag module from post module
r385 class TagManager(models.Manager):
neko259
Refactoring
r1027 def get_tag_url_list(self, tags: list) -> str:
"""
Gets a comma-separated list of tag links.
"""
neko259
Simplify some expressions
r2022 return TAG_DELIMITER.join([tag.get_view() for tag in tags])
neko259
Refactoring
r1027
neko259
Tags localization
r1860 def get_by_alias(self, alias):
neko259
Simplify some expressions
r2022 try:
neko259
Added constraint on a tag. Fixed creation of new tags
r2023 return self.filter(aliases__name__in=[alias]).first()
neko259
Simplify some expressions
r2022 except Tag.DoesNotExist:
pass
neko259
Tags localization
r1860
neko259
Tag name is now stored in the alias with default locale
r1874 def get_or_create_with_alias(self, name, required=False):
tag = self.get_by_alias(name)
created = False
if not tag:
tag = self.create(required=required)
neko259
Fixed creating threads with new tags
r1883 TagAlias.objects.create(name=name, locale=DEFAULT_LOCALE, parent=tag)
neko259
Tag name is now stored in the alias with default locale
r1874 created = True
return tag, created
neko259
Split up tag module from post module
r385
neko259
Added tag search. Refactored search to show any model results in a list.
r692 class Tag(models.Model, Viewable):
neko259
Split up tag module from post module
r385 """
neko259
Split up post model into post and thread to normalise models. Still need some refactoring
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
Split up tag module from post module
r385 """
objects = TagManager()
class Meta:
app_label = 'boards'
neko259
Made tag name field unique. Added index to "required" field for tag
r983 required = models.BooleanField(default=False, db_index=True)
neko259
Added tag description
r1258 description = models.TextField(blank=True)
neko259
Split up tag module from post module
r385
neko259
Adapt to django-2.0
r1986 parent = models.ForeignKey('Tag', on_delete=models.CASCADE, null=True,
blank=True, related_name='children')
neko259
Added categories -- a redesign of old-style linked tags, a tree-based...
r1348
neko259
Tag name is now stored in the alias with default locale
r1874 def get_name(self):
neko259
Properly handle tag without aliases (though don't know how this can happen)
r2033 try:
alias = self.aliases.get(locale=DEFAULT_LOCALE)
except TagAlias.DoesNotExist:
alias = self.aliases.first()
if alias:
return alias.name
else:
# This is an extremely bad situation, somehow we have a tag without
# any alias
return 'BROKEN #{}'.format(self.id)
neko259
Tag name is now stored in the alias with default locale
r1874
neko259
Show thread, post and tag names in admin with python3
r875 def __str__(self):
neko259
Tag name is now stored in the alias with default locale
r1874 return self.get_name()
neko259
Split up tag module from post module
r385
neko259
Use threads' tags list to aggregate threads by tag
r908 def is_empty(self) -> bool:
neko259
Small updates to the tag model docstrings.
r623 """
Checks if the tag has some threads.
"""
neko259
Speed up tag list generation a bit
r606 return self.get_thread_count() == 0
neko259
Split up tag module from post module
r385
neko259
Thread status field instead of bumpable and archived fields (per BB-73)
r1414 def get_thread_count(self, status=None) -> int:
neko259
Show active threads count in the tag info
r1260 threads = self.get_threads()
neko259
Thread status field instead of bumpable and archived fields (per BB-73)
r1414 if status is not None:
threads = threads.filter(status=status)
neko259
Show active threads count in the tag info
r1260 return threads.count()
def get_active_thread_count(self) -> int:
neko259
Thread status field instead of bumpable and archived fields (per BB-73)
r1414 return self.get_thread_count(status=STATUS_ACTIVE)
neko259
Show bumplimit thread count in the tag page
r1383
def get_bumplimit_thread_count(self) -> int:
neko259
Thread status field instead of bumpable and archived fields (per BB-73)
r1414 return self.get_thread_count(status=STATUS_BUMPLIMIT)
neko259
Split up tag module from post module
r385
neko259
Changed tag description, made it plural
r1364 def get_archived_thread_count(self) -> int:
neko259
Thread status field instead of bumpable and archived fields (per BB-73)
r1414 return self.get_thread_count(status=STATUS_ARCHIVE)
neko259
Changed tag description, made it plural
r1364
neko259
Cache tag URL
r1897 @cached_result()
neko259
Use get_absolute_url instead of get_url for post, tag and thread
r1160 def get_absolute_url(self):
neko259
Tag name is now stored in the alias with default locale
r1874 return reverse('tag', kwargs={'tag_name': self.get_name()})
neko259
Added tag search. Refactored search to show any model results in a list.
r692
neko259
Use threads' tags list to aggregate threads by tag
r908 def get_threads(self):
neko259
Show related tags in the tag page
r1269 return self.thread_tags.order_by('-bump_time')
neko259
Added required tags. At least one such tag is needed to create a thread. All...
r922
def is_required(self):
return self.required
neko259
Cache tag localized names
r1888 def _get_locale_cache_key(self):
neko259
Speed up tag local cache
r2021 return [get_language()]
neko259
Cache tag localized names
r1888
@cached_result(key_method=_get_locale_cache_key)
neko259
Show localized tags under the proper letter section in all tags list. Cache localized tag name, not the whole view
r1892 def get_localized_name(self):
neko259
Tags localization
r1860 locale = get_language()
neko259
Speed up tag localization
r1889 aliases = self.aliases.filter(Q(locale=locale) | Q(locale=DEFAULT_LOCALE))
localized_tag_name = None
default_tag_name = None
neko259
Tags localization
r1860
neko259
Speed up tag localization
r1889 for alias in aliases:
if alias.locale == locale:
localized_tag_name = alias.name
elif alias.locale == DEFAULT_LOCALE:
default_tag_name = alias.name
neko259
Tag name is now stored in the alias with default locale
r1874
neko259
Simplify some expressions
r2022 return localized_tag_name or default_tag_name
neko259
Show localized tags under the proper letter section in all tags list. Cache localized tag name, not the whole view
r1892
def get_view(self):
name = self.get_localized_name()
neko259
Added required tags. At least one such tag is needed to create a thread. All...
r922 link = '<a class="tag" href="{}">{}</a>'.format(
neko259
Show the original and localized tag names
r1861 self.get_absolute_url(), name)
neko259
Added required tags. At least one such tag is needed to create a thread. All...
r922 if self.is_required():
link = '<b>{}</b>'.format(link)
return link
neko259
Fixed tag post count cache
r1107 @cached_result()
neko259
Removed TODO as html5 does not support "s" and "strike" tags any more
r960 def get_post_count(self):
neko259
Removed multitread posts 'feature'
r1704 return self.get_threads().aggregate(num_posts=Count('replies'))['num_posts']
neko259
Added tag description
r1258
def get_description(self):
return self.description
neko259
Speed up getting tag's random image
r1264
neko259
Fixed random tag image
r1417 def get_random_image_post(self, status=[STATUS_ACTIVE, STATUS_BUMPLIMIT]):
neko259
Store images as regular attachments instead of separate model
r1590 posts = boards.models.Post.objects.filter(attachments__mimetype__in=FILE_TYPES_IMAGE)\
.annotate(images_count=Count(
neko259
Removed multitread posts 'feature'
r1704 'attachments')).filter(images_count__gt=0, thread__tags__in=[self])
neko259
Thread status field instead of bumpable and archived fields (per BB-73)
r1414 if status is not None:
neko259
Fixed random tag image
r1417 posts = posts.filter(thread__status__in=status)
neko259
Don't include archived posts in the tag images
r1265 return posts.order_by('?').first()
neko259
Speed up getting tag's random image
r1264
neko259
Show related tags in the tag page
r1269 def get_related_tags(self):
neko259
Add up to 5 random related tags instead of all related list
r1270 return set(Tag.objects.filter(thread_tags__in=self.get_threads()).exclude(
neko259
Tag colors
r1338 id=self.id).order_by('?')[:RELATED_TAGS_COUNT])
@cached_result()
def get_color(self):
"""
Gets color hashed from the tag name.
"""
neko259
Tag name is now stored in the alias with default locale
r1874 return hashlib.md5(self.get_name().encode()).hexdigest()[:6]
neko259
Added categories -- a redesign of old-style linked tags, a tree-based...
r1348
def get_parent(self):
return self.parent
def get_all_parents(self):
neko259
Show all tag parents at the tag page
r1361 parents = list()
neko259
Added categories -- a redesign of old-style linked tags, a tree-based...
r1348 parent = self.get_parent()
if parent and parent not in parents:
neko259
Show all tag parents at the tag page
r1361 parents.insert(0, parent)
parents = parent.get_all_parents() + parents
neko259
Added categories -- a redesign of old-style linked tags, a tree-based...
r1348
return parents
def get_children(self):
return self.children
neko259
Added tag gallery
r1419
def get_images(self):
neko259
Store images as regular attachments instead of separate model
r1590 return Attachment.objects.filter(
neko259
Fixed issues with new images storage
r1591 attachment_posts__thread__tags__in=[self]).filter(
neko259
Remove dependency on haystack, use only built-in full text search
r1729 mimetype__in=FILE_TYPES_IMAGE).order_by('-attachment_posts__pub_time')