##// END OF EJS Templates
Count total files size in a post instead of per-file basis
neko259 -
r1983:1ad01970 default
parent child Browse files
Show More
@@ -1,50 +1,50 b''
1 [Version]
1 [Version]
2 Version = 4.7.1 Elon
2 Version = 4.7.1 Elon
3 SiteName = Neboard DEV
3 SiteName = Neboard DEV
4
4
5 [Cache]
5 [Cache]
6 # Timeout for caching, if cache is used
6 # Timeout for caching, if cache is used
7 CacheTimeout = 600
7 CacheTimeout = 600
8
8
9 [Forms]
9 [Forms]
10 # Max post length in characters
10 # Max post length in characters
11 MaxTextLength = 30000
11 MaxTextLength = 30000
12 MaxFileSize = 8000000
12 MaxFileSize = 8000000
13 LimitFirstPosting = true
13 LimitFirstPosting = true
14 LimitPostingSpeed = false
14 LimitPostingSpeed = false
15 PowDifficulty = 0
15 PowDifficulty = 0
16 # Delay in seconds
16 # Delay in seconds
17 PostingDelay = 30
17 PostingDelay = 30
18 Autoban = false
18 Autoban = false
19 DefaultTag = test
19 DefaultTag = test
20 MaxFileCount = 1
20 MaxFileCount = 5
21 AdditionalSpoilerSpaces = false
21 AdditionalSpoilerSpaces = false
22
22
23 [Messages]
23 [Messages]
24 # Thread bumplimit
24 # Thread bumplimit
25 MaxPostsPerThread = 10
25 MaxPostsPerThread = 10
26 ThreadArchiveDays = 300
26 ThreadArchiveDays = 300
27 AnonymousMode = false
27 AnonymousMode = false
28
28
29 [View]
29 [View]
30 DefaultTheme = md
30 DefaultTheme = md
31 DefaultImageViewer = simple
31 DefaultImageViewer = simple
32 LastRepliesCount = 3
32 LastRepliesCount = 3
33 ThreadsPerPage = 3
33 ThreadsPerPage = 3
34 PostsPerPage = 10
34 PostsPerPage = 10
35 ImagesPerPageGallery = 20
35 ImagesPerPageGallery = 20
36 MaxFavoriteThreads = 20
36 MaxFavoriteThreads = 20
37 MaxLandingThreads = 20
37 MaxLandingThreads = 20
38 Themes=md:Mystic Dark,md_centered:Mystic Dark (centered),sw:Snow White,pg:Photon Grey,ad:Amanita Dark,iw:Inocibe White
38 Themes=md:Mystic Dark,md_centered:Mystic Dark (centered),sw:Snow White,pg:Photon Grey,ad:Amanita Dark,iw:Inocibe White
39 ImageViewers=simple:Simple,popup:Popup
39 ImageViewers=simple:Simple,popup:Popup
40
40
41 [Storage]
41 [Storage]
42 # Enable archiving threads instead of deletion when the thread limit is reached
42 # Enable archiving threads instead of deletion when the thread limit is reached
43 ArchiveThreads = true
43 ArchiveThreads = true
44
44
45 [RSS]
45 [RSS]
46 MaxItems = 20
46 MaxItems = 20
47
47
48 [External]
48 [External]
49 ImageSearchHost=
49 ImageSearchHost=
50 SourceFetcherTripcode=
50 SourceFetcherTripcode=
@@ -1,586 +1,588 b''
1 import logging
1 import logging
2 import time
2 import time
3
3
4 import hashlib
4 import hashlib
5 import pytz
5 import pytz
6 import re
6 import re
7 from PIL import Image
7 from PIL import Image
8 from django import forms
8 from django import forms
9 from django.core.cache import cache
9 from django.core.cache import cache
10 from django.core.files.images import get_image_dimensions
10 from django.core.files.images import get_image_dimensions
11 from django.core.files.uploadedfile import SimpleUploadedFile, UploadedFile
11 from django.core.files.uploadedfile import SimpleUploadedFile, UploadedFile
12 from django.forms.utils import ErrorList
12 from django.forms.utils import ErrorList
13 from django.utils.translation import ugettext_lazy as _, ungettext_lazy
13 from django.utils.translation import ugettext_lazy as _, ungettext_lazy
14
14
15 import boards.settings as board_settings
15 import boards.settings as board_settings
16 from boards import utils
16 from boards import utils
17 from boards.abstracts.constants import REGEX_TAGS
17 from boards.abstracts.constants import REGEX_TAGS
18 from boards.abstracts.settingsmanager import get_settings_manager
18 from boards.abstracts.settingsmanager import get_settings_manager
19 from boards.abstracts.sticker_factory import get_attachment_by_alias
19 from boards.abstracts.sticker_factory import get_attachment_by_alias
20 from boards.forms.fields import UrlFileField
20 from boards.forms.fields import UrlFileField
21 from boards.mdx_neboard import formatters
21 from boards.mdx_neboard import formatters
22 from boards.models import Attachment
22 from boards.models import Attachment
23 from boards.models import Tag
23 from boards.models import Tag
24 from boards.models.attachment import StickerPack
24 from boards.models.attachment import StickerPack
25 from boards.models.attachment.downloaders import download, REGEX_MAGNET
25 from boards.models.attachment.downloaders import download, REGEX_MAGNET
26 from boards.models.attachment.viewers import FILE_TYPES_IMAGE
26 from boards.models.attachment.viewers import FILE_TYPES_IMAGE
27 from boards.models.post import TITLE_MAX_LENGTH
27 from boards.models.post import TITLE_MAX_LENGTH
28 from boards.utils import validate_file_size, get_file_mimetype, \
28 from boards.utils import validate_file_size, get_file_mimetype, \
29 FILE_EXTENSION_DELIMITER, get_tripcode_from_text
29 FILE_EXTENSION_DELIMITER, get_tripcode_from_text
30
30
31 SECTION_FORMS = 'Forms'
31 SECTION_FORMS = 'Forms'
32
32
33 POW_HASH_LENGTH = 16
33 POW_HASH_LENGTH = 16
34 POW_LIFE_MINUTES = 5
34 POW_LIFE_MINUTES = 5
35
35
36 REGEX_USERNAMES = re.compile(r'^[\w\s\d,]+$', re.UNICODE)
36 REGEX_USERNAMES = re.compile(r'^[\w\s\d,]+$', re.UNICODE)
37 REGEX_URL = re.compile(r'^(http|https|ftp):\/\/', re.UNICODE)
37 REGEX_URL = re.compile(r'^(http|https|ftp):\/\/', re.UNICODE)
38
38
39 VETERAN_POSTING_DELAY = 5
39 VETERAN_POSTING_DELAY = 5
40
40
41 ATTRIBUTE_PLACEHOLDER = 'placeholder'
41 ATTRIBUTE_PLACEHOLDER = 'placeholder'
42 ATTRIBUTE_ROWS = 'rows'
42 ATTRIBUTE_ROWS = 'rows'
43
43
44 LAST_POST_TIME = 'last_post_time'
44 LAST_POST_TIME = 'last_post_time'
45 LAST_LOGIN_TIME = 'last_login_time'
45 LAST_LOGIN_TIME = 'last_login_time'
46 TEXT_PLACEHOLDER = _('Type message here. Use formatting panel for more advanced usage.')
46 TEXT_PLACEHOLDER = _('Type message here. Use formatting panel for more advanced usage.')
47 TAGS_PLACEHOLDER = _('music images i_dont_like_tags')
47 TAGS_PLACEHOLDER = _('music images i_dont_like_tags')
48
48
49 LABEL_TITLE = _('Title')
49 LABEL_TITLE = _('Title')
50 LABEL_TEXT = _('Text')
50 LABEL_TEXT = _('Text')
51 LABEL_TAG = _('Tag')
51 LABEL_TAG = _('Tag')
52 LABEL_SEARCH = _('Search')
52 LABEL_SEARCH = _('Search')
53 LABEL_FILE = _('File')
53 LABEL_FILE = _('File')
54 LABEL_DUPLICATES = _('Check for duplicates')
54 LABEL_DUPLICATES = _('Check for duplicates')
55 LABEL_URL = _('Do not download URLs')
55 LABEL_URL = _('Do not download URLs')
56
56
57 ERROR_SPEED = 'Please wait %(delay)d second before sending message'
57 ERROR_SPEED = 'Please wait %(delay)d second before sending message'
58 ERROR_SPEED_PLURAL = 'Please wait %(delay)d seconds before sending message'
58 ERROR_SPEED_PLURAL = 'Please wait %(delay)d seconds before sending message'
59 ERROR_MANY_FILES = 'You can post no more than %(files)d file.'
59 ERROR_MANY_FILES = 'You can post no more than %(files)d file.'
60 ERROR_MANY_FILES_PLURAL = 'You can post no more than %(files)d files.'
60 ERROR_MANY_FILES_PLURAL = 'You can post no more than %(files)d files.'
61 ERROR_DUPLICATES = 'Some files are already present on the board.'
61 ERROR_DUPLICATES = 'Some files are already present on the board.'
62
62
63 TAG_MAX_LENGTH = 20
63 TAG_MAX_LENGTH = 20
64
64
65 TEXTAREA_ROWS = 4
65 TEXTAREA_ROWS = 4
66
66
67 TRIPCODE_DELIM = '##'
67 TRIPCODE_DELIM = '##'
68
68
69 # TODO Maybe this may be converted into the database table?
69 # TODO Maybe this may be converted into the database table?
70 MIMETYPE_EXTENSIONS = {
70 MIMETYPE_EXTENSIONS = {
71 'image/jpeg': 'jpeg',
71 'image/jpeg': 'jpeg',
72 'image/png': 'png',
72 'image/png': 'png',
73 'image/gif': 'gif',
73 'image/gif': 'gif',
74 'video/webm': 'webm',
74 'video/webm': 'webm',
75 'application/pdf': 'pdf',
75 'application/pdf': 'pdf',
76 'x-diff': 'diff',
76 'x-diff': 'diff',
77 'image/svg+xml': 'svg',
77 'image/svg+xml': 'svg',
78 'application/x-shockwave-flash': 'swf',
78 'application/x-shockwave-flash': 'swf',
79 'image/x-ms-bmp': 'bmp',
79 'image/x-ms-bmp': 'bmp',
80 'image/bmp': 'bmp',
80 'image/bmp': 'bmp',
81 }
81 }
82
82
83 DOWN_MODE_DOWNLOAD = 'DOWNLOAD'
83 DOWN_MODE_DOWNLOAD = 'DOWNLOAD'
84 DOWN_MODE_DOWNLOAD_UNIQUE = 'DOWNLOAD_UNIQUE'
84 DOWN_MODE_DOWNLOAD_UNIQUE = 'DOWNLOAD_UNIQUE'
85 DOWN_MODE_URL = 'URL'
85 DOWN_MODE_URL = 'URL'
86 DOWN_MODE_TRY = 'TRY'
86 DOWN_MODE_TRY = 'TRY'
87
87
88
88
89 logger = logging.getLogger('boards.forms')
89 logger = logging.getLogger('boards.forms')
90
90
91
91
92 def get_timezones():
92 def get_timezones():
93 timezones = []
93 timezones = []
94 for tz in pytz.common_timezones:
94 for tz in pytz.common_timezones:
95 timezones.append((tz, tz),)
95 timezones.append((tz, tz),)
96 return timezones
96 return timezones
97
97
98
98
99 class FormatPanel(forms.Textarea):
99 class FormatPanel(forms.Textarea):
100 """
100 """
101 Panel for text formatting. Consists of buttons to add different tags to the
101 Panel for text formatting. Consists of buttons to add different tags to the
102 form text area.
102 form text area.
103 """
103 """
104
104
105 def render(self, name, value, attrs=None):
105 def render(self, name, value, attrs=None):
106 output = '<div id="mark-panel">'
106 output = '<div id="mark-panel">'
107 for formatter in formatters:
107 for formatter in formatters:
108 output += '<span class="mark_btn"' + \
108 output += '<span class="mark_btn"' + \
109 ' onClick="addMarkToMsg(\'' + formatter.format_left + \
109 ' onClick="addMarkToMsg(\'' + formatter.format_left + \
110 '\', \'' + formatter.format_right + '\')">' + \
110 '\', \'' + formatter.format_right + '\')">' + \
111 formatter.preview_left + formatter.name + \
111 formatter.preview_left + formatter.name + \
112 formatter.preview_right + '</span>'
112 formatter.preview_right + '</span>'
113
113
114 output += '</div>'
114 output += '</div>'
115 output += super(FormatPanel, self).render(name, value, attrs=attrs)
115 output += super(FormatPanel, self).render(name, value, attrs=attrs)
116
116
117 return output
117 return output
118
118
119
119
120 class PlainErrorList(ErrorList):
120 class PlainErrorList(ErrorList):
121 def __unicode__(self):
121 def __unicode__(self):
122 return self.as_text()
122 return self.as_text()
123
123
124 def as_text(self):
124 def as_text(self):
125 return ''.join(['(!) %s ' % e for e in self])
125 return ''.join(['(!) %s ' % e for e in self])
126
126
127
127
128 class NeboardForm(forms.Form):
128 class NeboardForm(forms.Form):
129 """
129 """
130 Form with neboard-specific formatting.
130 Form with neboard-specific formatting.
131 """
131 """
132 required_css_class = 'required-field'
132 required_css_class = 'required-field'
133
133
134 def as_div(self):
134 def as_div(self):
135 """
135 """
136 Returns this form rendered as HTML <as_div>s.
136 Returns this form rendered as HTML <as_div>s.
137 """
137 """
138
138
139 return self._html_output(
139 return self._html_output(
140 # TODO Do not show hidden rows in the list here
140 # TODO Do not show hidden rows in the list here
141 normal_row='<div class="form-row">'
141 normal_row='<div class="form-row">'
142 '<div class="form-label">'
142 '<div class="form-label">'
143 '%(label)s'
143 '%(label)s'
144 '</div>'
144 '</div>'
145 '<div class="form-input">'
145 '<div class="form-input">'
146 '%(field)s'
146 '%(field)s'
147 '</div>'
147 '</div>'
148 '</div>'
148 '</div>'
149 '<div class="form-row">'
149 '<div class="form-row">'
150 '%(help_text)s'
150 '%(help_text)s'
151 '</div>',
151 '</div>',
152 error_row='<div class="form-row">'
152 error_row='<div class="form-row">'
153 '<div class="form-label"></div>'
153 '<div class="form-label"></div>'
154 '<div class="form-errors">%s</div>'
154 '<div class="form-errors">%s</div>'
155 '</div>',
155 '</div>',
156 row_ender='</div>',
156 row_ender='</div>',
157 help_text_html='%s',
157 help_text_html='%s',
158 errors_on_separate_row=True)
158 errors_on_separate_row=True)
159
159
160 def as_json_errors(self):
160 def as_json_errors(self):
161 errors = []
161 errors = []
162
162
163 for name, field in list(self.fields.items()):
163 for name, field in list(self.fields.items()):
164 if self[name].errors:
164 if self[name].errors:
165 errors.append({
165 errors.append({
166 'field': name,
166 'field': name,
167 'errors': self[name].errors.as_text(),
167 'errors': self[name].errors.as_text(),
168 })
168 })
169
169
170 return errors
170 return errors
171
171
172
172
173 class PostForm(NeboardForm):
173 class PostForm(NeboardForm):
174
174
175 title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False,
175 title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False,
176 label=LABEL_TITLE,
176 label=LABEL_TITLE,
177 widget=forms.TextInput(
177 widget=forms.TextInput(
178 attrs={ATTRIBUTE_PLACEHOLDER: 'Title{}tripcode'.format(TRIPCODE_DELIM)}))
178 attrs={ATTRIBUTE_PLACEHOLDER: 'Title{}tripcode'.format(TRIPCODE_DELIM)}))
179 text = forms.CharField(
179 text = forms.CharField(
180 widget=FormatPanel(attrs={
180 widget=FormatPanel(attrs={
181 ATTRIBUTE_PLACEHOLDER: TEXT_PLACEHOLDER,
181 ATTRIBUTE_PLACEHOLDER: TEXT_PLACEHOLDER,
182 ATTRIBUTE_ROWS: TEXTAREA_ROWS,
182 ATTRIBUTE_ROWS: TEXTAREA_ROWS,
183 }),
183 }),
184 required=False, label=LABEL_TEXT)
184 required=False, label=LABEL_TEXT)
185 download_mode = forms.ChoiceField(
185 download_mode = forms.ChoiceField(
186 choices=(
186 choices=(
187 (DOWN_MODE_TRY, _('Download or insert as URLs')),
187 (DOWN_MODE_TRY, _('Download or insert as URLs')),
188 (DOWN_MODE_DOWNLOAD, _('Download')),
188 (DOWN_MODE_DOWNLOAD, _('Download')),
189 (DOWN_MODE_DOWNLOAD_UNIQUE, _('Download and check for uniqueness')),
189 (DOWN_MODE_DOWNLOAD_UNIQUE, _('Download and check for uniqueness')),
190 (DOWN_MODE_URL, _('Insert as URLs')),
190 (DOWN_MODE_URL, _('Insert as URLs')),
191 ),
191 ),
192 initial=DOWN_MODE_TRY,
192 initial=DOWN_MODE_TRY,
193 label=_('File process mode'))
193 label=_('File process mode'))
194 file = UrlFileField(required=False, label=LABEL_FILE)
194 file = UrlFileField(required=False, label=LABEL_FILE)
195
195
196 # This field is for spam prevention only
196 # This field is for spam prevention only
197 email = forms.CharField(max_length=100, required=False, label=_('e-mail'),
197 email = forms.CharField(max_length=100, required=False, label=_('e-mail'),
198 widget=forms.TextInput(attrs={
198 widget=forms.TextInput(attrs={
199 'class': 'form-email'}))
199 'class': 'form-email'}))
200 subscribe = forms.BooleanField(required=False, label=_('Subscribe to thread'))
200 subscribe = forms.BooleanField(required=False, label=_('Subscribe to thread'))
201
201
202 guess = forms.CharField(widget=forms.HiddenInput(), required=False)
202 guess = forms.CharField(widget=forms.HiddenInput(), required=False)
203 timestamp = forms.CharField(widget=forms.HiddenInput(), required=False)
203 timestamp = forms.CharField(widget=forms.HiddenInput(), required=False)
204 iteration = forms.CharField(widget=forms.HiddenInput(), required=False)
204 iteration = forms.CharField(widget=forms.HiddenInput(), required=False)
205
205
206 session = None
206 session = None
207 need_to_ban = False
207 need_to_ban = False
208
208
209 def clean_title(self):
209 def clean_title(self):
210 title = self.cleaned_data['title']
210 title = self.cleaned_data['title']
211 if title:
211 if title:
212 if len(title) > TITLE_MAX_LENGTH:
212 if len(title) > TITLE_MAX_LENGTH:
213 raise forms.ValidationError(_('Title must have less than %s '
213 raise forms.ValidationError(_('Title must have less than %s '
214 'characters') %
214 'characters') %
215 str(TITLE_MAX_LENGTH))
215 str(TITLE_MAX_LENGTH))
216 return title
216 return title
217
217
218 def clean_text(self):
218 def clean_text(self):
219 text = self.cleaned_data['text'].strip()
219 text = self.cleaned_data['text'].strip()
220 if text:
220 if text:
221 max_length = board_settings.get_int(SECTION_FORMS, 'MaxTextLength')
221 max_length = board_settings.get_int(SECTION_FORMS, 'MaxTextLength')
222 if len(text) > max_length:
222 if len(text) > max_length:
223 raise forms.ValidationError(_('Text must have less than %s '
223 raise forms.ValidationError(_('Text must have less than %s '
224 'characters') % str(max_length))
224 'characters') % str(max_length))
225 return text
225 return text
226
226
227 def clean_file(self):
227 def clean_file(self):
228 return self._clean_files(self.cleaned_data['file'])
228 return self._clean_files(self.cleaned_data['file'])
229
229
230 def clean(self):
230 def clean(self):
231 cleaned_data = super(PostForm, self).clean()
231 cleaned_data = super(PostForm, self).clean()
232
232
233 if cleaned_data['email']:
233 if cleaned_data['email']:
234 if board_settings.get_bool(SECTION_FORMS, 'Autoban'):
234 if board_settings.get_bool(SECTION_FORMS, 'Autoban'):
235 self.need_to_ban = True
235 self.need_to_ban = True
236 raise forms.ValidationError('A human cannot enter a hidden field')
236 raise forms.ValidationError('A human cannot enter a hidden field')
237
237
238 if not self.errors:
238 if not self.errors:
239 self._clean_text_file()
239 self._clean_text_file()
240
240
241 limit_speed = board_settings.get_bool(SECTION_FORMS, 'LimitPostingSpeed')
241 limit_speed = board_settings.get_bool(SECTION_FORMS, 'LimitPostingSpeed')
242 limit_first = board_settings.get_bool(SECTION_FORMS, 'LimitFirstPosting')
242 limit_first = board_settings.get_bool(SECTION_FORMS, 'LimitFirstPosting')
243
243
244 settings_manager = get_settings_manager(self)
244 settings_manager = get_settings_manager(self)
245 if not self.errors and limit_speed or (limit_first and not settings_manager.get_setting('confirmed_user')):
245 if not self.errors and limit_speed or (limit_first and not settings_manager.get_setting('confirmed_user')):
246 pow_difficulty = board_settings.get_int(SECTION_FORMS, 'PowDifficulty')
246 pow_difficulty = board_settings.get_int(SECTION_FORMS, 'PowDifficulty')
247 if pow_difficulty > 0:
247 if pow_difficulty > 0:
248 # PoW-based
248 # PoW-based
249 if cleaned_data['timestamp'] \
249 if cleaned_data['timestamp'] \
250 and cleaned_data['iteration'] and cleaned_data['guess'] \
250 and cleaned_data['iteration'] and cleaned_data['guess'] \
251 and not settings_manager.get_setting('confirmed_user'):
251 and not settings_manager.get_setting('confirmed_user'):
252 self._validate_hash(cleaned_data['timestamp'], cleaned_data['iteration'], cleaned_data['guess'], cleaned_data['text'])
252 self._validate_hash(cleaned_data['timestamp'], cleaned_data['iteration'], cleaned_data['guess'], cleaned_data['text'])
253 else:
253 else:
254 # Time-based
254 # Time-based
255 self._validate_posting_speed()
255 self._validate_posting_speed()
256 settings_manager.set_setting('confirmed_user', True)
256 settings_manager.set_setting('confirmed_user', True)
257 if self.cleaned_data['download_mode'] == DOWN_MODE_DOWNLOAD_UNIQUE:
257 if self.cleaned_data['download_mode'] == DOWN_MODE_DOWNLOAD_UNIQUE:
258 self._check_file_duplicates(self.get_files())
258 self._check_file_duplicates(self.get_files())
259
259
260 return cleaned_data
260 return cleaned_data
261
261
262 def get_files(self):
262 def get_files(self):
263 """
263 """
264 Gets file from form or URL.
264 Gets file from form or URL.
265 """
265 """
266
266
267 files = []
267 files = []
268 for file in self.cleaned_data['file']:
268 for file in self.cleaned_data['file']:
269 if isinstance(file, UploadedFile):
269 if isinstance(file, UploadedFile):
270 files.append(file)
270 files.append(file)
271
271
272 return files
272 return files
273
273
274 def get_file_urls(self):
274 def get_file_urls(self):
275 files = []
275 files = []
276 for file in self.cleaned_data['file']:
276 for file in self.cleaned_data['file']:
277 if type(file) == str:
277 if type(file) == str:
278 files.append(file)
278 files.append(file)
279
279
280 return files
280 return files
281
281
282 def get_tripcode(self):
282 def get_tripcode(self):
283 title = self.cleaned_data['title']
283 title = self.cleaned_data['title']
284 if title is not None and TRIPCODE_DELIM in title:
284 if title is not None and TRIPCODE_DELIM in title:
285 tripcode = get_tripcode_from_text(title.split(TRIPCODE_DELIM, maxsplit=1)[1])
285 tripcode = get_tripcode_from_text(title.split(TRIPCODE_DELIM, maxsplit=1)[1])
286 else:
286 else:
287 tripcode = ''
287 tripcode = ''
288 return tripcode
288 return tripcode
289
289
290 def get_title(self):
290 def get_title(self):
291 title = self.cleaned_data['title']
291 title = self.cleaned_data['title']
292 if title is not None and TRIPCODE_DELIM in title:
292 if title is not None and TRIPCODE_DELIM in title:
293 return title.split(TRIPCODE_DELIM, maxsplit=1)[0]
293 return title.split(TRIPCODE_DELIM, maxsplit=1)[0]
294 else:
294 else:
295 return title
295 return title
296
296
297 def get_images(self):
297 def get_images(self):
298 return self.cleaned_data.get('stickers', [])
298 return self.cleaned_data.get('stickers', [])
299
299
300 def is_subscribe(self):
300 def is_subscribe(self):
301 return self.cleaned_data['subscribe']
301 return self.cleaned_data['subscribe']
302
302
303 def _update_file_extension(self, file):
303 def _update_file_extension(self, file):
304 if file:
304 if file:
305 mimetype = get_file_mimetype(file)
305 mimetype = get_file_mimetype(file)
306 extension = MIMETYPE_EXTENSIONS.get(mimetype)
306 extension = MIMETYPE_EXTENSIONS.get(mimetype)
307 if extension:
307 if extension:
308 filename = file.name.split(FILE_EXTENSION_DELIMITER, 1)[0]
308 filename = file.name.split(FILE_EXTENSION_DELIMITER, 1)[0]
309 new_filename = filename + FILE_EXTENSION_DELIMITER + extension
309 new_filename = filename + FILE_EXTENSION_DELIMITER + extension
310
310
311 file.name = new_filename
311 file.name = new_filename
312 else:
312 else:
313 logger.info('Unrecognized file mimetype: {}'.format(mimetype))
313 logger.info('Unrecognized file mimetype: {}'.format(mimetype))
314
314
315 def _clean_files(self, inputs):
315 def _clean_files(self, inputs):
316 files = []
316 files = []
317
317
318 max_file_count = board_settings.get_int(SECTION_FORMS, 'MaxFileCount')
318 max_file_count = board_settings.get_int(SECTION_FORMS, 'MaxFileCount')
319 if len(inputs) > max_file_count:
319 if len(inputs) > max_file_count:
320 raise forms.ValidationError(
320 raise forms.ValidationError(
321 ungettext_lazy(ERROR_MANY_FILES, ERROR_MANY_FILES,
321 ungettext_lazy(ERROR_MANY_FILES, ERROR_MANY_FILES,
322 max_file_count) % {'files': max_file_count})
322 max_file_count) % {'files': max_file_count})
323
324 size = 0
323 for file_input in inputs:
325 for file_input in inputs:
324 if isinstance(file_input, UploadedFile):
326 if isinstance(file_input, UploadedFile):
325 files.append(self._clean_file_file(file_input))
327 file = self._clean_file_file(file_input)
328 size += file.size
329 files.append(file)
326 else:
330 else:
327 files.append(self._clean_file_url(file_input))
331 files.append(self._clean_file_url(file_input))
328
332
329 for file in files:
333 for file in files:
330 self._validate_image_dimensions(file)
334 self._validate_image_dimensions(file)
335 validate_file_size(size)
331
336
332 return files
337 return files
333
338
334 def _validate_image_dimensions(self, file):
339 def _validate_image_dimensions(self, file):
335 if isinstance(file, UploadedFile):
340 if isinstance(file, UploadedFile):
336 mimetype = get_file_mimetype(file)
341 mimetype = get_file_mimetype(file)
337 if mimetype.split('/')[-1] in FILE_TYPES_IMAGE:
342 if mimetype.split('/')[-1] in FILE_TYPES_IMAGE:
338 Image.warnings.simplefilter('error', Image.DecompressionBombWarning)
343 Image.warnings.simplefilter('error', Image.DecompressionBombWarning)
339 try:
344 try:
340 print(get_image_dimensions(file))
345 print(get_image_dimensions(file))
341 except Exception:
346 except Exception:
342 raise forms.ValidationError('Possible decompression bomb or large image.')
347 raise forms.ValidationError('Possible decompression bomb or large image.')
343
348
344 def _clean_file_file(self, file):
349 def _clean_file_file(self, file):
345 validate_file_size(file.size)
346 self._update_file_extension(file)
350 self._update_file_extension(file)
347
351
348 return file
352 return file
349
353
350 def _clean_file_url(self, url):
354 def _clean_file_url(self, url):
351 file = None
355 file = None
352
356
353 if url:
357 if url:
354 mode = self.cleaned_data['download_mode']
358 mode = self.cleaned_data['download_mode']
355 if mode == DOWN_MODE_URL:
359 if mode == DOWN_MODE_URL:
356 return url
360 return url
357
361
358 try:
362 try:
359 image = get_attachment_by_alias(url, self.session)
363 image = get_attachment_by_alias(url, self.session)
360 if image is not None:
364 if image is not None:
361 if 'stickers' not in self.cleaned_data:
365 if 'stickers' not in self.cleaned_data:
362 self.cleaned_data['stickers'] = []
366 self.cleaned_data['stickers'] = []
363 self.cleaned_data['stickers'].append(image)
367 self.cleaned_data['stickers'].append(image)
364 return
368 return
365
369
366 if file is None:
370 if file is None:
367 file = self._get_file_from_url(url)
371 file = self._get_file_from_url(url)
368 if not file:
372 if not file:
369 raise forms.ValidationError(_('Invalid URL'))
373 raise forms.ValidationError(_('Invalid URL'))
370 else:
371 validate_file_size(file.size)
372 self._update_file_extension(file)
374 self._update_file_extension(file)
373 except forms.ValidationError as e:
375 except forms.ValidationError as e:
374 # Assume we will get the plain URL instead of a file and save it
376 # Assume we will get the plain URL instead of a file and save it
375 if mode == DOWN_MODE_TRY and (REGEX_URL.match(url) or REGEX_MAGNET.match(url)):
377 if mode == DOWN_MODE_TRY and (REGEX_URL.match(url) or REGEX_MAGNET.match(url)):
376 logger.info('Error in forms: {}'.format(e))
378 logger.info('Error in forms: {}'.format(e))
377 return url
379 return url
378 else:
380 else:
379 raise e
381 raise e
380
382
381 return file
383 return file
382
384
383 def _clean_text_file(self):
385 def _clean_text_file(self):
384 text = self.cleaned_data.get('text')
386 text = self.cleaned_data.get('text')
385 file = self.get_files()
387 file = self.get_files()
386 file_url = self.get_file_urls()
388 file_url = self.get_file_urls()
387 images = self.get_images()
389 images = self.get_images()
388
390
389 if (not text) and (not file) and (not file_url) and len(images) == 0:
391 if (not text) and (not file) and (not file_url) and len(images) == 0:
390 error_message = _('Either text or file must be entered.')
392 error_message = _('Either text or file must be entered.')
391 self._add_general_error(error_message)
393 self._add_general_error(error_message)
392
394
393 def _get_cache_key(self, key):
395 def _get_cache_key(self, key):
394 return '{}_{}'.format(self.session.session_key, key)
396 return '{}_{}'.format(self.session.session_key, key)
395
397
396 def _set_session_cache(self, key, value):
398 def _set_session_cache(self, key, value):
397 cache.set(self._get_cache_key(key), value)
399 cache.set(self._get_cache_key(key), value)
398
400
399 def _get_session_cache(self, key):
401 def _get_session_cache(self, key):
400 return cache.get(self._get_cache_key(key))
402 return cache.get(self._get_cache_key(key))
401
403
402 def _get_last_post_time(self):
404 def _get_last_post_time(self):
403 last = self._get_session_cache(LAST_POST_TIME)
405 last = self._get_session_cache(LAST_POST_TIME)
404 if last is None:
406 if last is None:
405 last = self.session.get(LAST_POST_TIME)
407 last = self.session.get(LAST_POST_TIME)
406 return last
408 return last
407
409
408 def _validate_posting_speed(self):
410 def _validate_posting_speed(self):
409 can_post = True
411 can_post = True
410
412
411 posting_delay = board_settings.get_int(SECTION_FORMS, 'PostingDelay')
413 posting_delay = board_settings.get_int(SECTION_FORMS, 'PostingDelay')
412
414
413 if board_settings.get_bool(SECTION_FORMS, 'LimitPostingSpeed'):
415 if board_settings.get_bool(SECTION_FORMS, 'LimitPostingSpeed'):
414 now = time.time()
416 now = time.time()
415
417
416 current_delay = 0
418 current_delay = 0
417
419
418 if LAST_POST_TIME not in self.session:
420 if LAST_POST_TIME not in self.session:
419 self.session[LAST_POST_TIME] = now
421 self.session[LAST_POST_TIME] = now
420
422
421 need_delay = True
423 need_delay = True
422 else:
424 else:
423 last_post_time = self._get_last_post_time()
425 last_post_time = self._get_last_post_time()
424 current_delay = int(now - last_post_time)
426 current_delay = int(now - last_post_time)
425
427
426 need_delay = current_delay < posting_delay
428 need_delay = current_delay < posting_delay
427
429
428 self._set_session_cache(LAST_POST_TIME, now)
430 self._set_session_cache(LAST_POST_TIME, now)
429
431
430 if need_delay:
432 if need_delay:
431 delay = posting_delay - current_delay
433 delay = posting_delay - current_delay
432 error_message = ungettext_lazy(ERROR_SPEED, ERROR_SPEED_PLURAL,
434 error_message = ungettext_lazy(ERROR_SPEED, ERROR_SPEED_PLURAL,
433 delay) % {'delay': delay}
435 delay) % {'delay': delay}
434 self._add_general_error(error_message)
436 self._add_general_error(error_message)
435
437
436 can_post = False
438 can_post = False
437
439
438 if can_post:
440 if can_post:
439 self.session[LAST_POST_TIME] = now
441 self.session[LAST_POST_TIME] = now
440 else:
442 else:
441 # Reset the time since posting failed
443 # Reset the time since posting failed
442 self._set_session_cache(LAST_POST_TIME, self.session[LAST_POST_TIME])
444 self._set_session_cache(LAST_POST_TIME, self.session[LAST_POST_TIME])
443
445
444 def _get_file_from_url(self, url: str) -> SimpleUploadedFile:
446 def _get_file_from_url(self, url: str) -> SimpleUploadedFile:
445 """
447 """
446 Gets an file file from URL.
448 Gets an file file from URL.
447 """
449 """
448
450
449 try:
451 try:
450 return download(url)
452 return download(url)
451 except forms.ValidationError as e:
453 except forms.ValidationError as e:
452 raise e
454 raise e
453 except Exception as e:
455 except Exception as e:
454 raise forms.ValidationError(e)
456 raise forms.ValidationError(e)
455
457
456 def _validate_hash(self, timestamp: str, iteration: str, guess: str, message: str):
458 def _validate_hash(self, timestamp: str, iteration: str, guess: str, message: str):
457 payload = timestamp + message.replace('\r\n', '\n')
459 payload = timestamp + message.replace('\r\n', '\n')
458 difficulty = board_settings.get_int(SECTION_FORMS, 'PowDifficulty')
460 difficulty = board_settings.get_int(SECTION_FORMS, 'PowDifficulty')
459 target = str(int(2 ** (POW_HASH_LENGTH * 3) / difficulty))
461 target = str(int(2 ** (POW_HASH_LENGTH * 3) / difficulty))
460 if len(target) < POW_HASH_LENGTH:
462 if len(target) < POW_HASH_LENGTH:
461 target = '0' * (POW_HASH_LENGTH - len(target)) + target
463 target = '0' * (POW_HASH_LENGTH - len(target)) + target
462
464
463 computed_guess = hashlib.sha256((payload + iteration).encode())\
465 computed_guess = hashlib.sha256((payload + iteration).encode())\
464 .hexdigest()[0:POW_HASH_LENGTH]
466 .hexdigest()[0:POW_HASH_LENGTH]
465 if guess != computed_guess or guess > target:
467 if guess != computed_guess or guess > target:
466 self._add_general_error(_('Invalid PoW.'))
468 self._add_general_error(_('Invalid PoW.'))
467
469
468 def _check_file_duplicates(self, files):
470 def _check_file_duplicates(self, files):
469 for file in files:
471 for file in files:
470 file_hash = utils.get_file_hash(file)
472 file_hash = utils.get_file_hash(file)
471 if Attachment.objects.get_existing_duplicate(file_hash, file):
473 if Attachment.objects.get_existing_duplicate(file_hash, file):
472 self._add_general_error(_(ERROR_DUPLICATES))
474 self._add_general_error(_(ERROR_DUPLICATES))
473
475
474 def _add_general_error(self, message):
476 def _add_general_error(self, message):
475 self.add_error('text', forms.ValidationError(message))
477 self.add_error('text', forms.ValidationError(message))
476
478
477
479
478 class ThreadForm(PostForm):
480 class ThreadForm(PostForm):
479
481
480 tags = forms.CharField(
482 tags = forms.CharField(
481 widget=forms.TextInput(attrs={ATTRIBUTE_PLACEHOLDER: TAGS_PLACEHOLDER}),
483 widget=forms.TextInput(attrs={ATTRIBUTE_PLACEHOLDER: TAGS_PLACEHOLDER}),
482 max_length=100, label=_('Tags'), required=True)
484 max_length=100, label=_('Tags'), required=True)
483 monochrome = forms.BooleanField(label=_('Monochrome'), required=False)
485 monochrome = forms.BooleanField(label=_('Monochrome'), required=False)
484 stickerpack = forms.BooleanField(label=_('Sticker Pack'), required=False)
486 stickerpack = forms.BooleanField(label=_('Sticker Pack'), required=False)
485
487
486 def clean_tags(self):
488 def clean_tags(self):
487 tags = self.cleaned_data['tags'].strip()
489 tags = self.cleaned_data['tags'].strip()
488
490
489 if not tags or not REGEX_TAGS.match(tags):
491 if not tags or not REGEX_TAGS.match(tags):
490 raise forms.ValidationError(
492 raise forms.ValidationError(
491 _('Inappropriate characters in tags.'))
493 _('Inappropriate characters in tags.'))
492
494
493 default_tag_name = board_settings.get(SECTION_FORMS, 'DefaultTag')\
495 default_tag_name = board_settings.get(SECTION_FORMS, 'DefaultTag')\
494 .strip().lower()
496 .strip().lower()
495
497
496 required_tag_exists = False
498 required_tag_exists = False
497 tag_set = set()
499 tag_set = set()
498 for tag_string in tags.split():
500 for tag_string in tags.split():
499 tag_name = tag_string.strip().lower()
501 tag_name = tag_string.strip().lower()
500 if tag_name == default_tag_name:
502 if tag_name == default_tag_name:
501 required_tag_exists = True
503 required_tag_exists = True
502 tag, created = Tag.objects.get_or_create_with_alias(
504 tag, created = Tag.objects.get_or_create_with_alias(
503 name=tag_name, required=True)
505 name=tag_name, required=True)
504 else:
506 else:
505 tag, created = Tag.objects.get_or_create_with_alias(name=tag_name)
507 tag, created = Tag.objects.get_or_create_with_alias(name=tag_name)
506 tag_set.add(tag)
508 tag_set.add(tag)
507
509
508 # If this is a new tag, don't check for its parents because nobody
510 # If this is a new tag, don't check for its parents because nobody
509 # added them yet
511 # added them yet
510 if not created:
512 if not created:
511 tag_set |= set(tag.get_all_parents())
513 tag_set |= set(tag.get_all_parents())
512
514
513 for tag in tag_set:
515 for tag in tag_set:
514 if tag.required:
516 if tag.required:
515 required_tag_exists = True
517 required_tag_exists = True
516 break
518 break
517
519
518 # Use default tag if no section exists
520 # Use default tag if no section exists
519 if not required_tag_exists:
521 if not required_tag_exists:
520 default_tag, created = Tag.objects.get_or_create_with_alias(
522 default_tag, created = Tag.objects.get_or_create_with_alias(
521 name=default_tag_name, required=True)
523 name=default_tag_name, required=True)
522 tag_set.add(default_tag)
524 tag_set.add(default_tag)
523
525
524 return tag_set
526 return tag_set
525
527
526 def clean(self):
528 def clean(self):
527 cleaned_data = super(ThreadForm, self).clean()
529 cleaned_data = super(ThreadForm, self).clean()
528
530
529 return cleaned_data
531 return cleaned_data
530
532
531 def is_monochrome(self):
533 def is_monochrome(self):
532 return self.cleaned_data['monochrome']
534 return self.cleaned_data['monochrome']
533
535
534 def clean_stickerpack(self):
536 def clean_stickerpack(self):
535 stickerpack = self.cleaned_data['stickerpack']
537 stickerpack = self.cleaned_data['stickerpack']
536 if stickerpack:
538 if stickerpack:
537 tripcode = self.get_tripcode()
539 tripcode = self.get_tripcode()
538 if not tripcode:
540 if not tripcode:
539 raise forms.ValidationError(_(
541 raise forms.ValidationError(_(
540 'Tripcode should be specified to own a stickerpack.'))
542 'Tripcode should be specified to own a stickerpack.'))
541 title = self.get_title()
543 title = self.get_title()
542 if not title:
544 if not title:
543 raise forms.ValidationError(_(
545 raise forms.ValidationError(_(
544 'Title should be specified as a stickerpack name.'))
546 'Title should be specified as a stickerpack name.'))
545 if not REGEX_TAGS.match(title):
547 if not REGEX_TAGS.match(title):
546 raise forms.ValidationError(_('Inappropriate sticker pack name.'))
548 raise forms.ValidationError(_('Inappropriate sticker pack name.'))
547
549
548 existing_pack = StickerPack.objects.filter(name=title).first()
550 existing_pack = StickerPack.objects.filter(name=title).first()
549 if existing_pack:
551 if existing_pack:
550 if existing_pack.tripcode != tripcode:
552 if existing_pack.tripcode != tripcode:
551 raise forms.ValidationError(_(
553 raise forms.ValidationError(_(
552 'A sticker pack with this name already exists and is'
554 'A sticker pack with this name already exists and is'
553 ' owned by another tripcode.'))
555 ' owned by another tripcode.'))
554 if not existing_pack.tripcode:
556 if not existing_pack.tripcode:
555 raise forms.ValidationError(_(
557 raise forms.ValidationError(_(
556 'This sticker pack can only be updated by an '
558 'This sticker pack can only be updated by an '
557 'administrator.'))
559 'administrator.'))
558
560
559 return stickerpack
561 return stickerpack
560
562
561 def is_stickerpack(self):
563 def is_stickerpack(self):
562 return self.cleaned_data['stickerpack']
564 return self.cleaned_data['stickerpack']
563
565
564
566
565 class SettingsForm(NeboardForm):
567 class SettingsForm(NeboardForm):
566
568
567 theme = forms.ChoiceField(
569 theme = forms.ChoiceField(
568 choices=board_settings.get_list_dict('View', 'Themes'),
570 choices=board_settings.get_list_dict('View', 'Themes'),
569 label=_('Theme'))
571 label=_('Theme'))
570 image_viewer = forms.ChoiceField(
572 image_viewer = forms.ChoiceField(
571 choices=board_settings.get_list_dict('View', 'ImageViewers'),
573 choices=board_settings.get_list_dict('View', 'ImageViewers'),
572 label=_('Image view mode'))
574 label=_('Image view mode'))
573 username = forms.CharField(label=_('User name'), required=False)
575 username = forms.CharField(label=_('User name'), required=False)
574 timezone = forms.ChoiceField(choices=get_timezones(), label=_('Time zone'))
576 timezone = forms.ChoiceField(choices=get_timezones(), label=_('Time zone'))
575
577
576 def clean_username(self):
578 def clean_username(self):
577 username = self.cleaned_data['username']
579 username = self.cleaned_data['username']
578
580
579 if username and not REGEX_USERNAMES.match(username):
581 if username and not REGEX_USERNAMES.match(username):
580 raise forms.ValidationError(_('Inappropriate characters.'))
582 raise forms.ValidationError(_('Inappropriate characters.'))
581
583
582 return username
584 return username
583
585
584
586
585 class SearchForm(NeboardForm):
587 class SearchForm(NeboardForm):
586 query = forms.CharField(max_length=500, label=LABEL_SEARCH, required=False)
588 query = forms.CharField(max_length=500, label=LABEL_SEARCH, required=False)
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -1,645 +1,645 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: 2015-10-09 23:21+0300\n"
10 "POT-Creation-Date: 2015-10-09 23:21+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 #: admin.py:22
21 #: admin.py:22
22 msgid "{} posters were banned"
22 msgid "{} posters were banned"
23 msgstr ""
23 msgstr ""
24
24
25 #: authors.py:9
25 #: authors.py:9
26 msgid "author"
26 msgid "author"
27 msgstr "Π°Π²Ρ‚ΠΎΡ€"
27 msgstr "Π°Π²Ρ‚ΠΎΡ€"
28
28
29 #: authors.py:10
29 #: authors.py:10
30 msgid "developer"
30 msgid "developer"
31 msgstr "Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ"
31 msgstr "Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ"
32
32
33 #: authors.py:11
33 #: authors.py:11
34 msgid "javascript developer"
34 msgid "javascript developer"
35 msgstr "Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ javascript"
35 msgstr "Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ javascript"
36
36
37 #: authors.py:12
37 #: authors.py:12
38 msgid "designer"
38 msgid "designer"
39 msgstr "Π΄ΠΈΠ·Π°ΠΉΠ½Π΅Ρ€"
39 msgstr "Π΄ΠΈΠ·Π°ΠΉΠ½Π΅Ρ€"
40
40
41 #: forms.py:30
41 #: forms.py:30
42 msgid "Type message here. Use formatting panel for more advanced usage."
42 msgid "Type message here. Use formatting panel for more advanced usage."
43 msgstr ""
43 msgstr ""
44 "Π’Π²ΠΎΠ΄ΠΈΡ‚Π΅ сообщСниС сюда. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ панСль для Π±ΠΎΠ»Π΅Π΅ слоТного форматирования."
44 "Π’Π²ΠΎΠ΄ΠΈΡ‚Π΅ сообщСниС сюда. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ панСль для Π±ΠΎΠ»Π΅Π΅ слоТного форматирования."
45
45
46 #: forms.py:31
46 #: forms.py:31
47 msgid "music images i_dont_like_tags"
47 msgid "music images i_dont_like_tags"
48 msgstr "ΠΌΡƒΠ·Ρ‹ΠΊΠ° ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ Ρ‚Π΅Π³ΠΈ_Π½Π΅_Π½ΡƒΠΆΠ½Ρ‹"
48 msgstr "ΠΌΡƒΠ·Ρ‹ΠΊΠ° ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ Ρ‚Π΅Π³ΠΈ_Π½Π΅_Π½ΡƒΠΆΠ½Ρ‹"
49
49
50 #: forms.py:33
50 #: forms.py:33
51 msgid "Title"
51 msgid "Title"
52 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ"
52 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ"
53
53
54 #: forms.py:34
54 #: forms.py:34
55 msgid "Text"
55 msgid "Text"
56 msgstr "ВСкст"
56 msgstr "ВСкст"
57
57
58 #: forms.py:35
58 #: forms.py:35
59 msgid "Tag"
59 msgid "Tag"
60 msgstr "ΠœΠ΅Ρ‚ΠΊΠ°"
60 msgstr "ΠœΠ΅Ρ‚ΠΊΠ°"
61
61
62 #: forms.py:36 templates/boards/base.html:40 templates/search/search.html:7
62 #: forms.py:36 templates/boards/base.html:40 templates/search/search.html:7
63 msgid "Search"
63 msgid "Search"
64 msgstr "Поиск"
64 msgstr "Поиск"
65
65
66 #: forms.py:48
66 #: forms.py:48
67 msgid "File 1"
67 msgid "File 1"
68 msgstr "Π€Π°ΠΉΠ» 1"
68 msgstr "Π€Π°ΠΉΠ» 1"
69
69
70 #: forms.py:48
70 #: forms.py:48
71 msgid "File 2"
71 msgid "File 2"
72 msgstr "Π€Π°ΠΉΠ» 2"
72 msgstr "Π€Π°ΠΉΠ» 2"
73
73
74 #: forms.py:142
74 #: forms.py:142
75 msgid "File URL"
75 msgid "File URL"
76 msgstr "URL Ρ„Π°ΠΉΠ»Π°"
76 msgstr "URL Ρ„Π°ΠΉΠ»Π°"
77
77
78 #: forms.py:148
78 #: forms.py:148
79 msgid "e-mail"
79 msgid "e-mail"
80 msgstr ""
80 msgstr ""
81
81
82 #: forms.py:151
82 #: forms.py:151
83 msgid "Additional threads"
83 msgid "Additional threads"
84 msgstr "Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Π΅ΠΌΡ‹"
84 msgstr "Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Π΅ΠΌΡ‹"
85
85
86 #: forms.py:162
86 #: forms.py:162
87 #, python-format
87 #, python-format
88 msgid "Title must have less than %s characters"
88 msgid "Title must have less than %s characters"
89 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ мСньшС %s символов"
89 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ мСньшС %s символов"
90
90
91 #: forms.py:172
91 #: forms.py:172
92 #, python-format
92 #, python-format
93 msgid "Text must have less than %s characters"
93 msgid "Text must have less than %s characters"
94 msgstr "ВСкст Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΊΠΎΡ€ΠΎΡ‡Π΅ %s символов"
94 msgstr "ВСкст Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΊΠΎΡ€ΠΎΡ‡Π΅ %s символов"
95
95
96 #: forms.py:192
96 #: forms.py:192
97 msgid "Invalid URL"
97 msgid "Invalid URL"
98 msgstr "НСвСрный URL"
98 msgstr "НСвСрный URL"
99
99
100 #: forms.py:213
100 #: forms.py:213
101 msgid "Invalid additional thread list"
101 msgid "Invalid additional thread list"
102 msgstr "НСвСрный список Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ‚Π΅ΠΌ"
102 msgstr "НСвСрный список Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ‚Π΅ΠΌ"
103
103
104 #: forms.py:258
104 #: forms.py:258
105 msgid "Either text or file must be entered."
105 msgid "Either text or file must be entered."
106 msgstr "ВСкст ΠΈΠ»ΠΈ Ρ„Π°ΠΉΠ» Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π²Π²Π΅Π΄Π΅Π½Ρ‹."
106 msgstr "ВСкст ΠΈΠ»ΠΈ Ρ„Π°ΠΉΠ» Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π²Π²Π΅Π΄Π΅Π½Ρ‹."
107
107
108 #: forms.py:317 templates/boards/all_threads.html:153
108 #: forms.py:317 templates/boards/all_threads.html:153
109 #: templates/boards/rss/post.html:10 templates/boards/tags.html:6
109 #: templates/boards/rss/post.html:10 templates/boards/tags.html:6
110 msgid "Tags"
110 msgid "Tags"
111 msgstr "ΠœΠ΅Ρ‚ΠΊΠΈ"
111 msgstr "ΠœΠ΅Ρ‚ΠΊΠΈ"
112
112
113 #: forms.py:324
113 #: forms.py:324
114 msgid "Inappropriate characters in tags."
114 msgid "Inappropriate characters in tags."
115 msgstr "НСдопустимыС символы Π² ΠΌΠ΅Ρ‚ΠΊΠ°Ρ…."
115 msgstr "НСдопустимыС символы Π² ΠΌΠ΅Ρ‚ΠΊΠ°Ρ…."
116
116
117 #: forms.py:344
117 #: forms.py:344
118 msgid "Need at least one section."
118 msgid "Need at least one section."
119 msgstr "НуТСн хотя Π±Ρ‹ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·Π΄Π΅Π»."
119 msgstr "НуТСн хотя Π±Ρ‹ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·Π΄Π΅Π»."
120
120
121 #: forms.py:356
121 #: forms.py:356
122 msgid "Theme"
122 msgid "Theme"
123 msgstr "Π’Π΅ΠΌΠ°"
123 msgstr "Π’Π΅ΠΌΠ°"
124
124
125 #: forms.py:357
125 #: forms.py:357
126 msgid "Image view mode"
126 msgid "Image view mode"
127 msgstr "Π Π΅ΠΆΠΈΠΌ просмотра ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ"
127 msgstr "Π Π΅ΠΆΠΈΠΌ просмотра ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ"
128
128
129 #: forms.py:358
129 #: forms.py:358
130 msgid "User name"
130 msgid "User name"
131 msgstr "Имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ"
131 msgstr "Имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ"
132
132
133 #: forms.py:359
133 #: forms.py:359
134 msgid "Time zone"
134 msgid "Time zone"
135 msgstr "Часовой пояс"
135 msgstr "Часовой пояс"
136
136
137 #: forms.py:365
137 #: forms.py:365
138 msgid "Inappropriate characters."
138 msgid "Inappropriate characters."
139 msgstr "НСдопустимыС символы."
139 msgstr "НСдопустимыС символы."
140
140
141 #: templates/boards/404.html:6
141 #: templates/boards/404.html:6
142 msgid "Not found"
142 msgid "Not found"
143 msgstr "НС найдСно"
143 msgstr "НС найдСно"
144
144
145 #: templates/boards/404.html:12
145 #: templates/boards/404.html:12
146 msgid "This page does not exist"
146 msgid "This page does not exist"
147 msgstr "Π­Ρ‚ΠΎΠΉ страницы Π½Π΅ сущСствуСт"
147 msgstr "Π­Ρ‚ΠΎΠΉ страницы Π½Π΅ сущСствуСт"
148
148
149 #: templates/boards/all_threads.html:35
149 #: templates/boards/all_threads.html:35
150 msgid "Details"
150 msgid "Details"
151 msgstr "ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΡΡ‚ΠΈ"
151 msgstr "ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΡΡ‚ΠΈ"
152
152
153 #: templates/boards/all_threads.html:69
153 #: templates/boards/all_threads.html:69
154 msgid "Edit tag"
154 msgid "Edit tag"
155 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΊΡƒ"
155 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΊΡƒ"
156
156
157 #: templates/boards/all_threads.html:76
157 #: templates/boards/all_threads.html:76
158 #, python-format
158 #, python-format
159 msgid "%(count)s active thread"
159 msgid "%(count)s active thread"
160 msgid_plural "%(count)s active threads"
160 msgid_plural "%(count)s active threads"
161 msgstr[0] "%(count)s активная Ρ‚Π΅ΠΌΠ°"
161 msgstr[0] "%(count)s активная Ρ‚Π΅ΠΌΠ°"
162 msgstr[1] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Π΅ Ρ‚Π΅ΠΌΡ‹"
162 msgstr[1] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Π΅ Ρ‚Π΅ΠΌΡ‹"
163 msgstr[2] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… Ρ‚Π΅ΠΌ"
163 msgstr[2] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… Ρ‚Π΅ΠΌ"
164
164
165 #: templates/boards/all_threads.html:76
165 #: templates/boards/all_threads.html:76
166 #, python-format
166 #, python-format
167 msgid "%(count)s thread in bumplimit"
167 msgid "%(count)s thread in bumplimit"
168 msgid_plural "%(count)s threads in bumplimit"
168 msgid_plural "%(count)s threads in bumplimit"
169 msgstr[0] "%(count)s Ρ‚Π΅ΠΌΠ° Π² Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π΅"
169 msgstr[0] "%(count)s Ρ‚Π΅ΠΌΠ° Π² Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π΅"
170 msgstr[1] "%(count)s Ρ‚Π΅ΠΌΡ‹ Π² Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π΅"
170 msgstr[1] "%(count)s Ρ‚Π΅ΠΌΡ‹ Π² Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π΅"
171 msgstr[2] "%(count)s Ρ‚Π΅ΠΌ Π² Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π΅"
171 msgstr[2] "%(count)s Ρ‚Π΅ΠΌ Π² Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π΅"
172
172
173 #: templates/boards/all_threads.html:77
173 #: templates/boards/all_threads.html:77
174 #, python-format
174 #, python-format
175 msgid "%(count)s archived thread"
175 msgid "%(count)s archived thread"
176 msgid_plural "%(count)s archived thread"
176 msgid_plural "%(count)s archived thread"
177 msgstr[0] "%(count)s архивная Ρ‚Π΅ΠΌΠ°"
177 msgstr[0] "%(count)s архивная Ρ‚Π΅ΠΌΠ°"
178 msgstr[1] "%(count)s Π°Ρ€Ρ…ΠΈΠ²Π½Ρ‹Π΅ Ρ‚Π΅ΠΌΡ‹"
178 msgstr[1] "%(count)s Π°Ρ€Ρ…ΠΈΠ²Π½Ρ‹Π΅ Ρ‚Π΅ΠΌΡ‹"
179 msgstr[2] "%(count)s Π°Ρ€Ρ…ΠΈΠ²Π½Ρ‹Ρ… Ρ‚Π΅ΠΌ"
179 msgstr[2] "%(count)s Π°Ρ€Ρ…ΠΈΠ²Π½Ρ‹Ρ… Ρ‚Π΅ΠΌ"
180
180
181 #: templates/boards/all_threads.html:78 templates/boards/post.html:102
181 #: templates/boards/all_threads.html:78 templates/boards/post.html:102
182 #, python-format
182 #, python-format
183 #| msgid "%(count)s message"
183 #| msgid "%(count)s message"
184 #| msgid_plural "%(count)s messages"
184 #| msgid_plural "%(count)s messages"
185 msgid "%(count)s message"
185 msgid "%(count)s message"
186 msgid_plural "%(count)s messages"
186 msgid_plural "%(count)s messages"
187 msgstr[0] "%(count)s сообщСниС"
187 msgstr[0] "%(count)s сообщСниС"
188 msgstr[1] "%(count)s сообщСния"
188 msgstr[1] "%(count)s сообщСния"
189 msgstr[2] "%(count)s сообщСний"
189 msgstr[2] "%(count)s сообщСний"
190
190
191 #: templates/boards/all_threads.html:95 templates/boards/feed.html:30
191 #: templates/boards/all_threads.html:95 templates/boards/feed.html:30
192 #: templates/boards/notifications.html:17 templates/search/search.html:26
192 #: templates/boards/notifications.html:17 templates/search/search.html:26
193 msgid "Previous page"
193 msgid "Previous page"
194 msgstr "ΠŸΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π°Ρ страница"
194 msgstr "ΠŸΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π°Ρ страница"
195
195
196 #: templates/boards/all_threads.html:109
196 #: templates/boards/all_threads.html:109
197 #, python-format
197 #, python-format
198 msgid "Skipped %(count)s reply. Open thread to see all replies."
198 msgid "Skipped %(count)s reply. Open thread to see all replies."
199 msgid_plural "Skipped %(count)s replies. Open thread to see all replies."
199 msgid_plural "Skipped %(count)s replies. Open thread to see all replies."
200 msgstr[0] "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ %(count)s ΠΎΡ‚Π²Π΅Ρ‚. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ‚Ρ€Π΅Π΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ всС ΠΎΡ‚Π²Π΅Ρ‚Ρ‹."
200 msgstr[0] "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ %(count)s ΠΎΡ‚Π²Π΅Ρ‚. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ‚Ρ€Π΅Π΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ всС ΠΎΡ‚Π²Π΅Ρ‚Ρ‹."
201 msgstr[1] ""
201 msgstr[1] ""
202 "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s ΠΎΡ‚Π²Π΅Ρ‚Π°. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ‚Ρ€Π΅Π΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ всС ΠΎΡ‚Π²Π΅Ρ‚Ρ‹."
202 "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s ΠΎΡ‚Π²Π΅Ρ‚Π°. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ‚Ρ€Π΅Π΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ всС ΠΎΡ‚Π²Π΅Ρ‚Ρ‹."
203 msgstr[2] ""
203 msgstr[2] ""
204 "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ². ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ‚Ρ€Π΅Π΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ всС ΠΎΡ‚Π²Π΅Ρ‚Ρ‹."
204 "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ². ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ‚Ρ€Π΅Π΄, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ всС ΠΎΡ‚Π²Π΅Ρ‚Ρ‹."
205
205
206 #: templates/boards/all_threads.html:127 templates/boards/feed.html:40
206 #: templates/boards/all_threads.html:127 templates/boards/feed.html:40
207 #: templates/boards/notifications.html:27 templates/search/search.html:37
207 #: templates/boards/notifications.html:27 templates/search/search.html:37
208 msgid "Next page"
208 msgid "Next page"
209 msgstr "Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ страница"
209 msgstr "Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ страница"
210
210
211 #: templates/boards/all_threads.html:132
211 #: templates/boards/all_threads.html:132
212 msgid "No threads exist. Create the first one!"
212 msgid "No threads exist. Create the first one!"
213 msgstr "НСт Ρ‚Π΅ΠΌ. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π²ΡƒΡŽ!"
213 msgstr "НСт Ρ‚Π΅ΠΌ. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π²ΡƒΡŽ!"
214
214
215 #: templates/boards/all_threads.html:138
215 #: templates/boards/all_threads.html:138
216 msgid "Create new thread"
216 msgid "Create new thread"
217 msgstr "Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²ΡƒΡŽ Ρ‚Π΅ΠΌΡƒ"
217 msgstr "Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²ΡƒΡŽ Ρ‚Π΅ΠΌΡƒ"
218
218
219 #: templates/boards/all_threads.html:143 templates/boards/preview.html:16
219 #: templates/boards/all_threads.html:143 templates/boards/preview.html:16
220 #: templates/boards/thread_normal.html:51
220 #: templates/boards/thread_normal.html:51
221 msgid "Post"
221 msgid "Post"
222 msgstr "ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ"
222 msgstr "ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ"
223
223
224 #: templates/boards/all_threads.html:144 templates/boards/preview.html:6
224 #: templates/boards/all_threads.html:144 templates/boards/preview.html:6
225 #: templates/boards/staticpages/help.html:21
225 #: templates/boards/staticpages/help.html:21
226 #: templates/boards/thread_normal.html:52
226 #: templates/boards/thread_normal.html:52
227 msgid "Preview"
227 msgid "Preview"
228 msgstr "ΠŸΡ€Π΅Π΄ΠΏΡ€ΠΎΡΠΌΠΎΡ‚Ρ€"
228 msgstr "ΠŸΡ€Π΅Π΄ΠΏΡ€ΠΎΡΠΌΠΎΡ‚Ρ€"
229
229
230 #: templates/boards/all_threads.html:149
230 #: templates/boards/all_threads.html:149
231 msgid "Tags must be delimited by spaces. Text or image is required."
231 msgid "Tags must be delimited by spaces. Text or image is required."
232 msgstr ""
232 msgstr ""
233 "ΠœΠ΅Ρ‚ΠΊΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Ρ‹ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ. ВСкст ΠΈΠ»ΠΈ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹."
233 "ΠœΠ΅Ρ‚ΠΊΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Ρ‹ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ. ВСкст ΠΈΠ»ΠΈ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹."
234
234
235 #: templates/boards/all_threads.html:152 templates/boards/thread_normal.html:58
235 #: templates/boards/all_threads.html:152 templates/boards/thread_normal.html:58
236 msgid "Text syntax"
236 msgid "Text syntax"
237 msgstr "Бинтаксис тСкста"
237 msgstr "Бинтаксис тСкста"
238
238
239 #: templates/boards/all_threads.html:166 templates/boards/feed.html:53
239 #: templates/boards/all_threads.html:166 templates/boards/feed.html:53
240 msgid "Pages:"
240 msgid "Pages:"
241 msgstr "Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Ρ‹: "
241 msgstr "Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Ρ‹: "
242
242
243 #: templates/boards/authors.html:6 templates/boards/authors.html.py:12
243 #: templates/boards/authors.html:6 templates/boards/authors.html.py:12
244 msgid "Authors"
244 msgid "Authors"
245 msgstr "Авторы"
245 msgstr "Авторы"
246
246
247 #: templates/boards/authors.html:26
247 #: templates/boards/authors.html:26
248 msgid "Distributed under the"
248 msgid "Distributed under the"
249 msgstr "РаспространяСтся ΠΏΠΎΠ΄"
249 msgstr "РаспространяСтся ΠΏΠΎΠ΄"
250
250
251 #: templates/boards/authors.html:28
251 #: templates/boards/authors.html:28
252 msgid "license"
252 msgid "license"
253 msgstr "Π»ΠΈΡ†Π΅Π½Π·ΠΈΠ΅ΠΉ"
253 msgstr "Π»ΠΈΡ†Π΅Π½Π·ΠΈΠ΅ΠΉ"
254
254
255 #: templates/boards/authors.html:30
255 #: templates/boards/authors.html:30
256 msgid "Repository"
256 msgid "Repository"
257 msgstr "Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ"
257 msgstr "Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ"
258
258
259 #: templates/boards/base.html:14 templates/boards/base.html.py:41
259 #: templates/boards/base.html:14 templates/boards/base.html.py:41
260 msgid "Feed"
260 msgid "Feed"
261 msgstr "Π›Π΅Π½Ρ‚Π°"
261 msgstr "Π›Π΅Π½Ρ‚Π°"
262
262
263 #: templates/boards/base.html:31
263 #: templates/boards/base.html:31
264 msgid "All threads"
264 msgid "All threads"
265 msgstr "ВсС Ρ‚Π΅ΠΌΡ‹"
265 msgstr "ВсС Ρ‚Π΅ΠΌΡ‹"
266
266
267 #: templates/boards/base.html:37
267 #: templates/boards/base.html:37
268 msgid "Add tags"
268 msgid "Add tags"
269 msgstr "Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΊΠΈ"
269 msgstr "Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΊΠΈ"
270
270
271 #: templates/boards/base.html:39
271 #: templates/boards/base.html:39
272 msgid "Tag management"
272 msgid "Tag management"
273 msgstr "Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΊΠ°ΠΌΠΈ"
273 msgstr "Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΊΠ°ΠΌΠΈ"
274
274
275 #: templates/boards/base.html:39
275 #: templates/boards/base.html:39
276 msgid "tags"
276 msgid "tags"
277 msgstr "ΠΌΠ΅Ρ‚ΠΊΠΈ"
277 msgstr "ΠΌΠ΅Ρ‚ΠΊΠΈ"
278
278
279 #: templates/boards/base.html:40
279 #: templates/boards/base.html:40
280 msgid "search"
280 msgid "search"
281 msgstr "поиск"
281 msgstr "поиск"
282
282
283 #: templates/boards/base.html:41 templates/boards/feed.html:11
283 #: templates/boards/base.html:41 templates/boards/feed.html:11
284 msgid "feed"
284 msgid "feed"
285 msgstr "Π»Π΅Π½Ρ‚Π°"
285 msgstr "Π»Π΅Π½Ρ‚Π°"
286
286
287 #: templates/boards/base.html:42 templates/boards/random.html:6
287 #: templates/boards/base.html:42 templates/boards/random.html:6
288 msgid "Random images"
288 msgid "Random images"
289 msgstr "Π‘Π»ΡƒΡ‡Π°ΠΉΠ½Ρ‹Π΅ изобраТСния"
289 msgstr "Π‘Π»ΡƒΡ‡Π°ΠΉΠ½Ρ‹Π΅ изобраТСния"
290
290
291 #: templates/boards/base.html:42
291 #: templates/boards/base.html:42
292 msgid "random"
292 msgid "random"
293 msgstr "случайныС"
293 msgstr "случайныС"
294
294
295 #: templates/boards/base.html:44
295 #: templates/boards/base.html:44
296 msgid "favorites"
296 msgid "favorites"
297 msgstr "ΠΈΠ·Π±Ρ€Π°Π½Π½ΠΎΠ΅"
297 msgstr "ΠΈΠ·Π±Ρ€Π°Π½Π½ΠΎΠ΅"
298
298
299 #: templates/boards/base.html:48 templates/boards/base.html.py:49
299 #: templates/boards/base.html:48 templates/boards/base.html.py:49
300 #: templates/boards/notifications.html:8
300 #: templates/boards/notifications.html:8
301 msgid "Notifications"
301 msgid "Notifications"
302 msgstr "УвСдомлСния"
302 msgstr "УвСдомлСния"
303
303
304 #: templates/boards/base.html:56 templates/boards/settings.html:8
304 #: templates/boards/base.html:56 templates/boards/settings.html:8
305 msgid "Settings"
305 msgid "Settings"
306 msgstr "Настройки"
306 msgstr "Настройки"
307
307
308 #: templates/boards/base.html:59
308 #: templates/boards/base.html:59
309 msgid "Loading..."
309 msgid "Loading..."
310 msgstr "Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ°..."
310 msgstr "Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ°..."
311
311
312 #: templates/boards/base.html:71
312 #: templates/boards/base.html:71
313 msgid "Admin"
313 msgid "Admin"
314 msgstr "АдминистрированиС"
314 msgstr "АдминистрированиС"
315
315
316 #: templates/boards/base.html:73
316 #: templates/boards/base.html:73
317 #, python-format
317 #, python-format
318 msgid "Speed: %(ppd)s posts per day"
318 msgid "Speed: %(ppd)s posts per day"
319 msgstr "Π‘ΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ: %(ppd)s сообщСний Π² дСнь"
319 msgstr "Π‘ΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ: %(ppd)s сообщСний Π² дСнь"
320
320
321 #: templates/boards/base.html:75
321 #: templates/boards/base.html:75
322 msgid "Up"
322 msgid "Up"
323 msgstr "Π’Π²Π΅Ρ€Ρ…"
323 msgstr "Π’Π²Π΅Ρ€Ρ…"
324
324
325 #: templates/boards/feed.html:45
325 #: templates/boards/feed.html:45
326 msgid "No posts exist. Create the first one!"
326 msgid "No posts exist. Create the first one!"
327 msgstr "НСт сообщСний. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π²ΠΎΠ΅!"
327 msgstr "НСт сообщСний. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π²ΠΎΠ΅!"
328
328
329 #: templates/boards/post.html:33
329 #: templates/boards/post.html:33
330 msgid "Open"
330 msgid "Open"
331 msgstr "ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ"
331 msgstr "ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ"
332
332
333 #: templates/boards/post.html:35 templates/boards/post.html.py:46
333 #: templates/boards/post.html:35 templates/boards/post.html.py:46
334 msgid "Reply"
334 msgid "Reply"
335 msgstr "ΠžΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ"
335 msgstr "ΠžΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ"
336
336
337 #: templates/boards/post.html:41
337 #: templates/boards/post.html:41
338 msgid " in "
338 msgid " in "
339 msgstr " Π² "
339 msgstr " Π² "
340
340
341 #: templates/boards/post.html:51
341 #: templates/boards/post.html:51
342 msgid "Edit"
342 msgid "Edit"
343 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ"
343 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ"
344
344
345 #: templates/boards/post.html:53
345 #: templates/boards/post.html:53
346 msgid "Edit thread"
346 msgid "Edit thread"
347 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΌΡƒ"
347 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΌΡƒ"
348
348
349 #: templates/boards/post.html:91
349 #: templates/boards/post.html:91
350 msgid "Replies"
350 msgid "Replies"
351 msgstr "ΠžΡ‚Π²Π΅Ρ‚Ρ‹"
351 msgstr "ΠžΡ‚Π²Π΅Ρ‚Ρ‹"
352
352
353 #: templates/boards/post.html:103
353 #: templates/boards/post.html:103
354 #, python-format
354 #, python-format
355 msgid "%(count)s image"
355 msgid "%(count)s image"
356 msgid_plural "%(count)s images"
356 msgid_plural "%(count)s images"
357 msgstr[0] "%(count)s ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅"
357 msgstr[0] "%(count)s ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅"
358 msgstr[1] "%(count)s изобраТСния"
358 msgstr[1] "%(count)s изобраТСния"
359 msgstr[2] "%(count)s ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ"
359 msgstr[2] "%(count)s ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ"
360
360
361 #: templates/boards/rss/post.html:5
361 #: templates/boards/rss/post.html:5
362 msgid "Post image"
362 msgid "Post image"
363 msgstr "Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ сообщСния"
363 msgstr "Π˜Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ сообщСния"
364
364
365 #: templates/boards/settings.html:15
365 #: templates/boards/settings.html:15
366 msgid "You are moderator."
366 msgid "You are moderator."
367 msgstr "Π’Ρ‹ ΠΌΠΎΠ΄Π΅Ρ€Π°Ρ‚ΠΎΡ€."
367 msgstr "Π’Ρ‹ ΠΌΠΎΠ΄Π΅Ρ€Π°Ρ‚ΠΎΡ€."
368
368
369 #: templates/boards/settings.html:19
369 #: templates/boards/settings.html:19
370 msgid "Hidden tags:"
370 msgid "Hidden tags:"
371 msgstr "Π‘ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΊΠΈ:"
371 msgstr "Π‘ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΊΠΈ:"
372
372
373 #: templates/boards/settings.html:25
373 #: templates/boards/settings.html:25
374 msgid "No hidden tags."
374 msgid "No hidden tags."
375 msgstr "НСт скрытых ΠΌΠ΅Ρ‚ΠΎΠΊ."
375 msgstr "НСт скрытых ΠΌΠ΅Ρ‚ΠΎΠΊ."
376
376
377 #: templates/boards/settings.html:34
377 #: templates/boards/settings.html:34
378 msgid "Save"
378 msgid "Save"
379 msgstr "Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ"
379 msgstr "Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ"
380
380
381 #: templates/boards/staticpages/banned.html:6
381 #: templates/boards/staticpages/banned.html:6
382 msgid "Banned"
382 msgid "Banned"
383 msgstr "Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½"
383 msgstr "Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½"
384
384
385 #: templates/boards/staticpages/banned.html:11
385 #: templates/boards/staticpages/banned.html:11
386 msgid "Your IP address has been banned. Contact the administrator"
386 msgid "Your IP address has been banned. Contact the administrator"
387 msgstr "Π’Π°Ρˆ IP адрСс Π±Ρ‹Π» Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½. Π‘Π²ΡΠΆΠΈΡ‚Π΅ΡΡŒ с администратором"
387 msgstr "Π’Π°Ρˆ IP адрСс Π±Ρ‹Π» Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½. Π‘Π²ΡΠΆΠΈΡ‚Π΅ΡΡŒ с администратором"
388
388
389 #: templates/boards/staticpages/help.html:6
389 #: templates/boards/staticpages/help.html:6
390 #: templates/boards/staticpages/help.html:10
390 #: templates/boards/staticpages/help.html:10
391 msgid "Syntax"
391 msgid "Syntax"
392 msgstr "Бинтаксис"
392 msgstr "Бинтаксис"
393
393
394 #: templates/boards/staticpages/help.html:11
394 #: templates/boards/staticpages/help.html:11
395 msgid "Italic text"
395 msgid "Italic text"
396 msgstr "ΠšΡƒΡ€ΡΠΈΠ²Π½Ρ‹ΠΉ тСкст"
396 msgstr "ΠšΡƒΡ€ΡΠΈΠ²Π½Ρ‹ΠΉ тСкст"
397
397
398 #: templates/boards/staticpages/help.html:12
398 #: templates/boards/staticpages/help.html:12
399 msgid "Bold text"
399 msgid "Bold text"
400 msgstr "ΠŸΠΎΠ»ΡƒΠΆΠΈΡ€Π½Ρ‹ΠΉ тСкст"
400 msgstr "ΠŸΠΎΠ»ΡƒΠΆΠΈΡ€Π½Ρ‹ΠΉ тСкст"
401
401
402 #: templates/boards/staticpages/help.html:13
402 #: templates/boards/staticpages/help.html:13
403 msgid "Spoiler"
403 msgid "Spoiler"
404 msgstr "Π‘ΠΏΠΎΠΉΠ»Π΅Ρ€"
404 msgstr "Π‘ΠΏΠΎΠΉΠ»Π΅Ρ€"
405
405
406 #: templates/boards/staticpages/help.html:14
406 #: templates/boards/staticpages/help.html:14
407 msgid "Link to a post"
407 msgid "Link to a post"
408 msgstr "Бсылка Π½Π° сообщСниС"
408 msgstr "Бсылка Π½Π° сообщСниС"
409
409
410 #: templates/boards/staticpages/help.html:15
410 #: templates/boards/staticpages/help.html:15
411 msgid "Strikethrough text"
411 msgid "Strikethrough text"
412 msgstr "Π—Π°Ρ‡Π΅Ρ€ΠΊΠ½ΡƒΡ‚Ρ‹ΠΉ тСкст"
412 msgstr "Π—Π°Ρ‡Π΅Ρ€ΠΊΠ½ΡƒΡ‚Ρ‹ΠΉ тСкст"
413
413
414 #: templates/boards/staticpages/help.html:16
414 #: templates/boards/staticpages/help.html:16
415 msgid "Comment"
415 msgid "Comment"
416 msgstr "ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ"
416 msgstr "ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ"
417
417
418 #: templates/boards/staticpages/help.html:17
418 #: templates/boards/staticpages/help.html:17
419 #: templates/boards/staticpages/help.html:18
419 #: templates/boards/staticpages/help.html:18
420 msgid "Quote"
420 msgid "Quote"
421 msgstr "Π¦ΠΈΡ‚Π°Ρ‚Π°"
421 msgstr "Π¦ΠΈΡ‚Π°Ρ‚Π°"
422
422
423 #: templates/boards/staticpages/help.html:21
423 #: templates/boards/staticpages/help.html:21
424 msgid "You can try pasting the text and previewing the result here:"
424 msgid "You can try pasting the text and previewing the result here:"
425 msgstr "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ тСкст ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ здСсь:"
425 msgstr "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ тСкст ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ здСсь:"
426
426
427 #: templates/boards/thread.html:14
427 #: templates/boards/thread.html:14
428 msgid "Normal"
428 msgid "Normal"
429 msgstr "ΠΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ"
429 msgstr "ΠΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ"
430
430
431 #: templates/boards/thread.html:15
431 #: templates/boards/thread.html:15
432 msgid "Gallery"
432 msgid "Gallery"
433 msgstr "ГалСрСя"
433 msgstr "ГалСрСя"
434
434
435 #: templates/boards/thread.html:16
435 #: templates/boards/thread.html:16
436 msgid "Tree"
436 msgid "Tree"
437 msgstr "Π”Π΅Ρ€Π΅Π²ΠΎ"
437 msgstr "Π”Π΅Ρ€Π΅Π²ΠΎ"
438
438
439 #: templates/boards/thread.html:35
439 #: templates/boards/thread.html:35
440 msgid "message"
440 msgid "message"
441 msgid_plural "messages"
441 msgid_plural "messages"
442 msgstr[0] "сообщСниС"
442 msgstr[0] "сообщСниС"
443 msgstr[1] "сообщСния"
443 msgstr[1] "сообщСния"
444 msgstr[2] "сообщСний"
444 msgstr[2] "сообщСний"
445
445
446 #: templates/boards/thread.html:38
446 #: templates/boards/thread.html:38
447 msgid "image"
447 msgid "image"
448 msgid_plural "images"
448 msgid_plural "images"
449 msgstr[0] "ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅"
449 msgstr[0] "ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅"
450 msgstr[1] "изобраТСния"
450 msgstr[1] "изобраТСния"
451 msgstr[2] "ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ"
451 msgstr[2] "ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ"
452
452
453 #: templates/boards/thread.html:40
453 #: templates/boards/thread.html:40
454 msgid "Last update: "
454 msgid "Last update: "
455 msgstr "ПослСднСС обновлСниС: "
455 msgstr "ПослСднСС обновлСниС: "
456
456
457 #: templates/boards/thread_gallery.html:36
457 #: templates/boards/thread_gallery.html:36
458 msgid "No images."
458 msgid "No images."
459 msgstr "НСт ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ."
459 msgstr "НСт ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ."
460
460
461 #: templates/boards/thread_normal.html:30
461 #: templates/boards/thread_normal.html:30
462 msgid "posts to bumplimit"
462 msgid "posts to bumplimit"
463 msgstr "сообщСний Π΄ΠΎ Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π°"
463 msgstr "сообщСний Π΄ΠΎ Π±Π°ΠΌΠΏΠ»ΠΈΠΌΠΈΡ‚Π°"
464
464
465 #: templates/boards/thread_normal.html:44
465 #: templates/boards/thread_normal.html:44
466 msgid "Reply to thread"
466 msgid "Reply to thread"
467 msgstr "ΠžΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ Π² Ρ‚Π΅ΠΌΡƒ"
467 msgstr "ΠžΡ‚Π²Π΅Ρ‚ΠΈΡ‚ΡŒ Π² Ρ‚Π΅ΠΌΡƒ"
468
468
469 #: templates/boards/thread_normal.html:44
469 #: templates/boards/thread_normal.html:44
470 msgid "to message "
470 msgid "to message "
471 msgstr "Π½Π° сообщСниС"
471 msgstr "Π½Π° сообщСниС"
472
472
473 #: templates/boards/thread_normal.html:59
473 #: templates/boards/thread_normal.html:59
474 msgid "Reset form"
474 msgid "Reset form"
475 msgstr "Π‘Π±Ρ€ΠΎΡΠΈΡ‚ΡŒ Ρ„ΠΎΡ€ΠΌΡƒ"
475 msgstr "Π‘Π±Ρ€ΠΎΡΠΈΡ‚ΡŒ Ρ„ΠΎΡ€ΠΌΡƒ"
476
476
477 #: templates/search/search.html:17
477 #: templates/search/search.html:17
478 msgid "Ok"
478 msgid "Ok"
479 msgstr "Ок"
479 msgstr "Ок"
480
480
481 #: utils.py:120
481 #: utils.py:120
482 #, python-format
482 #, python-format
483 msgid "File must be less than %s but is %s."
483 msgid "Total file size must be less than %s but is %s."
484 msgstr "Π€Π°ΠΉΠ» Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΌΠ΅Π½Π΅Π΅ %s, Π½ΠΎ Π΅Π³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€ %s."
484 msgstr "ΠžΠ±Ρ‰ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„Π°ΠΉΠ»ΠΎΠ² Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΌΠ΅Π½Π΅Π΅ %s, Π½ΠΎ являСтся %s."
485
485
486 msgid "Please wait %(delay)d second before sending message"
486 msgid "Please wait %(delay)d second before sending message"
487 msgid_plural "Please wait %(delay)d seconds before sending message"
487 msgid_plural "Please wait %(delay)d seconds before sending message"
488 msgstr[0] "ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π° ΠΏΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %(delay)d сСкунду ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ сообщСния"
488 msgstr[0] "ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π° ΠΏΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %(delay)d сСкунду ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ сообщСния"
489 msgstr[1] "ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π° ΠΏΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %(delay)d сСкунды ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ сообщСния"
489 msgstr[1] "ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π° ΠΏΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %(delay)d сСкунды ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ сообщСния"
490 msgstr[2] "ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π° ΠΏΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %(delay)d сСкунд ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ сообщСния"
490 msgstr[2] "ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π° ΠΏΠΎΠ΄ΠΎΠΆΠ΄ΠΈΡ‚Π΅ %(delay)d сСкунд ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΎΠΉ сообщСния"
491
491
492 msgid "New threads"
492 msgid "New threads"
493 msgstr "НовыС Ρ‚Π΅ΠΌΡ‹"
493 msgstr "НовыС Ρ‚Π΅ΠΌΡ‹"
494
494
495 #, python-format
495 #, python-format
496 msgid "Max file size is %(size)s."
496 msgid "Max total file size is %(size)s."
497 msgstr "ΠœΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„Π°ΠΉΠ»Π° %(size)s."
497 msgstr "ΠœΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±Ρ‰ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„Π°ΠΉΠ»ΠΎΠ² %(size)s."
498
498
499 msgid "Size of media:"
499 msgid "Size of media:"
500 msgstr "Π Π°Π·ΠΌΠ΅Ρ€ ΠΌΠ΅Π΄ΠΈΠ°:"
500 msgstr "Π Π°Π·ΠΌΠ΅Ρ€ ΠΌΠ΅Π΄ΠΈΠ°:"
501
501
502 msgid "Statistics"
502 msgid "Statistics"
503 msgstr "Бтатистика"
503 msgstr "Бтатистика"
504
504
505 msgid "Invalid PoW."
505 msgid "Invalid PoW."
506 msgstr "НСвСрный PoW."
506 msgstr "НСвСрный PoW."
507
507
508 msgid "Stale PoW."
508 msgid "Stale PoW."
509 msgstr "PoW устарСл."
509 msgstr "PoW устарСл."
510
510
511 msgid "Show"
511 msgid "Show"
512 msgstr "ΠŸΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ"
512 msgstr "ΠŸΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ"
513
513
514 msgid "Hide"
514 msgid "Hide"
515 msgstr "Π‘ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ"
515 msgstr "Π‘ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ"
516
516
517 msgid "Add to favorites"
517 msgid "Add to favorites"
518 msgstr "Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² ΠΈΠ·Π±Ρ€Π°Π½Π½ΠΎΠ΅"
518 msgstr "Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² ΠΈΠ·Π±Ρ€Π°Π½Π½ΠΎΠ΅"
519
519
520 msgid "Remove from favorites"
520 msgid "Remove from favorites"
521 msgstr "Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΈΠ· ΠΈΠ·Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ"
521 msgstr "Π£Π±Ρ€Π°Ρ‚ΡŒ ΠΈΠ· ΠΈΠ·Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ"
522
522
523 msgid "Monochrome"
523 msgid "Monochrome"
524 msgstr "ΠœΠΎΠ½ΠΎΡ…Ρ€ΠΎΠΌΠ½Ρ‹ΠΉ"
524 msgstr "ΠœΠΎΠ½ΠΎΡ…Ρ€ΠΎΠΌΠ½Ρ‹ΠΉ"
525
525
526 msgid "Subsections: "
526 msgid "Subsections: "
527 msgstr "ΠŸΠΎΠ΄Ρ€Π°Π·Π΄Π΅Π»Ρ‹: "
527 msgstr "ΠŸΠΎΠ΄Ρ€Π°Π·Π΄Π΅Π»Ρ‹: "
528
528
529 msgid "Change file source"
529 msgid "Change file source"
530 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ источник Ρ„Π°ΠΉΠ»Π°"
530 msgstr "Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ источник Ρ„Π°ΠΉΠ»Π°"
531
531
532 msgid "interesting"
532 msgid "interesting"
533 msgstr "интСрСсноС"
533 msgstr "интСрСсноС"
534
534
535 msgid "images"
535 msgid "images"
536 msgstr "изобраТСния"
536 msgstr "изобраТСния"
537
537
538 msgid "Delete post"
538 msgid "Delete post"
539 msgstr "Π£Π΄Π°Π»ΠΈΡ‚ΡŒ пост"
539 msgstr "Π£Π΄Π°Π»ΠΈΡ‚ΡŒ пост"
540
540
541 msgid "Delete thread"
541 msgid "Delete thread"
542 msgstr "Π£Π΄Π°Π»ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΌΡƒ"
542 msgstr "Π£Π΄Π°Π»ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΌΡƒ"
543
543
544 msgid "Messages per day/week/month:"
544 msgid "Messages per day/week/month:"
545 msgstr "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠΉ Π·Π° дСнь/нСдСлю/мСсяц:"
545 msgstr "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠΉ Π·Π° дСнь/нСдСлю/мСсяц:"
546
546
547 msgid "Subscribe to thread"
547 msgid "Subscribe to thread"
548 msgstr "ΠŸΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒΡΡ Π½Π° Ρ‚Π΅ΠΌΡƒ"
548 msgstr "ΠŸΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒΡΡ Π½Π° Ρ‚Π΅ΠΌΡƒ"
549
549
550 msgid "Active threads:"
550 msgid "Active threads:"
551 msgstr "АктивныС Ρ‚Π΅ΠΌΡ‹:"
551 msgstr "АктивныС Ρ‚Π΅ΠΌΡ‹:"
552
552
553 msgid "No active threads today."
553 msgid "No active threads today."
554 msgstr "БСгодня Π½Π΅Ρ‚ Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… Ρ‚Π΅ΠΌ."
554 msgstr "БСгодня Π½Π΅Ρ‚ Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… Ρ‚Π΅ΠΌ."
555
555
556 msgid "Insert URLs on separate lines."
556 msgid "Insert URLs on separate lines."
557 msgstr "ВставляйтС ссылки Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… строках."
557 msgstr "ВставляйтС ссылки Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… строках."
558
558
559 msgid "You can post no more than %(files)d file."
559 msgid "You can post no more than %(files)d file."
560 msgid_plural "You can post no more than %(files)d files."
560 msgid_plural "You can post no more than %(files)d files."
561 msgstr[0] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ %(files)d Ρ„Π°ΠΉΠ»Π°."
561 msgstr[0] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ %(files)d Ρ„Π°ΠΉΠ»Π°."
562 msgstr[1] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ %(files)d Ρ„Π°ΠΉΠ»ΠΎΠ²."
562 msgstr[1] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ %(files)d Ρ„Π°ΠΉΠ»ΠΎΠ²."
563 msgstr[2] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ %(files)d Ρ„Π°ΠΉΠ»ΠΎΠ²."
563 msgstr[2] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ %(files)d Ρ„Π°ΠΉΠ»ΠΎΠ²."
564
564
565 #, python-format
565 #, python-format
566 msgid "Max file number is %(max_files)s."
566 msgid "Max file number is %(max_files)s."
567 msgstr "МаксимальноС количСство Ρ„Π°ΠΉΠ»ΠΎΠ² %(max_files)s."
567 msgstr "МаксимальноС количСство Ρ„Π°ΠΉΠ»ΠΎΠ² %(max_files)s."
568
568
569 msgid "Moderation"
569 msgid "Moderation"
570 msgstr "ΠœΠΎΠ΄Π΅Ρ€Π°Ρ†ΠΈΡ"
570 msgstr "ΠœΠΎΠ΄Π΅Ρ€Π°Ρ†ΠΈΡ"
571
571
572 msgid "Check for duplicates"
572 msgid "Check for duplicates"
573 msgstr "ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π½Π° Π΄ΡƒΠ±Π»ΠΈΠΊΠ°Ρ‚Ρ‹"
573 msgstr "ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ Π½Π° Π΄ΡƒΠ±Π»ΠΈΠΊΠ°Ρ‚Ρ‹"
574
574
575 msgid "Some files are already present on the board."
575 msgid "Some files are already present on the board."
576 msgstr "НСкоторыС Ρ„Π°ΠΉΠ»Ρ‹ ΡƒΠΆΠ΅ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π½Π° Π±ΠΎΡ€Π΄Π΅."
576 msgstr "НСкоторыС Ρ„Π°ΠΉΠ»Ρ‹ ΡƒΠΆΠ΅ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π½Π° Π±ΠΎΡ€Π΄Π΅."
577
577
578 msgid "Do not download URLs"
578 msgid "Do not download URLs"
579 msgstr "НС Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ссылки"
579 msgstr "НС Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ссылки"
580
580
581 msgid "Ban and delete"
581 msgid "Ban and delete"
582 msgstr "Π—Π°Π±Π°Π½ΠΈΡ‚ΡŒ ΠΈ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ"
582 msgstr "Π—Π°Π±Π°Π½ΠΈΡ‚ΡŒ ΠΈ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ"
583
583
584 msgid "Are you sure?"
584 msgid "Are you sure?"
585 msgstr "Π’Ρ‹ ΡƒΠ²Π΅Ρ€Π΅Π½Ρ‹?"
585 msgstr "Π’Ρ‹ ΡƒΠ²Π΅Ρ€Π΅Π½Ρ‹?"
586
586
587 msgid "Ban"
587 msgid "Ban"
588 msgstr "Π—Π°Π±Π°Π½ΠΈΡ‚ΡŒ"
588 msgstr "Π—Π°Π±Π°Π½ΠΈΡ‚ΡŒ"
589
589
590 msgid "File process mode"
590 msgid "File process mode"
591 msgstr "Π Π΅ΠΆΠΈΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²"
591 msgstr "Π Π΅ΠΆΠΈΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ²"
592
592
593 msgid "Download or insert as URLs"
593 msgid "Download or insert as URLs"
594 msgstr "Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ ΠΈΠ»ΠΈ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ ссылки"
594 msgstr "Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ ΠΈΠ»ΠΈ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ ссылки"
595
595
596 msgid "Download"
596 msgid "Download"
597 msgstr "Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ"
597 msgstr "Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ"
598
598
599 msgid "Download and check for uniqueness"
599 msgid "Download and check for uniqueness"
600 msgstr "Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π½Π° ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ"
600 msgstr "Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π½Π° ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ"
601
601
602 msgid "Insert as URLs"
602 msgid "Insert as URLs"
603 msgstr "Π’ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ ссылки"
603 msgstr "Π’ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ ссылки"
604
604
605 msgid "Help"
605 msgid "Help"
606 msgstr "Π‘ΠΏΡ€Π°Π²ΠΊΠ°"
606 msgstr "Π‘ΠΏΡ€Π°Π²ΠΊΠ°"
607
607
608 msgid "View available stickers:"
608 msgid "View available stickers:"
609 msgstr "ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ доступныС стикСры:"
609 msgstr "ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ доступныС стикСры:"
610
610
611 msgid "Stickers"
611 msgid "Stickers"
612 msgstr "Π‘Ρ‚ΠΈΠΊΠ΅Ρ€Ρ‹"
612 msgstr "Π‘Ρ‚ΠΈΠΊΠ΅Ρ€Ρ‹"
613
613
614 msgid "Available by addresses:"
614 msgid "Available by addresses:"
615 msgstr "Доступно ΠΏΠΎ адрСсам:"
615 msgstr "Доступно ΠΏΠΎ адрСсам:"
616
616
617 msgid "Local stickers"
617 msgid "Local stickers"
618 msgstr "Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ стикСры"
618 msgstr "Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ стикСры"
619
619
620 msgid "Global stickers"
620 msgid "Global stickers"
621 msgstr "Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ стикСры"
621 msgstr "Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ стикСры"
622
622
623 msgid "Remove sticker"
623 msgid "Remove sticker"
624 msgstr "Π£Π΄Π°Π»ΠΈΡ‚ΡŒ стикСр"
624 msgstr "Π£Π΄Π°Π»ΠΈΡ‚ΡŒ стикСр"
625
625
626 msgid "Sticker Pack"
626 msgid "Sticker Pack"
627 msgstr "Набор Π‘Ρ‚ΠΈΠΊΠ΅Ρ€ΠΎΠ²"
627 msgstr "Набор Π‘Ρ‚ΠΈΠΊΠ΅Ρ€ΠΎΠ²"
628
628
629 msgid "Tripcode should be specified to own a stickerpack."
629 msgid "Tripcode should be specified to own a stickerpack."
630 msgstr "Для владСния Π½Π°Π±ΠΎΡ€ΠΎΠΌ стикСров Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Ρ‚Ρ€ΠΈΠΏΠΊΠΎΠ΄."
630 msgstr "Для владСния Π½Π°Π±ΠΎΡ€ΠΎΠΌ стикСров Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Ρ‚Ρ€ΠΈΠΏΠΊΠΎΠ΄."
631
631
632 msgid "Title should be specified as a stickerpack name."
632 msgid "Title should be specified as a stickerpack name."
633 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Π½ Π² качСствС ΠΈΠΌΠ΅Π½ΠΈ Π½Π°Π±ΠΎΡ€Π° стикСров."
633 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Π½ Π² качСствС ΠΈΠΌΠ΅Π½ΠΈ Π½Π°Π±ΠΎΡ€Π° стикСров."
634
634
635 msgid "A sticker pack with this name already exists and is owned by another tripcode."
635 msgid "A sticker pack with this name already exists and is owned by another tripcode."
636 msgstr "Набор стикСров с Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΡƒΠΆΠ΅ сущСствуСт ΠΈ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ Ρ‚Ρ€ΠΈΠΏΠΊΠΎΠ΄Ρƒ."
636 msgstr "Набор стикСров с Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΡƒΠΆΠ΅ сущСствуСт ΠΈ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ Ρ‚Ρ€ΠΈΠΏΠΊΠΎΠ΄Ρƒ."
637
637
638 msgid "This sticker pack can only be updated by an administrator."
638 msgid "This sticker pack can only be updated by an administrator."
639 msgstr "Π­Ρ‚ΠΎΡ‚ Π½Π°Π±ΠΎΡ€ стикСров ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ администратором."
639 msgstr "Π­Ρ‚ΠΎΡ‚ Π½Π°Π±ΠΎΡ€ стикСров ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ администратором."
640
640
641 msgid "To add a sticker, create a stickerpack thread using the title as a pack name, and a tripcode to own the pack. Then, add posts with title as a sticker name, and the same tripcode, to the thread. Their attachments would become stickers."
641 msgid "To add a sticker, create a stickerpack thread using the title as a pack name, and a tripcode to own the pack. Then, add posts with title as a sticker name, and the same tripcode, to the thread. Their attachments would become stickers."
642 msgstr "Π§Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ стикСр, создайтС Ρ‚Π΅ΠΌΡƒ-Π½Π°Π±ΠΎΡ€ с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ Π² качСствС названия Π½Π°Π±ΠΎΡ€Π° стикСров, ΠΈ Ρ‚Ρ€ΠΈΠΏΠΊΠΎΠ΄ΠΎΠΌ для подтвСрТдСния владСния Π½Π°Π±ΠΎΡ€ΠΎΠΌ. Π—Π°Ρ‚Π΅ΠΌ, добавляйтС сообщСния с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ Π² качСствС ΠΈΠΌΠ΅Π½ΠΈ стикСра, ΠΈ Ρ‚Π΅ΠΌ ΠΆΠ΅ Ρ‚Ρ€ΠΈΠΏΠΊΠΎΠ΄ΠΎΠΌΠΌ. Π˜Ρ… влоТСния станут стикСрами."
642 msgstr "Π§Ρ‚ΠΎΠ±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ стикСр, создайтС Ρ‚Π΅ΠΌΡƒ-Π½Π°Π±ΠΎΡ€ с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ Π² качСствС названия Π½Π°Π±ΠΎΡ€Π° стикСров, ΠΈ Ρ‚Ρ€ΠΈΠΏΠΊΠΎΠ΄ΠΎΠΌ для подтвСрТдСния владСния Π½Π°Π±ΠΎΡ€ΠΎΠΌ. Π—Π°Ρ‚Π΅ΠΌ, добавляйтС сообщСния с Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ Π² качСствС ΠΈΠΌΠ΅Π½ΠΈ стикСра, ΠΈ Ρ‚Π΅ΠΌ ΠΆΠ΅ Ρ‚Ρ€ΠΈΠΏΠΊΠΎΠ΄ΠΎΠΌΠΌ. Π˜Ρ… влоТСния станут стикСрами."
643
643
644 msgid "Inappropriate sticker pack name."
644 msgid "Inappropriate sticker pack name."
645 msgstr "НСдопустимоС имя Π½Π°Π±ΠΎΡ€Π° стикСров."
645 msgstr "НСдопустимоС имя Π½Π°Π±ΠΎΡ€Π° стикСров."
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -1,645 +1,645 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: 2015-10-09 23:21+0300\n"
10 "POT-Creation-Date: 2015-10-09 23:21+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 #: admin.py:22
21 #: admin.py:22
22 msgid "{} posters were banned"
22 msgid "{} posters were banned"
23 msgstr "{} постСрів Π·Π°Π±Π»ΠΎΠΊΠΎΠ²Π°Π½ΠΎ"
23 msgstr "{} постСрів Π·Π°Π±Π»ΠΎΠΊΠΎΠ²Π°Π½ΠΎ"
24
24
25 #: authors.py:9
25 #: authors.py:9
26 msgid "author"
26 msgid "author"
27 msgstr "Π°Π²Ρ‚ΠΎΡ€"
27 msgstr "Π°Π²Ρ‚ΠΎΡ€"
28
28
29 #: authors.py:10
29 #: authors.py:10
30 msgid "developer"
30 msgid "developer"
31 msgstr "Ρ€ΠΎΠ·Ρ€ΠΎΠ±Π½ΠΈΠΊ"
31 msgstr "Ρ€ΠΎΠ·Ρ€ΠΎΠ±Π½ΠΈΠΊ"
32
32
33 #: authors.py:11
33 #: authors.py:11
34 msgid "javascript developer"
34 msgid "javascript developer"
35 msgstr "javascript-Ρ€ΠΎΠ·Ρ€ΠΎΠ±Π½ΠΈΠΊ"
35 msgstr "javascript-Ρ€ΠΎΠ·Ρ€ΠΎΠ±Π½ΠΈΠΊ"
36
36
37 #: authors.py:12
37 #: authors.py:12
38 msgid "designer"
38 msgid "designer"
39 msgstr "Π΄ΠΈΠ·Π°ΠΉΠ½Π΅Ρ€"
39 msgstr "Π΄ΠΈΠ·Π°ΠΉΠ½Π΅Ρ€"
40
40
41 #: forms.py:30
41 #: forms.py:30
42 msgid "Type message here. Use formatting panel for more advanced usage."
42 msgid "Type message here. Use formatting panel for more advanced usage."
43 msgstr ""
43 msgstr ""
44 "Π’Π²Π΅Π΄Ρ–Ρ‚ΡŒ сюди повідомлСння. ΠšΠΎΡ€ΠΈΡΡ‚Π°ΠΉΡ‚Π΅ панСль для ΡΠΊΠ»Π°Π΄Π½Ρ–ΡˆΠΎΠ³ΠΎ форматування."
44 "Π’Π²Π΅Π΄Ρ–Ρ‚ΡŒ сюди повідомлСння. ΠšΠΎΡ€ΠΈΡΡ‚Π°ΠΉΡ‚Π΅ панСль для ΡΠΊΠ»Π°Π΄Π½Ρ–ΡˆΠΎΠ³ΠΎ форматування."
45
45
46 #: forms.py:31
46 #: forms.py:31
47 msgid "music images i_dont_like_tags"
47 msgid "music images i_dont_like_tags"
48 msgstr "ΠΌΡƒΠ·ΠΈΠΊΠ° зобраТСння ΠΌΡ–Ρ‚ΠΊΠΈ_Π½Π΅_ΠΏΠΎΡ‚Ρ€Ρ–Π±Π½Ρ–"
48 msgstr "ΠΌΡƒΠ·ΠΈΠΊΠ° зобраТСння ΠΌΡ–Ρ‚ΠΊΠΈ_Π½Π΅_ΠΏΠΎΡ‚Ρ€Ρ–Π±Π½Ρ–"
49
49
50 #: forms.py:33
50 #: forms.py:33
51 msgid "Title"
51 msgid "Title"
52 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ"
52 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ"
53
53
54 #: forms.py:34
54 #: forms.py:34
55 msgid "Text"
55 msgid "Text"
56 msgstr "ВСкст"
56 msgstr "ВСкст"
57
57
58 #: forms.py:35
58 #: forms.py:35
59 msgid "Tag"
59 msgid "Tag"
60 msgstr "ΠœΡ–Ρ‚ΠΊΠ°"
60 msgstr "ΠœΡ–Ρ‚ΠΊΠ°"
61
61
62 #: forms.py:36 templates/boards/base.html:40 templates/search/search.html:7
62 #: forms.py:36 templates/boards/base.html:40 templates/search/search.html:7
63 msgid "Search"
63 msgid "Search"
64 msgstr "ΠŸΠΎΡˆΡƒΠΊ"
64 msgstr "ΠŸΠΎΡˆΡƒΠΊ"
65
65
66 #: forms.py:48
66 #: forms.py:48
67 msgid "File 1"
67 msgid "File 1"
68 msgstr "Π€Π°ΠΉΠ» 1"
68 msgstr "Π€Π°ΠΉΠ» 1"
69
69
70 #: forms.py:48
70 #: forms.py:48
71 msgid "File 2"
71 msgid "File 2"
72 msgstr "Π€Π°ΠΉΠ» 2"
72 msgstr "Π€Π°ΠΉΠ» 2"
73
73
74 #: forms.py:142
74 #: forms.py:142
75 msgid "File URL"
75 msgid "File URL"
76 msgstr "URL Ρ„Π°ΠΉΠ»Ρƒ"
76 msgstr "URL Ρ„Π°ΠΉΠ»Ρƒ"
77
77
78 #: forms.py:148
78 #: forms.py:148
79 msgid "e-mail"
79 msgid "e-mail"
80 msgstr ""
80 msgstr ""
81
81
82 #: forms.py:151
82 #: forms.py:151
83 msgid "Additional threads"
83 msgid "Additional threads"
84 msgstr "Π”ΠΎΠ΄Π°Ρ‚ΠΊΠΎΠ²Ρ– Π½ΠΈΡ‚ΠΊΠΈ"
84 msgstr "Π”ΠΎΠ΄Π°Ρ‚ΠΊΠΎΠ²Ρ– Π½ΠΈΡ‚ΠΊΠΈ"
85
85
86 #: forms.py:162
86 #: forms.py:162
87 #, python-format
87 #, python-format
88 msgid "Title must have less than %s characters"
88 msgid "Title must have less than %s characters"
89 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΌΠ°Ρ” містити мСншС %s символів"
89 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΌΠ°Ρ” містити мСншС %s символів"
90
90
91 #: forms.py:172
91 #: forms.py:172
92 #, python-format
92 #, python-format
93 msgid "Text must have less than %s characters"
93 msgid "Text must have less than %s characters"
94 msgstr "ВСкст ΠΌΠ°Ρ” Π±ΡƒΡ‚ΠΈ ΠΊΠΎΡ€ΠΎΡ‚ΡˆΠ΅ %s символів"
94 msgstr "ВСкст ΠΌΠ°Ρ” Π±ΡƒΡ‚ΠΈ ΠΊΠΎΡ€ΠΎΡ‚ΡˆΠ΅ %s символів"
95
95
96 #: forms.py:192
96 #: forms.py:192
97 msgid "Invalid URL"
97 msgid "Invalid URL"
98 msgstr "Π₯ΠΈΠ±Π½ΠΈΠΉ URL"
98 msgstr "Π₯ΠΈΠ±Π½ΠΈΠΉ URL"
99
99
100 #: forms.py:213
100 #: forms.py:213
101 msgid "Invalid additional thread list"
101 msgid "Invalid additional thread list"
102 msgstr "Π₯ΠΈΠ±Π½ΠΈΠΉ ΠΏΠ΅Ρ€Π΅Π»Ρ–ΠΊ Π΄ΠΎΠ΄Π°Ρ‚ΠΊΠΎΠ²ΠΈΡ… Π½ΠΈΡ‚ΠΎΠΊ"
102 msgstr "Π₯ΠΈΠ±Π½ΠΈΠΉ ΠΏΠ΅Ρ€Π΅Π»Ρ–ΠΊ Π΄ΠΎΠ΄Π°Ρ‚ΠΊΠΎΠ²ΠΈΡ… Π½ΠΈΡ‚ΠΎΠΊ"
103
103
104 #: forms.py:258
104 #: forms.py:258
105 msgid "Either text or file must be entered."
105 msgid "Either text or file must be entered."
106 msgstr "Π‘Π»Ρ–Π΄ Π΄ΠΎΠ΄Π°Ρ‚ΠΈ тСкст Π°Π±ΠΎ Ρ„Π°ΠΉΠ»."
106 msgstr "Π‘Π»Ρ–Π΄ Π΄ΠΎΠ΄Π°Ρ‚ΠΈ тСкст Π°Π±ΠΎ Ρ„Π°ΠΉΠ»."
107
107
108 #: forms.py:317 templates/boards/all_threads.html:153
108 #: forms.py:317 templates/boards/all_threads.html:153
109 #: templates/boards/rss/post.html:10 templates/boards/tags.html:6
109 #: templates/boards/rss/post.html:10 templates/boards/tags.html:6
110 msgid "Tags"
110 msgid "Tags"
111 msgstr "ΠœΡ–Ρ‚ΠΊΠΈ"
111 msgstr "ΠœΡ–Ρ‚ΠΊΠΈ"
112
112
113 #: forms.py:324
113 #: forms.py:324
114 msgid "Inappropriate characters in tags."
114 msgid "Inappropriate characters in tags."
115 msgstr "НСприйнятні символи Ρƒ ΠΌΡ–Ρ‚ΠΊΠ°Ρ…."
115 msgstr "НСприйнятні символи Ρƒ ΠΌΡ–Ρ‚ΠΊΠ°Ρ…."
116
116
117 #: forms.py:344
117 #: forms.py:344
118 msgid "Need at least one section."
118 msgid "Need at least one section."
119 msgstr "ΠœΡƒΡΠΈΡ‚ΡŒ Π±ΡƒΡ‚ΠΈ Ρ…ΠΎΡ‡Π° Π± ΠΎΠ΄ΠΈΠ½ Ρ€ΠΎΠ·Π΄Ρ–Π»."
119 msgstr "ΠœΡƒΡΠΈΡ‚ΡŒ Π±ΡƒΡ‚ΠΈ Ρ…ΠΎΡ‡Π° Π± ΠΎΠ΄ΠΈΠ½ Ρ€ΠΎΠ·Π΄Ρ–Π»."
120
120
121 #: forms.py:356
121 #: forms.py:356
122 msgid "Theme"
122 msgid "Theme"
123 msgstr "Π’Π΅ΠΌΠ°"
123 msgstr "Π’Π΅ΠΌΠ°"
124
124
125 #: forms.py:357
125 #: forms.py:357
126 msgid "Image view mode"
126 msgid "Image view mode"
127 msgstr "Π Π΅ΠΆΠΈΠΌ пСрСгляду Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΡŒ"
127 msgstr "Π Π΅ΠΆΠΈΠΌ пСрСгляду Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΡŒ"
128
128
129 #: forms.py:358
129 #: forms.py:358
130 msgid "User name"
130 msgid "User name"
131 msgstr "Им'я користувача"
131 msgstr "Им'я користувача"
132
132
133 #: forms.py:359
133 #: forms.py:359
134 msgid "Time zone"
134 msgid "Time zone"
135 msgstr "Часовий пояс"
135 msgstr "Часовий пояс"
136
136
137 #: forms.py:365
137 #: forms.py:365
138 msgid "Inappropriate characters."
138 msgid "Inappropriate characters."
139 msgstr "НСприйнятні символи."
139 msgstr "НСприйнятні символи."
140
140
141 #: templates/boards/404.html:6
141 #: templates/boards/404.html:6
142 msgid "Not found"
142 msgid "Not found"
143 msgstr "Загубилося"
143 msgstr "Загубилося"
144
144
145 #: templates/boards/404.html:12
145 #: templates/boards/404.html:12
146 msgid "This page does not exist"
146 msgid "This page does not exist"
147 msgstr "НСма ΠΏΡ€Π°Π²Π΄ΠΎΠ½ΡŒΠΊΠΈ Π½Π° світі, ΠΎΠΉ нСма…"
147 msgstr "НСма ΠΏΡ€Π°Π²Π΄ΠΎΠ½ΡŒΠΊΠΈ Π½Π° світі, ΠΎΠΉ нСма…"
148
148
149 #: templates/boards/all_threads.html:35
149 #: templates/boards/all_threads.html:35
150 msgid "Details"
150 msgid "Details"
151 msgstr "Π”Π΅Ρ‚Π°Π»Ρ–"
151 msgstr "Π”Π΅Ρ‚Π°Π»Ρ–"
152
152
153 #: templates/boards/all_threads.html:69
153 #: templates/boards/all_threads.html:69
154 msgid "Edit tag"
154 msgid "Edit tag"
155 msgstr "Π—ΠΌΡ–Π½ΠΈΡ‚ΠΈ ΠΌΡ–Ρ‚ΠΊΡƒ"
155 msgstr "Π—ΠΌΡ–Π½ΠΈΡ‚ΠΈ ΠΌΡ–Ρ‚ΠΊΡƒ"
156
156
157 #: templates/boards/all_threads.html:76
157 #: templates/boards/all_threads.html:76
158 #, python-format
158 #, python-format
159 msgid "%(count)s active thread"
159 msgid "%(count)s active thread"
160 msgid_plural "%(count)s active threads"
160 msgid_plural "%(count)s active threads"
161 msgstr[0] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½Π° Π½ΠΈΡ‚ΠΊΠ°"
161 msgstr[0] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½Π° Π½ΠΈΡ‚ΠΊΠ°"
162 msgstr[1] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½Ρ– Π½ΠΈΡ‚ΠΊΠΈ"
162 msgstr[1] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½Ρ– Π½ΠΈΡ‚ΠΊΠΈ"
163 msgstr[2] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½ΠΈΡ… Π½ΠΈΡ‚ΠΎΠΊ"
163 msgstr[2] "%(count)s Π°ΠΊΡ‚ΠΈΠ²Π½ΠΈΡ… Π½ΠΈΡ‚ΠΎΠΊ"
164
164
165 #: templates/boards/all_threads.html:76
165 #: templates/boards/all_threads.html:76
166 #, python-format
166 #, python-format
167 msgid "%(count)s thread in bumplimit"
167 msgid "%(count)s thread in bumplimit"
168 msgid_plural "%(count)s threads in bumplimit"
168 msgid_plural "%(count)s threads in bumplimit"
169 msgstr[0] "%(count)s Π½ΠΈΡ‚ΠΊΠ° Π² бампляматі"
169 msgstr[0] "%(count)s Π½ΠΈΡ‚ΠΊΠ° Π² бампляматі"
170 msgstr[1] "%(count)s Π½ΠΈΡ‚ΠΊΠΈ Π² бампляматі"
170 msgstr[1] "%(count)s Π½ΠΈΡ‚ΠΊΠΈ Π² бампляматі"
171 msgstr[2] "%(count)s Π½ΠΈΡ‚ΠΎΠΊ Ρƒ бампляматі"
171 msgstr[2] "%(count)s Π½ΠΈΡ‚ΠΎΠΊ Ρƒ бампляматі"
172
172
173 #: templates/boards/all_threads.html:77
173 #: templates/boards/all_threads.html:77
174 #, python-format
174 #, python-format
175 msgid "%(count)s archived thread"
175 msgid "%(count)s archived thread"
176 msgid_plural "%(count)s archived thread"
176 msgid_plural "%(count)s archived thread"
177 msgstr[0] "%(count)s Π°Ρ€Ρ…Ρ–Π²Π½Π° Π½ΠΈΡ‚ΠΊΠ°"
177 msgstr[0] "%(count)s Π°Ρ€Ρ…Ρ–Π²Π½Π° Π½ΠΈΡ‚ΠΊΠ°"
178 msgstr[1] "%(count)s Π°Ρ€Ρ…Ρ–Π²Π½Ρ– Π½ΠΈΡ‚ΠΊΠΈ"
178 msgstr[1] "%(count)s Π°Ρ€Ρ…Ρ–Π²Π½Ρ– Π½ΠΈΡ‚ΠΊΠΈ"
179 msgstr[2] "%(count)s Π°Ρ€Ρ…Ρ–Π²Π½ΠΈΡ… Π½ΠΈΡ‚ΠΎΠΊ"
179 msgstr[2] "%(count)s Π°Ρ€Ρ…Ρ–Π²Π½ΠΈΡ… Π½ΠΈΡ‚ΠΎΠΊ"
180
180
181 #: templates/boards/all_threads.html:78 templates/boards/post.html:102
181 #: templates/boards/all_threads.html:78 templates/boards/post.html:102
182 #, python-format
182 #, python-format
183 #| msgid "%(count)s message"
183 #| msgid "%(count)s message"
184 #| msgid_plural "%(count)s messages"
184 #| msgid_plural "%(count)s messages"
185 msgid "%(count)s message"
185 msgid "%(count)s message"
186 msgid_plural "%(count)s messages"
186 msgid_plural "%(count)s messages"
187 msgstr[0] "%(count)s повідомлСння"
187 msgstr[0] "%(count)s повідомлСння"
188 msgstr[1] "%(count)s повідомлСння"
188 msgstr[1] "%(count)s повідомлСння"
189 msgstr[2] "%(count)s ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ"
189 msgstr[2] "%(count)s ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ"
190
190
191 #: templates/boards/all_threads.html:95 templates/boards/feed.html:30
191 #: templates/boards/all_threads.html:95 templates/boards/feed.html:30
192 #: templates/boards/notifications.html:17 templates/search/search.html:26
192 #: templates/boards/notifications.html:17 templates/search/search.html:26
193 msgid "Previous page"
193 msgid "Previous page"
194 msgstr "ΠŸΠΎΠΏΡ”Ρ€Ρ”Π΄Π½Ρ сторінка"
194 msgstr "ΠŸΠΎΠΏΡ”Ρ€Ρ”Π΄Π½Ρ сторінка"
195
195
196 #: templates/boards/all_threads.html:109
196 #: templates/boards/all_threads.html:109
197 #, python-format
197 #, python-format
198 msgid "Skipped %(count)s reply. Open thread to see all replies."
198 msgid "Skipped %(count)s reply. Open thread to see all replies."
199 msgid_plural "Skipped %(count)s replies. Open thread to see all replies."
199 msgid_plural "Skipped %(count)s replies. Open thread to see all replies."
200 msgstr[0] "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄ΡŒ. Π ΠΎΠ·Π³ΠΎΡ€Π½Ρ–Ρ‚ΡŒ Π½ΠΈΡ‚ΠΊΡƒ, Ρ‰ΠΎΠ± ΠΏΠΎΠ±Π°Ρ‡ΠΈΡ‚ΠΈ всі Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–."
200 msgstr[0] "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄ΡŒ. Π ΠΎΠ·Π³ΠΎΡ€Π½Ρ–Ρ‚ΡŒ Π½ΠΈΡ‚ΠΊΡƒ, Ρ‰ΠΎΠ± ΠΏΠΎΠ±Π°Ρ‡ΠΈΡ‚ΠΈ всі Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–."
201 msgstr[1] ""
201 msgstr[1] ""
202 "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–. Π ΠΎΠ·Π³ΠΎΡ€Π½Ρ–Ρ‚ΡŒ Π½ΠΈΡ‚ΠΊΡƒ, Ρ‰ΠΎΠ± ΠΏΠΎΠ±Π°Ρ‡ΠΈΡ‚ΠΈ всі Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–."
202 "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–. Π ΠΎΠ·Π³ΠΎΡ€Π½Ρ–Ρ‚ΡŒ Π½ΠΈΡ‚ΠΊΡƒ, Ρ‰ΠΎΠ± ΠΏΠΎΠ±Π°Ρ‡ΠΈΡ‚ΠΈ всі Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–."
203 msgstr[2] ""
203 msgstr[2] ""
204 "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Π΅ΠΉ. Π ΠΎΠ·Π³ΠΎΡ€Π½Ρ–Ρ‚ΡŒ Π½ΠΈΡ‚ΠΊΡƒ, Ρ‰ΠΎΠ± ΠΏΠΎΠ±Π°Ρ‡ΠΈΡ‚ΠΈ всі Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–."
204 "ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ΠΎ %(count)s Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Π΅ΠΉ. Π ΠΎΠ·Π³ΠΎΡ€Π½Ρ–Ρ‚ΡŒ Π½ΠΈΡ‚ΠΊΡƒ, Ρ‰ΠΎΠ± ΠΏΠΎΠ±Π°Ρ‡ΠΈΡ‚ΠΈ всі Π²Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–."
205
205
206 #: templates/boards/all_threads.html:127 templates/boards/feed.html:40
206 #: templates/boards/all_threads.html:127 templates/boards/feed.html:40
207 #: templates/boards/notifications.html:27 templates/search/search.html:37
207 #: templates/boards/notifications.html:27 templates/search/search.html:37
208 msgid "Next page"
208 msgid "Next page"
209 msgstr "Наступна сторінка"
209 msgstr "Наступна сторінка"
210
210
211 #: templates/boards/all_threads.html:132
211 #: templates/boards/all_threads.html:132
212 msgid "No threads exist. Create the first one!"
212 msgid "No threads exist. Create the first one!"
213 msgstr "НСма ΠΏΡ€Π°Π²Π΄ΠΎΠ½ΡŒΠΊΠΈ Π½Π° світі. Π—Π°Ρ‡Π½Ρ–ΠΌΠΎ Ρ—Ρ—!"
213 msgstr "НСма ΠΏΡ€Π°Π²Π΄ΠΎΠ½ΡŒΠΊΠΈ Π½Π° світі. Π—Π°Ρ‡Π½Ρ–ΠΌΠΎ Ρ—Ρ—!"
214
214
215 #: templates/boards/all_threads.html:138
215 #: templates/boards/all_threads.html:138
216 msgid "Create new thread"
216 msgid "Create new thread"
217 msgstr "БплСсти Π½ΠΎΠ²Ρƒ Π½ΠΈΡ‚ΠΊΡƒ"
217 msgstr "БплСсти Π½ΠΎΠ²Ρƒ Π½ΠΈΡ‚ΠΊΡƒ"
218
218
219 #: templates/boards/all_threads.html:143 templates/boards/preview.html:16
219 #: templates/boards/all_threads.html:143 templates/boards/preview.html:16
220 #: templates/boards/thread_normal.html:51
220 #: templates/boards/thread_normal.html:51
221 msgid "Post"
221 msgid "Post"
222 msgstr "Надіслати"
222 msgstr "Надіслати"
223
223
224 #: templates/boards/all_threads.html:144 templates/boards/preview.html:6
224 #: templates/boards/all_threads.html:144 templates/boards/preview.html:6
225 #: templates/boards/staticpages/help.html:21
225 #: templates/boards/staticpages/help.html:21
226 #: templates/boards/thread_normal.html:52
226 #: templates/boards/thread_normal.html:52
227 msgid "Preview"
227 msgid "Preview"
228 msgstr "ΠŸΠΎΠΏΠ΅Ρ€Π΅Π³Π»ΡΠ΄"
228 msgstr "ΠŸΠΎΠΏΠ΅Ρ€Π΅Π³Π»ΡΠ΄"
229
229
230 #: templates/boards/all_threads.html:149
230 #: templates/boards/all_threads.html:149
231 msgid "Tags must be delimited by spaces. Text or image is required."
231 msgid "Tags must be delimited by spaces. Text or image is required."
232 msgstr ""
232 msgstr ""
233 "ΠœΡ–Ρ‚ΠΊΠΈ Ρ€ΠΎΠ·ΠΌΠ΅ΠΆΡƒΠ²Π°Ρ‚ΠΈ ΠΏΡ€ΠΎΠ±Ρ–Π»Π°ΠΌΠΈ. ВСкст Ρ‡ΠΈ зобраТСння Ρ” ΠΎΠ±ΠΎΠ²'язковими."
233 "ΠœΡ–Ρ‚ΠΊΠΈ Ρ€ΠΎΠ·ΠΌΠ΅ΠΆΡƒΠ²Π°Ρ‚ΠΈ ΠΏΡ€ΠΎΠ±Ρ–Π»Π°ΠΌΠΈ. ВСкст Ρ‡ΠΈ зобраТСння Ρ” ΠΎΠ±ΠΎΠ²'язковими."
234
234
235 #: templates/boards/all_threads.html:152 templates/boards/thread_normal.html:58
235 #: templates/boards/all_threads.html:152 templates/boards/thread_normal.html:58
236 msgid "Text syntax"
236 msgid "Text syntax"
237 msgstr "Бинтаксис тСксту"
237 msgstr "Бинтаксис тСксту"
238
238
239 #: templates/boards/all_threads.html:166 templates/boards/feed.html:53
239 #: templates/boards/all_threads.html:166 templates/boards/feed.html:53
240 msgid "Pages:"
240 msgid "Pages:"
241 msgstr "Π‘Ρ‚ΠΎΡ€Ρ–Π½ΠΊΠΈ:"
241 msgstr "Π‘Ρ‚ΠΎΡ€Ρ–Π½ΠΊΠΈ:"
242
242
243 #: templates/boards/authors.html:6 templates/boards/authors.html.py:12
243 #: templates/boards/authors.html:6 templates/boards/authors.html.py:12
244 msgid "Authors"
244 msgid "Authors"
245 msgstr "Автори"
245 msgstr "Автори"
246
246
247 #: templates/boards/authors.html:26
247 #: templates/boards/authors.html:26
248 msgid "Distributed under the"
248 msgid "Distributed under the"
249 msgstr "Π ΠΎΠ·ΠΏΠΎΠ²ΡΡŽΠ΄ΠΆΡƒΡ”Ρ‚ΡŒΡΡ ΠΏΡ–Π΄ Π»Ρ–Ρ†Π΅Π½Π·Ρ–Ρ”ΡŽ"
249 msgstr "Π ΠΎΠ·ΠΏΠΎΠ²ΡΡŽΠ΄ΠΆΡƒΡ”Ρ‚ΡŒΡΡ ΠΏΡ–Π΄ Π»Ρ–Ρ†Π΅Π½Π·Ρ–Ρ”ΡŽ"
250
250
251 #: templates/boards/authors.html:28
251 #: templates/boards/authors.html:28
252 msgid "license"
252 msgid "license"
253 msgstr ""
253 msgstr ""
254
254
255 #: templates/boards/authors.html:30
255 #: templates/boards/authors.html:30
256 msgid "Repository"
256 msgid "Repository"
257 msgstr "Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€Ρ–ΠΉ"
257 msgstr "Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€Ρ–ΠΉ"
258
258
259 #: templates/boards/base.html:14 templates/boards/base.html.py:41
259 #: templates/boards/base.html:14 templates/boards/base.html.py:41
260 msgid "Feed"
260 msgid "Feed"
261 msgstr "Π‘Ρ‚Ρ€Ρ–Ρ‡ΠΊΠ°"
261 msgstr "Π‘Ρ‚Ρ€Ρ–Ρ‡ΠΊΠ°"
262
262
263 #: templates/boards/base.html:31
263 #: templates/boards/base.html:31
264 msgid "All threads"
264 msgid "All threads"
265 msgstr "Усі Π½ΠΈΡ‚ΠΊΠΈ"
265 msgstr "Усі Π½ΠΈΡ‚ΠΊΠΈ"
266
266
267 #: templates/boards/base.html:37
267 #: templates/boards/base.html:37
268 msgid "Add tags"
268 msgid "Add tags"
269 msgstr "Π”ΠΎΠ΄Π°Ρ‚ΠΈ ΠΌΡ–Ρ‚ΠΊΠΈ"
269 msgstr "Π”ΠΎΠ΄Π°Ρ‚ΠΈ ΠΌΡ–Ρ‚ΠΊΠΈ"
270
270
271 #: templates/boards/base.html:39
271 #: templates/boards/base.html:39
272 msgid "Tag management"
272 msgid "Tag management"
273 msgstr "ΠšΠ΅Ρ€ΡƒΠ²Π°Π½Π½Ρ ΠΌΡ–Ρ‚ΠΊΠ°ΠΌΠΈ"
273 msgstr "ΠšΠ΅Ρ€ΡƒΠ²Π°Π½Π½Ρ ΠΌΡ–Ρ‚ΠΊΠ°ΠΌΠΈ"
274
274
275 #: templates/boards/base.html:39
275 #: templates/boards/base.html:39
276 msgid "tags"
276 msgid "tags"
277 msgstr "ΠΌΡ–Ρ‚ΠΊΠΈ"
277 msgstr "ΠΌΡ–Ρ‚ΠΊΠΈ"
278
278
279 #: templates/boards/base.html:40
279 #: templates/boards/base.html:40
280 msgid "search"
280 msgid "search"
281 msgstr "ΠΏΠΎΡˆΡƒΠΊ"
281 msgstr "ΠΏΠΎΡˆΡƒΠΊ"
282
282
283 #: templates/boards/base.html:41 templates/boards/feed.html:11
283 #: templates/boards/base.html:41 templates/boards/feed.html:11
284 msgid "feed"
284 msgid "feed"
285 msgstr "стрічка"
285 msgstr "стрічка"
286
286
287 #: templates/boards/base.html:42 templates/boards/random.html:6
287 #: templates/boards/base.html:42 templates/boards/random.html:6
288 msgid "Random images"
288 msgid "Random images"
289 msgstr "Π’ΠΈΠΏΠ°Π΄ΠΊΠΎΠ²Ρ– зобраТСння"
289 msgstr "Π’ΠΈΠΏΠ°Π΄ΠΊΠΎΠ²Ρ– зобраТСння"
290
290
291 #: templates/boards/base.html:42
291 #: templates/boards/base.html:42
292 msgid "random"
292 msgid "random"
293 msgstr "Π²ΠΈΠΏΠ°Π΄ΠΊΠΎΠ²Ρ–"
293 msgstr "Π²ΠΈΠΏΠ°Π΄ΠΊΠΎΠ²Ρ–"
294
294
295 #: templates/boards/base.html:44
295 #: templates/boards/base.html:44
296 msgid "favorites"
296 msgid "favorites"
297 msgstr "ΡƒΠ»ΡŽΠ±Π»Π΅Π½Π΅"
297 msgstr "ΡƒΠ»ΡŽΠ±Π»Π΅Π½Π΅"
298
298
299 #: templates/boards/base.html:48 templates/boards/base.html.py:49
299 #: templates/boards/base.html:48 templates/boards/base.html.py:49
300 #: templates/boards/notifications.html:8
300 #: templates/boards/notifications.html:8
301 msgid "Notifications"
301 msgid "Notifications"
302 msgstr "БповіщСння"
302 msgstr "БповіщСння"
303
303
304 #: templates/boards/base.html:56 templates/boards/settings.html:8
304 #: templates/boards/base.html:56 templates/boards/settings.html:8
305 msgid "Settings"
305 msgid "Settings"
306 msgstr "ΠΠ°Π»Π°ΡˆΡ‚ΡƒΠ²Π°Π½Π½Ρ"
306 msgstr "ΠΠ°Π»Π°ΡˆΡ‚ΡƒΠ²Π°Π½Π½Ρ"
307
307
308 #: templates/boards/base.html:59
308 #: templates/boards/base.html:59
309 msgid "Loading..."
309 msgid "Loading..."
310 msgstr "ЗавантаТСння..."
310 msgstr "ЗавантаТСння..."
311
311
312 #: templates/boards/base.html:71
312 #: templates/boards/base.html:71
313 msgid "Admin"
313 msgid "Admin"
314 msgstr "Адміністрування"
314 msgstr "Адміністрування"
315
315
316 #: templates/boards/base.html:73
316 #: templates/boards/base.html:73
317 #, python-format
317 #, python-format
318 msgid "Speed: %(ppd)s posts per day"
318 msgid "Speed: %(ppd)s posts per day"
319 msgstr "Π₯ΡƒΡ‚ΠΊΡ–ΡΡ‚ΡŒ: %(ppd)s ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ Π½Π° дСнь"
319 msgstr "Π₯ΡƒΡ‚ΠΊΡ–ΡΡ‚ΡŒ: %(ppd)s ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ Π½Π° дСнь"
320
320
321 #: templates/boards/base.html:75
321 #: templates/boards/base.html:75
322 msgid "Up"
322 msgid "Up"
323 msgstr "Π”ΠΎΠ³ΠΎΡ€ΠΈ"
323 msgstr "Π”ΠΎΠ³ΠΎΡ€ΠΈ"
324
324
325 #: templates/boards/feed.html:45
325 #: templates/boards/feed.html:45
326 msgid "No posts exist. Create the first one!"
326 msgid "No posts exist. Create the first one!"
327 msgstr "Π©Π΅ Π½Π΅ΠΌΠ° ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ. Π—Π°Ρ‡Π½Ρ–ΠΌΠΎ!"
327 msgstr "Π©Π΅ Π½Π΅ΠΌΠ° ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ. Π—Π°Ρ‡Π½Ρ–ΠΌΠΎ!"
328
328
329 #: templates/boards/post.html:33
329 #: templates/boards/post.html:33
330 msgid "Open"
330 msgid "Open"
331 msgstr "Π’Ρ–Π΄ΠΊΡ€ΠΈΡ‚ΠΈ"
331 msgstr "Π’Ρ–Π΄ΠΊΡ€ΠΈΡ‚ΠΈ"
332
332
333 #: templates/boards/post.html:35 templates/boards/post.html.py:46
333 #: templates/boards/post.html:35 templates/boards/post.html.py:46
334 msgid "Reply"
334 msgid "Reply"
335 msgstr "Відповісти"
335 msgstr "Відповісти"
336
336
337 #: templates/boards/post.html:41
337 #: templates/boards/post.html:41
338 msgid " in "
338 msgid " in "
339 msgstr " Ρƒ "
339 msgstr " Ρƒ "
340
340
341 #: templates/boards/post.html:51
341 #: templates/boards/post.html:51
342 msgid "Edit"
342 msgid "Edit"
343 msgstr "Π—ΠΌΡ–Π½ΠΈΡ‚ΠΈ"
343 msgstr "Π—ΠΌΡ–Π½ΠΈΡ‚ΠΈ"
344
344
345 #: templates/boards/post.html:53
345 #: templates/boards/post.html:53
346 msgid "Edit thread"
346 msgid "Edit thread"
347 msgstr "Π—ΠΌΡ–Π½ΠΈΡ‚ΠΈ Π½ΠΈΡ‚ΠΊΡƒ"
347 msgstr "Π—ΠΌΡ–Π½ΠΈΡ‚ΠΈ Π½ΠΈΡ‚ΠΊΡƒ"
348
348
349 #: templates/boards/post.html:91
349 #: templates/boards/post.html:91
350 msgid "Replies"
350 msgid "Replies"
351 msgstr "Π’Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–"
351 msgstr "Π’Ρ–Π΄ΠΏΠΎΠ²Ρ–Π΄Ρ–"
352
352
353 #: templates/boards/post.html:103
353 #: templates/boards/post.html:103
354 #, python-format
354 #, python-format
355 msgid "%(count)s image"
355 msgid "%(count)s image"
356 msgid_plural "%(count)s images"
356 msgid_plural "%(count)s images"
357 msgstr[0] "%(count)s зобраТСння"
357 msgstr[0] "%(count)s зобраТСння"
358 msgstr[1] "%(count)s зобраТСння"
358 msgstr[1] "%(count)s зобраТСння"
359 msgstr[2] "%(count)s Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΡŒ"
359 msgstr[2] "%(count)s Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΡŒ"
360
360
361 #: templates/boards/rss/post.html:5
361 #: templates/boards/rss/post.html:5
362 msgid "Post image"
362 msgid "Post image"
363 msgstr "ЗобраТСння повідомлСння"
363 msgstr "ЗобраТСння повідомлСння"
364
364
365 #: templates/boards/settings.html:15
365 #: templates/boards/settings.html:15
366 msgid "You are moderator."
366 msgid "You are moderator."
367 msgstr "Π’ΠΈ ΠΌΠΎΠ΄Π΅Ρ€Π°Ρ‚ΠΎΡ€."
367 msgstr "Π’ΠΈ ΠΌΠΎΠ΄Π΅Ρ€Π°Ρ‚ΠΎΡ€."
368
368
369 #: templates/boards/settings.html:19
369 #: templates/boards/settings.html:19
370 msgid "Hidden tags:"
370 msgid "Hidden tags:"
371 msgstr "ΠŸΡ€ΠΈΡ…ΠΎΠ²Π°Π½Ρ– ΠΌΡ–Ρ‚ΠΊΠΈ:"
371 msgstr "ΠŸΡ€ΠΈΡ…ΠΎΠ²Π°Π½Ρ– ΠΌΡ–Ρ‚ΠΊΠΈ:"
372
372
373 #: templates/boards/settings.html:25
373 #: templates/boards/settings.html:25
374 msgid "No hidden tags."
374 msgid "No hidden tags."
375 msgstr "НСма ΠΏΡ€ΠΈΡ…ΠΎΠ²Π°Π½ΠΈΡ… ΠΌΡ–Ρ‚ΠΎΠΊ."
375 msgstr "НСма ΠΏΡ€ΠΈΡ…ΠΎΠ²Π°Π½ΠΈΡ… ΠΌΡ–Ρ‚ΠΎΠΊ."
376
376
377 #: templates/boards/settings.html:34
377 #: templates/boards/settings.html:34
378 msgid "Save"
378 msgid "Save"
379 msgstr "Π—Π±Π΅Ρ€Π΅Π³Ρ‚ΠΈ"
379 msgstr "Π—Π±Π΅Ρ€Π΅Π³Ρ‚ΠΈ"
380
380
381 #: templates/boards/staticpages/banned.html:6
381 #: templates/boards/staticpages/banned.html:6
382 msgid "Banned"
382 msgid "Banned"
383 msgstr "Π—Π°Π±Π»ΠΎΠΊΠΎΠ²Π°Π½ΠΎ"
383 msgstr "Π—Π°Π±Π»ΠΎΠΊΠΎΠ²Π°Π½ΠΎ"
384
384
385 #: templates/boards/staticpages/banned.html:11
385 #: templates/boards/staticpages/banned.html:11
386 msgid "Your IP address has been banned. Contact the administrator"
386 msgid "Your IP address has been banned. Contact the administrator"
387 msgstr "Π’Π°ΡˆΡƒ IP-адрСсу Π·Π°Π±Π»ΠΎΠΊΠΎΠ²Π°Π½ΠΎ. Π—Π°Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½ΡƒΠΉΡ‚Π΅ Π΄ΠΎ спортлото"
387 msgstr "Π’Π°ΡˆΡƒ IP-адрСсу Π·Π°Π±Π»ΠΎΠΊΠΎΠ²Π°Π½ΠΎ. Π—Π°Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½ΡƒΠΉΡ‚Π΅ Π΄ΠΎ спортлото"
388
388
389 #: templates/boards/staticpages/help.html:6
389 #: templates/boards/staticpages/help.html:6
390 #: templates/boards/staticpages/help.html:10
390 #: templates/boards/staticpages/help.html:10
391 msgid "Syntax"
391 msgid "Syntax"
392 msgstr "Бинтаксис"
392 msgstr "Бинтаксис"
393
393
394 #: templates/boards/staticpages/help.html:11
394 #: templates/boards/staticpages/help.html:11
395 msgid "Italic text"
395 msgid "Italic text"
396 msgstr "ΠšΡƒΡ€ΡΠΈΠ²Π½ΠΈΠΉ тСкст"
396 msgstr "ΠšΡƒΡ€ΡΠΈΠ²Π½ΠΈΠΉ тСкст"
397
397
398 #: templates/boards/staticpages/help.html:12
398 #: templates/boards/staticpages/help.html:12
399 msgid "Bold text"
399 msgid "Bold text"
400 msgstr "Напівогрядний тСкст"
400 msgstr "Напівогрядний тСкст"
401
401
402 #: templates/boards/staticpages/help.html:13
402 #: templates/boards/staticpages/help.html:13
403 msgid "Spoiler"
403 msgid "Spoiler"
404 msgstr "Π‘ΠΏΠΎΠΉΠ»Π΅Ρ€"
404 msgstr "Π‘ΠΏΠΎΠΉΠ»Π΅Ρ€"
405
405
406 #: templates/boards/staticpages/help.html:14
406 #: templates/boards/staticpages/help.html:14
407 msgid "Link to a post"
407 msgid "Link to a post"
408 msgstr "Посилання Π½Π° повідомлСння"
408 msgstr "Посилання Π½Π° повідомлСння"
409
409
410 #: templates/boards/staticpages/help.html:15
410 #: templates/boards/staticpages/help.html:15
411 msgid "Strikethrough text"
411 msgid "Strikethrough text"
412 msgstr "ЗакрСслСний тСкст"
412 msgstr "ЗакрСслСний тСкст"
413
413
414 #: templates/boards/staticpages/help.html:16
414 #: templates/boards/staticpages/help.html:16
415 msgid "Comment"
415 msgid "Comment"
416 msgstr "ΠšΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€"
416 msgstr "ΠšΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€"
417
417
418 #: templates/boards/staticpages/help.html:17
418 #: templates/boards/staticpages/help.html:17
419 #: templates/boards/staticpages/help.html:18
419 #: templates/boards/staticpages/help.html:18
420 msgid "Quote"
420 msgid "Quote"
421 msgstr "Π¦ΠΈΡ‚Π°Ρ‚Π°"
421 msgstr "Π¦ΠΈΡ‚Π°Ρ‚Π°"
422
422
423 #: templates/boards/staticpages/help.html:21
423 #: templates/boards/staticpages/help.html:21
424 msgid "You can try pasting the text and previewing the result here:"
424 msgid "You can try pasting the text and previewing the result here:"
425 msgstr "ΠœΠΎΠΆΠ΅Ρ‚Π΅ спробувати вставити тСкст Ρ– ΠΏΠ΅Ρ€Π΅Π²Ρ–Ρ€ΠΈΡ‚ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚ΡƒΡ‚:"
425 msgstr "ΠœΠΎΠΆΠ΅Ρ‚Π΅ спробувати вставити тСкст Ρ– ΠΏΠ΅Ρ€Π΅Π²Ρ–Ρ€ΠΈΡ‚ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚ΡƒΡ‚:"
426
426
427 #: templates/boards/thread.html:14
427 #: templates/boards/thread.html:14
428 msgid "Normal"
428 msgid "Normal"
429 msgstr "Π—Π²ΠΈΡ‡Π°ΠΉΠ½ΠΈΠΉ"
429 msgstr "Π—Π²ΠΈΡ‡Π°ΠΉΠ½ΠΈΠΉ"
430
430
431 #: templates/boards/thread.html:15
431 #: templates/boards/thread.html:15
432 msgid "Gallery"
432 msgid "Gallery"
433 msgstr "ГалСрСя"
433 msgstr "ГалСрСя"
434
434
435 #: templates/boards/thread.html:16
435 #: templates/boards/thread.html:16
436 msgid "Tree"
436 msgid "Tree"
437 msgstr "Π’Ρ–Π½ΠΈΠΊ"
437 msgstr "Π’Ρ–Π½ΠΈΠΊ"
438
438
439 #: templates/boards/thread.html:35
439 #: templates/boards/thread.html:35
440 msgid "message"
440 msgid "message"
441 msgid_plural "messages"
441 msgid_plural "messages"
442 msgstr[0] "повідомлСння"
442 msgstr[0] "повідомлСння"
443 msgstr[1] "повідомлСння"
443 msgstr[1] "повідомлСння"
444 msgstr[2] "ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ"
444 msgstr[2] "ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ"
445
445
446 #: templates/boards/thread.html:38
446 #: templates/boards/thread.html:38
447 msgid "image"
447 msgid "image"
448 msgid_plural "images"
448 msgid_plural "images"
449 msgstr[0] "зобраТСння"
449 msgstr[0] "зобраТСння"
450 msgstr[1] "зобраТСння"
450 msgstr[1] "зобраТСння"
451 msgstr[2] "Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΡŒ"
451 msgstr[2] "Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΡŒ"
452
452
453 #: templates/boards/thread.html:40
453 #: templates/boards/thread.html:40
454 msgid "Last update: "
454 msgid "Last update: "
455 msgstr "ΠžΡΡ‚Π°Π½Π½Ρ” оновлСння: "
455 msgstr "ΠžΡΡ‚Π°Π½Π½Ρ” оновлСння: "
456
456
457 #: templates/boards/thread_gallery.html:36
457 #: templates/boards/thread_gallery.html:36
458 msgid "No images."
458 msgid "No images."
459 msgstr "НСма Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΡŒ."
459 msgstr "НСма Π·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΡŒ."
460
460
461 #: templates/boards/thread_normal.html:30
461 #: templates/boards/thread_normal.html:30
462 msgid "posts to bumplimit"
462 msgid "posts to bumplimit"
463 msgstr "ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ Π΄ΠΎ бамплямату"
463 msgstr "ΠΏΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ Π΄ΠΎ бамплямату"
464
464
465 #: templates/boards/thread_normal.html:44
465 #: templates/boards/thread_normal.html:44
466 msgid "Reply to thread"
466 msgid "Reply to thread"
467 msgstr "Відповісти Π΄ΠΎ Π½ΠΈΡ‚ΠΊΠΈ"
467 msgstr "Відповісти Π΄ΠΎ Π½ΠΈΡ‚ΠΊΠΈ"
468
468
469 #: templates/boards/thread_normal.html:44
469 #: templates/boards/thread_normal.html:44
470 msgid "to message "
470 msgid "to message "
471 msgstr "Π½Π° повідомлСння"
471 msgstr "Π½Π° повідомлСння"
472
472
473 #: templates/boards/thread_normal.html:59
473 #: templates/boards/thread_normal.html:59
474 msgid "Reset form"
474 msgid "Reset form"
475 msgstr "Π‘ΠΊΠΈΠ½ΡƒΡ‚ΠΈ Ρ„ΠΎΡ€ΠΌΡƒ"
475 msgstr "Π‘ΠΊΠΈΠ½ΡƒΡ‚ΠΈ Ρ„ΠΎΡ€ΠΌΡƒ"
476
476
477 #: templates/search/search.html:17
477 #: templates/search/search.html:17
478 msgid "Ok"
478 msgid "Ok"
479 msgstr "Π€Π°ΠΉΠ½ΠΎ"
479 msgstr "Π€Π°ΠΉΠ½ΠΎ"
480
480
481 #: utils.py:120
481 #: utils.py:120
482 #, python-format
482 #, python-format
483 msgid "File must be less than %s but is %s."
483 msgid "Total file size must be less than %s but is %s."
484 msgstr "Π€Π°ΠΉΠ» ΠΌΡƒΡΠΈΡ‚ΡŒ Π±ΡƒΡ‚ΠΈ мСншС %s, Π°Π»Π΅ ΠΉΠΎΠ³ΠΎ Ρ€ΠΎΠ·ΠΌΡ–Ρ€ %s."
484 msgstr "Π—Π°Π³Π°Π»ΡŒΠ½ΠΈΠΉ Ρ€ΠΎΠ·ΠΌΡ–Ρ€ Ρ„Π°ΠΉΠ»Ρ–Π² ΠΌΡƒΡΠΈΡ‚ΡŒ Π±ΡƒΡ‚ΠΈ мСншС %s, Π°Π»Π΅ Ρ” %s."
485
485
486 msgid "Please wait %(delay)d second before sending message"
486 msgid "Please wait %(delay)d second before sending message"
487 msgid_plural "Please wait %(delay)d seconds before sending message"
487 msgid_plural "Please wait %(delay)d seconds before sending message"
488 msgstr[0] "Π—Π°Ρ‡Π΅ΠΊΠ°ΠΉΡ‚Π΅, Π±ΡƒΠ΄ΡŒ ласка, %(delay)d сСкунду ΠΏΠ΅Ρ€Π΅Π΄ надсиланням повідомлСння"
488 msgstr[0] "Π—Π°Ρ‡Π΅ΠΊΠ°ΠΉΡ‚Π΅, Π±ΡƒΠ΄ΡŒ ласка, %(delay)d сСкунду ΠΏΠ΅Ρ€Π΅Π΄ надсиланням повідомлСння"
489 msgstr[1] "Π—Π°Ρ‡Π΅ΠΊΠ°ΠΉΡ‚Π΅, Π±ΡƒΠ΄ΡŒ ласка, %(delay)d сСкунди ΠΏΠ΅Ρ€Π΅Π΄ надсиланням повідомлСння"
489 msgstr[1] "Π—Π°Ρ‡Π΅ΠΊΠ°ΠΉΡ‚Π΅, Π±ΡƒΠ΄ΡŒ ласка, %(delay)d сСкунди ΠΏΠ΅Ρ€Π΅Π΄ надсиланням повідомлСння"
490 msgstr[2] "Π—Π°Ρ‡Π΅ΠΊΠ°ΠΉΡ‚Π΅, Π±ΡƒΠ΄ΡŒ ласка, %(delay)d сСкунд ΠΏΠ΅Ρ€Π΅Π΄ надсиланням повідомлСння"
490 msgstr[2] "Π—Π°Ρ‡Π΅ΠΊΠ°ΠΉΡ‚Π΅, Π±ΡƒΠ΄ΡŒ ласка, %(delay)d сСкунд ΠΏΠ΅Ρ€Π΅Π΄ надсиланням повідомлСння"
491
491
492 msgid "New threads"
492 msgid "New threads"
493 msgstr "Нові Π½ΠΈΡ‚ΠΊΠΈ"
493 msgstr "Нові Π½ΠΈΡ‚ΠΊΠΈ"
494
494
495 #, python-format
495 #, python-format
496 msgid "Max file size is %(size)s."
496 msgid "Max total file size is %(size)s."
497 msgstr "Максимальний Ρ€ΠΎΠ·ΠΌΡ–Ρ€ Ρ„Π°ΠΉΠ»Ρƒ %(size)s."
497 msgstr "Максимальний загальний Ρ€ΠΎΠ·ΠΌΡ–Ρ€ Ρ„Π°ΠΉΠ»Ρ–Π² %(size)s."
498
498
499 msgid "Size of media:"
499 msgid "Size of media:"
500 msgstr "Π ΠΎΠ·ΠΌΡ–Ρ€ посСрСдника:"
500 msgstr "Π ΠΎΠ·ΠΌΡ–Ρ€ посСрСдника:"
501
501
502 msgid "Statistics"
502 msgid "Statistics"
503 msgstr "Бтатистика"
503 msgstr "Бтатистика"
504
504
505 msgid "Invalid PoW."
505 msgid "Invalid PoW."
506 msgstr "Π₯ΠΈΠ±Π½ΠΈΠΉ PoW."
506 msgstr "Π₯ΠΈΠ±Π½ΠΈΠΉ PoW."
507
507
508 msgid "Stale PoW."
508 msgid "Stale PoW."
509 msgstr "PoW застарів."
509 msgstr "PoW застарів."
510
510
511 msgid "Show"
511 msgid "Show"
512 msgstr "ΠŸΠΎΠΊΠ°Π·ΡƒΠ²Π°Ρ‚ΠΈ"
512 msgstr "ΠŸΠΎΠΊΠ°Π·ΡƒΠ²Π°Ρ‚ΠΈ"
513
513
514 msgid "Hide"
514 msgid "Hide"
515 msgstr "Π₯ΠΎΠ²Π°Ρ‚ΠΈ"
515 msgstr "Π₯ΠΎΠ²Π°Ρ‚ΠΈ"
516
516
517 msgid "Add to favorites"
517 msgid "Add to favorites"
518 msgstr "Π― Ρ†Π΅ люблю"
518 msgstr "Π― Ρ†Π΅ люблю"
519
519
520 msgid "Remove from favorites"
520 msgid "Remove from favorites"
521 msgstr "Π’ΠΆΠ΅ Π½Π΅ люблю"
521 msgstr "Π’ΠΆΠ΅ Π½Π΅ люблю"
522
522
523 msgid "Monochrome"
523 msgid "Monochrome"
524 msgstr "Π‘Π΅Π· Π±Π°Ρ€Π²"
524 msgstr "Π‘Π΅Π· Π±Π°Ρ€Π²"
525
525
526 msgid "Subsections: "
526 msgid "Subsections: "
527 msgstr "ΠŸΡ–Π΄Ρ€ΠΎΠ·Π΄Ρ–Π»ΠΈ: "
527 msgstr "ΠŸΡ–Π΄Ρ€ΠΎΠ·Π΄Ρ–Π»ΠΈ: "
528
528
529 msgid "Change file source"
529 msgid "Change file source"
530 msgstr "Π—ΠΌΡ–Π½ΠΈΡ‚ΠΈ Π΄ΠΆΠ΅Ρ€Π΅Π»ΠΎ Ρ„Π°ΠΉΠ»Ρƒ"
530 msgstr "Π—ΠΌΡ–Π½ΠΈΡ‚ΠΈ Π΄ΠΆΠ΅Ρ€Π΅Π»ΠΎ Ρ„Π°ΠΉΠ»Ρƒ"
531
531
532 msgid "interesting"
532 msgid "interesting"
533 msgstr "Ρ†Ρ–ΠΊΠ°Π²Π΅"
533 msgstr "Ρ†Ρ–ΠΊΠ°Π²Π΅"
534
534
535 msgid "images"
535 msgid "images"
536 msgstr "ΠΏΡ–Ρ‡ΠΊΡƒΡ€ΠΈ"
536 msgstr "ΠΏΡ–Ρ‡ΠΊΡƒΡ€ΠΈ"
537
537
538 msgid "Delete post"
538 msgid "Delete post"
539 msgstr "Π’ΠΈΠ΄Π°Π»ΠΈΡ‚ΠΈ повідомлСння"
539 msgstr "Π’ΠΈΠ΄Π°Π»ΠΈΡ‚ΠΈ повідомлСння"
540
540
541 msgid "Delete thread"
541 msgid "Delete thread"
542 msgstr "Π’ΠΈΡ€Π²Π°Ρ‚ΠΈ Π½ΠΈΡ‚ΠΊΡƒ"
542 msgstr "Π’ΠΈΡ€Π²Π°Ρ‚ΠΈ Π½ΠΈΡ‚ΠΊΡƒ"
543
543
544 msgid "Messages per day/week/month:"
544 msgid "Messages per day/week/month:"
545 msgstr "ΠŸΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ Π·Π° дСнь/Ρ‚ΠΈΠΆΠ΄Π΅Π½ΡŒ/Ρ‚ΠΈΠΆΠΌΡ–ΡΡΡ†ΡŒ:"
545 msgstr "ΠŸΠΎΠ²Ρ–Π΄ΠΎΠΌΠ»Π΅Π½ΡŒ Π·Π° дСнь/Ρ‚ΠΈΠΆΠ΄Π΅Π½ΡŒ/Ρ‚ΠΈΠΆΠΌΡ–ΡΡΡ†ΡŒ:"
546
546
547 msgid "Subscribe to thread"
547 msgid "Subscribe to thread"
548 msgstr "Π‘Ρ‚Π΅ΠΆΠΈΡ‚ΠΈ Π·Π° Π½ΠΈΡ‚ΠΊΠΎΡŽ"
548 msgstr "Π‘Ρ‚Π΅ΠΆΠΈΡ‚ΠΈ Π·Π° Π½ΠΈΡ‚ΠΊΠΎΡŽ"
549
549
550 msgid "Active threads:"
550 msgid "Active threads:"
551 msgstr "Активні Π½ΠΈΡ‚ΠΊΠΈ:"
551 msgstr "Активні Π½ΠΈΡ‚ΠΊΠΈ:"
552
552
553 msgid "No active threads today."
553 msgid "No active threads today."
554 msgstr "Щось усі Π·Π°ΠΌΠΎΠ²ΠΊΠ»ΠΈ."
554 msgstr "Щось усі Π·Π°ΠΌΠΎΠ²ΠΊΠ»ΠΈ."
555
555
556 msgid "Insert URLs on separate lines."
556 msgid "Insert URLs on separate lines."
557 msgstr "ВставляйтС посилання ΠΎΠΊΡ€Π΅ΠΌΠΈΠΌΠΈ рядками."
557 msgstr "ВставляйтС посилання ΠΎΠΊΡ€Π΅ΠΌΠΈΠΌΠΈ рядками."
558
558
559 msgid "You can post no more than %(files)d file."
559 msgid "You can post no more than %(files)d file."
560 msgid_plural "You can post no more than %(files)d files."
560 msgid_plural "You can post no more than %(files)d files."
561 msgstr[0] "Π’ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ надіслати Π½Π΅ Π±Ρ–Π»ΡŒΡˆΠ΅ %(files)d Ρ„Π°ΠΉΠ»Ρƒ."
561 msgstr[0] "Π’ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ надіслати Π½Π΅ Π±Ρ–Π»ΡŒΡˆΠ΅ %(files)d Ρ„Π°ΠΉΠ»Ρƒ."
562 msgstr[1] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ надіслати Π½Π΅ Π±Ρ–Π»ΡŒΡˆΠ΅ %(files)d Ρ„Π°ΠΉΠ»Ρ–Π²."
562 msgstr[1] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ надіслати Π½Π΅ Π±Ρ–Π»ΡŒΡˆΠ΅ %(files)d Ρ„Π°ΠΉΠ»Ρ–Π²."
563 msgstr[2] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ надіслати Π½Π΅ Π±Ρ–Π»ΡŒΡˆΠ΅ %(files)d Ρ„Π°ΠΉΠ»Ρ–Π²."
563 msgstr[2] "Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ надіслати Π½Π΅ Π±Ρ–Π»ΡŒΡˆΠ΅ %(files)d Ρ„Π°ΠΉΠ»Ρ–Π²."
564
564
565 #, python-format
565 #, python-format
566 msgid "Max file number is %(max_files)s."
566 msgid "Max file number is %(max_files)s."
567 msgstr "Максимальна ΠΊΡ–Π»ΡŒΠΊΡ–ΡΡ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ–Π² %(max_files)s."
567 msgstr "Максимальна ΠΊΡ–Π»ΡŒΠΊΡ–ΡΡ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ–Π² %(max_files)s."
568
568
569 msgid "Moderation"
569 msgid "Moderation"
570 msgstr "ΠœΠΎΠ΄Π΅Ρ€Π°Ρ†Ρ–Ρ"
570 msgstr "ΠœΠΎΠ΄Π΅Ρ€Π°Ρ†Ρ–Ρ"
571
571
572 msgid "Check for duplicates"
572 msgid "Check for duplicates"
573 msgstr "ΠŸΠ΅Ρ€Π΅Π²Ρ–Ρ€ΡΡ‚ΠΈ Π½Π° Π΄ΡƒΠ±Π»Ρ–ΠΊΠ°Ρ‚ΠΈ"
573 msgstr "ΠŸΠ΅Ρ€Π΅Π²Ρ–Ρ€ΡΡ‚ΠΈ Π½Π° Π΄ΡƒΠ±Π»Ρ–ΠΊΠ°Ρ‚ΠΈ"
574
574
575 msgid "Some files are already present on the board."
575 msgid "Some files are already present on the board."
576 msgstr "ДСякі Ρ„Π°ΠΉΠ»ΠΈ Π²ΠΆΠ΅ Ρ” Π½Π° Π΄ΠΎΡˆΡ†Ρ–."
576 msgstr "ДСякі Ρ„Π°ΠΉΠ»ΠΈ Π²ΠΆΠ΅ Ρ” Π½Π° Π΄ΠΎΡˆΡ†Ρ–."
577
577
578 msgid "Do not download URLs"
578 msgid "Do not download URLs"
579 msgstr "НС Π·Π°Π²Π°Π½Ρ‚Π°ΠΆΡƒΠ²Π°Ρ‚ΠΈ посилання"
579 msgstr "НС Π·Π°Π²Π°Π½Ρ‚Π°ΠΆΡƒΠ²Π°Ρ‚ΠΈ посилання"
580
580
581 msgid "Ban and delete"
581 msgid "Ban and delete"
582 msgstr "Π—Π°Π±Π»ΠΎΠΊΡƒΠ²Π°Ρ‚ΠΈ ΠΉ Π²ΠΈΠ΄Π°Π»ΠΈΡ‚ΠΈ"
582 msgstr "Π—Π°Π±Π»ΠΎΠΊΡƒΠ²Π°Ρ‚ΠΈ ΠΉ Π²ΠΈΠ΄Π°Π»ΠΈΡ‚ΠΈ"
583
583
584 msgid "Are you sure?"
584 msgid "Are you sure?"
585 msgstr "Π§ΠΈ Π²ΠΈ ΠΏΠ΅Π²Π½Ρ–?"
585 msgstr "Π§ΠΈ Π²ΠΈ ΠΏΠ΅Π²Π½Ρ–?"
586
586
587 msgid "Ban"
587 msgid "Ban"
588 msgstr "Π—Π°Π±Π»ΠΎΠΊΡƒΠ²Π°Ρ‚ΠΈ"
588 msgstr "Π—Π°Π±Π»ΠΎΠΊΡƒΠ²Π°Ρ‚ΠΈ"
589
589
590 msgid "File process mode"
590 msgid "File process mode"
591 msgstr "Π Π΅ΠΆΠΈΠΌ ΠΎΠ±Ρ€ΠΎΠ±ΠΊΠΈ Ρ„Π°ΠΉΠ»Ρ–Π²"
591 msgstr "Π Π΅ΠΆΠΈΠΌ ΠΎΠ±Ρ€ΠΎΠ±ΠΊΠΈ Ρ„Π°ΠΉΠ»Ρ–Π²"
592
592
593 msgid "Download or insert as URLs"
593 msgid "Download or insert as URLs"
594 msgstr "Π—Π°Π²Π°Π½Ρ‚Π°ΠΆΠΈΡ‚ΠΈ Π°Π±ΠΎ вставити як посилання"
594 msgstr "Π—Π°Π²Π°Π½Ρ‚Π°ΠΆΠΈΡ‚ΠΈ Π°Π±ΠΎ вставити як посилання"
595
595
596 msgid "Download"
596 msgid "Download"
597 msgstr "Π—Π°Π²Π°Π½Ρ‚Π°ΠΆΠΈΡ‚ΠΈ"
597 msgstr "Π—Π°Π²Π°Π½Ρ‚Π°ΠΆΠΈΡ‚ΠΈ"
598
598
599 msgid "Download and check for uniqueness"
599 msgid "Download and check for uniqueness"
600 msgstr "Π—Π°Π²Π°Π½Ρ‚Π°ΠΆΠΈΡ‚ΠΈ Ρ‚Π° ΠΏΠ΅Ρ€Π΅Π²Ρ–Ρ€ΠΈΡ‚ΠΈ Π½Π° ΡƒΠ½Ρ–ΠΊΠ°Π»ΡŒΠ½Ρ–ΡΡ‚ΡŒ"
600 msgstr "Π—Π°Π²Π°Π½Ρ‚Π°ΠΆΠΈΡ‚ΠΈ Ρ‚Π° ΠΏΠ΅Ρ€Π΅Π²Ρ–Ρ€ΠΈΡ‚ΠΈ Π½Π° ΡƒΠ½Ρ–ΠΊΠ°Π»ΡŒΠ½Ρ–ΡΡ‚ΡŒ"
601
601
602 msgid "Insert as URLs"
602 msgid "Insert as URLs"
603 msgstr "Вставити як посилання"
603 msgstr "Вставити як посилання"
604
604
605 msgid "Help"
605 msgid "Help"
606 msgstr "Π‘ΠΏΡ€Π°Π²ΠΊΠ°"
606 msgstr "Π‘ΠΏΡ€Π°Π²ΠΊΠ°"
607
607
608 msgid "View available stickers:"
608 msgid "View available stickers:"
609 msgstr "ΠŸΠ΅Ρ€Π΅Π΄ΠΈΠ²ΠΈΡ‚ΠΈΡΡ доступні стікСри:"
609 msgstr "ΠŸΠ΅Ρ€Π΅Π΄ΠΈΠ²ΠΈΡ‚ΠΈΡΡ доступні стікСри:"
610
610
611 msgid "Stickers"
611 msgid "Stickers"
612 msgstr "Π‘Ρ‚Ρ–ΠΊΠ΅Ρ€ΠΈ"
612 msgstr "Π‘Ρ‚Ρ–ΠΊΠ΅Ρ€ΠΈ"
613
613
614 msgid "Available by addresses:"
614 msgid "Available by addresses:"
615 msgstr "Доступно Π·Π° адрСсами:"
615 msgstr "Доступно Π·Π° адрСсами:"
616
616
617 msgid "Local stickers"
617 msgid "Local stickers"
618 msgstr "Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ– стікСри"
618 msgstr "Π›ΠΎΠΊΠ°Π»ΡŒΠ½Ρ– стікСри"
619
619
620 msgid "Global stickers"
620 msgid "Global stickers"
621 msgstr "Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ– стікСри"
621 msgstr "Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ– стікСри"
622
622
623 msgid "Remove sticker"
623 msgid "Remove sticker"
624 msgstr "Π’ΠΈΠ΄Π°Π»ΠΈΡ‚ΠΈ стікСр"
624 msgstr "Π’ΠΈΠ΄Π°Π»ΠΈΡ‚ΠΈ стікСр"
625
625
626 msgid "Sticker Pack"
626 msgid "Sticker Pack"
627 msgstr "Набір Π‘Ρ‚Ρ–ΠΊΠ΅Ρ€Ρ–Π²"
627 msgstr "Набір Π‘Ρ‚Ρ–ΠΊΠ΅Ρ€Ρ–Π²"
628
628
629 msgid "Tripcode should be specified to own a stickerpack."
629 msgid "Tripcode should be specified to own a stickerpack."
630 msgstr "Для володіння Π½Π°Π±ΠΎΡ€ΠΎΠΌ стікСрів Π½Π΅ΠΎΠ±Ρ…Ρ–Π΄Π½ΠΎ Π²ΠΊΠ°Π·Π°Ρ‚ΠΈ Ρ‚Ρ€Ρ–ΠΏΠΊΠΎΠ΄."
630 msgstr "Для володіння Π½Π°Π±ΠΎΡ€ΠΎΠΌ стікСрів Π½Π΅ΠΎΠ±Ρ…Ρ–Π΄Π½ΠΎ Π²ΠΊΠ°Π·Π°Ρ‚ΠΈ Ρ‚Ρ€Ρ–ΠΏΠΊΠΎΠ΄."
631
631
632 msgid "Title should be specified as a stickerpack name."
632 msgid "Title should be specified as a stickerpack name."
633 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΏΠΎΠ²ΠΈΠ½Π΅Π½ Π±ΡƒΡ‚ΠΈ Π²ΠΊΠ°Π·Π°Π½ΠΈΠΉ Π² якості Ρ–ΠΌΠ΅Π½Ρ– Π½Π°Π±ΠΎΡ€Ρƒ стікСрів."
633 msgstr "Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΏΠΎΠ²ΠΈΠ½Π΅Π½ Π±ΡƒΡ‚ΠΈ Π²ΠΊΠ°Π·Π°Π½ΠΈΠΉ Π² якості Ρ–ΠΌΠ΅Π½Ρ– Π½Π°Π±ΠΎΡ€Ρƒ стікСрів."
634
634
635 msgid "A sticker pack with this name already exists and is owned by another tripcode."
635 msgid "A sticker pack with this name already exists and is owned by another tripcode."
636 msgstr "Набір стікСрів Π· Π²ΠΊΠ°Π·Π°Π½ΠΈΠΌ Ρ–ΠΌΠ΅Π½Π΅ΠΌ Π²ΠΆΠ΅ Ρ” Π² наявності Ρ‚Π° Π½Π°Π»Π΅ΠΆΠΈΡ‚ΡŒ Ρ–Π½ΡˆΠΎΠΌΡƒ Ρ‚Ρ€Ρ–ΠΏΠΊΠΎΠ΄Ρƒ."
636 msgstr "Набір стікСрів Π· Π²ΠΊΠ°Π·Π°Π½ΠΈΠΌ Ρ–ΠΌΠ΅Π½Π΅ΠΌ Π²ΠΆΠ΅ Ρ” Π² наявності Ρ‚Π° Π½Π°Π»Π΅ΠΆΠΈΡ‚ΡŒ Ρ–Π½ΡˆΠΎΠΌΡƒ Ρ‚Ρ€Ρ–ΠΏΠΊΠΎΠ΄Ρƒ."
637
637
638 msgid "This sticker pack can only be updated by an administrator."
638 msgid "This sticker pack can only be updated by an administrator."
639 msgstr "Π¦Π΅ΠΉ Π½Π°Π±Ρ–Ρ€ стікСрів ΠΌΠΎΠΆΠ΅ Π±ΡƒΡ‚ΠΈ Π·ΠΌΡ–Π½Π΅Π½ΠΈΠΉ лишС адміністратором."
639 msgstr "Π¦Π΅ΠΉ Π½Π°Π±Ρ–Ρ€ стікСрів ΠΌΠΎΠΆΠ΅ Π±ΡƒΡ‚ΠΈ Π·ΠΌΡ–Π½Π΅Π½ΠΈΠΉ лишС адміністратором."
640
640
641 msgid "To add a sticker, create a stickerpack thread using the title as a pack name, and a tripcode to own the pack. Then, add posts with title as a sticker name, and the same tripcode, to the thread. Their attachments would become stickers."
641 msgid "To add a sticker, create a stickerpack thread using the title as a pack name, and a tripcode to own the pack. Then, add posts with title as a sticker name, and the same tripcode, to the thread. Their attachments would become stickers."
642 msgstr "Π©ΠΎΠ± Π΄ΠΎΠ΄Π°Ρ‚ΠΈ стікСр, ΡΡ‚Π²ΠΎΡ€Ρ–Ρ‚ΡŒ Ρ‚Π΅ΠΌΡƒ-Π½Π°Π±Ρ–Ρ€ Π· Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ Ρƒ якості Π½Π°Π±ΠΎΡ€Ρƒ стікСрів, Ρ‚Π° Ρ‚Ρ€Ρ–ΠΏΠΊΠΎΠ΄ΠΎΠΌ для підтвСрдТСння володіння Π½Π°Π±ΠΎΡ€ΠΎΠΌΡ‚. ΠŸΠΎΡ‚Ρ–ΠΌ, Π΄ΠΎΠ΄Π°Π²Π°ΠΉΡ‚Π΅ повідомлСння Π· Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ Ρƒ якості Ρ–ΠΌΠ΅Π½Ρ– стікСру Ρ‚Π° Π· Ρ‚ΠΈΠΌ самим Ρ‚Ρ€Ρ–ΠΏΠΊΠΎΠ΄ΠΎΠΌ. Π‡Ρ…Π½Ρ– вкладСння станут стікСрами."
642 msgstr "Π©ΠΎΠ± Π΄ΠΎΠ΄Π°Ρ‚ΠΈ стікСр, ΡΡ‚Π²ΠΎΡ€Ρ–Ρ‚ΡŒ Ρ‚Π΅ΠΌΡƒ-Π½Π°Π±Ρ–Ρ€ Π· Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ Ρƒ якості Π½Π°Π±ΠΎΡ€Ρƒ стікСрів, Ρ‚Π° Ρ‚Ρ€Ρ–ΠΏΠΊΠΎΠ΄ΠΎΠΌ для підтвСрдТСння володіння Π½Π°Π±ΠΎΡ€ΠΎΠΌΡ‚. ΠŸΠΎΡ‚Ρ–ΠΌ, Π΄ΠΎΠ΄Π°Π²Π°ΠΉΡ‚Π΅ повідомлСння Π· Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ Ρƒ якості Ρ–ΠΌΠ΅Π½Ρ– стікСру Ρ‚Π° Π· Ρ‚ΠΈΠΌ самим Ρ‚Ρ€Ρ–ΠΏΠΊΠΎΠ΄ΠΎΠΌ. Π‡Ρ…Π½Ρ– вкладСння станут стікСрами."
643
643
644 msgid "Inappropriate sticker pack name."
644 msgid "Inappropriate sticker pack name."
645 msgstr "НСприпустимС Ρ–ΠΌ'я Π½Π°Π±ΠΎΡ€Ρƒ стікСрів."
645 msgstr "НСприпустимС Ρ–ΠΌ'я Π½Π°Π±ΠΎΡ€Ρƒ стікСрів."
@@ -1,210 +1,210 b''
1 {% extends "boards/paginated.html" %}
1 {% extends "boards/paginated.html" %}
2
2
3 {% load i18n %}
3 {% load i18n %}
4 {% load board %}
4 {% load board %}
5 {% load static %}
5 {% load static %}
6 {% load tz %}
6 {% load tz %}
7
7
8 {% block head %}
8 {% block head %}
9 <meta name="robots" content="noindex">
9 <meta name="robots" content="noindex">
10
10
11 {% if tag %}
11 {% if tag %}
12 <title>{{ tag.get_localized_name }} - {{ site_name }}</title>
12 <title>{{ tag.get_localized_name }} - {{ site_name }}</title>
13 {% else %}
13 {% else %}
14 <title>{{ site_name }}</title>
14 <title>{{ site_name }}</title>
15 {% endif %}
15 {% endif %}
16
16
17 {% if prev_page_link %}
17 {% if prev_page_link %}
18 <link rel="prev" href="{{ prev_page_link|safe }}" />
18 <link rel="prev" href="{{ prev_page_link|safe }}" />
19 {% endif %}
19 {% endif %}
20 {% if next_page_link %}
20 {% if next_page_link %}
21 <link rel="next" href="{{ next_page_link|safe }}" />
21 <link rel="next" href="{{ next_page_link|safe }}" />
22 {% endif %}
22 {% endif %}
23
23
24 {% endblock %}
24 {% endblock %}
25
25
26 {% block content %}
26 {% block content %}
27
27
28 {% get_current_language as LANGUAGE_CODE %}
28 {% get_current_language as LANGUAGE_CODE %}
29 {% get_current_timezone as TIME_ZONE %}
29 {% get_current_timezone as TIME_ZONE %}
30
30
31 {% for banner in banners %}
31 {% for banner in banners %}
32 <div class="post">
32 <div class="post">
33 <div class="title">{{ banner.title }}</div>
33 <div class="title">{{ banner.title }}</div>
34 <div>{{ banner.get_text|safe }}</div>
34 <div>{{ banner.get_text|safe }}</div>
35 <div>{% trans 'Details' %}: <a href="{{ banner.post.get_absolute_url|safe }}">>>{{ banner.post.id }}</a></div>
35 <div>{% trans 'Details' %}: <a href="{{ banner.post.get_absolute_url|safe }}">>>{{ banner.post.id }}</a></div>
36 </div>
36 </div>
37 {% endfor %}
37 {% endfor %}
38
38
39 {% if tag %}
39 {% if tag %}
40 <div class="tag_info" style="border-bottom: solid .5ex #{{ tag.get_color }}">
40 <div class="tag_info" style="border-bottom: solid .5ex #{{ tag.get_color }}">
41 {% if random_image_post %}
41 {% if random_image_post %}
42 <div class="tag-image">
42 <div class="tag-image">
43 {% with image=random_image_post.get_first_image %}
43 {% with image=random_image_post.get_first_image %}
44 <a href="{{ random_image_post.get_absolute_url|safe }}"><img
44 <a href="{{ random_image_post.get_absolute_url|safe }}"><img
45 src="{{ image.get_thumb_url|safe }}"
45 src="{{ image.get_thumb_url|safe }}"
46 width="{{ image.get_preview_size.0 }}"
46 width="{{ image.get_preview_size.0 }}"
47 height="{{ image.get_preview_size.1 }}"
47 height="{{ image.get_preview_size.1 }}"
48 alt="{{ random_image_post.id }}"/></a>
48 alt="{{ random_image_post.id }}"/></a>
49 {% endwith %}
49 {% endwith %}
50 </div>
50 </div>
51 {% endif %}
51 {% endif %}
52 <div class="tag-text-data">
52 <div class="tag-text-data">
53 <h2>
53 <h2>
54 /{{ tag.get_view|safe }}/
54 /{{ tag.get_view|safe }}/
55 </h2>
55 </h2>
56 {% if perms.change_tag %}
56 {% if perms.change_tag %}
57 <div class="moderator_info"><a href="{% url 'admin:boards_tag_change' tag.id %}">{% trans 'Edit tag' %}</a></div>
57 <div class="moderator_info"><a href="{% url 'admin:boards_tag_change' tag.id %}">{% trans 'Edit tag' %}</a></div>
58 {% endif %}
58 {% endif %}
59 <p>
59 <p>
60 <form action="{% url 'tag' tag.get_name %}" method="post" class="post-button-form">
60 <form action="{% url 'tag' tag.get_name %}" method="post" class="post-button-form">
61 {% if is_favorite %}
61 {% if is_favorite %}
62 <button name="method" value="unsubscribe" class="fav">β˜… {% trans "Remove from favorites" %}</button>
62 <button name="method" value="unsubscribe" class="fav">β˜… {% trans "Remove from favorites" %}</button>
63 {% else %}
63 {% else %}
64 <button name="method" value="subscribe" class="not_fav">β˜… {% trans "Add to favorites" %}</button>
64 <button name="method" value="subscribe" class="not_fav">β˜… {% trans "Add to favorites" %}</button>
65 {% endif %}
65 {% endif %}
66 </form>
66 </form>
67 &bull;
67 &bull;
68 <form action="{% url 'tag' tag.get_name %}" method="post" class="post-button-form">
68 <form action="{% url 'tag' tag.get_name %}" method="post" class="post-button-form">
69 {% if is_hidden %}
69 {% if is_hidden %}
70 <button name="method" value="unhide" class="fav">{% trans "Show" %}</button>
70 <button name="method" value="unhide" class="fav">{% trans "Show" %}</button>
71 {% else %}
71 {% else %}
72 <button name="method" value="hide" class="not_fav">{% trans "Hide" %}</button>
72 <button name="method" value="hide" class="not_fav">{% trans "Hide" %}</button>
73 {% endif %}
73 {% endif %}
74 </form>
74 </form>
75 &bull;
75 &bull;
76 <a href="{% url 'tag_gallery' tag.get_name %}">{% trans 'Gallery' %}</a>
76 <a href="{% url 'tag_gallery' tag.get_name %}">{% trans 'Gallery' %}</a>
77 </p>
77 </p>
78 {% if tag.get_description %}
78 {% if tag.get_description %}
79 <p>{{ tag.get_description|safe }}</p>
79 <p>{{ tag.get_description|safe }}</p>
80 {% endif %}
80 {% endif %}
81 <p>
81 <p>
82 {% with active_count=tag.get_active_thread_count bumplimit_count=tag.get_bumplimit_thread_count archived_count=tag.get_archived_thread_count %}
82 {% with active_count=tag.get_active_thread_count bumplimit_count=tag.get_bumplimit_thread_count archived_count=tag.get_archived_thread_count %}
83 {% if active_count %}
83 {% if active_count %}
84 ● {{ active_count }}&ensp;
84 ● {{ active_count }}&ensp;
85 {% endif %}
85 {% endif %}
86 {% if bumplimit_count %}
86 {% if bumplimit_count %}
87 ◍ {{ bumplimit_count }}&ensp;
87 ◍ {{ bumplimit_count }}&ensp;
88 {% endif %}
88 {% endif %}
89 {% if archived_count %}
89 {% if archived_count %}
90 β—‹ {{ archived_count }}&ensp;
90 β—‹ {{ archived_count }}&ensp;
91 {% endif %}
91 {% endif %}
92 {% endwith %}
92 {% endwith %}
93 β™₯ {{ tag.get_post_count }}
93 β™₯ {{ tag.get_post_count }}
94 </p>
94 </p>
95 {% if tag.get_all_parents %}
95 {% if tag.get_all_parents %}
96 <p>
96 <p>
97 {% for parent in tag.get_all_parents %}
97 {% for parent in tag.get_all_parents %}
98 {{ parent.get_view|safe }} &gt;
98 {{ parent.get_view|safe }} &gt;
99 {% endfor %}
99 {% endfor %}
100 {{ tag.get_view|safe }}
100 {{ tag.get_view|safe }}
101 </p>
101 </p>
102 {% endif %}
102 {% endif %}
103 {% if tag.get_children.all %}
103 {% if tag.get_children.all %}
104 <p>
104 <p>
105 {% trans "Subsections: " %}
105 {% trans "Subsections: " %}
106 {% for child in tag.get_children.all %}
106 {% for child in tag.get_children.all %}
107 {{ child.get_view|safe }}{% if not forloop.last%}, {% endif %}
107 {{ child.get_view|safe }}{% if not forloop.last%}, {% endif %}
108 {% endfor %}
108 {% endfor %}
109 </p>
109 </p>
110 {% endif %}
110 {% endif %}
111 </div>
111 </div>
112 </div>
112 </div>
113 {% endif %}
113 {% endif %}
114
114
115 {% if threads %}
115 {% if threads %}
116 {% if prev_page_link %}
116 {% if prev_page_link %}
117 <div class="page_link">
117 <div class="page_link">
118 <a href="{{ prev_page_link }}">&lt;&lt; {% trans "Previous page" %} &lt;&lt;</a>
118 <a href="{{ prev_page_link }}">&lt;&lt; {% trans "Previous page" %} &lt;&lt;</a>
119 </div>
119 </div>
120 {% endif %}
120 {% endif %}
121
121
122 {% for thread in threads %}
122 {% for thread in threads %}
123 <div class="thread">
123 <div class="thread">
124 {% post_view thread.get_opening_post thread=thread truncated=True need_open_link=True %}
124 {% post_view thread.get_opening_post thread=thread truncated=True need_open_link=True %}
125 {% if not thread.archived %}
125 {% if not thread.archived %}
126 {% with last_replies=thread.get_last_replies %}
126 {% with last_replies=thread.get_last_replies %}
127 {% if last_replies %}
127 {% if last_replies %}
128 {% with skipped_replies_count=thread.get_skipped_replies_count %}
128 {% with skipped_replies_count=thread.get_skipped_replies_count %}
129 {% if skipped_replies_count %}
129 {% if skipped_replies_count %}
130 <div class="skipped_replies">
130 <div class="skipped_replies">
131 <a href="{% url 'thread' thread.get_opening_post_id %}">
131 <a href="{% url 'thread' thread.get_opening_post_id %}">
132 {% blocktrans count count=skipped_replies_count %}Skipped {{ count }} reply. Open thread to see all replies.{% plural %}Skipped {{ count }} replies. Open thread to see all replies.{% endblocktrans %}
132 {% blocktrans count count=skipped_replies_count %}Skipped {{ count }} reply. Open thread to see all replies.{% plural %}Skipped {{ count }} replies. Open thread to see all replies.{% endblocktrans %}
133 </a>
133 </a>
134 </div>
134 </div>
135 {% endif %}
135 {% endif %}
136 {% endwith %}
136 {% endwith %}
137 <div class="last-replies">
137 <div class="last-replies">
138 {% for post in last_replies %}
138 {% for post in last_replies %}
139 {% post_view post truncated=True %}
139 {% post_view post truncated=True %}
140 {% endfor %}
140 {% endfor %}
141 </div>
141 </div>
142 {% endif %}
142 {% endif %}
143 {% endwith %}
143 {% endwith %}
144 {% endif %}
144 {% endif %}
145 </div>
145 </div>
146 {% endfor %}
146 {% endfor %}
147
147
148 {% if next_page_link %}
148 {% if next_page_link %}
149 <div class="page_link">
149 <div class="page_link">
150 <a href="{{ next_page_link }}">&gt;&gt; {% trans "Next page" %} &gt;&gt;</a>
150 <a href="{{ next_page_link }}">&gt;&gt; {% trans "Next page" %} &gt;&gt;</a>
151 </div>
151 </div>
152 {% endif %}
152 {% endif %}
153 {% else %}
153 {% else %}
154 <div class="post">
154 <div class="post">
155 {% trans 'No threads exist. Create the first one!' %}</div>
155 {% trans 'No threads exist. Create the first one!' %}</div>
156 {% endif %}
156 {% endif %}
157
157
158 <div class="post-form-w">
158 <div class="post-form-w">
159 <script src="{% static 'js/panel.js' %}"></script>
159 <script src="{% static 'js/panel.js' %}"></script>
160 <div class="post-form" data-hasher="{% static 'js/3party/sha256.js' %}"
160 <div class="post-form" data-hasher="{% static 'js/3party/sha256.js' %}"
161 data-pow-script="{% static 'js/proof_of_work.js' %}">
161 data-pow-script="{% static 'js/proof_of_work.js' %}">
162 <div class="form-title">{% trans "Create new thread" %}</div>
162 <div class="form-title">{% trans "Create new thread" %}</div>
163 <div class="swappable-form-full">
163 <div class="swappable-form-full">
164 <form enctype="multipart/form-data" method="post" id="form">{% csrf_token %}
164 <form enctype="multipart/form-data" method="post" id="form">{% csrf_token %}
165 {{ form.as_div }}
165 {{ form.as_div }}
166 <div class="form-submit">
166 <div class="form-submit">
167 <input type="submit" value="{% trans "Post" %}"/>
167 <input type="submit" value="{% trans "Post" %}"/>
168 <button id="preview-button" type="button" onclick="return false;">{% trans 'Preview' %}</button>
168 <button id="preview-button" type="button" onclick="return false;">{% trans 'Preview' %}</button>
169 </div>
169 </div>
170 </form>
170 </form>
171 </div>
171 </div>
172 <div>
172 <div>
173 {% trans 'Tags must be delimited by spaces. Text or image is required.' %}
173 {% trans 'Tags must be delimited by spaces. Text or image is required.' %}
174 {% with size=max_file_size|filesizeformat %}
174 {% with size=max_file_size|filesizeformat %}
175 {% blocktrans %}Max file size is {{ size }}.{% endblocktrans %}
175 {% blocktrans %}Max total file size is {{ size }}.{% endblocktrans %}
176 {% endwith %}
176 {% endwith %}
177 {% blocktrans %}Max file number is {{ max_files }}.{% endblocktrans %}
177 {% blocktrans %}Max file number is {{ max_files }}.{% endblocktrans %}
178 </div>
178 </div>
179 <div id="preview-text"></div>
179 <div id="preview-text"></div>
180 <div><a href="{% url "staticpage" name="help" %}">{% trans 'Help' %}</a></div>
180 <div><a href="{% url "staticpage" name="help" %}">{% trans 'Help' %}</a></div>
181 </div>
181 </div>
182 </div>
182 </div>
183
183
184 <script src="{% static 'js/form.js' %}"></script>
184 <script src="{% static 'js/form.js' %}"></script>
185 <script src="{% static 'js/3party/jquery.blockUI.js' %}"></script>
185 <script src="{% static 'js/3party/jquery.blockUI.js' %}"></script>
186 <script src="{% static 'js/thread_create.js' %}"></script>
186 <script src="{% static 'js/thread_create.js' %}"></script>
187
187
188 {% endblock %}
188 {% endblock %}
189
189
190 {% block metapanel %}
190 {% block metapanel %}
191
191
192 <span class="metapanel">
192 <span class="metapanel">
193 {% trans "Pages:" %}
193 {% trans "Pages:" %}
194 [
194 [
195 {% with dividers=paginator.get_dividers %}
195 {% with dividers=paginator.get_dividers %}
196 {% for page in paginator.get_divided_range %}
196 {% for page in paginator.get_divided_range %}
197 {% if page in dividers %}
197 {% if page in dividers %}
198 …,
198 …,
199 {% endif %}
199 {% endif %}
200 <a
200 <a
201 {% ifequal page current_page.number %}
201 {% ifequal page current_page.number %}
202 class="current_page"
202 class="current_page"
203 {% endifequal %}
203 {% endifequal %}
204 href="{% page_url paginator page %}">{{ page }}</a>{% if not forloop.last %},{% endif %}
204 href="{% page_url paginator page %}">{{ page }}</a>{% if not forloop.last %},{% endif %}
205 {% endfor %}
205 {% endfor %}
206 {% endwith %}
206 {% endwith %}
207 ]
207 ]
208 </span>
208 </span>
209
209
210 {% endblock %}
210 {% endblock %}
@@ -1,81 +1,81 b''
1 {% extends "boards/thread.html" %}
1 {% extends "boards/thread.html" %}
2
2
3 {% load i18n %}
3 {% load i18n %}
4 {% load static from staticfiles %}
4 {% load static from staticfiles %}
5 {% load board %}
5 {% load board %}
6 {% load tz %}
6 {% load tz %}
7
7
8 {% block thread_content %}
8 {% block thread_content %}
9 {% get_current_language as LANGUAGE_CODE %}
9 {% get_current_language as LANGUAGE_CODE %}
10 {% get_current_timezone as TIME_ZONE %}
10 {% get_current_timezone as TIME_ZONE %}
11
11
12 <button id="quote-button">{% trans 'Quote' %}</button>
12 <button id="quote-button">{% trans 'Quote' %}</button>
13
13
14 <div class="tag_info">
14 <div class="tag_info">
15 <h2>
15 <h2>
16 <form action="{% url 'thread' opening_post.id %}" method="post" class="post-button-form">
16 <form action="{% url 'thread' opening_post.id %}" method="post" class="post-button-form">
17 {% csrf_token %}
17 {% csrf_token %}
18 {% if is_favorite %}
18 {% if is_favorite %}
19 <button id="thread-fav-button" name="method" value="unsubscribe" class="fav">β˜…</button>
19 <button id="thread-fav-button" name="method" value="unsubscribe" class="fav">β˜…</button>
20 {% else %}
20 {% else %}
21 <button id="thread-fav-button" name="method" value="subscribe" class="not_fav">β˜…</button>
21 <button id="thread-fav-button" name="method" value="subscribe" class="not_fav">β˜…</button>
22 {% endif %}
22 {% endif %}
23 </form>
23 </form>
24 {{ opening_post.get_title_or_text }}
24 {{ opening_post.get_title_or_text }}
25 </h2>
25 </h2>
26 </div>
26 </div>
27
27
28 {% if bumpable and thread.has_post_limit %}
28 {% if bumpable and thread.has_post_limit %}
29 <div class="bar-bg">
29 <div class="bar-bg">
30 <div class="bar-value" style="width:{{ bumplimit_progress }}%" id="bumplimit_progress">
30 <div class="bar-value" style="width:{{ bumplimit_progress }}%" id="bumplimit_progress">
31 </div>
31 </div>
32 <div class="bar-text">
32 <div class="bar-text">
33 <span id="left_to_limit">{{ posts_left }}</span> {% trans 'posts to bumplimit' %}
33 <span id="left_to_limit">{{ posts_left }}</span> {% trans 'posts to bumplimit' %}
34 </div>
34 </div>
35 </div>
35 </div>
36 {% endif %}
36 {% endif %}
37
37
38 <div class="thread">
38 <div class="thread">
39 {% for post in thread.get_viewable_replies %}
39 {% for post in thread.get_viewable_replies %}
40 {% post_view post reply_link=True thread=thread %}
40 {% post_view post reply_link=True thread=thread %}
41 {% endfor %}
41 {% endfor %}
42 </div>
42 </div>
43
43
44 {% if not thread.is_archived %}
44 {% if not thread.is_archived %}
45 <div class="post-form-w">
45 <div class="post-form-w">
46 <script src="{% static 'js/panel.js' %}"></script>
46 <script src="{% static 'js/panel.js' %}"></script>
47 <div class="form-title">{% trans "Reply to thread" %} #{{ opening_post.id }}<span class="reply-to-message"> {% trans "to message " %} #<span id="reply-to-message-id"></span></span></div>
47 <div class="form-title">{% trans "Reply to thread" %} #{{ opening_post.id }}<span class="reply-to-message"> {% trans "to message " %} #<span id="reply-to-message-id"></span></span></div>
48 <div class="post-form" id="compact-form" data-hasher="{% static 'js/3party/sha256.js' %}"
48 <div class="post-form" id="compact-form" data-hasher="{% static 'js/3party/sha256.js' %}"
49 data-pow-script="{% static 'js/proof_of_work.js' %}">
49 data-pow-script="{% static 'js/proof_of_work.js' %}">
50 <div class="swappable-form-full">
50 <div class="swappable-form-full">
51 <form enctype="multipart/form-data" method="post" id="form">{% csrf_token %}
51 <form enctype="multipart/form-data" method="post" id="form">{% csrf_token %}
52 <div class="compact-form-text"></div>
52 <div class="compact-form-text"></div>
53 {{ form.as_div }}
53 {{ form.as_div }}
54 <div class="form-submit">
54 <div class="form-submit">
55 <input type="submit" value="{% trans "Post" %}"/>
55 <input type="submit" value="{% trans "Post" %}"/>
56 <button id="preview-button" type="button" onclick="return false;">{% trans 'Preview' %}</button>
56 <button id="preview-button" type="button" onclick="return false;">{% trans 'Preview' %}</button>
57 </div>
57 </div>
58 </form>
58 </form>
59 </div>
59 </div>
60 <div id="preview-text"></div>
60 <div id="preview-text"></div>
61 <div>
61 <div>
62 {% with size=max_file_size|filesizeformat %}
62 {% with size=max_file_size|filesizeformat %}
63 {% blocktrans %}Max file size is {{ size }}.{% endblocktrans %}
63 {% blocktrans %}Max total file size is {{ size }}.{% endblocktrans %}
64 {% endwith %}
64 {% endwith %}
65 {% blocktrans %}Max file number is {{ max_files }}.{% endblocktrans %}
65 {% blocktrans %}Max file number is {{ max_files }}.{% endblocktrans %}
66 </div>
66 </div>
67 <div><a href="{% url "staticpage" name="help" %}">
67 <div><a href="{% url "staticpage" name="help" %}">
68 {% trans 'Help' %}</a></div>
68 {% trans 'Help' %}</a></div>
69 <div><a href="#" onClick="resetForm(); return false;">{% trans 'Reset form' %}</a></div>
69 <div><a href="#" onClick="resetForm(); return false;">{% trans 'Reset form' %}</a></div>
70 </div>
70 </div>
71 </div>
71 </div>
72
72
73 <script src="{% static 'js/form.js' %}"></script>
73 <script src="{% static 'js/form.js' %}"></script>
74 <script src="{% static 'js/jquery.form.min.js' %}"></script>
74 <script src="{% static 'js/jquery.form.min.js' %}"></script>
75 <script src="{% static 'js/3party/jquery.blockUI.js' %}"></script>
75 <script src="{% static 'js/3party/jquery.blockUI.js' %}"></script>
76 <script src="{% static 'js/thread.js' %}"></script>
76 <script src="{% static 'js/thread.js' %}"></script>
77 <script src="{% static 'js/thread_update.js' %}"></script>
77 <script src="{% static 'js/thread_update.js' %}"></script>
78 {% endif %}
78 {% endif %}
79
79
80 <script src="{% static 'js/3party/centrifuge.js' %}"></script>
80 <script src="{% static 'js/3party/centrifuge.js' %}"></script>
81 {% endblock %}
81 {% endblock %}
@@ -1,152 +1,152 b''
1 """
1 """
2 This module contains helper functions and helper classes.
2 This module contains helper functions and helper classes.
3 """
3 """
4 import time
4 import time
5 import uuid
5 import uuid
6
6
7 import hashlib
7 import hashlib
8 import magic
8 import magic
9 import os
9 import os
10 from django import forms
10 from django import forms
11 from django.core.cache import cache
11 from django.core.cache import cache
12 from django.db.models import Model
12 from django.db.models import Model
13 from django.template.defaultfilters import filesizeformat
13 from django.template.defaultfilters import filesizeformat
14 from django.utils import timezone
14 from django.utils import timezone
15 from django.utils.translation import ugettext_lazy as _
15 from django.utils.translation import ugettext_lazy as _
16
16
17 import boards
17 import boards
18 from neboard import settings
18 from neboard import settings
19 from boards.abstracts.constants import FILE_DIRECTORY
19 from boards.abstracts.constants import FILE_DIRECTORY
20 from boards.settings import get_bool
20 from boards.settings import get_bool
21
21
22 CACHE_KEY_DELIMITER = '_'
22 CACHE_KEY_DELIMITER = '_'
23
23
24 HTTP_FORWARDED = 'HTTP_X_FORWARDED_FOR'
24 HTTP_FORWARDED = 'HTTP_X_FORWARDED_FOR'
25 META_REMOTE_ADDR = 'REMOTE_ADDR'
25 META_REMOTE_ADDR = 'REMOTE_ADDR'
26
26
27 SETTING_MESSAGES = 'Messages'
27 SETTING_MESSAGES = 'Messages'
28 SETTING_ANON_MODE = 'AnonymousMode'
28 SETTING_ANON_MODE = 'AnonymousMode'
29
29
30 ANON_IP = '127.0.0.1'
30 ANON_IP = '127.0.0.1'
31
31
32 FILE_EXTENSION_DELIMITER = '.'
32 FILE_EXTENSION_DELIMITER = '.'
33
33
34
34
35 def is_anonymous_mode():
35 def is_anonymous_mode():
36 return get_bool(SETTING_MESSAGES, SETTING_ANON_MODE)
36 return get_bool(SETTING_MESSAGES, SETTING_ANON_MODE)
37
37
38
38
39 def get_client_ip(request):
39 def get_client_ip(request):
40 if is_anonymous_mode():
40 if is_anonymous_mode():
41 ip = ANON_IP
41 ip = ANON_IP
42 else:
42 else:
43 x_forwarded_for = request.META.get(HTTP_FORWARDED)
43 x_forwarded_for = request.META.get(HTTP_FORWARDED)
44 if x_forwarded_for:
44 if x_forwarded_for:
45 ip = x_forwarded_for.split(',')[-1].strip()
45 ip = x_forwarded_for.split(',')[-1].strip()
46 else:
46 else:
47 ip = request.META.get(META_REMOTE_ADDR)
47 ip = request.META.get(META_REMOTE_ADDR)
48 return ip
48 return ip
49
49
50
50
51 # TODO The output format is not epoch because it includes microseconds
51 # TODO The output format is not epoch because it includes microseconds
52 def datetime_to_epoch(datetime):
52 def datetime_to_epoch(datetime):
53 return int(time.mktime(timezone.localtime(
53 return int(time.mktime(timezone.localtime(
54 datetime,timezone.get_current_timezone()).timetuple())
54 datetime,timezone.get_current_timezone()).timetuple())
55 * 1000000 + datetime.microsecond)
55 * 1000000 + datetime.microsecond)
56
56
57
57
58 # TODO Test this carefully
58 # TODO Test this carefully
59 def cached_result(key_method=None):
59 def cached_result(key_method=None):
60 """
60 """
61 Caches method result in the Django's cache system, persisted by object name,
61 Caches method result in the Django's cache system, persisted by object name,
62 object name, model id if object is a Django model, args and kwargs if any.
62 object name, model id if object is a Django model, args and kwargs if any.
63 """
63 """
64 def _cached_result(function):
64 def _cached_result(function):
65 def inner_func(obj, *args, **kwargs):
65 def inner_func(obj, *args, **kwargs):
66 cache_key_params = [obj.__class__.__name__, function.__name__]
66 cache_key_params = [obj.__class__.__name__, function.__name__]
67
67
68 cache_key_params += args
68 cache_key_params += args
69 for key, value in kwargs:
69 for key, value in kwargs:
70 cache_key_params.append(key + ':' + value)
70 cache_key_params.append(key + ':' + value)
71
71
72 if isinstance(obj, Model):
72 if isinstance(obj, Model):
73 cache_key_params.append(str(obj.id))
73 cache_key_params.append(str(obj.id))
74
74
75 if key_method is not None:
75 if key_method is not None:
76 cache_key_params += [str(arg) for arg in key_method(obj)]
76 cache_key_params += [str(arg) for arg in key_method(obj)]
77
77
78 cache_key = CACHE_KEY_DELIMITER.join(cache_key_params)
78 cache_key = CACHE_KEY_DELIMITER.join(cache_key_params)
79
79
80 persisted_result = cache.get(cache_key)
80 persisted_result = cache.get(cache_key)
81 if persisted_result is not None:
81 if persisted_result is not None:
82 result = persisted_result
82 result = persisted_result
83 else:
83 else:
84 result = function(obj, *args, **kwargs)
84 result = function(obj, *args, **kwargs)
85 if result is not None:
85 if result is not None:
86 cache.set(cache_key, result)
86 cache.set(cache_key, result)
87
87
88 return result
88 return result
89
89
90 return inner_func
90 return inner_func
91 return _cached_result
91 return _cached_result
92
92
93
93
94 def get_file_hash(file) -> str:
94 def get_file_hash(file) -> str:
95 md5 = hashlib.md5()
95 md5 = hashlib.md5()
96 for chunk in file.chunks():
96 for chunk in file.chunks():
97 md5.update(chunk)
97 md5.update(chunk)
98 return md5.hexdigest()
98 return md5.hexdigest()
99
99
100
100
101 def validate_file_size(size: int):
101 def validate_file_size(size: int):
102 max_size = boards.settings.get_int('Forms', 'MaxFileSize')
102 max_size = boards.settings.get_int('Forms', 'MaxFileSize')
103 if 0 < max_size < size:
103 if 0 < max_size < size:
104 raise forms.ValidationError(
104 raise forms.ValidationError(
105 _('File must be less than %s but is %s.')
105 _('Total file size must be less than %s but is %s.')
106 % (filesizeformat(max_size), filesizeformat(size)))
106 % (filesizeformat(max_size), filesizeformat(size)))
107
107
108
108
109 def get_extension(filename):
109 def get_extension(filename):
110 return filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
110 return filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
111
111
112
112
113 def get_upload_filename(model_instance, old_filename):
113 def get_upload_filename(model_instance, old_filename):
114 extension = get_extension(old_filename)
114 extension = get_extension(old_filename)
115 new_name = '{}.{}'.format(uuid.uuid4(), extension)
115 new_name = '{}.{}'.format(uuid.uuid4(), extension)
116
116
117 return os.path.join(FILE_DIRECTORY, new_name)
117 return os.path.join(FILE_DIRECTORY, new_name)
118
118
119
119
120 def get_file_mimetype(file) -> str:
120 def get_file_mimetype(file) -> str:
121 buf = b''
121 buf = b''
122 for chunk in file.chunks():
122 for chunk in file.chunks():
123 buf += chunk
123 buf += chunk
124
124
125 file_type = magic.from_buffer(buf, mime=True)
125 file_type = magic.from_buffer(buf, mime=True)
126 if file_type is None:
126 if file_type is None:
127 file_type = 'application/octet-stream'
127 file_type = 'application/octet-stream'
128 elif type(file_type) == bytes:
128 elif type(file_type) == bytes:
129 file_type = file_type.decode()
129 file_type = file_type.decode()
130 return file_type
130 return file_type
131
131
132
132
133 def get_domain(url: str) -> str:
133 def get_domain(url: str) -> str:
134 """
134 """
135 Gets domain from an URL with random number of domain levels.
135 Gets domain from an URL with random number of domain levels.
136 """
136 """
137 domain_parts = url.split('/')
137 domain_parts = url.split('/')
138 if len(domain_parts) >= 2:
138 if len(domain_parts) >= 2:
139 full_domain = domain_parts[2]
139 full_domain = domain_parts[2]
140 else:
140 else:
141 full_domain = ''
141 full_domain = ''
142
142
143 return full_domain
143 return full_domain
144
144
145
145
146 def get_tripcode_from_text(text: str) -> str:
146 def get_tripcode_from_text(text: str) -> str:
147 tripcode = ''
147 tripcode = ''
148 if text:
148 if text:
149 code = text + settings.SECRET_KEY
149 code = text + settings.SECRET_KEY
150 tripcode = hashlib.md5(code.encode()).hexdigest()
150 tripcode = hashlib.md5(code.encode()).hexdigest()
151 return tripcode
151 return tripcode
152
152
General Comments 0
You need to be logged in to leave comments. Login now