##// END OF EJS Templates
Add up to 5 random related tags instead of all related list
neko259 -
r1270:ba7bc8db default
parent child Browse files
Show More
@@ -1,106 +1,109 b''
1 from django.template.loader import render_to_string
1 from django.template.loader import render_to_string
2 from django.db import models
2 from django.db import models
3 from django.db.models import Count
3 from django.db.models import Count
4 from django.core.urlresolvers import reverse
4 from django.core.urlresolvers import reverse
5
5
6 from boards.models.base import Viewable
6 from boards.models.base import Viewable
7 from boards.utils import cached_result
7 from boards.utils import cached_result
8 import boards
8 import boards
9
9
10 __author__ = 'neko259'
10 __author__ = 'neko259'
11
11
12
12
13 RELATED_TAGS_COUNT = 5
14
15
13 class TagManager(models.Manager):
16 class TagManager(models.Manager):
14
17
15 def get_not_empty_tags(self):
18 def get_not_empty_tags(self):
16 """
19 """
17 Gets tags that have non-archived threads.
20 Gets tags that have non-archived threads.
18 """
21 """
19
22
20 return self.annotate(num_threads=Count('thread_tags')).filter(num_threads__gt=0)\
23 return self.annotate(num_threads=Count('thread_tags')).filter(num_threads__gt=0)\
21 .order_by('-required', 'name')
24 .order_by('-required', 'name')
22
25
23 def get_tag_url_list(self, tags: list) -> str:
26 def get_tag_url_list(self, tags: list) -> str:
24 """
27 """
25 Gets a comma-separated list of tag links.
28 Gets a comma-separated list of tag links.
26 """
29 """
27
30
28 return ', '.join([tag.get_view() for tag in tags])
31 return ', '.join([tag.get_view() for tag in tags])
29
32
30
33
31 class Tag(models.Model, Viewable):
34 class Tag(models.Model, Viewable):
32 """
35 """
33 A tag is a text node assigned to the thread. The tag serves as a board
36 A tag is a text node assigned to the thread. The tag serves as a board
34 section. There can be multiple tags for each thread
37 section. There can be multiple tags for each thread
35 """
38 """
36
39
37 objects = TagManager()
40 objects = TagManager()
38
41
39 class Meta:
42 class Meta:
40 app_label = 'boards'
43 app_label = 'boards'
41 ordering = ('name',)
44 ordering = ('name',)
42
45
43 name = models.CharField(max_length=100, db_index=True, unique=True)
46 name = models.CharField(max_length=100, db_index=True, unique=True)
44 required = models.BooleanField(default=False, db_index=True)
47 required = models.BooleanField(default=False, db_index=True)
45 description = models.TextField(blank=True)
48 description = models.TextField(blank=True)
46
49
47 def __str__(self):
50 def __str__(self):
48 return self.name
51 return self.name
49
52
50 def is_empty(self) -> bool:
53 def is_empty(self) -> bool:
51 """
54 """
52 Checks if the tag has some threads.
55 Checks if the tag has some threads.
53 """
56 """
54
57
55 return self.get_thread_count() == 0
58 return self.get_thread_count() == 0
56
59
57 def get_thread_count(self, archived=None) -> int:
60 def get_thread_count(self, archived=None) -> int:
58 threads = self.get_threads()
61 threads = self.get_threads()
59 if archived is not None:
62 if archived is not None:
60 threads = threads.filter(archived=archived)
63 threads = threads.filter(archived=archived)
61 return threads.count()
64 return threads.count()
62
65
63 def get_active_thread_count(self) -> int:
66 def get_active_thread_count(self) -> int:
64 return self.get_thread_count(archived=False)
67 return self.get_thread_count(archived=False)
65
68
66 def get_absolute_url(self):
69 def get_absolute_url(self):
67 return reverse('tag', kwargs={'tag_name': self.name})
70 return reverse('tag', kwargs={'tag_name': self.name})
68
71
69 def get_threads(self):
72 def get_threads(self):
70 return self.thread_tags.order_by('-bump_time')
73 return self.thread_tags.order_by('-bump_time')
71
74
72 def is_required(self):
75 def is_required(self):
73 return self.required
76 return self.required
74
77
75 def get_view(self):
78 def get_view(self):
76 link = '<a class="tag" href="{}">{}</a>'.format(
79 link = '<a class="tag" href="{}">{}</a>'.format(
77 self.get_absolute_url(), self.name)
80 self.get_absolute_url(), self.name)
78 if self.is_required():
81 if self.is_required():
79 link = '<b>{}</b>'.format(link)
82 link = '<b>{}</b>'.format(link)
80 return link
83 return link
81
84
82 def get_search_view(self, *args, **kwargs):
85 def get_search_view(self, *args, **kwargs):
83 return render_to_string('boards/tag.html', {
86 return render_to_string('boards/tag.html', {
84 'tag': self,
87 'tag': self,
85 })
88 })
86
89
87 @cached_result()
90 @cached_result()
88 def get_post_count(self):
91 def get_post_count(self):
89 return self.get_threads().aggregate(num_posts=Count('post'))['num_posts']
92 return self.get_threads().aggregate(num_posts=Count('post'))['num_posts']
90
93
91 def get_description(self):
94 def get_description(self):
92 return self.description
95 return self.description
93
96
94 def get_random_image_post(self, archived=False):
97 def get_random_image_post(self, archived=False):
95 posts = boards.models.Post.objects.annotate(images_count=Count(
98 posts = boards.models.Post.objects.annotate(images_count=Count(
96 'images')).filter(images_count__gt=0, threads__tags__in=[self])
99 'images')).filter(images_count__gt=0, threads__tags__in=[self])
97 if archived is not None:
100 if archived is not None:
98 posts = posts.filter(thread__archived=archived)
101 posts = posts.filter(thread__archived=archived)
99 return posts.order_by('?').first()
102 return posts.order_by('?').first()
100
103
101 def get_first_letter(self):
104 def get_first_letter(self):
102 return self.name and self.name[0] or ''
105 return self.name and self.name[0] or ''
103
106
104 def get_related_tags(self):
107 def get_related_tags(self):
105 return Tag.objects.filter(thread_tags__in=self.get_threads()).exclude(
108 return set(Tag.objects.filter(thread_tags__in=self.get_threads()).exclude(
106 id=self.id).distinct()
109 id=self.id).order_by('?')[:RELATED_TAGS_COUNT])
@@ -1,126 +1,126 b''
1 from django.shortcuts import get_object_or_404, redirect
1 from django.shortcuts import get_object_or_404, redirect
2 from django.core.urlresolvers import reverse
2 from django.core.urlresolvers import reverse
3
3
4 from boards.abstracts.settingsmanager import get_settings_manager, \
4 from boards.abstracts.settingsmanager import get_settings_manager, \
5 SETTING_FAVORITE_TAGS, SETTING_HIDDEN_TAGS
5 SETTING_FAVORITE_TAGS, SETTING_HIDDEN_TAGS
6 from boards.models import Tag, PostImage
6 from boards.models import Tag, PostImage
7 from boards.views.all_threads import AllThreadsView, DEFAULT_PAGE
7 from boards.views.all_threads import AllThreadsView, DEFAULT_PAGE
8 from boards.views.mixins import DispatcherMixin
8 from boards.views.mixins import DispatcherMixin
9 from boards.forms import ThreadForm, PlainErrorList
9 from boards.forms import ThreadForm, PlainErrorList
10
10
11 PARAM_HIDDEN_TAGS = 'hidden_tags'
11 PARAM_HIDDEN_TAGS = 'hidden_tags'
12 PARAM_TAG = 'tag'
12 PARAM_TAG = 'tag'
13 PARAM_IS_FAVORITE = 'is_favorite'
13 PARAM_IS_FAVORITE = 'is_favorite'
14 PARAM_IS_HIDDEN = 'is_hidden'
14 PARAM_IS_HIDDEN = 'is_hidden'
15 PARAM_RANDOM_IMAGE_POST = 'random_image_post'
15 PARAM_RANDOM_IMAGE_POST = 'random_image_post'
16 PARAM_RELATED_TAGS = 'related_tags'
16 PARAM_RELATED_TAGS = 'related_tags'
17
17
18
18
19 __author__ = 'neko259'
19 __author__ = 'neko259'
20
20
21
21
22 class TagView(AllThreadsView, DispatcherMixin):
22 class TagView(AllThreadsView, DispatcherMixin):
23
23
24 tag_name = None
24 tag_name = None
25
25
26 def get_threads(self):
26 def get_threads(self):
27 tag = get_object_or_404(Tag, name=self.tag_name)
27 tag = get_object_or_404(Tag, name=self.tag_name)
28
28
29 hidden_tags = self.settings_manager.get_hidden_tags()
29 hidden_tags = self.settings_manager.get_hidden_tags()
30
30
31 try:
31 try:
32 hidden_tags.remove(tag)
32 hidden_tags.remove(tag)
33 except ValueError:
33 except ValueError:
34 pass
34 pass
35
35
36 return tag.get_threads().exclude(
36 return tag.get_threads().exclude(
37 tags__in=hidden_tags)
37 tags__in=hidden_tags)
38
38
39 def get_context_data(self, **kwargs):
39 def get_context_data(self, **kwargs):
40 params = super(TagView, self).get_context_data(**kwargs)
40 params = super(TagView, self).get_context_data(**kwargs)
41
41
42 settings_manager = get_settings_manager(kwargs['request'])
42 settings_manager = get_settings_manager(kwargs['request'])
43
43
44 tag = get_object_or_404(Tag, name=self.tag_name)
44 tag = get_object_or_404(Tag, name=self.tag_name)
45 params[PARAM_TAG] = tag
45 params[PARAM_TAG] = tag
46
46
47 fav_tag_names = settings_manager.get_setting(SETTING_FAVORITE_TAGS)
47 fav_tag_names = settings_manager.get_setting(SETTING_FAVORITE_TAGS)
48 hidden_tag_names = settings_manager.get_setting(SETTING_HIDDEN_TAGS)
48 hidden_tag_names = settings_manager.get_setting(SETTING_HIDDEN_TAGS)
49
49
50 params[PARAM_IS_FAVORITE] = fav_tag_names is not None and tag.name in fav_tag_names
50 params[PARAM_IS_FAVORITE] = fav_tag_names is not None and tag.name in fav_tag_names
51 params[PARAM_IS_HIDDEN] = hidden_tag_names is not None and tag.name in hidden_tag_names
51 params[PARAM_IS_HIDDEN] = hidden_tag_names is not None and tag.name in hidden_tag_names
52
52
53 params[PARAM_RANDOM_IMAGE_POST] = tag.get_random_image_post()
53 params[PARAM_RANDOM_IMAGE_POST] = tag.get_random_image_post()
54 params[PARAM_RELATED_TAGS] = tag.get_related_tags().all()
54 params[PARAM_RELATED_TAGS] = tag.get_related_tags()
55
55
56 return params
56 return params
57
57
58 def get_previous_page_link(self, current_page):
58 def get_previous_page_link(self, current_page):
59 return reverse('tag', kwargs={
59 return reverse('tag', kwargs={
60 'tag_name': self.tag_name,
60 'tag_name': self.tag_name,
61 }) + '?page=' + str(current_page.previous_page_number())
61 }) + '?page=' + str(current_page.previous_page_number())
62
62
63 def get_next_page_link(self, current_page):
63 def get_next_page_link(self, current_page):
64 return reverse('tag', kwargs={
64 return reverse('tag', kwargs={
65 'tag_name': self.tag_name,
65 'tag_name': self.tag_name,
66 }) + '?page=' + str(current_page.next_page_number())
66 }) + '?page=' + str(current_page.next_page_number())
67
67
68 def get(self, request, tag_name, form=None):
68 def get(self, request, tag_name, form=None):
69 self.tag_name = tag_name
69 self.tag_name = tag_name
70
70
71 return super(TagView, self).get(request, form)
71 return super(TagView, self).get(request, form)
72
72
73
73
74 def post(self, request, tag_name):
74 def post(self, request, tag_name):
75 self.tag_name = tag_name
75 self.tag_name = tag_name
76
76
77 if 'method' in request.POST:
77 if 'method' in request.POST:
78 self.dispatch_method(request)
78 self.dispatch_method(request)
79 form = None
79 form = None
80
80
81 return redirect('tag', tag_name)
81 return redirect('tag', tag_name)
82 else:
82 else:
83 form = ThreadForm(request.POST, request.FILES,
83 form = ThreadForm(request.POST, request.FILES,
84 error_class=PlainErrorList)
84 error_class=PlainErrorList)
85 form.session = request.session
85 form.session = request.session
86
86
87 if form.is_valid():
87 if form.is_valid():
88 return self.create_thread(request, form)
88 return self.create_thread(request, form)
89 if form.need_to_ban:
89 if form.need_to_ban:
90 # Ban user because he is suspected to be a bot
90 # Ban user because he is suspected to be a bot
91 self._ban_current_user(request)
91 self._ban_current_user(request)
92
92
93 return self.get(request, tag_name, page, form)
93 return self.get(request, tag_name, page, form)
94
94
95 def subscribe(self, request):
95 def subscribe(self, request):
96 tag = get_object_or_404(Tag, name=self.tag_name)
96 tag = get_object_or_404(Tag, name=self.tag_name)
97
97
98 settings_manager = get_settings_manager(request)
98 settings_manager = get_settings_manager(request)
99 settings_manager.add_fav_tag(tag)
99 settings_manager.add_fav_tag(tag)
100
100
101 def unsubscribe(self, request):
101 def unsubscribe(self, request):
102 tag = get_object_or_404(Tag, name=self.tag_name)
102 tag = get_object_or_404(Tag, name=self.tag_name)
103
103
104 settings_manager = get_settings_manager(request)
104 settings_manager = get_settings_manager(request)
105 settings_manager.del_fav_tag(tag)
105 settings_manager.del_fav_tag(tag)
106
106
107 def hide(self, request):
107 def hide(self, request):
108 """
108 """
109 Adds tag to user's hidden tags. Threads with this tag will not be
109 Adds tag to user's hidden tags. Threads with this tag will not be
110 shown.
110 shown.
111 """
111 """
112
112
113 tag = get_object_or_404(Tag, name=self.tag_name)
113 tag = get_object_or_404(Tag, name=self.tag_name)
114
114
115 settings_manager = get_settings_manager(request)
115 settings_manager = get_settings_manager(request)
116 settings_manager.add_hidden_tag(tag)
116 settings_manager.add_hidden_tag(tag)
117
117
118 def unhide(self, request):
118 def unhide(self, request):
119 """
119 """
120 Removed tag from user's hidden tags.
120 Removed tag from user's hidden tags.
121 """
121 """
122
122
123 tag = get_object_or_404(Tag, name=self.tag_name)
123 tag = get_object_or_404(Tag, name=self.tag_name)
124
124
125 settings_manager = get_settings_manager(request)
125 settings_manager = get_settings_manager(request)
126 settings_manager.del_hidden_tag(tag)
126 settings_manager.del_hidden_tag(tag)
General Comments 0
You need to be logged in to leave comments. Login now