Show More
@@ -0,0 +1,92 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | from south.utils import datetime_utils as datetime | |
|
3 | from south.db import db | |
|
4 | from south.v2 import SchemaMigration | |
|
5 | from django.db import models | |
|
6 | ||
|
7 | ||
|
8 | class Migration(SchemaMigration): | |
|
9 | ||
|
10 | def forwards(self, orm): | |
|
11 | # Adding field 'Post.image_pre_width' | |
|
12 | db.add_column(u'boards_post', 'image_pre_width', | |
|
13 | self.gf('django.db.models.fields.IntegerField')(default=0), | |
|
14 | keep_default=False) | |
|
15 | ||
|
16 | # Adding field 'Post.image_pre_height' | |
|
17 | db.add_column(u'boards_post', 'image_pre_height', | |
|
18 | self.gf('django.db.models.fields.IntegerField')(default=0), | |
|
19 | keep_default=False) | |
|
20 | ||
|
21 | ||
|
22 | def backwards(self, orm): | |
|
23 | # Deleting field 'Post.image_pre_width' | |
|
24 | db.delete_column(u'boards_post', 'image_pre_width') | |
|
25 | ||
|
26 | # Deleting field 'Post.image_pre_height' | |
|
27 | db.delete_column(u'boards_post', 'image_pre_height') | |
|
28 | ||
|
29 | ||
|
30 | models = { | |
|
31 | 'boards.ban': { | |
|
32 | 'Meta': {'object_name': 'Ban'}, | |
|
33 | 'can_read': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |
|
34 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
|
35 | 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | |
|
36 | 'reason': ('django.db.models.fields.CharField', [], {'default': "'Auto'", 'max_length': '200'}) | |
|
37 | }, | |
|
38 | 'boards.post': { | |
|
39 | 'Meta': {'object_name': 'Post'}, | |
|
40 | '_text_rendered': ('django.db.models.fields.TextField', [], {}), | |
|
41 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
|
42 | 'image': ('boards.thumbs.ImageWithThumbsField', [], {'max_length': '100', 'blank': 'True'}), | |
|
43 | 'image_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |
|
44 | 'image_pre_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |
|
45 | 'image_pre_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |
|
46 | 'image_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | |
|
47 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |
|
48 | 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), | |
|
49 | 'poster_user_agent': ('django.db.models.fields.TextField', [], {}), | |
|
50 | 'pub_time': ('django.db.models.fields.DateTimeField', [], {}), | |
|
51 | 'referenced_posts': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'rfp+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Post']"}), | |
|
52 | 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}), | |
|
53 | 'text_markup_type': ('django.db.models.fields.CharField', [], {'default': "'markdown'", 'max_length': '30'}), | |
|
54 | 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.Post']", 'null': 'True'}), | |
|
55 | 'thread_new': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.Thread']", 'null': 'True'}), | |
|
56 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), | |
|
57 | 'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['boards.User']", 'null': 'True'}) | |
|
58 | }, | |
|
59 | 'boards.setting': { | |
|
60 | 'Meta': {'object_name': 'Setting'}, | |
|
61 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
|
62 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), | |
|
63 | 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['boards.User']"}), | |
|
64 | 'value': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | |
|
65 | }, | |
|
66 | 'boards.tag': { | |
|
67 | 'Meta': {'object_name': 'Tag'}, | |
|
68 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
|
69 | 'linked': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['boards.Tag']", 'null': 'True', 'blank': 'True'}), | |
|
70 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
|
71 | 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'tag+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Thread']"}) | |
|
72 | }, | |
|
73 | 'boards.thread': { | |
|
74 | 'Meta': {'object_name': 'Thread'}, | |
|
75 | 'bump_time': ('django.db.models.fields.DateTimeField', [], {}), | |
|
76 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
|
77 | 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), | |
|
78 | 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'tre+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Post']"}), | |
|
79 | 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['boards.Tag']", 'symmetrical': 'False'}) | |
|
80 | }, | |
|
81 | 'boards.user': { | |
|
82 | 'Meta': {'object_name': 'User'}, | |
|
83 | 'fav_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['boards.Tag']", 'null': 'True', 'blank': 'True'}), | |
|
84 | 'fav_threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['boards.Post']"}), | |
|
85 | u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
|
86 | 'rank': ('django.db.models.fields.IntegerField', [], {}), | |
|
87 | 'registration_time': ('django.db.models.fields.DateTimeField', [], {}), | |
|
88 | 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | |
|
89 | } | |
|
90 | } | |
|
91 | ||
|
92 | complete_apps = ['boards'] No newline at end of file |
@@ -0,0 +1,66 b'' | |||
|
1 | {% extends "boards/base.html" %} | |
|
2 | ||
|
3 | {% load i18n %} | |
|
4 | {% load cache %} | |
|
5 | {% load static from staticfiles %} | |
|
6 | {% load board %} | |
|
7 | ||
|
8 | {% block head %} | |
|
9 | <title>Neboard - {{ thread.get_opening_post.get_title }}</title> | |
|
10 | {% endblock %} | |
|
11 | ||
|
12 | {% block content %} | |
|
13 | {% spaceless %} | |
|
14 | {% get_current_language as LANGUAGE_CODE %} | |
|
15 | ||
|
16 | <script src="{% static 'js/thread.js' %}"></script> | |
|
17 | ||
|
18 | {% cache 600 thread_gallery_view thread.id thread.last_edit_time LANGUAGE_CODE %} | |
|
19 | <div class="image-mode-tab"> | |
|
20 | <a href="{% url 'thread' thread.get_opening_post.id %}">{% trans 'Normal mode' %}</a>, | |
|
21 | <a class="current_mode" href="{% url 'thread_mode' thread.get_opening_post.id 'gallery' %}">{% trans 'Gallery mode' %}</a> | |
|
22 | </div> | |
|
23 | ||
|
24 | <div id="posts-table"> | |
|
25 | {% for post in thread.get_replies %} | |
|
26 | {% if post.image %} | |
|
27 | <div class="gallery_image"> | |
|
28 | <div> | |
|
29 | <a | |
|
30 | class="thumb" | |
|
31 | href="{{ post.image.url }}"><img | |
|
32 | src="{{ post.image.url_200x150 }}" | |
|
33 | alt="{{ post.id }}" | |
|
34 | width="{{ post.image_pre_width }}" | |
|
35 | height="{{ post.image_pre_height }}" | |
|
36 | data-width="{{ post.image_width }}" | |
|
37 | data-height="{{ post.image_height }}"/> | |
|
38 | </a> | |
|
39 | </div> | |
|
40 | <div class="gallery_image_metadata"> | |
|
41 | {{ post.image_width }}x{{ post.image_height }} | |
|
42 | {% image_actions post.image.url request.get_host %} | |
|
43 | </div> | |
|
44 | </div> | |
|
45 | {% endif %} | |
|
46 | {% endfor %} | |
|
47 | </div> | |
|
48 | {% endcache %} | |
|
49 | ||
|
50 | {% endspaceless %} | |
|
51 | {% endblock %} | |
|
52 | ||
|
53 | {% block metapanel %} | |
|
54 | ||
|
55 | {% get_current_language as LANGUAGE_CODE %} | |
|
56 | ||
|
57 | <span class="metapanel" data-last-update="{{ last_update }}"> | |
|
58 | {% cache 600 thread_meta thread.last_edit_time moderator LANGUAGE_CODE %} | |
|
59 | <span id="reply-count">{{ thread.get_reply_count }}</span> {% trans 'replies' %}, | |
|
60 | <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}. | |
|
61 | {% trans 'Last update: ' %}{{ thread.last_edit_time }} | |
|
62 | [<a href="rss/">RSS</a>] | |
|
63 | {% endcache %} | |
|
64 | </span> | |
|
65 | ||
|
66 | {% endblock %} |
@@ -0,0 +1,7 b'' | |||
|
1 | # 1.5 Aker # | |
|
2 | * Saving image previews size. No space will be shown below images in some | |
|
3 | styles. | |
|
4 | * Showing notification in page title when new posts are loaded into the open | |
|
5 | thread. | |
|
6 | * Thread moderation fixes | |
|
7 | * Added new gallery with search links and image metadata No newline at end of file |
|
1 | NO CONTENT: modified file, binary diff hidden |
@@ -7,7 +7,7 b' msgid ""' | |||
|
7 | 7 | msgstr "" |
|
8 | 8 | "Project-Id-Version: PACKAGE VERSION\n" |
|
9 | 9 | "Report-Msgid-Bugs-To: \n" |
|
10 |
"POT-Creation-Date: 2013-1 |
|
|
10 | "POT-Creation-Date: 2013-12-24 20:39+0200\n" | |
|
11 | 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
|
12 | 12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
|
13 | 13 | "Language-Team: LANGUAGE <LL@li.org>\n" |
@@ -34,77 +34,72 b' msgstr "\xd1\x80\xd0\xb0\xd0\xb7\xd1\x80\xd0\xb0\xd0\xb1\xd0\xbe\xd1\x82\xd1\x87\xd0\xb8\xd0\xba javascript"' | |||
|
34 | 34 | msgid "designer" |
|
35 | 35 | msgstr "дизайнер" |
|
36 | 36 | |
|
37 | #: forms.py:48 templates/boards/posting_general.html:209 | |
|
38 | #: templates/boards/thread.html:101 | |
|
37 | #: forms.py:72 | |
|
39 | 38 | msgid "Title" |
|
40 | 39 | msgstr "Заголовок" |
|
41 | 40 | |
|
42 | #: forms.py:50 templates/boards/posting_general.html:224 | |
|
43 | #: templates/boards/thread.html:116 | |
|
41 | #: forms.py:74 | |
|
44 | 42 | msgid "Text" |
|
45 | 43 | msgstr "Текст" |
|
46 | 44 | |
|
47 | #: forms.py:51 templates/boards/posting_general.html:229 | |
|
48 | #: templates/boards/thread.html:121 | |
|
45 | #: forms.py:75 | |
|
49 | 46 | msgid "Image" |
|
50 | 47 | msgstr "Изображение" |
|
51 | 48 | |
|
52 | #: forms.py:54 templates/boards/posting_general.html:239 | |
|
53 | #: templates/boards/thread.html:126 | |
|
49 | #: forms.py:78 | |
|
54 | 50 | msgid "e-mail" |
|
55 | 51 | msgstr "" |
|
56 | 52 | |
|
57 |
#: forms.py: |
|
|
53 | #: forms.py:89 | |
|
58 | 54 | #, python-format |
|
59 | 55 | msgid "Title must have less than %s characters" |
|
60 | 56 | msgstr "Заголовок должен иметь меньше %s символов" |
|
61 | 57 | |
|
62 |
#: forms.py: |
|
|
58 | #: forms.py:98 | |
|
63 | 59 | #, python-format |
|
64 | 60 | msgid "Text must have less than %s characters" |
|
65 | 61 | msgstr "Текст должен быть короче %s символов" |
|
66 | 62 | |
|
67 |
#: forms.py: |
|
|
63 | #: forms.py:109 | |
|
68 | 64 | #, python-format |
|
69 | 65 | msgid "Image must be less than %s bytes" |
|
70 | 66 | msgstr "Изображение должно быть менее %s байт" |
|
71 | 67 | |
|
72 |
#: forms.py:1 |
|
|
68 | #: forms.py:136 | |
|
73 | 69 | msgid "Either text or image must be entered." |
|
74 | 70 | msgstr "Текст или картинка должны быть введены." |
|
75 | 71 | |
|
76 |
#: forms.py:1 |
|
|
72 | #: forms.py:149 | |
|
77 | 73 | #, python-format |
|
78 | 74 | msgid "Wait %s seconds after last posting" |
|
79 | 75 | msgstr "Подождите %s секунд после последнего постинга" |
|
80 | 76 | |
|
81 |
#: forms.py:13 |
|
|
82 | #: templates/boards/posting_general.html:234 templates/boards/tags.html:6 | |
|
77 | #: forms.py:163 templates/boards/post.html:61 templates/boards/tags.html:6 | |
|
83 | 78 | #: templates/boards/rss/post.html:10 |
|
84 | 79 | msgid "Tags" |
|
85 | 80 | msgstr "Теги" |
|
86 | 81 | |
|
87 |
#: forms.py:1 |
|
|
82 | #: forms.py:171 | |
|
88 | 83 | msgid "Inappropriate characters in tags." |
|
89 | 84 | msgstr "Недопустимые символы в тегах." |
|
90 | 85 | |
|
91 |
#: forms.py:1 |
|
|
86 | #: forms.py:199 forms.py:220 | |
|
92 | 87 | msgid "Captcha validation failed" |
|
93 | 88 | msgstr "Проверка капчи провалена" |
|
94 | 89 | |
|
95 |
#: forms.py:2 |
|
|
90 | #: forms.py:226 | |
|
96 | 91 | msgid "Theme" |
|
97 | 92 | msgstr "Тема" |
|
98 | 93 | |
|
99 |
#: forms.py:2 |
|
|
94 | #: forms.py:231 | |
|
100 | 95 | msgid "Enable moderation panel" |
|
101 | 96 | msgstr "Включить панель модерации" |
|
102 | 97 | |
|
103 |
#: forms.py:2 |
|
|
98 | #: forms.py:246 | |
|
104 | 99 | msgid "No such user found" |
|
105 | 100 | msgstr "Данный пользователь не найден" |
|
106 | 101 | |
|
107 |
#: forms.py:2 |
|
|
102 | #: forms.py:260 | |
|
108 | 103 | #, python-format |
|
109 | 104 | msgid "Wait %s minutes after last login" |
|
110 | 105 | msgstr "Подождите %s минут после последнего входа" |
@@ -137,15 +132,15 b' msgstr "\xd0\xa0\xd0\xb5\xd0\xbf\xd0\xbe\xd0\xb7\xd0\xb8\xd1\x82\xd0\xbe\xd1\x80\xd0\xb8\xd0\xb9"' | |||
|
137 | 132 | msgid "Feed" |
|
138 | 133 | msgstr "Лента" |
|
139 | 134 | |
|
140 |
#: templates/boards/base.html:3 |
|
|
135 | #: templates/boards/base.html:31 | |
|
141 | 136 | msgid "All threads" |
|
142 | 137 | msgstr "Все темы" |
|
143 | 138 | |
|
144 |
#: templates/boards/base.html: |
|
|
139 | #: templates/boards/base.html:36 | |
|
145 | 140 | msgid "Tag management" |
|
146 | 141 | msgstr "Управление тегами" |
|
147 | 142 | |
|
148 |
#: templates/boards/base.html: |
|
|
143 | #: templates/boards/base.html:38 | |
|
149 | 144 | msgid "Settings" |
|
150 | 145 | msgstr "Настройки" |
|
151 | 146 | |
@@ -171,92 +166,65 b' msgstr "ID \xd0\xbf\xd0\xbe\xd0\xbb\xd1\x8c\xd0\xb7\xd0\xbe\xd0\xb2\xd0\xb0\xd1\x82\xd0\xb5\xd0\xbb\xd1\x8f"' | |||
|
171 | 166 | msgid "Insert your user id above" |
|
172 | 167 | msgstr "Вставьте свой ID пользователя выше" |
|
173 | 168 | |
|
174 |
#: templates/boards/post.html:3 |
|
|
175 |
#: templates/boards/thread.html: |
|
|
169 | #: templates/boards/post.html:35 templates/boards/posting_general.html:103 | |
|
170 | #: templates/boards/thread.html:68 | |
|
176 | 171 | msgid "Delete" |
|
177 | 172 | msgstr "Удалить" |
|
178 | 173 | |
|
179 |
#: templates/boards/post.html:3 |
|
|
180 |
#: templates/boards/thread.html: |
|
|
174 | #: templates/boards/post.html:38 templates/boards/posting_general.html:107 | |
|
175 | #: templates/boards/thread.html:71 | |
|
181 | 176 | msgid "Ban IP" |
|
182 | 177 | msgstr "Заблокировать IP" |
|
183 | 178 | |
|
184 |
#: templates/boards/post.html:5 |
|
|
185 |
#: templates/boards/posting_general.html:1 |
|
|
179 | #: templates/boards/post.html:51 templates/boards/posting_general.html:116 | |
|
180 | #: templates/boards/posting_general.html:180 templates/boards/thread.html:80 | |
|
186 | 181 | msgid "Replies" |
|
187 | 182 | msgstr "Ответы" |
|
188 | 183 | |
|
189 |
#: templates/boards/posting_general.html:6 |
|
|
184 | #: templates/boards/posting_general.html:64 | |
|
190 | 185 | msgid "Previous page" |
|
191 | 186 | msgstr "Предыдущая страница" |
|
192 | 187 | |
|
193 |
#: templates/boards/posting_general.html:9 |
|
|
188 | #: templates/boards/posting_general.html:97 | |
|
194 | 189 | msgid "Reply" |
|
195 | 190 | msgstr "Ответ" |
|
196 | 191 | |
|
197 |
#: templates/boards/posting_general.html:12 |
|
|
198 | msgid "replies" | |
|
199 | msgstr "ответов" | |
|
200 | ||
|
201 | #: templates/boards/posting_general.html:123 templates/boards/thread.html:155 | |
|
192 | #: templates/boards/posting_general.html:125 templates/boards/thread.html:130 | |
|
193 | #: templates/boards/thread_gallery.html:52 | |
|
202 | 194 | msgid "images" |
|
203 | 195 | msgstr "изображений" |
|
204 | 196 | |
|
205 |
#: templates/boards/posting_general.html:1 |
|
|
197 | #: templates/boards/posting_general.html:142 | |
|
206 | 198 | #, python-format |
|
207 | 199 | msgid "Skipped %(count)s replies. Open thread to see all replies." |
|
208 | 200 | msgstr "Пропущено %(count)s ответов. Откройте тред, чтобы увидеть все ответы." |
|
209 | 201 | |
|
210 |
#: templates/boards/posting_general.html: |
|
|
202 | #: templates/boards/posting_general.html:203 | |
|
211 | 203 | msgid "Next page" |
|
212 | 204 | msgstr "Следующая страница" |
|
213 | 205 | |
|
214 |
#: templates/boards/posting_general.html:20 |
|
|
206 | #: templates/boards/posting_general.html:208 | |
|
215 | 207 | msgid "No threads exist. Create the first one!" |
|
216 | 208 | msgstr "Нет тем. Создайте первую!" |
|
217 | 209 | |
|
218 |
#: templates/boards/posting_general.html:2 |
|
|
210 | #: templates/boards/posting_general.html:214 | |
|
219 | 211 | msgid "Create new thread" |
|
220 | 212 | msgstr "Создать новую тему" |
|
221 | 213 | |
|
222 |
#: templates/boards/posting_general.html:21 |
|
|
223 | msgid "Formatting" | |
|
224 | msgstr "Форматирование" | |
|
225 | ||
|
226 | #: templates/boards/posting_general.html:216 templates/boards/thread.html:108 | |
|
227 | msgid "quote" | |
|
228 | msgstr "цитата" | |
|
229 | ||
|
230 | #: templates/boards/posting_general.html:217 templates/boards/thread.html:109 | |
|
231 | msgid "italic" | |
|
232 | msgstr "курсив" | |
|
233 | ||
|
234 | #: templates/boards/posting_general.html:218 templates/boards/thread.html:110 | |
|
235 | msgid "bold" | |
|
236 | msgstr "полужирный" | |
|
237 | ||
|
238 | #: templates/boards/posting_general.html:219 templates/boards/thread.html:111 | |
|
239 | msgid "spoiler" | |
|
240 | msgstr "спойлер" | |
|
241 | ||
|
242 | #: templates/boards/posting_general.html:220 templates/boards/thread.html:112 | |
|
243 | msgid "comment" | |
|
244 | msgstr "комментарий" | |
|
245 | ||
|
246 | #: templates/boards/posting_general.html:252 templates/boards/thread.html:140 | |
|
214 | #: templates/boards/posting_general.html:218 templates/boards/thread.html:112 | |
|
247 | 215 | msgid "Post" |
|
248 | 216 | msgstr "Отправить" |
|
249 | 217 | |
|
250 |
#: templates/boards/posting_general.html:2 |
|
|
218 | #: templates/boards/posting_general.html:222 | |
|
251 | 219 | msgid "Tags must be delimited by spaces. Text or image is required." |
|
252 | 220 | msgstr "" |
|
253 | 221 | "Теги должны быть разделены пробелами. Текст или изображение обязательны." |
|
254 | 222 | |
|
255 |
#: templates/boards/posting_general.html:25 |
|
|
223 | #: templates/boards/posting_general.html:225 templates/boards/thread.html:116 | |
|
256 | 224 | msgid "Text syntax" |
|
257 | 225 | msgstr "Синтаксис текста" |
|
258 | 226 | |
|
259 |
#: templates/boards/posting_general.html:2 |
|
|
227 | #: templates/boards/posting_general.html:235 | |
|
260 | 228 | msgid "Pages:" |
|
261 | 229 | msgstr "Страницы: " |
|
262 | 230 | |
@@ -292,15 +260,27 b' msgstr "\xd1\x82\xd0\xb5\xd0\xbc"' | |||
|
292 | 260 | msgid "No tags found." |
|
293 | 261 | msgstr "Теги не найдены." |
|
294 | 262 | |
|
295 |
#: templates/boards/thread.html:2 |
|
|
263 | #: templates/boards/thread.html:22 templates/boards/thread_gallery.html:20 | |
|
264 | msgid "Normal mode" | |
|
265 | msgstr "Нормальный режим" | |
|
266 | ||
|
267 | #: templates/boards/thread.html:23 templates/boards/thread_gallery.html:21 | |
|
268 | msgid "Gallery mode" | |
|
269 | msgstr "Режим галереи" | |
|
270 | ||
|
271 | #: templates/boards/thread.html:31 | |
|
296 | 272 | msgid "posts to bumplimit" |
|
297 | 273 | msgstr "сообщений до бамплимита" |
|
298 | 274 | |
|
299 |
#: templates/boards/thread.html: |
|
|
275 | #: templates/boards/thread.html:106 | |
|
300 | 276 | msgid "Reply to thread" |
|
301 | 277 | msgstr "Ответить в тему" |
|
302 | 278 | |
|
303 |
#: templates/boards/thread.html:1 |
|
|
279 | #: templates/boards/thread.html:129 templates/boards/thread_gallery.html:51 | |
|
280 | msgid "replies" | |
|
281 | msgstr "ответов" | |
|
282 | ||
|
283 | #: templates/boards/thread.html:131 templates/boards/thread_gallery.html:53 | |
|
304 | 284 | msgid "Last update: " |
|
305 | 285 | msgstr "Последнее обновление: " |
|
306 | 286 | |
@@ -353,6 +333,24 b' msgstr "\xd0\xa1\xd1\x81\xd1\x8b\xd0\xbb\xd0\xba\xd0\xb0 \xd0\xbd\xd0\xb0 \xd1\x81\xd0\xbe\xd0\xbe\xd0\xb1\xd1\x89\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5"' | |||
|
353 | 333 | msgid "Strikethrough text" |
|
354 | 334 | msgstr "Зачеркнутый текст" |
|
355 | 335 | |
|
336 | #~ msgid "Formatting" | |
|
337 | #~ msgstr "Форматирование" | |
|
338 | ||
|
339 | #~ msgid "quote" | |
|
340 | #~ msgstr "цитата" | |
|
341 | ||
|
342 | #~ msgid "italic" | |
|
343 | #~ msgstr "курсив" | |
|
344 | ||
|
345 | #~ msgid "bold" | |
|
346 | #~ msgstr "полужирный" | |
|
347 | ||
|
348 | #~ msgid "spoiler" | |
|
349 | #~ msgstr "спойлер" | |
|
350 | ||
|
351 | #~ msgid "comment" | |
|
352 | #~ msgstr "комментарий" | |
|
353 | ||
|
356 | 354 | #~ msgid "Tag: " |
|
357 | 355 | #~ msgstr "Тег: " |
|
358 | 356 |
|
1 | NO CONTENT: modified file, binary diff hidden |
@@ -8,7 +8,7 b' msgid ""' | |||
|
8 | 8 | msgstr "" |
|
9 | 9 | "Project-Id-Version: PACKAGE VERSION\n" |
|
10 | 10 | "Report-Msgid-Bugs-To: \n" |
|
11 |
"POT-Creation-Date: 2013-1 |
|
|
11 | "POT-Creation-Date: 2013-12-21 21:45+0200\n" | |
|
12 | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
|
13 | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
|
14 | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" |
@@ -19,11 +19,11 b' msgstr ""' | |||
|
19 | 19 | "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" |
|
20 | 20 | "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" |
|
21 | 21 | |
|
22 |
#: static/js/refpopup.js: |
|
|
22 | #: static/js/refpopup.js:57 | |
|
23 | 23 | msgid "Loading..." |
|
24 | 24 | msgstr "Загрузка..." |
|
25 | 25 | |
|
26 |
#: static/js/refpopup.js: |
|
|
26 | #: static/js/refpopup.js:76 | |
|
27 | 27 | msgid "Post not found" |
|
28 | 28 | msgstr "Сообщение не найдено" |
|
29 | 29 | |
@@ -35,5 +35,9 b' msgstr "\xd0\x9d\xd0\xbe\xd1\x80\xd0\xbc\xd0\xb0\xd0\xbb\xd1\x8c\xd0\xbd\xd1\x8b\xd0\xb9"' | |||
|
35 | 35 | msgid "Gallery" |
|
36 | 36 | msgstr "Галерея" |
|
37 | 37 | |
|
38 | #: static/js/thread_update.js:177 | |
|
39 | msgid "[new posts]" | |
|
40 | msgstr "[новые посты]" | |
|
41 | ||
|
38 | 42 | #~ msgid "Replies" |
|
39 | 43 | #~ msgstr "Ответы" |
@@ -34,7 +34,8 b' class MinifyHTMLMiddleware(object):' | |||
|
34 | 34 | except AttributeError: |
|
35 | 35 | compress_html = False |
|
36 | 36 | |
|
37 |
if |
|
|
37 | if RESPONSE_CONTENT_TYPE in response\ | |
|
38 | and TYPE_HTML in response[RESPONSE_CONTENT_TYPE] and compress_html: | |
|
38 | 39 | response.content = strip_spaces_between_tags( |
|
39 | 40 | response.content.strip()) |
|
40 | 41 | return response No newline at end of file |
@@ -86,12 +86,18 b' class PostManager(models.Manager):' | |||
|
86 | 86 | |
|
87 | 87 | def delete_post(self, post): |
|
88 | 88 | """ |
|
89 | Delete post and update its thread | |
|
89 | Delete post and update or delete its thread | |
|
90 | 90 | """ |
|
91 | ||
|
92 | thread = post.thread_new | |
|
91 | 93 | |
|
92 | thread = post.thread_new | |
|
93 | thread.last_edit_time = timezone.now() | |
|
94 | thread.save() | |
|
94 | if thread.get_opening_post() == self: | |
|
95 | thread.replies.delete() | |
|
96 | ||
|
97 | thread.delete() | |
|
98 | else: | |
|
99 | thread.last_edit_time = timezone.now() | |
|
100 | thread.save() | |
|
95 | 101 | |
|
96 | 102 | post.delete() |
|
97 | 103 | |
@@ -235,10 +241,15 b' class Post(models.Model):' | |||
|
235 | 241 | image_width = models.IntegerField(default=0) |
|
236 | 242 | image_height = models.IntegerField(default=0) |
|
237 | 243 | |
|
244 | image_pre_width = models.IntegerField(default=0) | |
|
245 | image_pre_height = models.IntegerField(default=0) | |
|
246 | ||
|
238 | 247 | image = thumbs.ImageWithThumbsField(upload_to=_update_image_filename, |
|
239 | 248 | blank=True, sizes=(IMAGE_THUMB_SIZE,), |
|
240 | 249 | width_field='image_width', |
|
241 |
height_field='image_height' |
|
|
250 | height_field='image_height', | |
|
251 | preview_width_field='image_pre_width', | |
|
252 | preview_height_field='image_pre_height') | |
|
242 | 253 | |
|
243 | 254 | poster_ip = models.GenericIPAddressField() |
|
244 | 255 | poster_user_agent = models.TextField() |
@@ -27,3 +27,7 b'' | |||
|
27 | 27 | z-index: 300; |
|
28 | 28 | position:absolute; |
|
29 | 29 | } |
|
30 | ||
|
31 | .gallery_image { | |
|
32 | display: inline-block; | |
|
33 | } No newline at end of file |
@@ -173,8 +173,6 b' blockquote {' | |||
|
173 | 173 | min-width: 1px; |
|
174 | 174 | text-align: center; |
|
175 | 175 | display: table-row; |
|
176 | ||
|
177 | height: 150px; | |
|
178 | 176 | } |
|
179 | 177 | |
|
180 | 178 | .post > .metadata { |
@@ -356,3 +354,15 b' li {' | |||
|
356 | 354 | .skipped_replies { |
|
357 | 355 | margin: 5px; |
|
358 | 356 | } |
|
357 | ||
|
358 | .current_page, .current_mode { | |
|
359 | border: solid 1px #afdcec; | |
|
360 | padding: 2px; | |
|
361 | } | |
|
362 | ||
|
363 | .gallery_image { | |
|
364 | border: solid 1px; | |
|
365 | padding: 0.5ex; | |
|
366 | margin: 0.5ex; | |
|
367 | text-align: center; | |
|
368 | } No newline at end of file |
@@ -171,8 +171,6 b' blockquote {' | |||
|
171 | 171 | min-width: 1px; |
|
172 | 172 | text-align: center; |
|
173 | 173 | display: table-row; |
|
174 | ||
|
175 | height: 150px; | |
|
176 | 174 | } |
|
177 | 175 | |
|
178 | 176 | .post > .metadata { |
@@ -342,3 +340,8 b' input[type="submit"]:hover {' | |||
|
342 | 340 | .skipped_replies { |
|
343 | 341 | margin: 5px; |
|
344 | 342 | } |
|
343 | ||
|
344 | .current_page, .current_mode { | |
|
345 | border: solid 1px #000; | |
|
346 | padding: 2px; | |
|
347 | } No newline at end of file |
@@ -330,4 +330,28 b' li {' | |||
|
330 | 330 | |
|
331 | 331 | .mark_btn:last-child { |
|
332 | 332 | border-right: 1px solid #182F6F; |
|
333 | } | |
|
334 | ||
|
335 | .current_page { | |
|
336 | border-bottom: 1px solid #FFF; | |
|
337 | padding: 0px 0.5ex; | |
|
338 | } | |
|
339 | ||
|
340 | .image-mode-tab a { | |
|
341 | text-decoration: none; | |
|
342 | } | |
|
343 | .image-mode-tab .current_mode::before { | |
|
344 | content: "✓ "; | |
|
345 | padding: 0 0 0 .5ex; | |
|
346 | color: #182F6F; | |
|
347 | background: #FFF; | |
|
348 | } | |
|
349 | .image-mode-tab .current_mode { | |
|
350 | padding: 0 .5ex 0 0; | |
|
351 | color: #182F6F; | |
|
352 | background: #FFF; | |
|
353 | } | |
|
354 | ||
|
355 | .gallery_image_metadata { | |
|
356 | margin-bottom: 1em; | |
|
333 | 357 | } No newline at end of file |
@@ -23,33 +23,6 b'' | |||
|
23 | 23 | for the JavaScript code in this page. |
|
24 | 24 | */ |
|
25 | 25 | |
|
26 | function addGalleryPanel() { | |
|
27 | var gallery = $('a[class="thumb"]').clone(true), | |
|
28 | normal = $('.post').clone(true); | |
|
29 | ||
|
30 | $('.navigation_panel').filter(':first').after( | |
|
31 | '<div class="image-mode-tab" role="radiogroup" aria-label="Image mode2">' + | |
|
32 | '<label><input type="radio" class="image-mode-normal" name="image-mode" value="0" checked="checked"/>'+ gettext('Normal') +'</label>' + | |
|
33 | '<label><input type="radio" class="image-mode-table" name="image-mode" value="1"/>'+ gettext('Gallery') +'</label>' + | |
|
34 | '</div>' | |
|
35 | ); | |
|
36 | ||
|
37 | $('input[name="image-mode"]').change(function() { | |
|
38 | //gallery mode | |
|
39 | if($(this).val() === '1') { | |
|
40 | $('.thread').replaceWith( | |
|
41 | $('<div id="posts-table"></div>').append(gallery) | |
|
42 | ); | |
|
43 | } | |
|
44 | //normal mode | |
|
45 | else { | |
|
46 | $('#posts-table').replaceWith( | |
|
47 | $('<div class="thread"></div>').append(normal) | |
|
48 | ); | |
|
49 | } | |
|
50 | }); | |
|
51 | } | |
|
52 | ||
|
53 | 26 | function moveCaretToEnd(el) { |
|
54 | 27 | if (typeof el.selectionStart == "number") { |
|
55 | 28 | el.selectionStart = el.selectionEnd = el.value.length; |
@@ -72,10 +45,3 b' function addQuickReply(postId) {' | |||
|
72 | 45 | |
|
73 | 46 | $("html, body").animate({ scrollTop: $(textAreaId).offset().top }, "slow"); |
|
74 | 47 | } |
|
75 | ||
|
76 | ||
|
77 | ||
|
78 | $(document).ready(function(){ | |
|
79 | addGalleryPanel(); | |
|
80 | initAutoupdate(); | |
|
81 | }); |
@@ -97,6 +97,10 b' function updateThread() {' | |||
|
97 | 97 | |
|
98 | 98 | updateBumplimitProgress(data.added.length); |
|
99 | 99 | updatePostBumpableStatus(); |
|
100 | ||
|
101 | if (data.added.length + data.updated.length > 0) { | |
|
102 | showNewPostsTitle(); | |
|
103 | } | |
|
100 | 104 | }) |
|
101 | 105 | .error(function(data) { |
|
102 | 106 | // TODO Show error message that server is unavailable? |
@@ -162,3 +166,27 b' function updatePostBumpableStatus() {' | |||
|
162 | 166 | $('.thread').find('.post').addClass('dead_post'); |
|
163 | 167 | } |
|
164 | 168 | } |
|
169 | ||
|
170 | var documentOriginalTitle = ''; | |
|
171 | /** | |
|
172 | * Show 'new posts' text in the title if the document is not visible to a user | |
|
173 | */ | |
|
174 | function showNewPostsTitle() { | |
|
175 | if (document.hidden) { | |
|
176 | documentOriginalTitle = document.title; | |
|
177 | document.title = gettext('[new posts]') + ' ' + document.title; | |
|
178 | ||
|
179 | document.addEventListener('visibilitychange', function() { | |
|
180 | if (documentOriginalTitle !== '') { | |
|
181 | document.title = documentOriginalTitle; | |
|
182 | documentOriginalTitle = ''; | |
|
183 | } | |
|
184 | ||
|
185 | document.removeEventListener('visibilitychange', null); | |
|
186 | }); | |
|
187 | } | |
|
188 | } | |
|
189 | ||
|
190 | $(document).ready(function(){ | |
|
191 | initAutoupdate(); | |
|
192 | }); |
@@ -79,6 +79,8 b'' | |||
|
79 | 79 | href="{{ thread.op.image.url }}"><img |
|
80 | 80 | src="{{ thread.op.image.url_200x150 }}" |
|
81 | 81 | alt="{{ thread.op.id }}" |
|
82 | width="{{ thread.op.image_pre_width }}" | |
|
83 | height="{{ thread.op.image_pre_height }}" | |
|
82 | 84 | data-width="{{ thread.op.image_width }}" |
|
83 | 85 | data-height="{{ thread.op.image_height }}"/> |
|
84 | 86 | </a> |
@@ -99,7 +101,7 b'' | |||
|
99 | 101 | [<a href=" |
|
100 | 102 | {% url 'delete' post_id=thread.op.id %}?next={{ request.path }}" |
|
101 | 103 | >{% trans 'Delete' %}</a>] |
|
102 |
({{ thread. |
|
|
104 | ({{ thread.op.poster_ip }}) | |
|
103 | 105 | [<a href=" |
|
104 | 106 | {% url 'ban' post_id=thread.op.id %}?next={{ request.path }}" |
|
105 | 107 | >{% trans 'Ban IP' %}</a>] |
@@ -154,6 +156,8 b'' | |||
|
154 | 156 | href="{{ post.image.url }}"><img |
|
155 | 157 | src=" {{ post.image.url_200x150 }}" |
|
156 | 158 | alt="{{ post.id }}" |
|
159 | width="{{ post.image_pre_width }}" | |
|
160 | height="{{ post.image_pre_height }}" | |
|
157 | 161 | data-width="{{ post.image_width }}" |
|
158 | 162 | data-height="{{ post.image_height }}"/> |
|
159 | 163 | </a> |
@@ -227,17 +231,23 b'' | |||
|
227 | 231 | {% block metapanel %} |
|
228 | 232 | |
|
229 | 233 | <span class="metapanel"> |
|
230 |
<b><a href="{% url "authors" %}">Neboard</a> 1. |
|
|
231 | {% trans "Pages:" %} | |
|
234 | <b><a href="{% url "authors" %}">Neboard</a> 1.5 Aker</b> | |
|
235 | {% trans "Pages:" %}[ | |
|
232 | 236 | {% for page in pages %} |
|
233 |
|
|
|
237 | <a | |
|
238 | {% ifequal page current_page %} | |
|
239 | class="current_page" | |
|
240 | {% endifequal %} | |
|
241 | href=" | |
|
234 | 242 | {% if tag %} |
|
235 | 243 | {% url "tag" tag_name=tag page=page %} |
|
236 | 244 | {% else %} |
|
237 | 245 | {% url "index" page=page %} |
|
238 | 246 | {% endif %} |
|
239 |
">{{ page }}</a> |
|
|
247 | ">{{ page }}</a> | |
|
248 | {% if not forloop.last %},{% endif %} | |
|
240 | 249 | {% endfor %} |
|
250 | ] | |
|
241 | 251 | [<a href="rss/">RSS</a>] |
|
242 | 252 | </span> |
|
243 | 253 |
@@ -6,7 +6,7 b'' | |||
|
6 | 6 | {% load board %} |
|
7 | 7 | |
|
8 | 8 | {% block head %} |
|
9 |
<title>Neboard - {{ thread.get_ |
|
|
9 | <title>Neboard - {{ thread.get_opening_post.get_title }}</title> | |
|
10 | 10 | {% endblock %} |
|
11 | 11 | |
|
12 | 12 | {% block content %} |
@@ -17,6 +17,12 b'' | |||
|
17 | 17 | <script src="{% static 'js/thread.js' %}"></script> |
|
18 | 18 | |
|
19 | 19 | {% cache 600 thread_view thread.id thread.last_edit_time moderator LANGUAGE_CODE %} |
|
20 | ||
|
21 | <div class="image-mode-tab"> | |
|
22 | <a class="current_mode" href="{% url 'thread' thread.get_opening_post.id %}">{% trans 'Normal mode' %}</a>, | |
|
23 | <a href="{% url 'thread_mode' thread.get_opening_post.id 'gallery' %}">{% trans 'Gallery mode' %}</a> | |
|
24 | </div> | |
|
25 | ||
|
20 | 26 | {% if bumpable %} |
|
21 | 27 | <div class="bar-bg"> |
|
22 | 28 | <div class="bar-value" style="width:{{ bumplimit_progress }}%" id="bumplimit_progress"> |
@@ -40,6 +46,8 b'' | |||
|
40 | 46 | href="{{ post.image.url }}"><img |
|
41 | 47 | src="{{ post.image.url_200x150 }}" |
|
42 | 48 | alt="{{ post.id }}" |
|
49 | width="{{ post.image_pre_width }}" | |
|
50 | height="{{ post.image_pre_height }}" | |
|
43 | 51 | data-width="{{ post.image_width }}" |
|
44 | 52 | data-height="{{ post.image_height }}"/> |
|
45 | 53 | </a> |
@@ -6,6 +6,17 b' from django import template' | |||
|
6 | 6 | |
|
7 | 7 | register = template.Library() |
|
8 | 8 | |
|
9 | actions = [ | |
|
10 | { | |
|
11 | 'name': 'google', | |
|
12 | 'link': 'http://google.com/searchbyimage?image_url=%s', | |
|
13 | }, | |
|
14 | { | |
|
15 | 'name': 'iqdb', | |
|
16 | 'link': 'http://iqdb.org/?url=%s', | |
|
17 | }, | |
|
18 | ] | |
|
19 | ||
|
9 | 20 | |
|
10 | 21 | @register.simple_tag(name='post_url') |
|
11 | 22 | def post_url(*args, **kwargs): |
@@ -21,3 +32,18 b' def post_url(*args, **kwargs):' | |||
|
21 | 32 | link = reverse(thread, kwargs={'post_id': post_id}) |
|
22 | 33 | |
|
23 | 34 | return link |
|
35 | ||
|
36 | ||
|
37 | @register.simple_tag(name='image_actions') | |
|
38 | def image_actions(*args, **kwargs): | |
|
39 | image_link = args[0] | |
|
40 | if len(args) > 1: | |
|
41 | image_link = 'http://' + args[1] + image_link # TODO https? | |
|
42 | ||
|
43 | result = '' | |
|
44 | ||
|
45 | for action in actions: | |
|
46 | result += '[<a href="' + action['link'] % image_link + '">' + \ | |
|
47 | action['name'] + '</a>]' | |
|
48 | ||
|
49 | return result |
@@ -3,6 +3,7 b'' | |||
|
3 | 3 | django-thumbs by Antonio Melé |
|
4 | 4 | http://django.es |
|
5 | 5 | """ |
|
6 | from django.core.files.images import ImageFile | |
|
6 | 7 | from django.db.models import ImageField |
|
7 | 8 | from django.db.models.fields.files import ImageFieldFile |
|
8 | 9 | from PIL import Image |
@@ -13,13 +14,13 b' import cStringIO' | |||
|
13 | 14 | def generate_thumb(img, thumb_size, format): |
|
14 | 15 | """ |
|
15 | 16 | Generates a thumbnail image and returns a ContentFile object with the thumbnail |
|
16 | ||
|
17 | ||
|
17 | 18 | Parameters: |
|
18 | 19 | =========== |
|
19 | 20 | img File object |
|
20 | ||
|
21 | ||
|
21 | 22 | thumb_size desired thumbnail size, ie: (200,120) |
|
22 | ||
|
23 | ||
|
23 | 24 | format format of the original image ('jpeg','gif','png',...) |
|
24 | 25 | (this format will be used for the generated thumbnail, too) |
|
25 | 26 | """ |
@@ -41,7 +42,7 b' def generate_thumb(img, thumb_size, form' | |||
|
41 | 42 | # crop it |
|
42 | 43 | image2 = image.crop( |
|
43 | 44 | (xnewsize, ynewsize, xsize - xnewsize, ysize - ynewsize)) |
|
44 |
# load is necessary after crop |
|
|
45 | # load is necessary after crop | |
|
45 | 46 | image2.load() |
|
46 | 47 | # thumbnail of the cropped image (with ANTIALIAS to make it look better) |
|
47 | 48 | image2.thumbnail(thumb_size, Image.ANTIALIAS) |
@@ -160,7 +161,9 b' class ImageWithThumbsField(ImageField):' | |||
|
160 | 161 | """ |
|
161 | 162 | |
|
162 | 163 | def __init__(self, verbose_name=None, name=None, width_field=None, |
|
163 |
height_field=None, sizes=None, |
|
|
164 | height_field=None, sizes=None, | |
|
165 | preview_width_field=None, preview_height_field=None, | |
|
166 | **kwargs): | |
|
164 | 167 | self.verbose_name = verbose_name |
|
165 | 168 | self.name = name |
|
166 | 169 | self.width_field = width_field |
@@ -168,6 +171,46 b' class ImageWithThumbsField(ImageField):' | |||
|
168 | 171 | self.sizes = sizes |
|
169 | 172 | super(ImageField, self).__init__(**kwargs) |
|
170 | 173 | |
|
174 | if sizes is not None and len(sizes) == 1: | |
|
175 | self.preview_width_field = preview_width_field | |
|
176 | self.preview_height_field = preview_height_field | |
|
177 | ||
|
178 | def update_dimension_fields(self, instance, force=False, *args, **kwargs): | |
|
179 | """ | |
|
180 | Update original image dimension fields and thumb dimension fields | |
|
181 | (only if 1 thumb size is defined) | |
|
182 | """ | |
|
183 | ||
|
184 | super(ImageWithThumbsField, self).update_dimension_fields(instance, | |
|
185 | force, *args, | |
|
186 | **kwargs) | |
|
187 | thumb_width_field = self.preview_width_field | |
|
188 | thumb_height_field = self.preview_height_field | |
|
189 | ||
|
190 | if thumb_width_field is None or thumb_height_field is None \ | |
|
191 | or len(self.sizes) != 1: | |
|
192 | return | |
|
193 | ||
|
194 | original_width = getattr(instance, self.width_field) | |
|
195 | original_height = getattr(instance, self.height_field) | |
|
196 | ||
|
197 | if original_width > 0 and original_height > 0: | |
|
198 | thumb_width, thumb_height = self.sizes[0] | |
|
199 | ||
|
200 | w_scale = float(thumb_width) / original_width | |
|
201 | h_scale = float(thumb_height) / original_height | |
|
202 | scale_ratio = min(w_scale, h_scale) | |
|
203 | ||
|
204 | if scale_ratio >= 1: | |
|
205 | thumb_width_ratio = original_width | |
|
206 | thumb_height_ratio = original_height | |
|
207 | else: | |
|
208 | thumb_width_ratio = int(original_width * scale_ratio) | |
|
209 | thumb_height_ratio = int(original_height * scale_ratio) | |
|
210 | ||
|
211 | setattr(instance, thumb_width_field, thumb_width_ratio) | |
|
212 | setattr(instance, thumb_height_field, thumb_height_ratio) | |
|
213 | ||
|
171 | 214 | |
|
172 | 215 | from south.modelsinspector import add_introspection_rules |
|
173 | 216 | add_introspection_rules([], ["^boards\.thumbs\.ImageWithThumbsField"]) |
@@ -31,6 +31,7 b" urlpatterns = patterns(''," | |||
|
31 | 31 | |
|
32 | 32 | # /boards/thread/ |
|
33 | 33 | url(r'^thread/(?P<post_id>\w+)/$', views.thread, name='thread'), |
|
34 | url(r'^thread/(?P<post_id>\w+)/(?P<mode>\w+)/$', views.thread, name='thread_mode'), | |
|
34 | 35 | url(r'^settings/$', views.settings, name='settings'), |
|
35 | 36 | url(r'^tags/$', views.all_tags, name='tags'), |
|
36 | 37 | url(r'^captcha/', include('captcha.urls')), |
@@ -7,7 +7,7 b' import re' | |||
|
7 | 7 | |
|
8 | 8 | from django.core import serializers |
|
9 | 9 | from django.core.urlresolvers import reverse |
|
10 | from django.http import HttpResponseRedirect | |
|
10 | from django.http import HttpResponseRedirect, Http404 | |
|
11 | 11 | from django.http.response import HttpResponse |
|
12 | 12 | from django.template import RequestContext |
|
13 | 13 | from django.shortcuts import render, redirect, get_object_or_404 |
@@ -30,6 +30,8 b' import neboard' | |||
|
30 | 30 | |
|
31 | 31 | |
|
32 | 32 | BAN_REASON_SPAM = 'Autoban: spam bot' |
|
33 | MODE_GALLERY = 'gallery' | |
|
34 | MODE_NORMAL = 'normal' | |
|
33 | 35 | |
|
34 | 36 | |
|
35 | 37 | def index(request, page=0): |
@@ -62,6 +64,7 b' def index(request, page=0):' | |||
|
62 | 64 | # TODO Make this generic for tag and threads list pages |
|
63 | 65 | context['threads'] = None if len(threads) == 0 else threads |
|
64 | 66 | context['form'] = form |
|
67 | context['current_page'] = int(page) | |
|
65 | 68 | |
|
66 | 69 | page_count = Post.objects.get_thread_page_count() |
|
67 | 70 | context['pages'] = range(page_count) |
@@ -154,6 +157,7 b' def tag(request, tag_name, page=0):' | |||
|
154 | 157 | context = _init_default_context(request) |
|
155 | 158 | context['threads'] = None if len(threads) == 0 else threads |
|
156 | 159 | context['tag'] = tag |
|
160 | context['current_page'] = int(page) | |
|
157 | 161 | |
|
158 | 162 | page_count = Post.objects.get_thread_page_count(tag=tag) |
|
159 | 163 | context['pages'] = range(page_count) |
@@ -169,7 +173,7 b' def tag(request, tag_name, page=0):' | |||
|
169 | 173 | context) |
|
170 | 174 | |
|
171 | 175 | |
|
172 | def thread(request, post_id): | |
|
176 | def thread(request, post_id, mode=MODE_NORMAL): | |
|
173 | 177 | """Get all thread posts""" |
|
174 | 178 | |
|
175 | 179 | if utils.need_include_captcha(request): |
@@ -209,7 +213,14 b' def thread(request, post_id):' | |||
|
209 | 213 | context["last_update"] = _datetime_to_epoch(thread_to_show.last_edit_time) |
|
210 | 214 | context["thread"] = thread_to_show |
|
211 | 215 | |
|
212 | return render(request, 'boards/thread.html', context) | |
|
216 | if MODE_NORMAL == mode: | |
|
217 | document = 'boards/thread.html' | |
|
218 | elif MODE_GALLERY == mode: | |
|
219 | document = 'boards/thread_gallery.html' | |
|
220 | else: | |
|
221 | raise Http404 | |
|
222 | ||
|
223 | return render(request, document, context) | |
|
213 | 224 | |
|
214 | 225 | |
|
215 | 226 | def login(request): |
@@ -27,7 +27,7 b' Site: http://neboard.me/' | |||
|
27 | 27 | # INSTALLATION # |
|
28 | 28 | |
|
29 | 29 | 1. Install all dependencies over pip or system-wide |
|
30 | 2. Setup a database in neboard/settings.py | |
|
30 | 2. Setup a database in `neboard/settings.py` | |
|
31 | 31 | 3. Run `./manage.py syncdb` and ensure the database was created |
|
32 | 32 | 4. Run `./manage.py migrate boards` to apply all south migrations |
|
33 | 33 | |
@@ -41,6 +41,15 b' See django-admin command help for detail' | |||
|
41 | 41 | |
|
42 | 42 | Also consider using wsgi or fcgi interfaces on production servers. |
|
43 | 43 | |
|
44 | # UPGRADE # | |
|
45 | ||
|
46 | 1. Backup your project data. | |
|
47 | 2. Save the settings in `neboard/settings.py` and `boards/settings.py` | |
|
48 | 3. Copy the project contents over the old project directory | |
|
49 | 4. Run migrations by `./manage.py migrate boards` | |
|
50 | ||
|
51 | You can also just clone the mercurial project and pull it to update | |
|
52 | ||
|
44 | 53 | # CONCLUSION # |
|
45 | 54 | |
|
46 | 55 | Enjoy our software and thank you! |
@@ -12,6 +12,7 b' denied". Use second only for autoban for' | |||
|
12 | 12 | [DONE] Split up post model into post and thread, |
|
13 | 13 | and move everything that is used only in 1st post to thread model. |
|
14 | 14 | [DONE] Show board speed in the lower panel (posts per day) |
|
15 | [DONE] Save image thumbnails size to the separate field | |
|
15 | 16 | |
|
16 | 17 | [NOT STARTED] Tree view (JS) |
|
17 | 18 | [NOT STARTED] Adding tags to images filename |
@@ -22,7 +23,6 b' and move everything that is used only in' | |||
|
22 | 23 | [NOT STARTED] Javascript disabling engine |
|
23 | 24 | [NOT STARTED] Group tags by first letter in all tags list |
|
24 | 25 | [NOT STARTED] Character counter in the post field |
|
25 | [NOT STARTED] Save image thumbnails size to the separate field | |
|
26 | 26 | [NOT STARTED] Whitelist functionality. Permin autoban of an address |
|
27 | 27 | [NOT STARTED] Statistics module. Count views (optional, may result in bad |
|
28 | 28 | performance), posts per day/week/month, users (or IPs) |
General Comments 0
You need to be logged in to leave comments.
Login now