##// END OF EJS Templates
Merged with default
neko259 -
r834:cfa74d10 merge decentral
parent child Browse files
Show More
@@ -0,0 +1,30 b''
1 {% extends "boards/base.html" %}
2
3 {% load i18n %}
4
5 {% block head %}
6 <title>{% trans 'Preview' %} - {{ site_name }}</title>
7 {% endblock %}
8
9 {% block content %}
10
11 <div class="post-form-w">
12 <div class="post-form">
13 <form enctype="multipart/form-data" method="post">
14 <textarea name="query">{{ query }}</textarea>
15 <div class="form-submit">
16 <input type="submit" value="{% trans "Post" %}"/>
17 </div>
18 </form>
19 </div>
20 </div>
21
22 {% if result %}
23 <div class="post">
24 {% autoescape off %}
25 {{ result }}
26 {% endautoescape %}
27 </div>
28 {% endif %}
29
30 {% endblock %}
@@ -0,0 +1,35 b''
1 from django.shortcuts import render
2 from django.template import RequestContext
3 from django.views.generic import View
4
5 from boards.mdx_neboard import bbcode_extended
6
7 FORM_QUERY = 'query'
8
9 CONTEXT_RESULT = 'result'
10 CONTEXT_QUERY = 'query'
11
12 __author__ = 'neko259'
13
14 TEMPLATE = 'boards/preview.html'
15
16
17 class PostPreviewView(View):
18 def get(self, request):
19 context = RequestContext(request)
20
21 return render(request, TEMPLATE, context)
22
23 def post(self, request):
24 context = RequestContext(request)
25
26 if FORM_QUERY in request.POST:
27 raw_text = request.POST[FORM_QUERY]
28
29 if len(raw_text) >= 0:
30 rendered_text = bbcode_extended(raw_text)
31
32 context[CONTEXT_RESULT] = rendered_text
33 context[CONTEXT_QUERY] = raw_text
34
35 return render(request, TEMPLATE, context)
@@ -1,298 +1,294 b''
1 import re
1 import re
2 import time
2 import time
3 import hashlib
3 import hashlib
4
4
5 from django import forms
5 from django import forms
6 from django.forms.util import ErrorList
6 from django.forms.util import ErrorList
7 from django.utils.translation import ugettext_lazy as _
7 from django.utils.translation import ugettext_lazy as _
8
8
9 from boards.mdx_neboard import formatters
9 from boards.mdx_neboard import formatters
10 from boards.models.post import TITLE_MAX_LENGTH
10 from boards.models.post import TITLE_MAX_LENGTH
11 from boards.models import PostImage
11 from boards.models import PostImage
12 from neboard import settings
12 from neboard import settings
13 from boards import utils
13 from boards import utils
14 import boards.settings as board_settings
14 import boards.settings as board_settings
15
15
16 VETERAN_POSTING_DELAY = 5
16 VETERAN_POSTING_DELAY = 5
17
17
18 ATTRIBUTE_PLACEHOLDER = 'placeholder'
18 ATTRIBUTE_PLACEHOLDER = 'placeholder'
19
19
20 LAST_POST_TIME = 'last_post_time'
20 LAST_POST_TIME = 'last_post_time'
21 LAST_LOGIN_TIME = 'last_login_time'
21 LAST_LOGIN_TIME = 'last_login_time'
22 TEXT_PLACEHOLDER = _('''Type message here. Use formatting panel for more advanced usage.''')
22 TEXT_PLACEHOLDER = _('''Type message here. Use formatting panel for more advanced usage.''')
23 TAGS_PLACEHOLDER = _('tag1 several_words_tag')
23 TAGS_PLACEHOLDER = _('tag1 several_words_tag')
24
24
25 ERROR_IMAGE_DUPLICATE = _('Such image was already posted')
25 ERROR_IMAGE_DUPLICATE = _('Such image was already posted')
26
26
27 LABEL_TITLE = _('Title')
27 LABEL_TITLE = _('Title')
28 LABEL_TEXT = _('Text')
28 LABEL_TEXT = _('Text')
29 LABEL_TAG = _('Tag')
29 LABEL_TAG = _('Tag')
30 LABEL_SEARCH = _('Search')
30 LABEL_SEARCH = _('Search')
31
31
32 TAG_MAX_LENGTH = 20
32 TAG_MAX_LENGTH = 20
33
33
34 REGEX_TAG = r'^[\w\d]+$'
34 REGEX_TAG = r'^[\w\d]+$'
35
35
36
36
37 class FormatPanel(forms.Textarea):
37 class FormatPanel(forms.Textarea):
38 def render(self, name, value, attrs=None):
38 def render(self, name, value, attrs=None):
39 output = '<div id="mark-panel">'
39 output = '<div id="mark-panel">'
40 for formatter in formatters:
40 for formatter in formatters:
41 output += '<span class="mark_btn"' + \
41 output += '<span class="mark_btn"' + \
42 ' onClick="addMarkToMsg(\'' + formatter.format_left + \
42 ' onClick="addMarkToMsg(\'' + formatter.format_left + \
43 '\', \'' + formatter.format_right + '\')">' + \
43 '\', \'' + formatter.format_right + '\')">' + \
44 formatter.preview_left + formatter.name + \
44 formatter.preview_left + formatter.name + \
45 formatter.preview_right + '</span>'
45 formatter.preview_right + '</span>'
46
46
47 output += '</div>'
47 output += '</div>'
48 output += super(FormatPanel, self).render(name, value, attrs=None)
48 output += super(FormatPanel, self).render(name, value, attrs=None)
49
49
50 return output
50 return output
51
51
52
52
53 class PlainErrorList(ErrorList):
53 class PlainErrorList(ErrorList):
54 def __unicode__(self):
54 def __unicode__(self):
55 return self.as_text()
55 return self.as_text()
56
56
57 def as_text(self):
57 def as_text(self):
58 return ''.join(['(!) %s ' % e for e in self])
58 return ''.join(['(!) %s ' % e for e in self])
59
59
60
60
61 class NeboardForm(forms.Form):
61 class NeboardForm(forms.Form):
62
62
63 def as_div(self):
63 def as_div(self):
64 """
64 """
65 Returns this form rendered as HTML <as_div>s.
65 Returns this form rendered as HTML <as_div>s.
66 """
66 """
67
67
68 return self._html_output(
68 return self._html_output(
69 # TODO Do not show hidden rows in the list here
69 # TODO Do not show hidden rows in the list here
70 normal_row='<div class="form-row"><div class="form-label">'
70 normal_row='<div class="form-row"><div class="form-label">'
71 '%(label)s'
71 '%(label)s'
72 '</div></div>'
72 '</div></div>'
73 '<div class="form-row"><div class="form-input">'
73 '<div class="form-row"><div class="form-input">'
74 '%(field)s'
74 '%(field)s'
75 '</div></div>'
75 '</div></div>'
76 '<div class="form-row">'
76 '<div class="form-row">'
77 '%(help_text)s'
77 '%(help_text)s'
78 '</div>',
78 '</div>',
79 error_row='<div class="form-row">'
79 error_row='<div class="form-row">'
80 '<div class="form-label"></div>'
80 '<div class="form-label"></div>'
81 '<div class="form-errors">%s</div>'
81 '<div class="form-errors">%s</div>'
82 '</div>',
82 '</div>',
83 row_ender='</div>',
83 row_ender='</div>',
84 help_text_html='%s',
84 help_text_html='%s',
85 errors_on_separate_row=True)
85 errors_on_separate_row=True)
86
86
87 def as_json_errors(self):
87 def as_json_errors(self):
88 errors = []
88 errors = []
89
89
90 for name, field in list(self.fields.items()):
90 for name, field in list(self.fields.items()):
91 if self[name].errors:
91 if self[name].errors:
92 errors.append({
92 errors.append({
93 'field': name,
93 'field': name,
94 'errors': self[name].errors.as_text(),
94 'errors': self[name].errors.as_text(),
95 })
95 })
96
96
97 return errors
97 return errors
98
98
99
99
100 class PostForm(NeboardForm):
100 class PostForm(NeboardForm):
101
101
102 title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False,
102 title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False,
103 label=LABEL_TITLE)
103 label=LABEL_TITLE)
104 text = forms.CharField(
104 text = forms.CharField(
105 widget=FormatPanel(attrs={ATTRIBUTE_PLACEHOLDER: TEXT_PLACEHOLDER}),
105 widget=FormatPanel(attrs={ATTRIBUTE_PLACEHOLDER: TEXT_PLACEHOLDER}),
106 required=False, label=LABEL_TEXT)
106 required=False, label=LABEL_TEXT)
107 image = forms.ImageField(required=False, label=_('Image'),
107 image = forms.ImageField(required=False, label=_('Image'),
108 widget=forms.ClearableFileInput(
108 widget=forms.ClearableFileInput(
109 attrs={'accept': 'image/*'}))
109 attrs={'accept': 'image/*'}))
110
110
111 # This field is for spam prevention only
111 # This field is for spam prevention only
112 email = forms.CharField(max_length=100, required=False, label=_('e-mail'),
112 email = forms.CharField(max_length=100, required=False, label=_('e-mail'),
113 widget=forms.TextInput(attrs={
113 widget=forms.TextInput(attrs={
114 'class': 'form-email'}))
114 'class': 'form-email'}))
115
115
116 session = None
116 session = None
117 need_to_ban = False
117 need_to_ban = False
118
118
119 def clean_title(self):
119 def clean_title(self):
120 title = self.cleaned_data['title']
120 title = self.cleaned_data['title']
121 if title:
121 if title:
122 if len(title) > TITLE_MAX_LENGTH:
122 if len(title) > TITLE_MAX_LENGTH:
123 raise forms.ValidationError(_('Title must have less than %s '
123 raise forms.ValidationError(_('Title must have less than %s '
124 'characters') %
124 'characters') %
125 str(TITLE_MAX_LENGTH))
125 str(TITLE_MAX_LENGTH))
126 return title
126 return title
127
127
128 def clean_text(self):
128 def clean_text(self):
129 text = self.cleaned_data['text'].strip()
129 text = self.cleaned_data['text'].strip()
130 if text:
130 if text:
131 if len(text) > board_settings.MAX_TEXT_LENGTH:
131 if len(text) > board_settings.MAX_TEXT_LENGTH:
132 raise forms.ValidationError(_('Text must have less than %s '
132 raise forms.ValidationError(_('Text must have less than %s '
133 'characters') %
133 'characters') %
134 str(board_settings
134 str(board_settings
135 .MAX_TEXT_LENGTH))
135 .MAX_TEXT_LENGTH))
136 return text
136 return text
137
137
138 def clean_image(self):
138 def clean_image(self):
139 image = self.cleaned_data['image']
139 image = self.cleaned_data['image']
140 if image:
140 if image:
141 if image.size > board_settings.MAX_IMAGE_SIZE:
141 if image.size > board_settings.MAX_IMAGE_SIZE:
142 raise forms.ValidationError(
142 raise forms.ValidationError(
143 _('Image must be less than %s bytes')
143 _('Image must be less than %s bytes')
144 % str(board_settings.MAX_IMAGE_SIZE))
144 % str(board_settings.MAX_IMAGE_SIZE))
145
145
146 md5 = hashlib.md5()
146 md5 = hashlib.md5()
147 for chunk in image.chunks():
147 for chunk in image.chunks():
148 md5.update(chunk)
148 md5.update(chunk)
149 image_hash = md5.hexdigest()
149 image_hash = md5.hexdigest()
150 if PostImage.objects.filter(hash=image_hash).exists():
150 if PostImage.objects.filter(hash=image_hash).exists():
151 raise forms.ValidationError(ERROR_IMAGE_DUPLICATE)
151 raise forms.ValidationError(ERROR_IMAGE_DUPLICATE)
152
152
153 return image
153 return image
154
154
155 def clean(self):
155 def clean(self):
156 cleaned_data = super(PostForm, self).clean()
156 cleaned_data = super(PostForm, self).clean()
157
157
158 if not self.session:
158 if not self.session:
159 raise forms.ValidationError('Humans have sessions')
159 raise forms.ValidationError('Humans have sessions')
160
160
161 if cleaned_data['email']:
161 if cleaned_data['email']:
162 self.need_to_ban = True
162 self.need_to_ban = True
163 raise forms.ValidationError('A human cannot enter a hidden field')
163 raise forms.ValidationError('A human cannot enter a hidden field')
164
164
165 if not self.errors:
165 if not self.errors:
166 self._clean_text_image()
166 self._clean_text_image()
167
167
168 if not self.errors and self.session:
168 if not self.errors and self.session:
169 self._validate_posting_speed()
169 self._validate_posting_speed()
170
170
171 return cleaned_data
171 return cleaned_data
172
172
173 def _clean_text_image(self):
173 def _clean_text_image(self):
174 text = self.cleaned_data.get('text')
174 text = self.cleaned_data.get('text')
175 image = self.cleaned_data.get('image')
175 image = self.cleaned_data.get('image')
176
176
177 if (not text) and (not image):
177 if (not text) and (not image):
178 error_message = _('Either text or image must be entered.')
178 error_message = _('Either text or image must be entered.')
179 self._errors['text'] = self.error_class([error_message])
179 self._errors['text'] = self.error_class([error_message])
180
180
181 def _validate_posting_speed(self):
181 def _validate_posting_speed(self):
182 can_post = True
182 can_post = True
183
183
184 # TODO Remove this, it's only for test
185 if not 'user_id' in self.session:
186 return
187
188 posting_delay = settings.POSTING_DELAY
184 posting_delay = settings.POSTING_DELAY
189
185
190 if board_settings.LIMIT_POSTING_SPEED and LAST_POST_TIME in \
186 if board_settings.LIMIT_POSTING_SPEED and LAST_POST_TIME in \
191 self.session:
187 self.session:
192 now = time.time()
188 now = time.time()
193 last_post_time = self.session[LAST_POST_TIME]
189 last_post_time = self.session[LAST_POST_TIME]
194
190
195 current_delay = int(now - last_post_time)
191 current_delay = int(now - last_post_time)
196
192
197 if current_delay < posting_delay:
193 if current_delay < posting_delay:
198 error_message = _('Wait %s seconds after last posting') % str(
194 error_message = _('Wait %s seconds after last posting') % str(
199 posting_delay - current_delay)
195 posting_delay - current_delay)
200 self._errors['text'] = self.error_class([error_message])
196 self._errors['text'] = self.error_class([error_message])
201
197
202 can_post = False
198 can_post = False
203
199
204 if can_post:
200 if can_post:
205 self.session[LAST_POST_TIME] = time.time()
201 self.session[LAST_POST_TIME] = time.time()
206
202
207
203
208 class ThreadForm(PostForm):
204 class ThreadForm(PostForm):
209
205
210 regex_tags = re.compile(r'^[\w\s\d]+$', re.UNICODE)
206 regex_tags = re.compile(r'^[\w\s\d]+$', re.UNICODE)
211
207
212 tags = forms.CharField(
208 tags = forms.CharField(
213 widget=forms.TextInput(attrs={ATTRIBUTE_PLACEHOLDER: TAGS_PLACEHOLDER}),
209 widget=forms.TextInput(attrs={ATTRIBUTE_PLACEHOLDER: TAGS_PLACEHOLDER}),
214 max_length=100, label=_('Tags'), required=True)
210 max_length=100, label=_('Tags'), required=True)
215
211
216 def clean_tags(self):
212 def clean_tags(self):
217 tags = self.cleaned_data['tags'].strip()
213 tags = self.cleaned_data['tags'].strip()
218
214
219 if not tags or not self.regex_tags.match(tags):
215 if not tags or not self.regex_tags.match(tags):
220 raise forms.ValidationError(
216 raise forms.ValidationError(
221 _('Inappropriate characters in tags.'))
217 _('Inappropriate characters in tags.'))
222
218
223 return tags
219 return tags
224
220
225 def clean(self):
221 def clean(self):
226 cleaned_data = super(ThreadForm, self).clean()
222 cleaned_data = super(ThreadForm, self).clean()
227
223
228 return cleaned_data
224 return cleaned_data
229
225
230
226
231 class SettingsForm(NeboardForm):
227 class SettingsForm(NeboardForm):
232
228
233 theme = forms.ChoiceField(choices=settings.THEMES,
229 theme = forms.ChoiceField(choices=settings.THEMES,
234 label=_('Theme'))
230 label=_('Theme'))
235
231
236
232
237 class AddTagForm(NeboardForm):
233 class AddTagForm(NeboardForm):
238
234
239 tag = forms.CharField(max_length=TAG_MAX_LENGTH, label=LABEL_TAG)
235 tag = forms.CharField(max_length=TAG_MAX_LENGTH, label=LABEL_TAG)
240 method = forms.CharField(widget=forms.HiddenInput(), initial='add_tag')
236 method = forms.CharField(widget=forms.HiddenInput(), initial='add_tag')
241
237
242 def clean_tag(self):
238 def clean_tag(self):
243 tag = self.cleaned_data['tag']
239 tag = self.cleaned_data['tag']
244
240
245 regex_tag = re.compile(REGEX_TAG, re.UNICODE)
241 regex_tag = re.compile(REGEX_TAG, re.UNICODE)
246 if not regex_tag.match(tag):
242 if not regex_tag.match(tag):
247 raise forms.ValidationError(_('Inappropriate characters in tags.'))
243 raise forms.ValidationError(_('Inappropriate characters in tags.'))
248
244
249 return tag
245 return tag
250
246
251 def clean(self):
247 def clean(self):
252 cleaned_data = super(AddTagForm, self).clean()
248 cleaned_data = super(AddTagForm, self).clean()
253
249
254 return cleaned_data
250 return cleaned_data
255
251
256
252
257 class SearchForm(NeboardForm):
253 class SearchForm(NeboardForm):
258 query = forms.CharField(max_length=500, label=LABEL_SEARCH, required=False)
254 query = forms.CharField(max_length=500, label=LABEL_SEARCH, required=False)
259
255
260
256
261 class LoginForm(NeboardForm):
257 class LoginForm(NeboardForm):
262
258
263 password = forms.CharField()
259 password = forms.CharField()
264
260
265 session = None
261 session = None
266
262
267 def clean_password(self):
263 def clean_password(self):
268 password = self.cleaned_data['password']
264 password = self.cleaned_data['password']
269 if board_settings.MASTER_PASSWORD != password:
265 if board_settings.MASTER_PASSWORD != password:
270 raise forms.ValidationError(_('Invalid master password'))
266 raise forms.ValidationError(_('Invalid master password'))
271
267
272 return password
268 return password
273
269
274 def _validate_login_speed(self):
270 def _validate_login_speed(self):
275 can_post = True
271 can_post = True
276
272
277 if LAST_LOGIN_TIME in self.session:
273 if LAST_LOGIN_TIME in self.session:
278 now = time.time()
274 now = time.time()
279 last_login_time = self.session[LAST_LOGIN_TIME]
275 last_login_time = self.session[LAST_LOGIN_TIME]
280
276
281 current_delay = int(now - last_login_time)
277 current_delay = int(now - last_login_time)
282
278
283 if current_delay < board_settings.LOGIN_TIMEOUT:
279 if current_delay < board_settings.LOGIN_TIMEOUT:
284 error_message = _('Wait %s minutes after last login') % str(
280 error_message = _('Wait %s minutes after last login') % str(
285 (board_settings.LOGIN_TIMEOUT - current_delay) / 60)
281 (board_settings.LOGIN_TIMEOUT - current_delay) / 60)
286 self._errors['password'] = self.error_class([error_message])
282 self._errors['password'] = self.error_class([error_message])
287
283
288 can_post = False
284 can_post = False
289
285
290 if can_post:
286 if can_post:
291 self.session[LAST_LOGIN_TIME] = time.time()
287 self.session[LAST_LOGIN_TIME] = time.time()
292
288
293 def clean(self):
289 def clean(self):
294 self._validate_login_speed()
290 self._validate_login_speed()
295
291
296 cleaned_data = super(LoginForm, self).clean()
292 cleaned_data = super(LoginForm, self).clean()
297
293
298 return cleaned_data
294 return cleaned_data
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -1,361 +1,365 b''
1 # SOME DESCRIPTIVE TITLE.
1 # SOME DESCRIPTIVE TITLE.
2 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
2 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3 # This file is distributed under the same license as the PACKAGE package.
3 # This file is distributed under the same license as the PACKAGE package.
4 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
4 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5 #
5 #
6 msgid ""
6 msgid ""
7 msgstr ""
7 msgstr ""
8 "Project-Id-Version: PACKAGE VERSION\n"
8 "Project-Id-Version: PACKAGE VERSION\n"
9 "Report-Msgid-Bugs-To: \n"
9 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2014-07-20 20:11+0300\n"
10 "POT-Creation-Date: 2014-08-19 15:51+0300\n"
11 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
11 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 "Language-Team: LANGUAGE <LL@li.org>\n"
13 "Language-Team: LANGUAGE <LL@li.org>\n"
14 "Language: ru\n"
14 "Language: ru\n"
15 "MIME-Version: 1.0\n"
15 "MIME-Version: 1.0\n"
16 "Content-Type: text/plain; charset=UTF-8\n"
16 "Content-Type: text/plain; charset=UTF-8\n"
17 "Content-Transfer-Encoding: 8bit\n"
17 "Content-Transfer-Encoding: 8bit\n"
18 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
18 "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
19 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
19 "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
20
20
21 #: authors.py:9
21 #: authors.py:9
22 msgid "author"
22 msgid "author"
23 msgstr "Π°Π²Ρ‚ΠΎΡ€"
23 msgstr "Π°Π²Ρ‚ΠΎΡ€"
24
24
25 #: authors.py:10
25 #: authors.py:10
26 msgid "developer"
26 msgid "developer"
27 msgstr "Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ"
27 msgstr "Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ"
28
28
29 #: authors.py:11
29 #: authors.py:11
30 msgid "javascript developer"
30 msgid "javascript developer"
31 msgstr "Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ javascript"
31 msgstr "Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ javascript"
32
32
33 #: authors.py:12
33 #: authors.py:12
34 msgid "designer"
34 msgid "designer"
35 msgstr "Π΄ΠΈΠ·Π°ΠΉΠ½Π΅Ρ€"
35 msgstr "Π΄ΠΈΠ·Π°ΠΉΠ½Π΅Ρ€"
36
36
37 #: forms.py:23
37 #: forms.py:22
38 msgid "Type message here. Use formatting panel for more advanced usage."
38 msgid "Type message here. Use formatting panel for more advanced usage."
39 msgstr ""
39 msgstr ""
40 "Π’Π²ΠΎΠ΄ΠΈΡ‚Π΅ сообщСниС сюда. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ панСль для Π±ΠΎΠ»Π΅Π΅ слоТного форматирования."
40 "Π’Π²ΠΎΠ΄ΠΈΡ‚Π΅ сообщСниС сюда. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ панСль для Π±ΠΎΠ»Π΅Π΅ слоТного форматирования."
41
41
42 #: forms.py:24
42 #: forms.py:23
43 msgid "tag1 several_words_tag"
43 msgid "tag1 several_words_tag"
44 msgstr "Ρ‚Π΅Π³1 Ρ‚Π΅Π³_ΠΈΠ·_Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ…_слов"
44 msgstr "Ρ‚Π΅Π³1 Ρ‚Π΅Π³_ΠΈΠ·_Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ…_слов"
45
45
46 #: forms.py:26
46 #: forms.py:25
47 msgid "Such image was already posted"
47 msgid "Such image was already posted"
48 msgstr "Π’Π°ΠΊΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π±Ρ‹Π»ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½ΠΎ"
48 msgstr "Π’Π°ΠΊΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΡƒΠΆΠ΅ Π±Ρ‹Π»ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½ΠΎ"
49
49
50 #: forms.py:28
50 #: forms.py:27
51 msgid "Title"
51 msgid "Title"
52 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ"
52 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ"
53
53
54 #: forms.py:29
54 #: forms.py:28
55 msgid "Text"
55 msgid "Text"
56 msgstr "ВСкст"
56 msgstr "ВСкст"
57
57
58 #: forms.py:30
58 #: forms.py:29
59 msgid "Tag"
59 msgid "Tag"
60 msgstr "Π’Π΅Π³"
60 msgstr "Π’Π΅Π³"
61
61
62 #: forms.py:31 templates/boards/base.html:54 templates/search/search.html:9
62 #: forms.py:30 templates/boards/base.html:36 templates/search/search.html:9
63 #: templates/search/search.html.py:13
63 #: templates/search/search.html.py:13
64 msgid "Search"
64 msgid "Search"
65 msgstr "Поиск"
65 msgstr "Поиск"
66
66
67 #: forms.py:108
67 #: forms.py:107
68 msgid "Image"
68 msgid "Image"
69 msgstr "Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅"
69 msgstr "Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅"
70
70
71 #: forms.py:113
71 #: forms.py:112
72 msgid "e-mail"
72 msgid "e-mail"
73 msgstr ""
73 msgstr ""
74
74
75 #: forms.py:124
75 #: forms.py:123
76 #, python-format
76 #, python-format
77 msgid "Title must have less than %s characters"
77 msgid "Title must have less than %s characters"
78 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ мСньшС %s символов"
78 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ мСньшС %s символов"
79
79
80 #: forms.py:133
80 #: forms.py:132
81 #, python-format
81 #, python-format
82 msgid "Text must have less than %s characters"
82 msgid "Text must have less than %s characters"
83 msgstr "ВСкст Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΊΠΎΡ€ΠΎΡ‡Π΅ %s символов"
83 msgstr "ВСкст Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΊΠΎΡ€ΠΎΡ‡Π΅ %s символов"
84
84
85 #: forms.py:144
85 #: forms.py:143
86 #, python-format
86 #, python-format
87 msgid "Image must be less than %s bytes"
87 msgid "Image must be less than %s bytes"
88 msgstr "Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΌΠ΅Π½Π΅Π΅ %s Π±Π°ΠΉΡ‚"
88 msgstr "Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΌΠ΅Π½Π΅Π΅ %s Π±Π°ΠΉΡ‚"
89
89
90 #: forms.py:179
90 #: forms.py:178
91 msgid "Either text or image must be entered."
91 msgid "Either text or image must be entered."
92 msgstr "ВСкст ΠΈΠ»ΠΈ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π²Π²Π΅Π΄Π΅Π½Ρ‹."
92 msgstr "ВСкст ΠΈΠ»ΠΈ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π²Π²Π΅Π΄Π΅Π½Ρ‹."
93
93
94 #: forms.py:199
94 #: forms.py:198
95 #, python-format
95 #, python-format
96 msgid "Wait %s seconds after last posting"
96 msgid "Wait %s seconds after last posting"
97 msgstr "ΠŸΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %s сСкунд послС послСднСго постинга"
97 msgstr "ΠŸΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %s сСкунд послС послСднСго постинга"
98
98
99 #: forms.py:215 templates/boards/tags.html:7 templates/boards/rss/post.html:10
99 #: forms.py:214 templates/boards/tags.html:7 templates/boards/rss/post.html:10
100 msgid "Tags"
100 msgid "Tags"
101 msgstr "Π’Π΅Π³ΠΈ"
101 msgstr "Π’Π΅Π³ΠΈ"
102
102
103 #: forms.py:222 forms.py:290
103 #: forms.py:221 forms.py:247
104 msgid "Inappropriate characters in tags."
104 msgid "Inappropriate characters in tags."
105 msgstr "НСдопустимыС символы Π² Ρ‚Π΅Π³Π°Ρ…."
105 msgstr "НСдопустимыС символы Π² Ρ‚Π΅Π³Π°Ρ…."
106
106
107 #: forms.py:250 forms.py:271
107 #: forms.py:234
108 msgid "Captcha validation failed"
109 msgstr "ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΊΠ°ΠΏΡ‡ΠΈ ΠΏΡ€ΠΎΠ²Π°Π»Π΅Π½Π°"
110
111 #: forms.py:277
112 msgid "Theme"
108 msgid "Theme"
113 msgstr "Π’Π΅ΠΌΠ°"
109 msgstr "Π’Π΅ΠΌΠ°"
114
110
115 #: forms.py:313
111 #: forms.py:270
116 msgid "Invalid master password"
112 msgid "Invalid master password"
117 msgstr "НСвСрный мастСр-ΠΏΠ°Ρ€ΠΎΠ»ΡŒ"
113 msgstr "НСвСрный мастСр-ΠΏΠ°Ρ€ΠΎΠ»ΡŒ"
118
114
119 #: forms.py:327
115 #: forms.py:284
120 #, python-format
116 #, python-format
121 msgid "Wait %s minutes after last login"
117 msgid "Wait %s minutes after last login"
122 msgstr "ΠŸΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %s ΠΌΠΈΠ½ΡƒΡ‚ послС послСднСго Π²Ρ…ΠΎΠ΄Π°"
118 msgstr "ΠŸΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %s ΠΌΠΈΠ½ΡƒΡ‚ послС послСднСго Π²Ρ…ΠΎΠ΄Π°"
123
119
124 #: templates/boards/404.html:6
120 #: templates/boards/404.html:6
125 msgid "Not found"
121 msgid "Not found"
126 msgstr "НС найдСно"
122 msgstr "НС найдСно"
127
123
128 #: templates/boards/404.html:12
124 #: templates/boards/404.html:12
129 msgid "This page does not exist"
125 msgid "This page does not exist"
130 msgstr "Π­Ρ‚ΠΎΠΉ страницы Π½Π΅ сущСствуСт"
126 msgstr "Π­Ρ‚ΠΎΠΉ страницы Π½Π΅ сущСствуСт"
131
127
132 #: templates/boards/authors.html:6 templates/boards/authors.html.py:12
128 #: templates/boards/authors.html:6 templates/boards/authors.html.py:12
133 msgid "Authors"
129 msgid "Authors"
134 msgstr "Авторы"
130 msgstr "Авторы"
135
131
136 #: templates/boards/authors.html:26
132 #: templates/boards/authors.html:26
137 msgid "Distributed under the"
133 msgid "Distributed under the"
138 msgstr "РаспространяСтся ΠΏΠΎΠ΄"
134 msgstr "РаспространяСтся ΠΏΠΎΠ΄"
139
135
140 #: templates/boards/authors.html:28
136 #: templates/boards/authors.html:28
141 msgid "license"
137 msgid "license"
142 msgstr "Π»ΠΈΡ†Π΅Π½Π·ΠΈΠ΅ΠΉ"
138 msgstr "Π»ΠΈΡ†Π΅Π½Π·ΠΈΠ΅ΠΉ"
143
139
144 #: templates/boards/authors.html:30
140 #: templates/boards/authors.html:30
145 msgid "Repository"
141 msgid "Repository"
146 msgstr "Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ"
142 msgstr "Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ"
147
143
148 #: templates/boards/base.html:12
144 #: templates/boards/base.html:12
149 msgid "Feed"
145 msgid "Feed"
150 msgstr "Π›Π΅Π½Ρ‚Π°"
146 msgstr "Π›Π΅Π½Ρ‚Π°"
151
147
152 #: templates/boards/base.html:29
148 #: templates/boards/base.html:29
153 msgid "All threads"
149 msgid "All threads"
154 msgstr "ВсС Ρ‚Π΅ΠΌΡ‹"
150 msgstr "ВсС Ρ‚Π΅ΠΌΡ‹"
155
151
156 #: templates/boards/base.html:34
152 #: templates/boards/base.html:34
157 msgid "Tag management"
153 msgid "Tag management"
158 msgstr "Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ‚Π΅Π³Π°ΠΌΠΈ"
154 msgstr "Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ‚Π΅Π³Π°ΠΌΠΈ"
159
155
160 #: templates/boards/base.html:36 templates/boards/settings.html:7
156 #: templates/boards/base.html:37 templates/boards/settings.html:7
161 msgid "Settings"
157 msgid "Settings"
162 msgstr "Настройки"
158 msgstr "Настройки"
163
159
164 #: templates/boards/base.html:50
160 #: templates/boards/base.html:50
165 msgid "Logout"
161 msgid "Admin"
166 msgstr "Π’Ρ‹Ρ…ΠΎΠ΄"
162 msgstr ""
167
163
168 #: templates/boards/base.html:52 templates/boards/login.html:6
164 #: templates/boards/base.html:52
169 #: templates/boards/login.html.py:16
170 msgid "Login"
171 msgstr "Π’Ρ…ΠΎΠ΄"
172
173 #: templates/boards/base.html:56
174 #, python-format
165 #, python-format
175 msgid "Speed: %(ppd)s posts per day"
166 msgid "Speed: %(ppd)s posts per day"
176 msgstr "Π‘ΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ: %(ppd)s сообщСний Π² дСнь"
167 msgstr "Π‘ΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ: %(ppd)s сообщСний Π² дСнь"
177
168
178 #: templates/boards/base.html:58
169 #: templates/boards/base.html:54
179 msgid "Up"
170 msgid "Up"
180 msgstr "Π’Π²Π΅Ρ€Ρ…"
171 msgstr "Π’Π²Π΅Ρ€Ρ…"
181
172
173 #: templates/boards/login.html:6 templates/boards/login.html.py:16
174 msgid "Login"
175 msgstr "Π’Ρ…ΠΎΠ΄"
176
182 #: templates/boards/login.html:19
177 #: templates/boards/login.html:19
183 msgid "Insert your user id above"
178 msgid "Insert your user id above"
184 msgstr "Π’ΡΡ‚Π°Π²ΡŒΡ‚Π΅ свой ID ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π²Ρ‹ΡˆΠ΅"
179 msgstr "Π’ΡΡ‚Π°Π²ΡŒΡ‚Π΅ свой ID ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π²Ρ‹ΡˆΠ΅"
185
180
186 #: templates/boards/post.html:21 templates/boards/staticpages/help.html:17
181 #: templates/boards/post.html:21 templates/boards/staticpages/help.html:17
187 msgid "Quote"
182 msgid "Quote"
188 msgstr "Π¦ΠΈΡ‚Π°Ρ‚Π°"
183 msgstr "Π¦ΠΈΡ‚Π°Ρ‚Π°"
189
184
190 #: templates/boards/post.html:31
185 #: templates/boards/post.html:31
191 msgid "Open"
186 msgid "Open"
192 msgstr "ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ"
187 msgstr "ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ"
193
188
194 #: templates/boards/post.html:33
189 #: templates/boards/post.html:33
195 msgid "Reply"
190 msgid "Reply"
196 msgstr "ΠžΡ‚Π²Π΅Ρ‚"
191 msgstr "ΠžΡ‚Π²Π΅Ρ‚"
197
192
198 #: templates/boards/post.html:40
193 #: templates/boards/post.html:40
199 msgid "Edit"
194 msgid "Edit"
200 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ"
195 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ"
201
196
202 #: templates/boards/post.html:42
197 #: templates/boards/post.html:42
203 msgid "Delete"
198 msgid "Delete"
204 msgstr "Π£Π΄Π°Π»ΠΈΡ‚ΡŒ"
199 msgstr "Π£Π΄Π°Π»ΠΈΡ‚ΡŒ"
205
200
206 #: templates/boards/post.html:45
201 #: templates/boards/post.html:45
207 msgid "Ban IP"
202 msgid "Ban IP"
208 msgstr "Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ IP"
203 msgstr "Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ IP"
209
204
210 #: templates/boards/post.html:76
205 #: templates/boards/post.html:76
211 msgid "Replies"
206 msgid "Replies"
212 msgstr "ΠžΡ‚Π²Π΅Ρ‚Ρ‹"
207 msgstr "ΠžΡ‚Π²Π΅Ρ‚Ρ‹"
213
208
214 #: templates/boards/post.html:86 templates/boards/thread.html:88
209 #: templates/boards/post.html:86 templates/boards/thread.html:88
215 #: templates/boards/thread_gallery.html:61
210 #: templates/boards/thread_gallery.html:59
216 msgid "messages"
211 msgid "messages"
217 msgstr "сообщСний"
212 msgstr "сообщСний"
218
213
219 #: templates/boards/post.html:87 templates/boards/thread.html:89
214 #: templates/boards/post.html:87 templates/boards/thread.html:89
220 #: templates/boards/thread_gallery.html:62
215 #: templates/boards/thread_gallery.html:60
221 msgid "images"
216 msgid "images"
222 msgstr "ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ"
217 msgstr "ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ"
223
218
224 #: templates/boards/post_admin.html:19
219 #: templates/boards/post_admin.html:19
225 msgid "Tags:"
220 msgid "Tags:"
226 msgstr "Π’Π΅Π³ΠΈ:"
221 msgstr "Π’Π΅Π³ΠΈ:"
227
222
228 #: templates/boards/post_admin.html:30
223 #: templates/boards/post_admin.html:30
229 msgid "Add tag"
224 msgid "Add tag"
230 msgstr "Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‚Π΅Π³"
225 msgstr "Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‚Π΅Π³"
231
226
232 #: templates/boards/posting_general.html:56
227 #: templates/boards/posting_general.html:56
233 msgid "Show tag"
228 msgid "Show tag"
234 msgstr "ΠŸΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚Π΅Π³"
229 msgstr "ΠŸΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚Π΅Π³"
235
230
236 #: templates/boards/posting_general.html:60
231 #: templates/boards/posting_general.html:60
237 msgid "Hide tag"
232 msgid "Hide tag"
238 msgstr "Π‘ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚Π΅Π³"
233 msgstr "Π‘ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚Π΅Π³"
239
234
240 #: templates/boards/posting_general.html:79 templates/search/search.html:22
235 #: templates/boards/posting_general.html:79 templates/search/search.html:22
241 msgid "Previous page"
236 msgid "Previous page"
242 msgstr "ΠŸΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π°Ρ страница"
237 msgstr "ΠŸΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π°Ρ страница"
243
238
244 #: templates/boards/posting_general.html:94
239 #: templates/boards/posting_general.html:94
245 #, python-format
240 #, python-format
246 msgid "Skipped %(count)s replies. Open thread to see all replies."
241 msgid "Skipped %(count)s replies. Open thread to see all replies."
247 msgstr "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ². ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ‚Ρ€Π΅Π΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ всС ΠΎΡ‚Π²Π΅Ρ‚Ρ‹."
242 msgstr "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ². ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ‚Ρ€Π΅Π΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ всС ΠΎΡ‚Π²Π΅Ρ‚Ρ‹."
248
243
249 #: templates/boards/posting_general.html:121 templates/search/search.html:33
244 #: templates/boards/posting_general.html:121 templates/search/search.html:33
250 msgid "Next page"
245 msgid "Next page"
251 msgstr "Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ страница"
246 msgstr "Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ страница"
252
247
253 #: templates/boards/posting_general.html:126
248 #: templates/boards/posting_general.html:126
254 msgid "No threads exist. Create the first one!"
249 msgid "No threads exist. Create the first one!"
255 msgstr "НСт Ρ‚Π΅ΠΌ. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π²ΡƒΡŽ!"
250 msgstr "НСт Ρ‚Π΅ΠΌ. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π²ΡƒΡŽ!"
256
251
257 #: templates/boards/posting_general.html:132
252 #: templates/boards/posting_general.html:132
258 msgid "Create new thread"
253 msgid "Create new thread"
259 msgstr "Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²ΡƒΡŽ Ρ‚Π΅ΠΌΡƒ"
254 msgstr "Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²ΡƒΡŽ Ρ‚Π΅ΠΌΡƒ"
260
255
261 #: templates/boards/posting_general.html:137 templates/boards/thread.html:58
256 #: templates/boards/posting_general.html:137 templates/boards/preview.html:16
257 #: templates/boards/thread.html:58
262 msgid "Post"
258 msgid "Post"
263 msgstr "ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ"
259 msgstr "ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ"
264
260
265 #: templates/boards/posting_general.html:142
261 #: templates/boards/posting_general.html:142
266 msgid "Tags must be delimited by spaces. Text or image is required."
262 msgid "Tags must be delimited by spaces. Text or image is required."
267 msgstr ""
263 msgstr ""
268 "Π’Π΅Π³ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Ρ‹ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ. ВСкст ΠΈΠ»ΠΈ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹."
264 "Π’Π΅Π³ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Ρ‹ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ. ВСкст ΠΈΠ»ΠΈ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹."
269
265
270 #: templates/boards/posting_general.html:145 templates/boards/thread.html:66
266 #: templates/boards/posting_general.html:145 templates/boards/thread.html:66
271 msgid "Text syntax"
267 msgid "Text syntax"
272 msgstr "Бинтаксис тСкста"
268 msgstr "Бинтаксис тСкста"
273
269
274 #: templates/boards/posting_general.html:157
270 #: templates/boards/posting_general.html:157
275 msgid "Pages:"
271 msgid "Pages:"
276 msgstr "Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Ρ‹: "
272 msgstr "Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Ρ‹: "
277
273
274 #: templates/boards/preview.html:6 templates/boards/staticpages/help.html:19
275 msgid "Preview"
276 msgstr "ΠŸΡ€Π΅Π΄ΠΏΡ€ΠΎΡΠΌΠΎΡ‚Ρ€"
277
278 #: templates/boards/settings.html:15
278 #: templates/boards/settings.html:15
279 msgid "You are moderator."
279 msgid "You are moderator."
280 msgstr "Π’Ρ‹ ΠΌΠΎΠ΄Π΅Ρ€Π°Ρ‚ΠΎΡ€."
280 msgstr "Π’Ρ‹ ΠΌΠΎΠ΄Π΅Ρ€Π°Ρ‚ΠΎΡ€."
281
281
282 #: templates/boards/settings.html:19
282 #: templates/boards/settings.html:19
283 msgid "Hidden tags:"
283 msgid "Hidden tags:"
284 msgstr "Π‘ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ‚Π΅Π³ΠΈ:"
284 msgstr "Π‘ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ‚Π΅Π³ΠΈ:"
285
285
286 #: templates/boards/settings.html:26
286 #: templates/boards/settings.html:26
287 msgid "No hidden tags."
287 msgid "No hidden tags."
288 msgstr "НСт скрытых Ρ‚Π΅Π³ΠΎΠ²."
288 msgstr "НСт скрытых Ρ‚Π΅Π³ΠΎΠ²."
289
289
290 #: templates/boards/settings.html:35
290 #: templates/boards/settings.html:35
291 msgid "Save"
291 msgid "Save"
292 msgstr "Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ"
292 msgstr "Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ"
293
293
294 #: templates/boards/tags.html:22
294 #: templates/boards/tags.html:22
295 msgid "No tags found."
295 msgid "No tags found."
296 msgstr "Π’Π΅Π³ΠΈ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Ρ‹."
296 msgstr "Π’Π΅Π³ΠΈ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Ρ‹."
297
297
298 #: templates/boards/thread.html:20 templates/boards/thread_gallery.html:21
298 #: templates/boards/thread.html:20 templates/boards/thread_gallery.html:19
299 msgid "Normal mode"
299 msgid "Normal mode"
300 msgstr "ΠΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ"
300 msgstr "ΠΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ"
301
301
302 #: templates/boards/thread.html:21 templates/boards/thread_gallery.html:22
302 #: templates/boards/thread.html:21 templates/boards/thread_gallery.html:20
303 msgid "Gallery mode"
303 msgid "Gallery mode"
304 msgstr "Π Π΅ΠΆΠΈΠΌ Π³Π°Π»Π΅Ρ€Π΅ΠΈ"
304 msgstr "Π Π΅ΠΆΠΈΠΌ Π³Π°Π»Π΅Ρ€Π΅ΠΈ"
305
305
306 #: templates/boards/thread.html:29
306 #: templates/boards/thread.html:29
307 msgid "posts to bumplimit"
307 msgid "posts to bumplimit"
308 msgstr "сообщСний Π΄ΠΎ Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π°"
308 msgstr "сообщСний Π΄ΠΎ Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π°"
309
309
310 #: templates/boards/thread.html:50
310 #: templates/boards/thread.html:50
311 msgid "Reply to thread"
311 msgid "Reply to thread"
312 msgstr "ΠžΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ Π² Ρ‚Π΅ΠΌΡƒ"
312 msgstr "ΠžΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ Π² Ρ‚Π΅ΠΌΡƒ"
313
313
314 #: templates/boards/thread.html:63
314 #: templates/boards/thread.html:63
315 msgid "Switch mode"
315 msgid "Switch mode"
316 msgstr "ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ€Π΅ΠΆΠΈΠΌ"
316 msgstr "ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ€Π΅ΠΆΠΈΠΌ"
317
317
318 #: templates/boards/thread.html:90 templates/boards/thread_gallery.html:63
318 #: templates/boards/thread.html:90 templates/boards/thread_gallery.html:61
319 msgid "Last update: "
319 msgid "Last update: "
320 msgstr "ПослСднСС обновлСниС: "
320 msgstr "ПослСднСС обновлСниС: "
321
321
322 #: templates/boards/rss/post.html:5
322 #: templates/boards/rss/post.html:5
323 msgid "Post image"
323 msgid "Post image"
324 msgstr "Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ сообщСния"
324 msgstr "Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ сообщСния"
325
325
326 #: templates/boards/staticpages/banned.html:6
326 #: templates/boards/staticpages/banned.html:6
327 msgid "Banned"
327 msgid "Banned"
328 msgstr "Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½"
328 msgstr "Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½"
329
329
330 #: templates/boards/staticpages/banned.html:11
330 #: templates/boards/staticpages/banned.html:11
331 msgid "Your IP address has been banned. Contact the administrator"
331 msgid "Your IP address has been banned. Contact the administrator"
332 msgstr "Π’Π°Ρˆ IP адрСс Π±Ρ‹Π» Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½. Π‘Π²ΡΠΆΠΈΡ‚Π΅ΡΡŒ с администратором"
332 msgstr "Π’Π°Ρˆ IP адрСс Π±Ρ‹Π» Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½. Π‘Π²ΡΠΆΠΈΡ‚Π΅ΡΡŒ с администратором"
333
333
334 #: templates/boards/staticpages/help.html:6
334 #: templates/boards/staticpages/help.html:6
335 #: templates/boards/staticpages/help.html:10
335 #: templates/boards/staticpages/help.html:10
336 msgid "Syntax"
336 msgid "Syntax"
337 msgstr "Бинтаксис"
337 msgstr "Бинтаксис"
338
338
339 #: templates/boards/staticpages/help.html:11
339 #: templates/boards/staticpages/help.html:11
340 msgid "Italic text"
340 msgid "Italic text"
341 msgstr "ΠšΡƒΡ€ΡΠΈΠ²Π½Ρ‹ΠΉ тСкст"
341 msgstr "ΠšΡƒΡ€ΡΠΈΠ²Π½Ρ‹ΠΉ тСкст"
342
342
343 #: templates/boards/staticpages/help.html:12
343 #: templates/boards/staticpages/help.html:12
344 msgid "Bold text"
344 msgid "Bold text"
345 msgstr "ΠŸΠΎΠ»ΡƒΠΆΠΈΡ€Π½Ρ‹ΠΉ тСкст"
345 msgstr "ΠŸΠΎΠ»ΡƒΠΆΠΈΡ€Π½Ρ‹ΠΉ тСкст"
346
346
347 #: templates/boards/staticpages/help.html:13
347 #: templates/boards/staticpages/help.html:13
348 msgid "Spoiler"
348 msgid "Spoiler"
349 msgstr "Π‘ΠΏΠΎΠΉΠ»Π΅Ρ€"
349 msgstr "Π‘ΠΏΠΎΠΉΠ»Π΅Ρ€"
350
350
351 #: templates/boards/staticpages/help.html:14
351 #: templates/boards/staticpages/help.html:14
352 msgid "Link to a post"
352 msgid "Link to a post"
353 msgstr "Бсылка Π½Π° сообщСниС"
353 msgstr "Бсылка Π½Π° сообщСниС"
354
354
355 #: templates/boards/staticpages/help.html:15
355 #: templates/boards/staticpages/help.html:15
356 msgid "Strikethrough text"
356 msgid "Strikethrough text"
357 msgstr "Π—Π°Ρ‡Π΅Ρ€ΠΊΠ½ΡƒΡ‚Ρ‹ΠΉ тСкст"
357 msgstr "Π—Π°Ρ‡Π΅Ρ€ΠΊΠ½ΡƒΡ‚Ρ‹ΠΉ тСкст"
358
358
359 #: templates/boards/staticpages/help.html:16
359 #: templates/boards/staticpages/help.html:16
360 msgid "Comment"
360 msgid "Comment"
361 msgstr "ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ"
361 msgstr "ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ"
362
363 #: templates/boards/staticpages/help.html:19
364 msgid "You can try pasting the text and previewing the result here:"
365 msgstr "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ тСкст ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ здСсь:"
@@ -1,180 +1,182 b''
1 # coding=utf-8
1 # coding=utf-8
2
2
3 import re
3 import re
4 import bbcode
4 import bbcode
5
5
6 import boards
6 import boards
7
7
8
8
9 __author__ = 'neko259'
9 __author__ = 'neko259'
10
10
11
11
12 REFLINK_PATTERN = re.compile(r'^\d+$')
12 REFLINK_PATTERN = re.compile(r'^\d+$')
13 MULTI_NEWLINES_PATTERN = re.compile(r'(\r?\n){2,}')
13 MULTI_NEWLINES_PATTERN = re.compile(r'(\r?\n){2,}')
14 ONE_NEWLINE = '\n'
14 ONE_NEWLINE = '\n'
15
15
16
16
17 class TextFormatter():
17 class TextFormatter():
18 """
18 """
19 An interface for formatter that can be used in the text format panel
19 An interface for formatter that can be used in the text format panel
20 """
20 """
21
21
22 def __init__(self):
22 def __init__(self):
23 pass
23 pass
24
24
25 name = ''
25 name = ''
26
26
27 # Left and right tags for the button preview
27 # Left and right tags for the button preview
28 preview_left = ''
28 preview_left = ''
29 preview_right = ''
29 preview_right = ''
30
30
31 # Left and right characters for the textarea input
31 # Left and right characters for the textarea input
32 format_left = ''
32 format_left = ''
33 format_right = ''
33 format_right = ''
34
34
35
35
36 class AutolinkPattern():
36 class AutolinkPattern():
37 def handleMatch(self, m):
37 def handleMatch(self, m):
38 link_element = etree.Element('a')
38 link_element = etree.Element('a')
39 href = m.group(2)
39 href = m.group(2)
40 link_element.set('href', href)
40 link_element.set('href', href)
41 link_element.text = href
41 link_element.text = href
42
42
43 return link_element
43 return link_element
44
44
45
45
46 class QuotePattern(TextFormatter):
46 class QuotePattern(TextFormatter):
47 name = 'q'
47 name = 'q'
48 preview_left = '<span class="multiquote">'
48 preview_left = '<span class="multiquote">'
49 preview_right = '</span>'
49 preview_right = '</span>'
50
50
51 format_left = '[quote]'
51 format_left = '[quote]'
52 format_right = '[/quote]'
52 format_right = '[/quote]'
53
53
54
54
55 class SpoilerPattern(TextFormatter):
55 class SpoilerPattern(TextFormatter):
56 name = 'spoiler'
56 name = 'spoiler'
57 preview_left = '<span class="spoiler">'
57 preview_left = '<span class="spoiler">'
58 preview_right = '</span>'
58 preview_right = '</span>'
59
59
60 format_left = '[spoiler]'
60 format_left = '[spoiler]'
61 format_right = '[/spoiler]'
61 format_right = '[/spoiler]'
62
62
63 def handleMatch(self, m):
63 def handleMatch(self, m):
64 quote_element = etree.Element('span')
64 quote_element = etree.Element('span')
65 quote_element.set('class', 'spoiler')
65 quote_element.set('class', 'spoiler')
66 quote_element.text = m.group(2)
66 quote_element.text = m.group(2)
67
67
68 return quote_element
68 return quote_element
69
69
70
70
71 class CommentPattern(TextFormatter):
71 class CommentPattern(TextFormatter):
72 name = ''
72 name = ''
73 preview_left = '<span class="comment">// '
73 preview_left = '<span class="comment">// '
74 preview_right = '</span>'
74 preview_right = '</span>'
75
75
76 format_left = '[comment]'
76 format_left = '[comment]'
77 format_right = '[/comment]'
77 format_right = '[/comment]'
78
78
79
79
80 # TODO Use <s> tag here
80 # TODO Use <s> tag here
81 class StrikeThroughPattern(TextFormatter):
81 class StrikeThroughPattern(TextFormatter):
82 name = 's'
82 name = 's'
83 preview_left = '<span class="strikethrough">'
83 preview_left = '<span class="strikethrough">'
84 preview_right = '</span>'
84 preview_right = '</span>'
85
85
86 format_left = '[s]'
86 format_left = '[s]'
87 format_right = '[/s]'
87 format_right = '[/s]'
88
88
89
89
90 class ItalicPattern(TextFormatter):
90 class ItalicPattern(TextFormatter):
91 name = 'i'
91 name = 'i'
92 preview_left = '<i>'
92 preview_left = '<i>'
93 preview_right = '</i>'
93 preview_right = '</i>'
94
94
95 format_left = '[i]'
95 format_left = '[i]'
96 format_right = '[/i]'
96 format_right = '[/i]'
97
97
98
98
99 class BoldPattern(TextFormatter):
99 class BoldPattern(TextFormatter):
100 name = 'b'
100 name = 'b'
101 preview_left = '<b>'
101 preview_left = '<b>'
102 preview_right = '</b>'
102 preview_right = '</b>'
103
103
104 format_left = '[b]'
104 format_left = '[b]'
105 format_right = '[/b]'
105 format_right = '[/b]'
106
106
107
107
108 class CodePattern(TextFormatter):
108 class CodePattern(TextFormatter):
109 name = 'code'
109 name = 'code'
110 preview_left = '<code>'
110 preview_left = '<code>'
111 preview_right = '</code>'
111 preview_right = '</code>'
112
112
113 format_left = '[code]'
113 format_left = '[code]'
114 format_right = '[/code]'
114 format_right = '[/code]'
115
115
116
116
117 def render_reflink(tag_name, value, options, parent, context):
117 def render_reflink(tag_name, value, options, parent, context):
118 if not REFLINK_PATTERN.match(value):
118 if not REFLINK_PATTERN.match(value):
119 return u'>>%s' % value
119 return '>>%s' % value
120
120
121 post_id = int(value)
121 post_id = int(value)
122
122
123 posts = boards.models.Post.objects.filter(id=post_id)
123 posts = boards.models.Post.objects.filter(id=post_id)
124 if posts.exists():
124 if posts.exists():
125 post = posts[0]
125 post = posts[0]
126
126
127 return u'<a href="%s">&gt;&gt;%s</a>' % (post.get_url(), post_id)
127 return '<a href="%s">&gt;&gt;%s</a>' % (post.get_url(), post_id)
128 else:
128 else:
129 return u'>>%s' % value
129 return '>>%s' % value
130
130
131
131
132 def render_quote(tag_name, value, options, parent, context):
132 def render_quote(tag_name, value, options, parent, context):
133 source = u''
133 source = ''
134 if 'source' in options:
134 if 'source' in options:
135 source = options['source']
135 source = options['source']
136
136
137 result = u''
137 result = ''
138 if source:
138 if source:
139 result = u'<div class="multiquote"><div class="quote-header">%s</div><div class="quote-text">%s</div></div>' % (source, value)
139 result = '<div class="multiquote"><div class="quote-header">%s</div><div class="quote-text">%s</div></div>' % (source, value)
140 else:
140 else:
141 result = u'<div class="multiquote"><div class="quote-text">%s</div></div>' % value
141 result = '<div class="multiquote"><div class="quote-text">%s</div></div>' % value
142
142
143 return result
143 return result
144
144
145
145
146 def preparse_text(text):
146 def preparse_text(text):
147 """
147 """
148 Performs manual parsing before the bbcode parser is used.
148 Performs manual parsing before the bbcode parser is used.
149 """
149 """
150
150
151 return MULTI_NEWLINES_PATTERN.sub(ONE_NEWLINE, text)
151 return MULTI_NEWLINES_PATTERN.sub(ONE_NEWLINE, text)
152
152
153
153
154 def bbcode_extended(markup):
154 def bbcode_extended(markup):
155 parser = bbcode.Parser()
155 # The newline hack is added because br's margin does not work in all
156 # browsers except firefox, when the div's does.
157 parser = bbcode.Parser(newline='<div class="br"></div>')
156 parser.add_formatter('post', render_reflink, strip=True)
158 parser.add_formatter('post', render_reflink, strip=True)
157 parser.add_formatter('quote', render_quote, strip=True)
159 parser.add_formatter('quote', render_quote, strip=True)
158 parser.add_simple_formatter('comment',
160 parser.add_simple_formatter('comment',
159 u'<span class="comment">//%(value)s</span>')
161 u'<span class="comment">//%(value)s</span>')
160 parser.add_simple_formatter('spoiler',
162 parser.add_simple_formatter('spoiler',
161 u'<span class="spoiler">%(value)s</span>')
163 u'<span class="spoiler">%(value)s</span>')
162 # TODO Use <s> here
164 # TODO Use <s> here
163 parser.add_simple_formatter('s',
165 parser.add_simple_formatter('s',
164 u'<span class="strikethrough">%(value)s</span>')
166 u'<span class="strikethrough">%(value)s</span>')
165 # TODO Why not use built-in tag?
167 # TODO Why not use built-in tag?
166 parser.add_simple_formatter('code',
168 parser.add_simple_formatter('code',
167 u'<pre><code>%(value)s</pre></code>', render_embedded=False)
169 u'<pre><code>%(value)s</pre></code>', render_embedded=False)
168
170
169 text = preparse_text(markup)
171 text = preparse_text(markup)
170 return parser.format(text)
172 return parser.format(text)
171
173
172 formatters = [
174 formatters = [
173 QuotePattern,
175 QuotePattern,
174 SpoilerPattern,
176 SpoilerPattern,
175 ItalicPattern,
177 ItalicPattern,
176 BoldPattern,
178 BoldPattern,
177 CommentPattern,
179 CommentPattern,
178 StrikeThroughPattern,
180 StrikeThroughPattern,
179 CodePattern,
181 CodePattern,
180 ]
182 ]
@@ -1,23 +1,20 b''
1 VERSION = '2.1 Aya'
1 VERSION = '2.1 Aya'
2 SITE_NAME = 'n3b0a2d'
2 SITE_NAME = 'n3b0a2d'
3
3
4 CACHE_TIMEOUT = 600 # Timeout for caching, if cache is used
4 CACHE_TIMEOUT = 600 # Timeout for caching, if cache is used
5 LOGIN_TIMEOUT = 3600 # Timeout between login tries
5 LOGIN_TIMEOUT = 3600 # Timeout between login tries
6 MAX_TEXT_LENGTH = 30000 # Max post length in characters
6 MAX_TEXT_LENGTH = 30000 # Max post length in characters
7 MAX_IMAGE_SIZE = 8 * 1024 * 1024 # Max image size
7 MAX_IMAGE_SIZE = 8 * 1024 * 1024 # Max image size
8
8
9 # Thread bumplimit
9 # Thread bumplimit
10 MAX_POSTS_PER_THREAD = 10
10 MAX_POSTS_PER_THREAD = 10
11 # Old posts will be archived or deleted if this value is reached
11 # Old posts will be archived or deleted if this value is reached
12 MAX_THREAD_COUNT = 5
12 MAX_THREAD_COUNT = 5
13 THREADS_PER_PAGE = 3
13 THREADS_PER_PAGE = 3
14 DEFAULT_THEME = 'md'
14 DEFAULT_THEME = 'md'
15 LAST_REPLIES_COUNT = 3
15 LAST_REPLIES_COUNT = 3
16
16
17 # Enable archiving threads instead of deletion when the thread limit is reached
17 # Enable archiving threads instead of deletion when the thread limit is reached
18 ARCHIVE_THREADS = True
18 ARCHIVE_THREADS = True
19 # Limit posting speed
19 # Limit posting speed
20 LIMIT_POSTING_SPEED = False
20 LIMIT_POSTING_SPEED = False
21
22 # This password is used to add admin permissions to the user
23 MASTER_PASSWORD = u'password'
@@ -1,472 +1,473 b''
1 html {
1 html {
2 background: #555;
2 background: #555;
3 color: #ffffff;
3 color: #ffffff;
4 }
4 }
5
5
6 body {
6 body {
7 margin: 0;
7 margin: 0;
8 }
8 }
9
9
10 #admin_panel {
10 #admin_panel {
11 background: #FF0000;
11 background: #FF0000;
12 color: #00FF00
12 color: #00FF00
13 }
13 }
14
14
15 .input_field_error {
15 .input_field_error {
16 color: #FF0000;
16 color: #FF0000;
17 }
17 }
18
18
19 .title {
19 .title {
20 font-weight: bold;
20 font-weight: bold;
21 color: #ffcc00;
21 color: #ffcc00;
22 }
22 }
23
23
24 .link, a {
24 .link, a {
25 color: #afdcec;
25 color: #afdcec;
26 }
26 }
27
27
28 .block {
28 .block {
29 display: inline-block;
29 display: inline-block;
30 vertical-align: top;
30 vertical-align: top;
31 }
31 }
32
32
33 .tag {
33 .tag {
34 color: #FFD37D;
34 color: #FFD37D;
35 }
35 }
36
36
37 .post_id {
37 .post_id {
38 color: #fff380;
38 color: #fff380;
39 }
39 }
40
40
41 .post, .dead_post, .archive_post, #posts-table {
41 .post, .dead_post, .archive_post, #posts-table {
42 background: #333;
42 background: #333;
43 padding: 10px;
43 padding: 10px;
44 clear: left;
44 clear: left;
45 word-wrap: break-word;
45 word-wrap: break-word;
46 border-top: 1px solid #777;
46 border-top: 1px solid #777;
47 border-bottom: 1px solid #777;
47 border-bottom: 1px solid #777;
48 }
48 }
49
49
50 .post + .post {
50 .post + .post {
51 border-top: none;
51 border-top: none;
52 }
52 }
53
53
54 .dead_post + .dead_post {
54 .dead_post + .dead_post {
55 border-top: none;
55 border-top: none;
56 }
56 }
57
57
58 .archive_post + .archive_post {
58 .archive_post + .archive_post {
59 border-top: none;
59 border-top: none;
60 }
60 }
61
61
62 .metadata {
62 .metadata {
63 padding-top: 5px;
63 padding-top: 5px;
64 margin-top: 10px;
64 margin-top: 10px;
65 border-top: solid 1px #666;
65 border-top: solid 1px #666;
66 color: #ddd;
66 color: #ddd;
67 }
67 }
68
68
69 .navigation_panel, .tag_info {
69 .navigation_panel, .tag_info {
70 background: #444;
70 background: #444;
71 margin-bottom: 5px;
71 margin-bottom: 5px;
72 margin-top: 5px;
72 margin-top: 5px;
73 padding: 10px;
73 padding: 10px;
74 border-bottom: solid 1px #888;
74 border-bottom: solid 1px #888;
75 border-top: solid 1px #888;
75 border-top: solid 1px #888;
76 color: #eee;
76 color: #eee;
77 }
77 }
78
78
79 .navigation_panel .link {
79 .navigation_panel .link {
80 border-right: 1px solid #fff;
80 border-right: 1px solid #fff;
81 font-weight: bold;
81 font-weight: bold;
82 margin-right: 1ex;
82 margin-right: 1ex;
83 padding-right: 1ex;
83 padding-right: 1ex;
84 }
84 }
85 .navigation_panel .link:last-child {
85 .navigation_panel .link:last-child {
86 border-left: 1px solid #fff;
86 border-left: 1px solid #fff;
87 border-right: none;
87 border-right: none;
88 float: right;
88 float: right;
89 margin-left: 1ex;
89 margin-left: 1ex;
90 margin-right: 0;
90 margin-right: 0;
91 padding-left: 1ex;
91 padding-left: 1ex;
92 padding-right: 0;
92 padding-right: 0;
93 }
93 }
94
94
95 .navigation_panel::after, .post::after {
95 .navigation_panel::after, .post::after {
96 clear: both;
96 clear: both;
97 content: ".";
97 content: ".";
98 display: block;
98 display: block;
99 height: 0;
99 height: 0;
100 line-height: 0;
100 line-height: 0;
101 visibility: hidden;
101 visibility: hidden;
102 }
102 }
103
103
104 p {
104 p, .br {
105 margin-top: .5em;
105 margin-top: .5em;
106 margin-bottom: .5em;
106 margin-bottom: .5em;
107 }
107 }
108
108
109 br {
110 margin-bottom: .5em;
111 }
112
113 .post-form-w {
109 .post-form-w {
114 background: #333344;
110 background: #333344;
115 border-top: solid 1px #888;
111 border-top: solid 1px #888;
116 border-bottom: solid 1px #888;
112 border-bottom: solid 1px #888;
117 color: #fff;
113 color: #fff;
118 padding: 10px;
114 padding: 10px;
119 margin-bottom: 5px;
115 margin-bottom: 5px;
120 margin-top: 5px;
116 margin-top: 5px;
121 }
117 }
122
118
123 .form-row {
119 .form-row {
124 width: 100%;
120 width: 100%;
125 }
121 }
126
122
127 .form-label {
123 .form-label {
128 padding: .25em 1ex .25em 0;
124 padding: .25em 1ex .25em 0;
129 vertical-align: top;
125 vertical-align: top;
130 }
126 }
131
127
132 .form-input {
128 .form-input {
133 padding: .25em 0;
129 padding: .25em 0;
134 }
130 }
135
131
136 .form-errors {
132 .form-errors {
137 font-weight: bolder;
133 font-weight: bolder;
138 vertical-align: middle;
134 vertical-align: middle;
139 }
135 }
140
136
141 .post-form input:not([name="image"]), .post-form textarea {
137 .post-form input:not([name="image"]), .post-form textarea {
142 background: #333;
138 background: #333;
143 color: #fff;
139 color: #fff;
144 border: solid 1px;
140 border: solid 1px;
145 padding: 0;
141 padding: 0;
146 font: medium sans-serif;
142 font: medium sans-serif;
147 width: 100%;
143 width: 100%;
148 }
144 }
149
145
150 .form-submit {
146 .form-submit {
151 display: table;
147 display: table;
152 margin-bottom: 1ex;
148 margin-bottom: 1ex;
153 margin-top: 1ex;
149 margin-top: 1ex;
154 }
150 }
155
151
156 .form-title {
152 .form-title {
157 font-weight: bold;
153 font-weight: bold;
158 font-size: 2ex;
154 font-size: 2ex;
159 margin-bottom: 0.5ex;
155 margin-bottom: 0.5ex;
160 }
156 }
161
157
162 .post-form input[type="submit"], input[type="submit"] {
158 .post-form input[type="submit"], input[type="submit"] {
163 background: #222;
159 background: #222;
164 border: solid 2px #fff;
160 border: solid 2px #fff;
165 color: #fff;
161 color: #fff;
166 padding: 0.5ex;
162 padding: 0.5ex;
167 }
163 }
168
164
169 input[type="submit"]:hover {
165 input[type="submit"]:hover {
170 background: #060;
166 background: #060;
171 }
167 }
172
168
173 blockquote {
169 blockquote {
174 border-left: solid 2px;
170 border-left: solid 2px;
175 padding-left: 5px;
171 padding-left: 5px;
176 color: #B1FB17;
172 color: #B1FB17;
177 margin: 0;
173 margin: 0;
178 }
174 }
179
175
180 .post > .image {
176 .post > .image {
181 float: left;
177 float: left;
182 margin: 0 1ex .5ex 0;
178 margin: 0 1ex .5ex 0;
183 min-width: 1px;
179 min-width: 1px;
184 text-align: center;
180 text-align: center;
185 display: table-row;
181 display: table-row;
186 }
182 }
187
183
188 .post > .metadata {
184 .post > .metadata {
189 clear: left;
185 clear: left;
190 }
186 }
191
187
192 .get {
188 .get {
193 font-weight: bold;
189 font-weight: bold;
194 color: #d55;
190 color: #d55;
195 }
191 }
196
192
197 * {
193 * {
198 text-decoration: none;
194 text-decoration: none;
199 }
195 }
200
196
201 .dead_post {
197 .dead_post {
202 background-color: #442222;
198 background-color: #442222;
203 }
199 }
204
200
205 .archive_post {
201 .archive_post {
206 background-color: #000;
202 background-color: #000;
207 }
203 }
208
204
209 .mark_btn {
205 .mark_btn {
210 border: 1px solid;
206 border: 1px solid;
211 min-width: 2ex;
207 min-width: 2ex;
212 padding: 2px 2ex;
208 padding: 2px 2ex;
213 }
209 }
214
210
215 .mark_btn:hover {
211 .mark_btn:hover {
216 background: #555;
212 background: #555;
217 }
213 }
218
214
219 .quote {
215 .quote {
220 color: #92cf38;
216 color: #92cf38;
221 font-style: italic;
217 font-style: italic;
222 }
218 }
223
219
224 .multiquote {
220 .multiquote {
225 padding: 3px;
221 padding: 3px;
226 display: inline-block;
222 display: inline-block;
227 background: #222;
223 background: #222;
228 border-style: solid;
224 border-style: solid;
229 border-width: 1px 1px 1px 4px;
225 border-width: 1px 1px 1px 4px;
230 font-size: 0.9em;
226 font-size: 0.9em;
231 }
227 }
232
228
233 .spoiler {
229 .spoiler {
234 background: white;
230 background: white;
235 color: white;
231 color: white;
236 }
232 }
237
233
238 .spoiler:hover {
234 .spoiler:hover {
239 color: black;
235 color: black;
240 }
236 }
241
237
242 .comment {
238 .comment {
243 color: #eb2;
239 color: #eb2;
244 }
240 }
245
241
246 a:hover {
242 a:hover {
247 text-decoration: underline;
243 text-decoration: underline;
248 }
244 }
249
245
250 .last-replies {
246 .last-replies {
251 margin-left: 3ex;
247 margin-left: 3ex;
252 margin-right: 3ex;
248 margin-right: 3ex;
253 border-left: solid 1px #777;
249 border-left: solid 1px #777;
254 border-right: solid 1px #777;
250 border-right: solid 1px #777;
255 }
251 }
256
252
253 .last-replies > .post:first-child {
254 border-top: none;
255 }
256
257 .thread {
257 .thread {
258 margin-bottom: 3ex;
258 margin-bottom: 3ex;
259 margin-top: 1ex;
259 margin-top: 1ex;
260 }
260 }
261
261
262 .post:target {
262 .post:target {
263 border: solid 2px white;
263 border: solid 2px white;
264 }
264 }
265
265
266 pre{
266 pre{
267 white-space:pre-wrap
267 white-space:pre-wrap
268 }
268 }
269
269
270 li {
270 li {
271 list-style-position: inside;
271 list-style-position: inside;
272 }
272 }
273
273
274 .fancybox-skin {
274 .fancybox-skin {
275 position: relative;
275 position: relative;
276 background-color: #fff;
276 background-color: #fff;
277 color: #ddd;
277 color: #ddd;
278 text-shadow: none;
278 text-shadow: none;
279 }
279 }
280
280
281 .fancybox-image {
281 .fancybox-image {
282 border: 1px solid black;
282 border: 1px solid black;
283 }
283 }
284
284
285 .image-mode-tab {
285 .image-mode-tab {
286 background: #444;
286 background: #444;
287 color: #eee;
287 color: #eee;
288 margin-top: 5px;
288 margin-top: 5px;
289 padding: 5px;
289 padding: 5px;
290 border-top: 1px solid #888;
290 border-top: 1px solid #888;
291 border-bottom: 1px solid #888;
291 border-bottom: 1px solid #888;
292 }
292 }
293
293
294 .image-mode-tab > label {
294 .image-mode-tab > label {
295 margin: 0 1ex;
295 margin: 0 1ex;
296 }
296 }
297
297
298 .image-mode-tab > label > input {
298 .image-mode-tab > label > input {
299 margin-right: .5ex;
299 margin-right: .5ex;
300 }
300 }
301
301
302 #posts-table {
302 #posts-table {
303 margin-top: 5px;
303 margin-top: 5px;
304 margin-bottom: 5px;
304 margin-bottom: 5px;
305 }
305 }
306
306
307 .tag_info > h2 {
307 .tag_info > h2 {
308 margin: 0;
308 margin: 0;
309 }
309 }
310
310
311 .post-info {
311 .post-info {
312 color: #ddd;
312 color: #ddd;
313 margin-bottom: 1ex;
313 margin-bottom: 1ex;
314 }
314 }
315
315
316 .moderator_info {
316 .moderator_info {
317 color: #e99d41;
317 color: #e99d41;
318 float: right;
318 float: right;
319 font-weight: bold;
319 font-weight: bold;
320 }
320 }
321
321
322 .refmap {
322 .refmap {
323 font-size: 0.9em;
323 font-size: 0.9em;
324 color: #ccc;
324 color: #ccc;
325 margin-top: 1em;
325 margin-top: 1em;
326 }
326 }
327
327
328 .fav {
328 .fav {
329 color: yellow;
329 color: yellow;
330 }
330 }
331
331
332 .not_fav {
332 .not_fav {
333 color: #ccc;
333 color: #ccc;
334 }
334 }
335
335
336 .role {
336 .role {
337 text-decoration: underline;
337 text-decoration: underline;
338 }
338 }
339
339
340 .form-email {
340 .form-email {
341 display: none;
341 display: none;
342 }
342 }
343
343
344 .footer {
344 .footer {
345 margin: 5px;
345 margin: 5px;
346 }
346 }
347
347
348 .bar-value {
348 .bar-value {
349 background: rgba(50, 55, 164, 0.45);
349 background: rgba(50, 55, 164, 0.45);
350 font-size: 0.9em;
350 font-size: 0.9em;
351 height: 1.5em;
351 height: 1.5em;
352 }
352 }
353
353
354 .bar-bg {
354 .bar-bg {
355 position: relative;
355 position: relative;
356 border-top: solid 1px #888;
356 border-top: solid 1px #888;
357 border-bottom: solid 1px #888;
357 border-bottom: solid 1px #888;
358 margin-top: 5px;
358 margin-top: 5px;
359 overflow: hidden;
359 overflow: hidden;
360 }
360 }
361
361
362 .bar-text {
362 .bar-text {
363 padding: 2px;
363 padding: 2px;
364 position: absolute;
364 position: absolute;
365 left: 0;
365 left: 0;
366 top: 0;
366 top: 0;
367 }
367 }
368
368
369 .page_link {
369 .page_link {
370 background: #444;
370 background: #444;
371 border-top: solid 1px #888;
371 border-top: solid 1px #888;
372 border-bottom: solid 1px #888;
372 border-bottom: solid 1px #888;
373 padding: 5px;
373 padding: 5px;
374 color: #eee;
374 color: #eee;
375 font-size: 2ex;
375 font-size: 2ex;
376 }
376 }
377
377
378 .skipped_replies {
378 .skipped_replies {
379 padding: 5px;
379 padding: 5px;
380 margin-left: 3ex;
380 margin-left: 3ex;
381 margin-right: 3ex;
381 margin-right: 3ex;
382 border-left: solid 1px #888;
382 border-left: solid 1px #888;
383 border-right: solid 1px #888;
383 border-right: solid 1px #888;
384 border-bottom: solid 1px #888;
384 background: #000;
385 background: #000;
385 }
386 }
386
387
387 .current_page {
388 .current_page {
388 border: solid 1px #afdcec;
389 border: solid 1px #afdcec;
389 padding: 2px;
390 padding: 2px;
390 }
391 }
391
392
392 .current_mode {
393 .current_mode {
393 font-weight: bold;
394 font-weight: bold;
394 }
395 }
395
396
396 .gallery_image {
397 .gallery_image {
397 border: solid 1px;
398 border: solid 1px;
398 padding: 0.5ex;
399 padding: 0.5ex;
399 margin: 0.5ex;
400 margin: 0.5ex;
400 text-align: center;
401 text-align: center;
401 }
402 }
402
403
403 code {
404 code {
404 border: dashed 1px #ccc;
405 border: dashed 1px #ccc;
405 background: #111;
406 background: #111;
406 padding: 2px;
407 padding: 2px;
407 font-size: 1.2em;
408 font-size: 1.2em;
408 display: inline-block;
409 display: inline-block;
409 }
410 }
410
411
411 pre {
412 pre {
412 overflow: auto;
413 overflow: auto;
413 }
414 }
414
415
415 .img-full {
416 .img-full {
416 background: #222;
417 background: #222;
417 border: solid 1px white;
418 border: solid 1px white;
418 }
419 }
419
420
420 .tag_item {
421 .tag_item {
421 display: inline-block;
422 display: inline-block;
422 border: 1px dashed #666;
423 border: 1px dashed #666;
423 margin: 0.2ex;
424 margin: 0.2ex;
424 padding: 0.1ex;
425 padding: 0.1ex;
425 }
426 }
426
427
427 #id_models li {
428 #id_models li {
428 list-style: none;
429 list-style: none;
429 }
430 }
430
431
431 #id_q {
432 #id_q {
432 margin-left: 1ex;
433 margin-left: 1ex;
433 }
434 }
434
435
435 ul {
436 ul {
436 padding-left: 0px;
437 padding-left: 0px;
437 }
438 }
438
439
439 .quote-header {
440 .quote-header {
440 border-bottom: 2px solid #ddd;
441 border-bottom: 2px solid #ddd;
441 margin-bottom: 1ex;
442 margin-bottom: 1ex;
442 padding-bottom: .5ex;
443 padding-bottom: .5ex;
443 color: #ddd;
444 color: #ddd;
444 font-size: 1.2em;
445 font-size: 1.2em;
445 }
446 }
446
447
447 .global-id {
448 .global-id {
448 font-weight: bolder;
449 font-weight: bolder;
449 opacity: .5;
450 opacity: .5;
450 }
451 }
451
452
452 /* Post */
453 /* Post */
453 .post > .message, .post > .image {
454 .post > .message, .post > .image {
454 padding-left: 1em;
455 padding-left: 1em;
455 }
456 }
456
457
457 /* Reflink preview */
458 /* Reflink preview */
458 .post_preview {
459 .post_preview {
459 border-left: 1px solid #777;
460 border-left: 1px solid #777;
460 border-right: 1px solid #777;
461 border-right: 1px solid #777;
461 }
462 }
462
463
463 /* Code highlighter */
464 /* Code highlighter */
464 .hljs {
465 .hljs {
465 color: #fff;
466 color: #fff;
466 background: #000;
467 background: #000;
467 display: inline-block;
468 display: inline-block;
468 }
469 }
469
470
470 .hljs, .hljs-subst, .hljs-tag .hljs-title, .lisp .hljs-title, .clojure .hljs-built_in, .nginx .hljs-title {
471 .hljs, .hljs-subst, .hljs-tag .hljs-title, .lisp .hljs-title, .clojure .hljs-built_in, .nginx .hljs-title {
471 color: #fff;
472 color: #fff;
472 }
473 }
@@ -1,354 +1,364 b''
1 html {
1 html {
2 background: rgb(238, 238, 238);
2 background: rgb(238, 238, 238);
3 color: rgb(51, 51, 51);
3 color: rgb(51, 51, 51);
4 }
4 }
5
5
6 #admin_panel {
6 #admin_panel {
7 background: #FF0000;
7 background: #FF0000;
8 color: #00FF00
8 color: #00FF00
9 }
9 }
10
10
11 .input_field {
11 .input_field {
12
12
13 }
13 }
14
14
15 .input_field_name {
15 .input_field_name {
16
16
17 }
17 }
18
18
19 .input_field_error {
19 .input_field_error {
20 color: #FF0000;
20 color: #FF0000;
21 }
21 }
22
22
23
23
24 .title {
24 .title {
25 font-weight: bold;
25 font-weight: bold;
26 color: #333;
26 color: #333;
27 font-size: 2ex;
27 font-size: 2ex;
28 }
28 }
29
29
30 .link, a {
30 .link, a {
31 color: rgb(255, 102, 0);
31 color: rgb(255, 102, 0);
32 }
32 }
33
33
34 .block {
34 .block {
35 display: inline-block;
35 display: inline-block;
36 vertical-align: top;
36 vertical-align: top;
37 }
37 }
38
38
39 .tag {
39 .tag {
40 color: #222;
40 color: #222;
41 }
41 }
42
42
43 .post_id:hover {
43 .post_id:hover {
44 color: #11f;
44 color: #11f;
45 }
45 }
46
46
47 .post_id {
47 .post_id {
48 color: #444;
48 color: #444;
49 }
49 }
50
50
51 .post, .dead_post, #posts-table {
51 .post, .dead_post, #posts-table {
52 margin: 5px;
52 margin: 5px;
53 padding: 10px;
53 padding: 10px;
54 background: rgb(221, 221, 221);
54 background: rgb(221, 221, 221);
55 border: 1px solid rgb(204, 204, 204);
55 border: 1px solid rgb(204, 204, 204);
56 border-radius: 5px 5px 5px 5px;
56 border-radius: 5px 5px 5px 5px;
57 clear: left;
57 clear: left;
58 word-wrap: break-word;
58 word-wrap: break-word;
59 display: table;
59 display: table;
60 }
60 }
61
61
62 .metadata {
62 .metadata {
63 padding: 5px;
63 padding: 5px;
64 margin-top: 10px;
64 margin-top: 10px;
65 border: solid 1px #666;
65 border: solid 1px #666;
66 font-size: 0.9em;
66 font-size: 0.9em;
67 display: table;
67 display: table;
68 }
68 }
69
69
70 .navigation_panel, .tag_info, .page_link {
70 .navigation_panel, .tag_info, .page_link {
71 margin: 5px;
71 margin: 5px;
72 padding: 10px;
72 padding: 10px;
73 border: 1px solid rgb(204, 204, 204);
73 border: 1px solid rgb(204, 204, 204);
74 border-radius: 5px 5px 5px 5px;
74 border-radius: 5px 5px 5px 5px;
75 }
75 }
76
76
77 .navigation_panel .link {
77 .navigation_panel .link {
78 border-right: 1px solid #000;
78 border-right: 1px solid #000;
79 font-weight: bold;
79 font-weight: bold;
80 margin-right: 1ex;
80 margin-right: 1ex;
81 padding-right: 1ex;
81 padding-right: 1ex;
82 }
82 }
83 .navigation_panel .link:last-child {
83 .navigation_panel .link:last-child {
84 border-left: 1px solid #000;
84 border-left: 1px solid #000;
85 border-right: none;
85 border-right: none;
86 float: right;
86 float: right;
87 margin-left: 1ex;
87 margin-left: 1ex;
88 margin-right: 0;
88 margin-right: 0;
89 padding-left: 1ex;
89 padding-left: 1ex;
90 padding-right: 0;
90 padding-right: 0;
91 }
91 }
92
92
93 .navigation_panel::after, .post::after {
93 .navigation_panel::after, .post::after {
94 clear: both;
94 clear: both;
95 content: ".";
95 content: ".";
96 display: block;
96 display: block;
97 height: 0;
97 height: 0;
98 line-height: 0;
98 line-height: 0;
99 visibility: hidden;
99 visibility: hidden;
100 }
100 }
101
101
102 p {
102 p {
103 margin-top: .5em;
103 margin-top: .5em;
104 margin-bottom: .5em;
104 margin-bottom: .5em;
105 }
105 }
106
106
107 .post-form-w {
107 .post-form-w {
108 display: table;
108 display: table;
109 padding: 10px;
109 padding: 10px;
110 margin: 5px
110 margin: 5px
111 }
111 }
112
112
113 .form-row {
113 .form-row {
114 display: table-row;
114 display: table-row;
115 }
115 }
116
116
117 .form-label, .form-input, .form-errors {
117 .form-label, .form-input, .form-errors {
118 display: table-cell;
118 display: table-cell;
119 }
119 }
120
120
121 .form-label {
121 .form-label {
122 padding: .25em 1ex .25em 0;
122 padding: .25em 1ex .25em 0;
123 vertical-align: top;
123 vertical-align: top;
124 }
124 }
125
125
126 .form-input {
126 .form-input {
127 padding: .25em 0;
127 padding: .25em 0;
128 }
128 }
129
129
130 .form-errors {
130 .form-errors {
131 padding-left: 1ex;
131 padding-left: 1ex;
132 font-weight: bold;
132 font-weight: bold;
133 vertical-align: middle;
133 vertical-align: middle;
134 }
134 }
135
135
136 .post-form input, .post-form textarea {
136 .post-form input:not([name="image"]), .post-form textarea {
137 background: #fff;
137 background: #fff;
138 color: #000;
138 color: #000;
139 border: solid 1px;
139 border: solid 1px;
140 padding: 0;
140 padding: 0;
141 width: 100%;
141 width: 100%;
142 font: medium sans;
142 font: medium sans;
143 }
143 }
144
144
145 .form-submit {
145 .form-submit {
146 border-bottom: 2px solid #ddd;
146 border-bottom: 2px solid #ddd;
147 margin-bottom: .5em;
147 margin-bottom: .5em;
148 padding-bottom: .5em;
148 padding-bottom: .5em;
149 }
149 }
150
150
151 .form-title {
151 .form-title {
152 font-weight: bold;
152 font-weight: bold;
153 }
153 }
154
154
155 input[type="submit"] {
155 input[type="submit"] {
156 background: #fff;
156 background: #fff;
157 border: solid 1px #000;
157 border: solid 1px #000;
158 color: #000;
158 color: #000;
159 }
159 }
160
160
161 blockquote {
161 blockquote {
162 border-left: solid 2px;
162 border-left: solid 2px;
163 padding-left: 5px;
163 padding-left: 5px;
164 color: #B1FB17;
164 color: #B1FB17;
165 margin: 0;
165 margin: 0;
166 }
166 }
167
167
168 .post > .image {
168 .post > .image {
169 float: left;
169 float: left;
170 margin: 0 1ex .5ex 0;
170 margin: 0 1ex .5ex 0;
171 min-width: 1px;
171 min-width: 1px;
172 text-align: center;
172 text-align: center;
173 display: table-row;
173 display: table-row;
174 }
174 }
175
175
176 .post > .metadata {
176 .post > .metadata {
177 clear: left;
177 clear: left;
178 }
178 }
179
179
180 .get {
180 .get {
181 font-weight: bold;
181 font-weight: bold;
182 color: #d55;
182 color: #d55;
183 }
183 }
184
184
185 * {
185 * {
186 text-decoration: none;
186 text-decoration: none;
187 }
187 }
188
188
189 .dead_post {
189 .dead_post {
190 background-color: #ecc;
190 background-color: #ecc;
191 }
191 }
192
192
193 .quote {
193 .quote {
194 color: #080;
194 color: #080;
195 font-style: italic;
195 font-style: italic;
196 }
196 }
197
197
198 .spoiler {
198 .spoiler {
199 background: white;
199 background: white;
200 color: white;
200 color: white;
201 }
201 }
202
202
203 .spoiler:hover {
203 .spoiler:hover {
204 color: black;
204 color: black;
205 }
205 }
206
206
207 .comment {
207 .comment {
208 color: #8B6914;
208 color: #8B6914;
209 font-style: italic;
209 font-style: italic;
210 }
210 }
211
211
212 a:hover {
212 a:hover {
213 text-decoration: underline;
213 text-decoration: underline;
214 }
214 }
215
215
216 .last-replies {
216 .last-replies {
217 margin-left: 3ex;
217 margin-left: 3ex;
218 }
218 }
219
219
220 .thread {
220 .thread {
221 margin-bottom: 3ex;
221 margin-bottom: 3ex;
222 }
222 }
223
223
224 .post:target {
224 .post:target {
225 border: solid 2px black;
225 border: solid 2px black;
226 }
226 }
227
227
228 pre{
228 pre{
229 white-space:pre-wrap
229 white-space:pre-wrap
230 }
230 }
231
231
232 li {
232 li {
233 list-style-position: inside;
233 list-style-position: inside;
234 }
234 }
235
235
236 .fancybox-skin {
236 .fancybox-skin {
237 position: relative;
237 position: relative;
238 background-color: #fff;
238 background-color: #fff;
239 color: #ddd;
239 color: #ddd;
240 text-shadow: none;
240 text-shadow: none;
241 }
241 }
242
242
243 .fancybox-image {
243 .fancybox-image {
244 border: 1px solid black;
244 border: 1px solid black;
245 }
245 }
246
246
247 .image-mode-tab {
247 .image-mode-tab {
248 display: table;
248 display: table;
249 margin: 5px;
249 margin: 5px;
250 padding: 5px;
250 padding: 5px;
251 background: rgb(221, 221, 221);
251 background: rgb(221, 221, 221);
252 border: 1px solid rgb(204, 204, 204);
252 border: 1px solid rgb(204, 204, 204);
253 border-radius: 5px 5px 5px 5px;
253 border-radius: 5px 5px 5px 5px;
254 }
254 }
255
255
256 .image-mode-tab > label {
256 .image-mode-tab > label {
257 margin: 0 1ex;
257 margin: 0 1ex;
258 }
258 }
259
259
260 .image-mode-tab > label > input {
260 .image-mode-tab > label > input {
261 margin-right: .5ex;
261 margin-right: .5ex;
262 }
262 }
263
263
264 #posts-table {
264 #posts-table {
265 margin: 5px;
265 margin: 5px;
266 }
266 }
267
267
268 .tag_info, .page_link {
268 .tag_info, .page_link {
269 display: table;
269 display: table;
270 }
270 }
271
271
272 .tag_info > h2 {
272 .tag_info > h2 {
273 margin: 0;
273 margin: 0;
274 }
274 }
275
275
276 .moderator_info {
276 .moderator_info {
277 color: #e99d41;
277 color: #e99d41;
278 border: dashed 1px;
278 border: dashed 1px;
279 padding: 3px;
279 padding: 3px;
280 }
280 }
281
281
282 .refmap {
282 .refmap {
283 font-size: 0.9em;
283 font-size: 0.9em;
284 color: #444;
284 color: #444;
285 margin-top: 1em;
285 margin-top: 1em;
286 }
286 }
287
287
288 input[type="submit"]:hover {
288 input[type="submit"]:hover {
289 background: #ccc;
289 background: #ccc;
290 }
290 }
291
291
292
292
293 .fav {
293 .fav {
294 color: rgb(255, 102, 0);
294 color: rgb(255, 102, 0);
295 }
295 }
296
296
297 .not_fav {
297 .not_fav {
298 color: #555;
298 color: #555;
299 }
299 }
300
300
301 .role {
301 .role {
302 text-decoration: underline;
302 text-decoration: underline;
303 }
303 }
304
304
305 .form-email {
305 .form-email {
306 display: none;
306 display: none;
307 }
307 }
308
308
309 .mark_btn {
309 .mark_btn {
310 padding: 2px 2ex;
310 padding: 2px 2ex;
311 border: 1px solid;
311 border: 1px solid;
312 }
312 }
313
313
314 .mark_btn:hover {
314 .mark_btn:hover {
315 background: #ccc;
315 background: #ccc;
316 }
316 }
317
317
318 .bar-value {
318 .bar-value {
319 background: rgba(251, 199, 16, 0.61);
319 background: rgba(251, 199, 16, 0.61);
320 padding: 2px;
320 padding: 2px;
321 font-size: 0.9em;
321 font-size: 0.9em;
322 height: 1.5em;
322 height: 1.5em;
323 }
323 }
324
324
325 .bar-bg {
325 .bar-bg {
326 position: relative;
326 position: relative;
327 border: 1px solid rgb(204, 204, 204);
327 border: 1px solid rgb(204, 204, 204);
328 border-radius: 5px 5px 5px 5px;
328 border-radius: 5px 5px 5px 5px;
329 margin: 5px;
329 margin: 5px;
330 overflow: hidden;
330 overflow: hidden;
331 }
331 }
332
332
333 .bar-text {
333 .bar-text {
334 padding: 2px;
334 padding: 2px;
335 position: absolute;
335 position: absolute;
336 left: 0;
336 left: 0;
337 top: 0;
337 top: 0;
338 }
338 }
339
339
340 .skipped_replies {
340 .skipped_replies {
341 margin: 5px;
341 margin: 5px;
342 }
342 }
343
343
344 .current_page, .current_mode {
344 .current_page, .current_mode {
345 border: solid 1px #000;
345 border: solid 1px #000;
346 padding: 2px;
346 padding: 2px;
347 }
347 }
348
348
349 .tag_item {
349 .tag_item {
350 display: inline-block;
350 display: inline-block;
351 border: 1px solid #ccc;
351 border: 1px solid #ccc;
352 margin: 0.3ex;
352 margin: 0.3ex;
353 padding: 0.2ex;
353 padding: 0.2ex;
354 }
354 }
355
356 .multiquote {
357 padding: 3px;
358 display: inline-block;
359 background: #ddd;
360 border-style: solid;
361 border-width: 1px 1px 1px 4px;
362 border-color: #222;
363 font-size: 0.9em;
364 }
@@ -1,62 +1,62 b''
1 {% load staticfiles %}
1 {% load staticfiles %}
2 {% load i18n %}
2 {% load i18n %}
3 {% load l10n %}
3 {% load l10n %}
4 {% load static from staticfiles %}
4 {% load static from staticfiles %}
5
5
6 <!DOCTYPE html>
6 <!DOCTYPE html>
7 <html>
7 <html>
8 <head>
8 <head>
9 <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}" media="all"/>
9 <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}" media="all"/>
10 <link rel="stylesheet" type="text/css" href="{% static 'css/3party/highlight.css' %}" media="all"/>
10 <link rel="stylesheet" type="text/css" href="{% static 'css/3party/highlight.css' %}" media="all"/>
11 <link rel="stylesheet" type="text/css" href="{% static theme_css %}" media="all"/>
11 <link rel="stylesheet" type="text/css" href="{% static theme_css %}" media="all"/>
12 <link rel="alternate" type="application/rss+xml" href="rss/" title="{% trans 'Feed' %}"/>
12 <link rel="alternate" type="application/rss+xml" href="rss/" title="{% trans 'Feed' %}"/>
13
13
14 <link rel="icon" type="image/png"
14 <link rel="icon" type="image/png"
15 href="{% static 'favicon.png' %}">
15 href="{% static 'favicon.png' %}">
16
16
17 <meta name="viewport" content="width=device-width, initial-scale=1"/>
17 <meta name="viewport" content="width=device-width, initial-scale=1"/>
18 <meta charset="utf-8"/>
18 <meta charset="utf-8"/>
19
19
20 {% block head %}{% endblock %}
20 {% block head %}{% endblock %}
21 </head>
21 </head>
22 <body>
22 <body>
23 <script src="{% static 'js/jquery-2.0.1.min.js' %}"></script>
23 <script src="{% static 'js/jquery-2.0.1.min.js' %}"></script>
24 <script src="{% static 'js/jquery-ui-1.10.3.custom.min.js' %}"></script>
24 <script src="{% static 'js/jquery-ui-1.10.3.custom.min.js' %}"></script>
25 <script src="{% static 'js/jquery.mousewheel.js' %}"></script>
25 <script src="{% static 'js/jquery.mousewheel.js' %}"></script>
26 <script src="{% url 'js_info_dict' %}"></script>
26 <script src="{% url 'js_info_dict' %}"></script>
27
27
28 <div class="navigation_panel">
28 <div class="navigation_panel">
29 <a class="link" href="{% url 'index' %}">{% trans "All threads" %}</a>
29 <a class="link" href="{% url 'index' %}">{% trans "All threads" %}</a>
30 {% for tag in tags %}
30 {% for tag in tags %}
31 <a class="tag" href="{% url 'tag' tag_name=tag.name %}"
31 <a class="tag" href="{% url 'tag' tag_name=tag.name %}"
32 >#{{ tag.name }}</a>,
32 >#{{ tag.name }}</a>,
33 {% endfor %}
33 {% endfor %}
34 <a href="{% url 'tags' %}" title="{% trans 'Tag management' %}"
34 <a href="{% url 'tags' %}" title="{% trans 'Tag management' %}"
35 >[...]</a>
35 >[...]</a>,
36 <a href="{% url 'search' %}" title="{% trans 'Search' %}">[S]</a>
36 <a class="link" href="{% url 'settings' %}">{% trans 'Settings' %}</a>
37 <a class="link" href="{% url 'settings' %}">{% trans 'Settings' %}</a>
37 </div>
38 </div>
38
39
39 {% block content %}{% endblock %}
40 {% block content %}{% endblock %}
40
41
41 <script src="{% static 'js/popup.js' %}"></script>
42 <script src="{% static 'js/popup.js' %}"></script>
42 <script src="{% static 'js/image.js' %}"></script>
43 <script src="{% static 'js/image.js' %}"></script>
43 <script src="{% static 'js/3party/highlight.min.js' %}"></script>
44 <script src="{% static 'js/3party/highlight.min.js' %}"></script>
44 <script src="{% static 'js/refpopup.js' %}"></script>
45 <script src="{% static 'js/refpopup.js' %}"></script>
45 <script src="{% static 'js/main.js' %}"></script>
46 <script src="{% static 'js/main.js' %}"></script>
46
47
47 <div class="navigation_panel">
48 <div class="navigation_panel">
48 {% block metapanel %}{% endblock %}
49 {% block metapanel %}{% endblock %}
49 [<a href="{% url 'admin:index' %}">{% trans 'Admin' %}</a>]
50 [<a href="{% url 'admin:index' %}">{% trans 'Admin' %}</a>]
50 [<a href="{% url 'search' %}">{% trans 'Search' %}</a>]
51 {% with ppd=posts_per_day|floatformat:2 %}
51 {% with ppd=posts_per_day|floatformat:2 %}
52 {% blocktrans %}Speed: {{ ppd }} posts per day{% endblocktrans %}
52 {% blocktrans %}Speed: {{ ppd }} posts per day{% endblocktrans %}
53 {% endwith %}
53 {% endwith %}
54 <a class="link" href="#top">{% trans 'Up' %}</a>
54 <a class="link" href="#top">{% trans 'Up' %}</a>
55 </div>
55 </div>
56
56
57 <div class="footer">
57 <div class="footer">
58 <!-- Put your banners here -->
58 <!-- Put your banners here -->
59 </div>
59 </div>
60
60
61 </body>
61 </body>
62 </html>
62 </html>
@@ -1,18 +1,20 b''
1 {% extends "boards/static_base.html" %}
1 {% extends "boards/static_base.html" %}
2
2
3 {% load i18n %}
3 {% load i18n %}
4
4
5 {% block head %}
5 {% block head %}
6 <title>{% trans "Syntax" %}</title>
6 <title>{% trans "Syntax" %}</title>
7 {% endblock %}
7 {% endblock %}
8
8
9 {% block staticcontent %}
9 {% block staticcontent %}
10 <h2>{% trans 'Syntax' %}</h2>
10 <h2>{% trans 'Syntax' %}</h2>
11 <p>[i]<i>{% trans 'Italic text' %}</i>[/i]</p>
11 <p>[i]<i>{% trans 'Italic text' %}</i>[/i]</p>
12 <p>[b]<b>{% trans 'Bold text' %}</b>[/b]</p>
12 <p>[b]<b>{% trans 'Bold text' %}</b>[/b]</p>
13 <p>[spoiler]<span class="spoiler">{% trans 'Spoiler' %}</span>[/spoiler]</p>
13 <p>[spoiler]<span class="spoiler">{% trans 'Spoiler' %}</span>[/spoiler]</p>
14 <p>[post]123[/post] -- {% trans 'Link to a post' %}</p>
14 <p>[post]123[/post] -- {% trans 'Link to a post' %}</p>
15 <p>[s]<span class="strikethrough">{% trans 'Strikethrough text' %}</span>[/s]</p>
15 <p>[s]<span class="strikethrough">{% trans 'Strikethrough text' %}</span>[/s]</p>
16 <p>[comment]<span class="comment">{% trans 'Comment' %}</span>[/comment]</p>
16 <p>[comment]<span class="comment">{% trans 'Comment' %}</span>[/comment]</p>
17 <p>[quote]<span class="multiquote">{% trans 'Quote' %}</span>[/quote]</p>
17 <p>[quote]<span class="multiquote">{% trans 'Quote' %}</span>[/quote]</p>
18 <br/>
19 <p>{% trans 'You can try pasting the text and previewing the result here:' %} <a href="{% url 'preview' %}">{% trans 'Preview' %}</a></p>
18 {% endblock %}
20 {% endblock %}
@@ -1,79 +1,83 b''
1 from django.conf.urls import patterns, url, include
1 from django.conf.urls import patterns, url, include
2 from django.contrib import admin
2 from django.contrib import admin
3 from boards import views
3 from boards import views
4 from boards.rss import AllThreadsFeed, TagThreadsFeed, ThreadPostsFeed
4 from boards.rss import AllThreadsFeed, TagThreadsFeed, ThreadPostsFeed
5 from boards.views import api, tag_threads, all_threads, \
5 from boards.views import api, tag_threads, all_threads, \
6 settings, all_tags
6 settings, all_tags
7 from boards.views.authors import AuthorsView
7 from boards.views.authors import AuthorsView
8 from boards.views.delete_post import DeletePostView
8 from boards.views.delete_post import DeletePostView
9 from boards.views.ban import BanUserView
9 from boards.views.ban import BanUserView
10 from boards.views.search import BoardSearchView
10 from boards.views.search import BoardSearchView
11 from boards.views.static import StaticPageView
11 from boards.views.static import StaticPageView
12 from boards.views.post_admin import PostAdminView
12 from boards.views.post_admin import PostAdminView
13 from boards.views.preview import PostPreviewView
13
14
14 js_info_dict = {
15 js_info_dict = {
15 'packages': ('boards',),
16 'packages': ('boards',),
16 }
17 }
17
18
18 urlpatterns = patterns('',
19 urlpatterns = patterns('',
19 # /boards/
20 # /boards/
20 url(r'^$', all_threads.AllThreadsView.as_view(), name='index'),
21 url(r'^$', all_threads.AllThreadsView.as_view(), name='index'),
21 # /boards/page/
22 # /boards/page/
22 url(r'^page/(?P<page>\w+)/$', all_threads.AllThreadsView.as_view(),
23 url(r'^page/(?P<page>\w+)/$', all_threads.AllThreadsView.as_view(),
23 name='index'),
24 name='index'),
24
25
25 # /boards/tag/tag_name/
26 # /boards/tag/tag_name/
26 url(r'^tag/(?P<tag_name>\w+)/$', tag_threads.TagView.as_view(),
27 url(r'^tag/(?P<tag_name>\w+)/$', tag_threads.TagView.as_view(),
27 name='tag'),
28 name='tag'),
28 # /boards/tag/tag_id/page/
29 # /boards/tag/tag_id/page/
29 url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/$',
30 url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/$',
30 tag_threads.TagView.as_view(), name='tag'),
31 tag_threads.TagView.as_view(), name='tag'),
31
32
32 # /boards/thread/
33 # /boards/thread/
33 url(r'^thread/(?P<post_id>\w+)/$', views.thread.ThreadView.as_view(),
34 url(r'^thread/(?P<post_id>\w+)/$', views.thread.ThreadView.as_view(),
34 name='thread'),
35 name='thread'),
35 url(r'^thread/(?P<post_id>\w+)/mode/(?P<mode>\w+)/$', views.thread.ThreadView
36 url(r'^thread/(?P<post_id>\w+)/mode/(?P<mode>\w+)/$', views.thread.ThreadView
36 .as_view(), name='thread_mode'),
37 .as_view(), name='thread_mode'),
37
38
38 # /boards/post_admin/
39 # /boards/post_admin/
39 url(r'^post_admin/(?P<post_id>\w+)/$', PostAdminView.as_view(),
40 url(r'^post_admin/(?P<post_id>\w+)/$', PostAdminView.as_view(),
40 name='post_admin'),
41 name='post_admin'),
41
42
42 url(r'^settings/$', settings.SettingsView.as_view(), name='settings'),
43 url(r'^settings/$', settings.SettingsView.as_view(), name='settings'),
43 url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'),
44 url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'),
44 url(r'^authors/$', AuthorsView.as_view(), name='authors'),
45 url(r'^authors/$', AuthorsView.as_view(), name='authors'),
45 url(r'^delete/(?P<post_id>\w+)/$', DeletePostView.as_view(),
46 url(r'^delete/(?P<post_id>\w+)/$', DeletePostView.as_view(),
46 name='delete'),
47 name='delete'),
47 url(r'^ban/(?P<post_id>\w+)/$', BanUserView.as_view(), name='ban'),
48 url(r'^ban/(?P<post_id>\w+)/$', BanUserView.as_view(), name='ban'),
48
49
49 url(r'^banned/$', views.banned.BannedView.as_view(), name='banned'),
50 url(r'^banned/$', views.banned.BannedView.as_view(), name='banned'),
50 url(r'^staticpage/(?P<name>\w+)/$', StaticPageView.as_view(),
51 url(r'^staticpage/(?P<name>\w+)/$', StaticPageView.as_view(),
51 name='staticpage'),
52 name='staticpage'),
52
53
53 # RSS feeds
54 # RSS feeds
54 url(r'^rss/$', AllThreadsFeed()),
55 url(r'^rss/$', AllThreadsFeed()),
55 url(r'^page/(?P<page>\w+)/rss/$', AllThreadsFeed()),
56 url(r'^page/(?P<page>\w+)/rss/$', AllThreadsFeed()),
56 url(r'^tag/(?P<tag_name>\w+)/rss/$', TagThreadsFeed()),
57 url(r'^tag/(?P<tag_name>\w+)/rss/$', TagThreadsFeed()),
57 url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/rss/$', TagThreadsFeed()),
58 url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/rss/$', TagThreadsFeed()),
58 url(r'^thread/(?P<post_id>\w+)/rss/$', ThreadPostsFeed()),
59 url(r'^thread/(?P<post_id>\w+)/rss/$', ThreadPostsFeed()),
59
60
60 # i18n
61 # i18n
61 url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict,
62 url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict,
62 name='js_info_dict'),
63 name='js_info_dict'),
63
64
64 # API
65 # API
65 url(r'^api/post/(?P<post_id>\w+)/$', api.get_post, name="get_post"),
66 url(r'^api/post/(?P<post_id>\w+)/$', api.get_post, name="get_post"),
66 url(r'^api/diff_thread/(?P<thread_id>\w+)/(?P<last_update_time>\w+)/$',
67 url(r'^api/diff_thread/(?P<thread_id>\w+)/(?P<last_update_time>\w+)/$',
67 api.api_get_threaddiff, name="get_thread_diff"),
68 api.api_get_threaddiff, name="get_thread_diff"),
68 url(r'^api/threads/(?P<count>\w+)/$', api.api_get_threads,
69 url(r'^api/threads/(?P<count>\w+)/$', api.api_get_threads,
69 name='get_threads'),
70 name='get_threads'),
70 url(r'^api/tags/$', api.api_get_tags, name='get_tags'),
71 url(r'^api/tags/$', api.api_get_tags, name='get_tags'),
71 url(r'^api/thread/(?P<opening_post_id>\w+)/$', api.api_get_thread_posts,
72 url(r'^api/thread/(?P<opening_post_id>\w+)/$', api.api_get_thread_posts,
72 name='get_thread'),
73 name='get_thread'),
73 url(r'^api/add_post/(?P<opening_post_id>\w+)/$', api.api_add_post,
74 url(r'^api/add_post/(?P<opening_post_id>\w+)/$', api.api_add_post,
74 name='add_post'),
75 name='add_post'),
75
76
76 # Search
77 # Search
77 url(r'^search/$', BoardSearchView.as_view(), name='search'),
78 url(r'^search/$', BoardSearchView.as_view(), name='search'),
78
79
80 # Post preview
81 url(r'^preview/$', PostPreviewView.as_view(), name='preview')
82
79 )
83 )
General Comments 0
You need to be logged in to leave comments. Login now