Show More
@@ -38,7 +38,7 b' class PostForm(forms.Form):' | |||||
38 |
|
38 | |||
39 |
|
39 | |||
40 | class ThreadForm(PostForm): |
|
40 | class ThreadForm(PostForm): | |
41 | INVALID_TAG_CHARACTERS = ['+', '/', '&', '=', '?', '-'] |
|
41 | INVALID_TAG_CHARACTERS = ['+', '/', '&', '=', '?', '-', '.', ','] | |
42 |
|
42 | |||
43 | tags = forms.CharField(max_length=100) |
|
43 | tags = forms.CharField(max_length=100) | |
44 |
|
44 |
@@ -137,6 +137,14 b' class TagManager(models.Manager):' | |||||
137 |
|
137 | |||
138 | return tags |
|
138 | return tags | |
139 |
|
139 | |||
|
140 | def get_popular_tags(self): | |||
|
141 | all_tags = self.get_not_empty_tags() | |||
|
142 | ||||
|
143 | sorted_tags = sorted(all_tags, key=lambda tag: tag.get_popularity(), | |||
|
144 | reverse=True) | |||
|
145 | ||||
|
146 | return sorted_tags[:settings.POPULAR_TAGS] | |||
|
147 | ||||
140 |
|
148 | |||
141 | class Tag(models.Model): |
|
149 | class Tag(models.Model): | |
142 | """ |
|
150 | """ | |
@@ -160,6 +168,14 b' class Tag(models.Model):' | |||||
160 | posts_with_tag = Post.objects.get_threads(tag=self) |
|
168 | posts_with_tag = Post.objects.get_threads(tag=self) | |
161 | return len(posts_with_tag) |
|
169 | return len(posts_with_tag) | |
162 |
|
170 | |||
|
171 | def get_popularity(self): | |||
|
172 | posts_with_tag = Post.objects.get_threads(tag=self) | |||
|
173 | reply_count = 0 | |||
|
174 | for post in posts_with_tag: | |||
|
175 | reply_count += post.get_reply_count() | |||
|
176 | ||||
|
177 | return reply_count | |||
|
178 | ||||
163 |
|
179 | |||
164 | class Post(models.Model): |
|
180 | class Post(models.Model): | |
165 | """A post is a message.""" |
|
181 | """A post is a message.""" |
@@ -17,14 +17,6 b' html {' | |||||
17 | color: #afdcec; |
|
17 | color: #afdcec; | |
18 | } |
|
18 | } | |
19 |
|
19 | |||
20 | .link:hover, a:hover { |
|
|||
21 | color: #fff380; |
|
|||
22 | } |
|
|||
23 |
|
||||
24 | .post_id:hover { |
|
|||
25 | color: #ccc555; |
|
|||
26 | } |
|
|||
27 |
|
||||
28 | .block { |
|
20 | .block { | |
29 | display: inline-block; |
|
21 | display: inline-block; | |
30 | vertical-align: top; |
|
22 | vertical-align: top; | |
@@ -34,10 +26,6 b' html {' | |||||
34 | color: #b4cfec; |
|
26 | color: #b4cfec; | |
35 | } |
|
27 | } | |
36 |
|
28 | |||
37 | .tag:hover { |
|
|||
38 | color: #d0edb4; |
|
|||
39 | } |
|
|||
40 |
|
||||
41 | .post_id { |
|
29 | .post_id { | |
42 | color: #fff380; |
|
30 | color: #fff380; | |
43 | } |
|
31 | } | |
@@ -192,4 +180,8 b' blockquote {' | |||||
192 |
|
180 | |||
193 | .comment { |
|
181 | .comment { | |
194 | color: darkseagreen; |
|
182 | color: darkseagreen; | |
195 | } No newline at end of file |
|
183 | } | |
|
184 | ||||
|
185 | a:hover { | |||
|
186 | text-decoration: underline; | |||
|
187 | } |
@@ -21,4 +21,5 b" urlpatterns = patterns(''," | |||||
21 | url(r'^thread/(?P<post_id>\w+)/$', views.thread, name='thread'), |
|
21 | url(r'^thread/(?P<post_id>\w+)/$', views.thread, name='thread'), | |
22 | # /boards/theme/theme_name/ |
|
22 | # /boards/theme/theme_name/ | |
23 | url(r'^settings$', views.settings, name='settings'), |
|
23 | url(r'^settings$', views.settings, name='settings'), | |
|
24 | url(r'^tags$', views.all_tags, name='tags'), | |||
24 | ) |
|
25 | ) |
@@ -20,7 +20,7 b' def index(request, page=0):' | |||||
20 | # TODO Get rid of the duplicate code in index and tag views |
|
20 | # TODO Get rid of the duplicate code in index and tag views | |
21 | context['threads'] = None if len(threads) == 0 else threads |
|
21 | context['threads'] = None if len(threads) == 0 else threads | |
22 | context['form'] = forms.ThreadForm() |
|
22 | context['form'] = forms.ThreadForm() | |
23 |
context['tags'] = Tag.objects.get_ |
|
23 | context['tags'] = Tag.objects.get_popular_tags() | |
24 | context['theme'] = _get_theme(request) |
|
24 | context['theme'] = _get_theme(request) | |
25 | context['pages'] = range(Post.objects.get_thread_page_count()) |
|
25 | context['pages'] = range(Post.objects.get_thread_page_count()) | |
26 |
|
26 | |||
@@ -94,7 +94,7 b' def tag(request, tag_name, page=0):' | |||||
94 | context = RequestContext(request) |
|
94 | context = RequestContext(request) | |
95 | context['threads'] = None if len(threads) == 0 else threads |
|
95 | context['threads'] = None if len(threads) == 0 else threads | |
96 | context['tag'] = tag_name |
|
96 | context['tag'] = tag_name | |
97 |
context['tags'] = Tag.objects.get_ |
|
97 | context['tags'] = Tag.objects.get_popular_tags() | |
98 | context['theme'] = _get_theme(request) |
|
98 | context['theme'] = _get_theme(request) | |
99 | context['pages'] = range(Post.objects.get_thread_page_count(tag=tag)) |
|
99 | context['pages'] = range(Post.objects.get_thread_page_count(tag=tag)) | |
100 |
|
100 | |||
@@ -117,7 +117,7 b' def thread(request, post_id):' | |||||
117 |
|
117 | |||
118 | context['posts'] = posts |
|
118 | context['posts'] = posts | |
119 | context['form'] = forms.PostForm() |
|
119 | context['form'] = forms.PostForm() | |
120 |
context['tags'] = Tag.objects.get_ |
|
120 | context['tags'] = Tag.objects.get_popular_tags() | |
121 | context['theme'] = _get_theme(request) |
|
121 | context['theme'] = _get_theme(request) | |
122 |
|
122 | |||
123 | return render(request, 'thread.html', context) |
|
123 | return render(request, 'thread.html', context) | |
@@ -165,11 +165,20 b' def settings(request):' | |||||
165 | selected_theme = _get_theme(request) |
|
165 | selected_theme = _get_theme(request) | |
166 | form = SettingsForm(initial={'theme': selected_theme}) |
|
166 | form = SettingsForm(initial={'theme': selected_theme}) | |
167 | context['form'] = form |
|
167 | context['form'] = form | |
168 |
context['tags'] = Tag.objects.get_ |
|
168 | context['tags'] = Tag.objects.get_popular_tags() | |
169 | context['theme'] = _get_theme(request) |
|
169 | context['theme'] = _get_theme(request) | |
170 |
|
170 | |||
171 | return render(request, 'settings.html', context) |
|
171 | return render(request, 'settings.html', context) | |
172 |
|
172 | |||
173 |
|
173 | |||
|
174 | def all_tags(request): | |||
|
175 | context = RequestContext(request) | |||
|
176 | context['tags'] = Tag.objects.get_popular_tags() | |||
|
177 | context['theme'] = _get_theme(request) | |||
|
178 | context['all_tags'] = Tag.objects.get_not_empty_tags() | |||
|
179 | ||||
|
180 | return render(request, 'tags.html', context) | |||
|
181 | ||||
|
182 | ||||
174 | def _get_theme(request): |
|
183 | def _get_theme(request): | |
175 | return request.session.get('theme', neboard.settings.DEFAULT_THEME) No newline at end of file |
|
184 | return request.session.get('theme', neboard.settings.DEFAULT_THEME) |
@@ -169,6 +169,9 b' LOGGING = {' | |||||
169 | } |
|
169 | } | |
170 | } |
|
170 | } | |
171 |
|
171 | |||
|
172 | MARKUP_FIELD_TYPES = ( | |||
|
173 | ('markdown', markdown_extended), | |||
|
174 | ) | |||
172 | # Custom imageboard settings |
|
175 | # Custom imageboard settings | |
173 | MAX_POSTS_PER_THREAD = 10 # Thread bumplimit |
|
176 | MAX_POSTS_PER_THREAD = 10 # Thread bumplimit | |
174 | MAX_THREAD_COUNT = 500 # Old threads will be deleted to preserve this count |
|
177 | MAX_THREAD_COUNT = 500 # Old threads will be deleted to preserve this count | |
@@ -180,6 +183,4 b' THEMES = [' | |||||
180 | ('sw', 'Snow White') ] |
|
183 | ('sw', 'Snow White') ] | |
181 | DEFAULT_THEME = 'md' |
|
184 | DEFAULT_THEME = 'md' | |
182 |
|
185 | |||
183 | MARKUP_FIELD_TYPES = ( |
|
186 | POPULAR_TAGS=10 No newline at end of file | |
184 | ('markdown', markdown_extended), |
|
|||
185 | ) No newline at end of file |
|
@@ -26,6 +26,7 b'' | |||||
26 | <a class="tag" href=" {% url 'tag' tag_name=tag.name %}"> |
|
26 | <a class="tag" href=" {% url 'tag' tag_name=tag.name %}"> | |
27 | {{ tag.name }}</a>({{ tag.get_post_count }}) |
|
27 | {{ tag.name }}</a>({{ tag.get_post_count }}) | |
28 | {% endfor %} |
|
28 | {% endfor %} | |
|
29 | <a class="tag" href="{% url 'tags' %}">[...]</a> | |||
29 | <a class="link" href="{% url 'settings' %}">{% trans 'Settings' %}</a> |
|
30 | <a class="link" href="{% url 'settings' %}">{% trans 'Settings' %}</a> | |
30 | </div> |
|
31 | </div> | |
31 |
|
32 |
@@ -35,9 +35,6 b'' | |||||
35 | {% endautoescape %} |
|
35 | {% endautoescape %} | |
36 | </div> |
|
36 | </div> | |
37 | <div class="metadata"> |
|
37 | <div class="metadata"> | |
38 | {{ thread.get_reply_count }} {% trans 'replies' %}, |
|
|||
39 | {{ thread.get_images_count }} {% trans 'images' %}, |
|
|||
40 | {{ thread.get_gets_count }} {% trans 'gets' %}. |
|
|||
41 | {% if thread.tags.all %} |
|
38 | {% if thread.tags.all %} | |
42 | <span class="tags">{% trans 'Tags' %}: |
|
39 | <span class="tags">{% trans 'Tags' %}: | |
43 | {% for tag in thread.tags.all %} |
|
40 | {% for tag in thread.tags.all %} | |
@@ -46,7 +43,10 b'' | |||||
46 | {{ tag.name }}</a> |
|
43 | {{ tag.name }}</a> | |
47 | {% endfor %} |
|
44 | {% endfor %} | |
48 | </span> |
|
45 | </span> | |
49 | {% endif %} |
|
46 | {% endif %}, | |
|
47 | {{ thread.get_reply_count }} {% trans 'replies' %}, | |||
|
48 | {{ thread.get_images_count }} {% trans 'images' %}. | |||
|
49 | {% trans 'Last update: ' %}{{ thread.last_edit_time }} | |||
50 | </div> |
|
50 | </div> | |
51 | </div> |
|
51 | </div> | |
52 | {% endfor %} |
|
52 | {% endfor %} |
@@ -4,89 +4,21 b'' | |||||
4 | {% load markup %} |
|
4 | {% load markup %} | |
5 |
|
5 | |||
6 | {% block head %} |
|
6 | {% block head %} | |
7 |
<title>Neboard - { |
|
7 | <title>Neboard - {% trans "tags" %}</title> | |
8 | {% endblock %} |
|
8 | {% endblock %} | |
9 |
|
9 | |||
10 | {% block content %} |
|
10 | {% block content %} | |
11 |
|
11 | |||
12 | {% if posts %} |
|
12 | <div class="post"> | |
13 | {% for post in posts %} |
|
13 | {% if tags %} | |
14 | <a id="{{ post.id }}"></a> |
|
14 | {% for tag in all_tags %} | |
15 | <div class="post"> |
|
15 | <a class="tag" href="{% url 'tag' tag.name %}"> | |
16 | {% if post.image %} |
|
16 | {{ tag.name }}</a><br /> | |
17 | <div class="image"> |
|
|||
18 | <a href="{{ post.image.url }}"><img |
|
|||
19 | src="{{ post.image.url_200x150 }}" /> |
|
|||
20 | </a> |
|
|||
21 | </div> |
|
|||
22 | {% endif %} |
|
|||
23 | <div class="message"> |
|
|||
24 | <span class="title">{{ post.title }}</span> |
|
|||
25 | <a class="post_id" href="#{{ post.id }}"> |
|
|||
26 | (#{{ post.id }})</a> |
|
|||
27 | [{{ post.pub_time }}] |
|
|||
28 | {% if post.is_get %} |
|
|||
29 | <span class="get"> |
|
|||
30 | {% trans "Get!" %} |
|
|||
31 | </span> |
|
|||
32 | {% endif %} |
|
|||
33 | {% autoescape off %} |
|
|||
34 | {{ post.text.rendered }} |
|
|||
35 | {% endautoescape %} |
|
|||
36 | </div> |
|
|||
37 | {% if post.tags.all %} |
|
|||
38 | <div class="metadata"> |
|
|||
39 | <span class="tags">{% trans 'Tags' %}: |
|
|||
40 | {% for tag in post.tags.all %} |
|
|||
41 | <a class="tag" href="{% url 'tag' tag.name %}"> |
|
|||
42 | {{ tag.name }}</a> |
|
|||
43 | {% endfor %} |
|
|||
44 | </span> |
|
|||
45 | </div> |
|
|||
46 | {% endif %} |
|
|||
47 | </div> |
|
|||
48 | {% endfor %} |
|
17 | {% endfor %} | |
49 | {% else %} |
|
18 | {% else %} | |
50 |
No t |
|
19 | No tags found. | |
51 | <hr /> |
|
20 | <hr /> | |
52 | {% endif %} |
|
21 | {% endif %} | |
53 |
|
22 | </div> | ||
54 | <form id="form" enctype="multipart/form-data" method="post" |
|
|||
55 | >{% csrf_token %} |
|
|||
56 | <div class="post-form-w"> |
|
|||
57 | <div class="form-title">{% trans "Reply to thread" %}</div> |
|
|||
58 | <div class="post-form"> |
|
|||
59 | <div class="form-row"> |
|
|||
60 | <div class="form-label">{% trans 'Title' %}</div> |
|
|||
61 | <div class="form-input">{{ form.title }}</div> |
|
|||
62 | </div> |
|
|||
63 | <div class="form-row"> |
|
|||
64 | <div class="form-label">{% trans 'Text' %}</div> |
|
|||
65 | <div class="form-input">{{ form.text }}</div> |
|
|||
66 | </div> |
|
|||
67 | <div class="form-row"> |
|
|||
68 | <div class="form-label">{% trans 'Image' %}</div> |
|
|||
69 | <div class="form-input">{{ form.image }}</div> |
|
|||
70 | </div> |
|
|||
71 | </div> |
|
|||
72 | <div class="form-submit"><input type="submit" |
|
|||
73 | value="{% trans "Post" %}"/></div> |
|
|||
74 | <div>Use <a |
|
|||
75 | href="http://daringfireball.net/projects/markdown/basics"> |
|
|||
76 | markdown</a> syntax for posting.</div> |
|
|||
77 | <div>Example: *<i>italic</i>*, **<b>bold</b>**</div> |
|
|||
78 | <div>Insert quotes with ">"</div> |
|
|||
79 | </div> |
|
|||
80 | </form> |
|
|||
81 |
|
||||
82 | {% endblock %} |
|
|||
83 |
|
||||
84 | {% block metapanel %} |
|
|||
85 |
|
||||
86 | <span class="metapanel"> |
|
|||
87 | {{ posts.0.get_reply_count }} {% trans 'replies' %}, |
|
|||
88 | {{ posts.0.get_images_count }} {% trans 'images' %}, |
|
|||
89 | {{ posts.0.get_gets_count }} {% trans 'gets' %} |
|
|||
90 | </span> |
|
|||
91 |
|
23 | |||
92 | {% endblock %} No newline at end of file |
|
24 | {% endblock %} |
@@ -85,8 +85,8 b'' | |||||
85 |
|
85 | |||
86 | <span class="metapanel"> |
|
86 | <span class="metapanel"> | |
87 | {{ posts.0.get_reply_count }} {% trans 'replies' %}, |
|
87 | {{ posts.0.get_reply_count }} {% trans 'replies' %}, | |
88 |
{{ posts.0.get_images_count }} {% trans 'images' %} |
|
88 | {{ posts.0.get_images_count }} {% trans 'images' %}. | |
89 | {{ posts.0.get_gets_count }} {% trans 'gets' %} |
|
89 | {% trans 'Last update: ' %}{{ posts.0.last_edit_time }} | |
90 | </span> |
|
90 | </span> | |
91 |
|
91 | |||
92 | {% endblock %} No newline at end of file |
|
92 | {% endblock %} |
General Comments 0
You need to be logged in to leave comments.
Login now