##// END OF EJS Templates
Tag name is now stored in the alias with default locale
neko259 -
r1874:aaf6b563 default
parent child Browse files
Show More
@@ -0,0 +1,23 b''
1 # -*- coding: utf-8 -*-
2 # Generated by Django 1.10.5 on 2017-03-01 08:53
3 from __future__ import unicode_literals
4
5 from django.db import migrations
6
7
8 class Migration(migrations.Migration):
9
10 def tag_name_to_alias(apps, schema_editor):
11 Tag = apps.get_model('boards', 'Tag')
12 TagAlias = apps.get_model('boards', 'TagAlias')
13
14 for tag in Tag.objects.all():
15 TagAlias.objects.get_or_create(name=tag.name, locale='default', parent=tag)
16
17 dependencies = [
18 ('boards', '0061_auto_20170227_1739'),
19 ]
20
21 operations = [
22 migrations.RunPython(tag_name_to_alias),
23 ]
@@ -0,0 +1,23 b''
1 # -*- coding: utf-8 -*-
2 # Generated by Django 1.10.5 on 2017-03-01 08:58
3 from __future__ import unicode_literals
4
5 from django.db import migrations
6
7
8 class Migration(migrations.Migration):
9
10 dependencies = [
11 ('boards', '0062_auto_20170301_1053'),
12 ]
13
14 operations = [
15 migrations.AlterModelOptions(
16 name='tag',
17 options={},
18 ),
19 migrations.RemoveField(
20 model_name='tag',
21 name='name',
22 ),
23 ]
@@ -78,49 +78,49 b' class SettingsManager:'
78 tag_names = self.get_setting(SETTING_FAVORITE_TAGS)
78 tag_names = self.get_setting(SETTING_FAVORITE_TAGS)
79 tags = []
79 tags = []
80 if tag_names:
80 if tag_names:
81 tags = list(Tag.objects.filter(name__in=tag_names))
81 tags = list(Tag.objects.filter(aliases__name__in=tag_names))
82 return tags
82 return tags
83
83
84 def add_fav_tag(self, tag):
84 def add_fav_tag(self, tag):
85 tags = self.get_setting(SETTING_FAVORITE_TAGS)
85 tags = self.get_setting(SETTING_FAVORITE_TAGS)
86 if not tags:
86 if not tags:
87 tags = [tag.name]
87 tags = [tag.get_name()]
88 else:
88 else:
89 if not tag.name in tags:
89 if not tag.get_name() in tags:
90 tags.append(tag.name)
90 tags.append(tag.get_name())
91
91
92 tags.sort()
92 tags.sort()
93 self.set_setting(SETTING_FAVORITE_TAGS, tags)
93 self.set_setting(SETTING_FAVORITE_TAGS, tags)
94
94
95 def del_fav_tag(self, tag):
95 def del_fav_tag(self, tag):
96 tags = self.get_setting(SETTING_FAVORITE_TAGS)
96 tags = self.get_setting(SETTING_FAVORITE_TAGS)
97 if tag.name in tags:
97 if tag.get_name() in tags:
98 tags.remove(tag.name)
98 tags.remove(tag.get_name())
99 self.set_setting(SETTING_FAVORITE_TAGS, tags)
99 self.set_setting(SETTING_FAVORITE_TAGS, tags)
100
100
101 def get_hidden_tags(self) -> list:
101 def get_hidden_tags(self) -> list:
102 tag_names = self.get_setting(SETTING_HIDDEN_TAGS)
102 tag_names = self.get_setting(SETTING_HIDDEN_TAGS)
103 tags = []
103 tags = []
104 if tag_names:
104 if tag_names:
105 tags = list(Tag.objects.filter(name__in=tag_names))
105 tags = list(Tag.objects.filter(aliases__name__in=tag_names))
106
106
107 return tags
107 return tags
108
108
109 def add_hidden_tag(self, tag):
109 def add_hidden_tag(self, tag):
110 tags = self.get_setting(SETTING_HIDDEN_TAGS)
110 tags = self.get_setting(SETTING_HIDDEN_TAGS)
111 if not tags:
111 if not tags:
112 tags = [tag.name]
112 tags = [tag.get_name()]
113 else:
113 else:
114 if not tag.name in tags:
114 if not tag.get_name() in tags:
115 tags.append(tag.name)
115 tags.append(tag.get_name())
116
116
117 tags.sort()
117 tags.sort()
118 self.set_setting(SETTING_HIDDEN_TAGS, tags)
118 self.set_setting(SETTING_HIDDEN_TAGS, tags)
119
119
120 def del_hidden_tag(self, tag):
120 def del_hidden_tag(self, tag):
121 tags = self.get_setting(SETTING_HIDDEN_TAGS)
121 tags = self.get_setting(SETTING_HIDDEN_TAGS)
122 if tag.name in tags:
122 if tag.get_name() in tags:
123 tags.remove(tag.name)
123 tags.remove(tag.get_name())
124 self.set_setting(SETTING_HIDDEN_TAGS, tags)
124 self.set_setting(SETTING_HIDDEN_TAGS, tags)
125
125
126 def get_fav_threads(self) -> dict:
126 def get_fav_threads(self) -> dict:
@@ -83,12 +83,16 b' class TagAdmin(admin.ModelAdmin):'
83 def display_children(self, obj: Tag):
83 def display_children(self, obj: Tag):
84 return ', '.join([str(child) for child in obj.get_children().all()])
84 return ', '.join([str(child) for child in obj.get_children().all()])
85
85
86 def name(self, obj: Tag):
87 return obj.get_name()
88
86 def save_model(self, request, obj, form, change):
89 def save_model(self, request, obj, form, change):
87 super().save_model(request, obj, form, change)
90 super().save_model(request, obj, form, change)
88 for thread in obj.get_threads().all():
91 for thread in obj.get_threads().all():
89 thread.refresh_tags()
92 thread.refresh_tags()
90 list_display = ('name', 'thread_count', 'display_children')
93 list_display = ('name', 'thread_count', 'display_children')
91 search_fields = ('name',)
94 search_fields = ('name',)
95 readonly_fields = ('name',)
92
96
93
97
94 @admin.register(TagAlias)
98 @admin.register(TagAlias)
@@ -472,15 +472,10 b' class ThreadForm(PostForm):'
472 tag_name = tag_string.strip().lower()
472 tag_name = tag_string.strip().lower()
473 if tag_name == default_tag_name:
473 if tag_name == default_tag_name:
474 required_tag_exists = True
474 required_tag_exists = True
475 tag, created = Tag.objects.get_or_create(
475 tag, created = Tag.objects.get_or_create_with_alias(
476 name=tag_name, required=True)
476 name=tag_name, required=True)
477 else:
477 else:
478 tag = Tag.objects.get_by_alias(tag_name)
478 tag, created = Tag.objects.get_or_create_with_alias(name=tag_name)
479 if tag:
480 created = False
481 else:
482 tag, created = Tag.objects.get_or_create(
483 name=tag_name)
484 tag_set.add(tag)
479 tag_set.add(tag)
485
480
486 # If this is a new tag, don't check for its parents because nobody
481 # If this is a new tag, don't check for its parents because nobody
@@ -18,6 +18,7 b' import boards'
18
18
19
19
20 RELATED_TAGS_COUNT = 5
20 RELATED_TAGS_COUNT = 5
21 DEFAULT_LOCALE = 'default'
21
22
22
23
23 class TagAlias(models.Model, Viewable):
24 class TagAlias(models.Model, Viewable):
@@ -38,8 +39,10 b' class TagManager(models.Manager):'
38 Gets tags that have non-archived threads.
39 Gets tags that have non-archived threads.
39 """
40 """
40
41
41 return self.annotate(num_threads=Count('thread_tags')).filter(num_threads__gt=0)\
42 return self.annotate(num_threads=Count('thread_tags'))\
42 .order_by('name')
43 .filter(num_threads__gt=0)\
44 .filter(aliases__locale=DEFAULT_LOCALE)\
45 .order_by('aliases__name')
43
46
44 def get_tag_url_list(self, tags: list) -> str:
47 def get_tag_url_list(self, tags: list) -> str:
45 """
48 """
@@ -56,6 +59,15 b' class TagManager(models.Manager):'
56
59
57 return tag
60 return tag
58
61
62 def get_or_create_with_alias(self, name, required=False):
63 tag = self.get_by_alias(name)
64 created = False
65 if not tag:
66 tag = self.create(required=required)
67 TagAlias.objects.create(name=alias, locale=DEFAULT_LOCALE, parent=tag)
68 created = True
69 return tag, created
70
59
71
60 class Tag(models.Model, Viewable):
72 class Tag(models.Model, Viewable):
61 """
73 """
@@ -67,17 +79,19 b' class Tag(models.Model, Viewable):'
67
79
68 class Meta:
80 class Meta:
69 app_label = 'boards'
81 app_label = 'boards'
70 ordering = ('name',)
71
82
72 name = models.CharField(max_length=100, db_index=True, unique=True)
73 required = models.BooleanField(default=False, db_index=True)
83 required = models.BooleanField(default=False, db_index=True)
74 description = models.TextField(blank=True)
84 description = models.TextField(blank=True)
75
85
76 parent = models.ForeignKey('Tag', null=True, blank=True,
86 parent = models.ForeignKey('Tag', null=True, blank=True,
77 related_name='children')
87 related_name='children')
78
88
89 @cached_result()
90 def get_name(self):
91 return self.aliases.get(locale=DEFAULT_LOCALE).name
92
79 def __str__(self):
93 def __str__(self):
80 return self.name
94 return self.get_name()
81
95
82 def is_empty(self) -> bool:
96 def is_empty(self) -> bool:
83 """
97 """
@@ -102,7 +116,7 b' class Tag(models.Model, Viewable):'
102 return self.get_thread_count(status=STATUS_ARCHIVE)
116 return self.get_thread_count(status=STATUS_ARCHIVE)
103
117
104 def get_absolute_url(self):
118 def get_absolute_url(self):
105 return reverse('tag', kwargs={'tag_name': self.name})
119 return reverse('tag', kwargs={'tag_name': self.get_name()})
106
120
107 def get_threads(self):
121 def get_threads(self):
108 return self.thread_tags.order_by('-bump_time')
122 return self.thread_tags.order_by('-bump_time')
@@ -118,7 +132,9 b' class Tag(models.Model, Viewable):'
118 except TagAlias.DoesNotExist:
132 except TagAlias.DoesNotExist:
119 localized_tag_name = ''
133 localized_tag_name = ''
120
134
121 name = '{} ({})'.format(self.name, localized_tag_name) if localized_tag_name else self.name
135 default_name = self.get_name()
136
137 name = '{} ({})'.format(default_name, localized_tag_name) if localized_tag_name else default_name
122 link = '<a class="tag" href="{}">{}</a>'.format(
138 link = '<a class="tag" href="{}">{}</a>'.format(
123 self.get_absolute_url(), name)
139 self.get_absolute_url(), name)
124 if self.is_required():
140 if self.is_required():
@@ -141,7 +157,8 b' class Tag(models.Model, Viewable):'
141 return posts.order_by('?').first()
157 return posts.order_by('?').first()
142
158
143 def get_first_letter(self):
159 def get_first_letter(self):
144 return self.name and self.name[0] or ''
160 name = self.get_name()
161 return name and name[0] or ''
145
162
146 def get_related_tags(self):
163 def get_related_tags(self):
147 return set(Tag.objects.filter(thread_tags__in=self.get_threads()).exclude(
164 return set(Tag.objects.filter(thread_tags__in=self.get_threads()).exclude(
@@ -152,7 +169,7 b' class Tag(models.Model, Viewable):'
152 """
169 """
153 Gets color hashed from the tag name.
170 Gets color hashed from the tag name.
154 """
171 """
155 return hashlib.md5(self.name.encode()).hexdigest()[:6]
172 return hashlib.md5(self.get_name().encode()).hexdigest()[:6]
156
173
157 def get_parent(self):
174 def get_parent(self):
158 return self.parent
175 return self.parent
@@ -10,7 +10,7 b' from boards import settings'
10 from boards.models import STATUS_BUMPLIMIT, STATUS_ACTIVE, STATUS_ARCHIVE
10 from boards.models import STATUS_BUMPLIMIT, STATUS_ACTIVE, STATUS_ARCHIVE
11 from boards.models.attachment import FILE_TYPES_IMAGE
11 from boards.models.attachment import FILE_TYPES_IMAGE
12 from boards.models.post import Post
12 from boards.models.post import Post
13 from boards.models.tag import Tag
13 from boards.models.tag import Tag, DEFAULT_LOCALE
14 from boards.utils import cached_result, datetime_to_epoch
14 from boards.utils import cached_result, datetime_to_epoch
15
15
16 FAV_THREAD_NO_UPDATES = -1
16 FAV_THREAD_NO_UPDATES = -1
@@ -103,7 +103,7 b' class Thread(models.Model):'
103 Gets a sorted tag list.
103 Gets a sorted tag list.
104 """
104 """
105
105
106 return self.tags.order_by('name')
106 return self.tags.filter(aliases__locale=DEFAULT_LOCALE).order_by('aliases__name')
107
107
108 def bump(self):
108 def bump(self):
109 """
109 """
@@ -230,7 +230,7 b' class Thread(models.Model):'
230 return 'T#{}'.format(self.id)
230 return 'T#{}'.format(self.id)
231
231
232 def get_tag_url_list(self) -> list:
232 def get_tag_url_list(self) -> list:
233 return boards.models.Tag.objects.get_tag_url_list(self.get_tags())
233 return boards.models.Tag.objects.get_tag_url_list(self.get_tags().all())
234
234
235 def update_posts_time(self, exclude_posts=None):
235 def update_posts_time(self, exclude_posts=None):
236 last_edit_time = self.last_edit_time
236 last_edit_time = self.last_edit_time
@@ -9,7 +9,7 b''
9 <meta name="robots" content="noindex">
9 <meta name="robots" content="noindex">
10
10
11 {% if tag %}
11 {% if tag %}
12 <title>{{ tag.name }} - {{ site_name }}</title>
12 <title>{{ tag.get_name }} - {{ site_name }}</title>
13 {% else %}
13 {% else %}
14 <title>{{ site_name }}</title>
14 <title>{{ site_name }}</title>
15 {% endif %}
15 {% endif %}
@@ -57,21 +57,21 b''
57 <div class="moderator_info"><a href="{% url 'admin:boards_tag_change' tag.id %}">{% trans 'Edit tag' %}</a></div>
57 <div class="moderator_info"><a href="{% url 'admin:boards_tag_change' tag.id %}">{% trans 'Edit tag' %}</a></div>
58 {% endif %}
58 {% endif %}
59 <p>
59 <p>
60 <form action="{% url 'tag' tag.name %}" method="post" class="post-button-form">
60 <form action="{% url 'tag' tag.get_name %}" method="post" class="post-button-form">
61 {% if is_favorite %}
61 {% if is_favorite %}
62 <button name="method" value="unsubscribe" class="fav">β˜… {% trans "Remove from favorites" %}</button>
62 <button name="method" value="unsubscribe" class="fav">β˜… {% trans "Remove from favorites" %}</button>
63 {% else %}
63 {% else %}
64 <button name="method" value="subscribe" class="not_fav">β˜… {% trans "Add to favorites" %}</button>
64 <button name="method" value="subscribe" class="not_fav">β˜… {% trans "Add to favorites" %}</button>
65 {% endif %}
65 {% endif %}
66 </form>
66 </form>
67 <form action="{% url 'tag' tag.name %}" method="post" class="post-button-form">
67 <form action="{% url 'tag' tag.get_name %}" method="post" class="post-button-form">
68 {% if is_hidden %}
68 {% if is_hidden %}
69 <button name="method" value="unhide" class="fav">{% trans "Show" %}</button>
69 <button name="method" value="unhide" class="fav">{% trans "Show" %}</button>
70 {% else %}
70 {% else %}
71 <button name="method" value="hide" class="not_fav">{% trans "Hide" %}</button>
71 <button name="method" value="hide" class="not_fav">{% trans "Hide" %}</button>
72 {% endif %}
72 {% endif %}
73 </form>
73 </form>
74 <a href="{% url 'tag_gallery' tag.name %}">{% trans 'Gallery' %}</a>
74 <a href="{% url 'tag_gallery' tag.get_name %}">{% trans 'Gallery' %}</a>
75 </p>
75 </p>
76 {% if tag.get_description %}
76 {% if tag.get_description %}
77 <p>{{ tag.get_description|safe }}</p>
77 <p>{{ tag.get_description|safe }}</p>
@@ -10,7 +10,7 b' from django.views.decorators.csrf import'
10 from boards.abstracts.settingsmanager import get_settings_manager
10 from boards.abstracts.settingsmanager import get_settings_manager
11 from boards.forms import PostForm, PlainErrorList
11 from boards.forms import PostForm, PlainErrorList
12 from boards.mdx_neboard import Parser
12 from boards.mdx_neboard import Parser
13 from boards.models import Post, Thread, Tag, Attachment
13 from boards.models import Post, Thread, Tag, Attachment, TagAlias
14 from boards.models.thread import STATUS_ARCHIVE
14 from boards.models.thread import STATUS_ARCHIVE
15 from boards.models.user import Notification
15 from boards.models.user import Notification
16 from boards.utils import datetime_to_epoch
16 from boards.utils import datetime_to_epoch
@@ -178,7 +178,7 b' def api_get_tags(request):'
178
178
179 # TODO Get favorite tags for the given user ID
179 # TODO Get favorite tags for the given user ID
180
180
181 tags = Tag.objects.get_not_empty_tags()
181 tags = TagAlias.objects.all()
182
182
183 term = request.GET.get('term')
183 term = request.GET.get('term')
184 if term is not None:
184 if term is not None:
@@ -9,6 +9,7 b' from django.views.decorators.csrf import'
9 from boards import settings
9 from boards import settings
10 from boards.models import Post
10 from boards.models import Post
11 from boards.models import Tag, Attachment, STATUS_ACTIVE
11 from boards.models import Tag, Attachment, STATUS_ACTIVE
12 from boards.models.tag import DEFAULT_LOCALE
12 from boards.views.base import BaseBoardView
13 from boards.views.base import BaseBoardView
13
14
14 PARAM_SECTION_STR = 'section_str'
15 PARAM_SECTION_STR = 'section_str'
@@ -23,7 +24,8 b' class LandingView(BaseBoardView):'
23 params = dict()
24 params = dict()
24
25
25 params[PARAM_SECTION_STR] = Tag.objects.get_tag_url_list(
26 params[PARAM_SECTION_STR] = Tag.objects.get_tag_url_list(
26 Tag.objects.filter(required=True))
27 Tag.objects.filter(required=True).filter(
28 aliases__locale=DEFAULT_LOCALE).order_by('aliases__name'))
27
29
28 today = datetime.now() - timedelta(1)
30 today = datetime.now() - timedelta(1)
29 ops = Post.objects.filter(thread__replies__pub_time__gt=today, opening=True, thread__status=STATUS_ACTIVE)\
31 ops = Post.objects.filter(thread__replies__pub_time__gt=today, opening=True, thread__status=STATUS_ACTIVE)\
@@ -3,7 +3,7 b' from django.core.urlresolvers import rev'
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
6 from boards.models import Tag, TagAlias
7 from boards.views.all_threads import AllThreadsView
7 from boards.views.all_threads import AllThreadsView
8 from boards.views.mixins import DispatcherMixin, PARAMETER_METHOD
8 from boards.views.mixins import DispatcherMixin, PARAMETER_METHOD
9 from boards.forms import ThreadForm, PlainErrorList
9 from boards.forms import ThreadForm, PlainErrorList
@@ -24,7 +24,8 b' class TagView(AllThreadsView, Dispatcher'
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_alias = get_object_or_404(TagAlias, name=self.tag_name)
28 tag = tag_alias.parent
28
29
29 hidden_tags = self.settings_manager.get_hidden_tags()
30 hidden_tags = self.settings_manager.get_hidden_tags()
30
31
@@ -41,14 +42,15 b' class TagView(AllThreadsView, Dispatcher'
41
42
42 settings_manager = get_settings_manager(kwargs['request'])
43 settings_manager = get_settings_manager(kwargs['request'])
43
44
44 tag = get_object_or_404(Tag, name=self.tag_name)
45 tag_alias = get_object_or_404(TagAlias, name=self.tag_name)
46 tag = tag_alias.parent
45 params[PARAM_TAG] = tag
47 params[PARAM_TAG] = tag
46
48
47 fav_tag_names = settings_manager.get_setting(SETTING_FAVORITE_TAGS)
49 fav_tag_names = settings_manager.get_setting(SETTING_FAVORITE_TAGS)
48 hidden_tag_names = settings_manager.get_setting(SETTING_HIDDEN_TAGS)
50 hidden_tag_names = settings_manager.get_setting(SETTING_HIDDEN_TAGS)
49
51
50 params[PARAM_IS_FAVORITE] = fav_tag_names is not None and tag.name in fav_tag_names
52 params[PARAM_IS_FAVORITE] = fav_tag_names is not None and tag.get_name() in fav_tag_names
51 params[PARAM_IS_HIDDEN] = hidden_tag_names is not None and tag.name in hidden_tag_names
53 params[PARAM_IS_HIDDEN] = hidden_tag_names is not None and tag.get_name() in hidden_tag_names
52
54
53 params[PARAM_RANDOM_IMAGE_POST] = tag.get_random_image_post()
55 params[PARAM_RANDOM_IMAGE_POST] = tag.get_random_image_post()
54 params[PARAM_RELATED_TAGS] = tag.get_related_tags()
56 params[PARAM_RELATED_TAGS] = tag.get_related_tags()
@@ -85,13 +87,15 b' class TagView(AllThreadsView, Dispatcher'
85 return self.get(request, tag_name, form)
87 return self.get(request, tag_name, form)
86
88
87 def subscribe(self, request):
89 def subscribe(self, request):
88 tag = get_object_or_404(Tag, name=self.tag_name)
90 alias = get_object_or_404(TagAlias, name=self.tag_name)
91 tag = alias.parent
89
92
90 settings_manager = get_settings_manager(request)
93 settings_manager = get_settings_manager(request)
91 settings_manager.add_fav_tag(tag)
94 settings_manager.add_fav_tag(tag)
92
95
93 def unsubscribe(self, request):
96 def unsubscribe(self, request):
94 tag = get_object_or_404(Tag, name=self.tag_name)
97 alias = get_object_or_404(TagAlias, name=self.tag_name)
98 tag = alias.parent
95
99
96 settings_manager = get_settings_manager(request)
100 settings_manager = get_settings_manager(request)
97 settings_manager.del_fav_tag(tag)
101 settings_manager.del_fav_tag(tag)
@@ -102,7 +106,8 b' class TagView(AllThreadsView, Dispatcher'
102 shown.
106 shown.
103 """
107 """
104
108
105 tag = get_object_or_404(Tag, name=self.tag_name)
109 alias = get_object_or_404(TagAlias, name=self.tag_name)
110 tag = alias.parent
106
111
107 settings_manager = get_settings_manager(request)
112 settings_manager = get_settings_manager(request)
108 settings_manager.add_hidden_tag(tag)
113 settings_manager.add_hidden_tag(tag)
@@ -112,7 +117,8 b' class TagView(AllThreadsView, Dispatcher'
112 Removed tag from user's hidden tags.
117 Removed tag from user's hidden tags.
113 """
118 """
114
119
115 tag = get_object_or_404(Tag, name=self.tag_name)
120 alias = get_object_or_404(TagAlias, name=self.tag_name)
121 tag = alias.parent
116
122
117 settings_manager = get_settings_manager(request)
123 settings_manager = get_settings_manager(request)
118 settings_manager.del_hidden_tag(tag)
124 settings_manager.del_hidden_tag(tag)
General Comments 0
You need to be logged in to leave comments. Login now