# HG changeset patch # User Pavel Ryapolov # Date 2013-10-24 14:26:13 # Node ID da4642af5ffc741b10b84706796e54755370ddfc # Parent 40c951678aa66054fd5cd9b05512c4a7eaa73f5b # Parent 431372d7819752fa635d58824b0d391704af02a9 Merged with BB diff --git a/boards/locale/ru/LC_MESSAGES/django.mo b/boards/locale/ru/LC_MESSAGES/django.mo index 306aec722436cad7fc7394be5a3e59326b9f5fae..eb71554a659e555d9de5704b5077918b5fded624 GIT binary patch literal 5580 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\n" "Language-Team: LANGUAGE \n" @@ -35,22 +35,22 @@ msgid "designer" msgstr "дизайнер" #: forms.py:51 templates/boards/posting_general.html:135 -#: templates/boards/thread.html:90 +#: templates/boards/thread.html:100 msgid "Title" msgstr "Заголовок" #: forms.py:53 templates/boards/posting_general.html:150 -#: templates/boards/thread.html:105 +#: templates/boards/thread.html:115 msgid "Text" msgstr "Текст" #: forms.py:54 templates/boards/posting_general.html:155 -#: templates/boards/thread.html:110 +#: templates/boards/thread.html:120 msgid "Image" msgstr "Изображение" #: forms.py:57 templates/boards/posting_general.html:165 -#: templates/boards/thread.html:115 +#: templates/boards/thread.html:125 msgid "e-mail" msgstr "" @@ -81,7 +81,7 @@ msgstr "Подождите %s секунд после последнего постинга" #: forms.py:140 templates/boards/post.html:39 #: templates/boards/posting_general.html:77 #: templates/boards/posting_general.html:160 templates/boards/tags.html:7 -#: templates/boards/thread.html:70 templates/boards/rss/post.html:10 +#: templates/boards/thread.html:80 templates/boards/rss/post.html:10 msgid "Tags" msgstr "Теги" @@ -118,19 +118,19 @@ msgstr "Не найдено" msgid "This page does not exist" msgstr "Этой страницы не существует" -#: templates/boards/authors.html:6 +#: templates/boards/authors.html:6 templates/boards/authors.html.py:12 msgid "Authors" msgstr "Авторы" -#: templates/boards/authors.html:24 +#: templates/boards/authors.html:25 msgid "Distributed under the" msgstr "Распространяется под" -#: templates/boards/authors.html:26 +#: templates/boards/authors.html:27 msgid "license" msgstr "лицензией" -#: templates/boards/authors.html:28 +#: templates/boards/authors.html:29 msgid "Repository" msgstr "Репозиторий" @@ -172,12 +172,12 @@ msgid "Post image" msgstr "Изображение сообщения" #: templates/boards/post.html:26 templates/boards/posting_general.html:62 -#: templates/boards/thread.html:57 +#: templates/boards/thread.html:59 msgid "Delete" msgstr "Удалить" #: templates/boards/post.html:29 templates/boards/posting_general.html:65 -#: templates/boards/thread.html:60 +#: templates/boards/thread.html:62 msgid "Ban IP" msgstr "Заблокировать IP" @@ -189,11 +189,11 @@ msgstr "Тег: " msgid "Reply" msgstr "Ответ" -#: templates/boards/posting_general.html:74 templates/boards/thread.html:143 +#: templates/boards/posting_general.html:74 templates/boards/thread.html:153 msgid "replies" msgstr "ответов" -#: templates/boards/posting_general.html:75 templates/boards/thread.html:144 +#: templates/boards/posting_general.html:75 templates/boards/thread.html:154 msgid "images" msgstr "изображений" @@ -205,31 +205,31 @@ msgstr "Нет тем. Создайте первую!" msgid "Create new thread" msgstr "Создать новую тему" -#: templates/boards/posting_general.html:140 templates/boards/thread.html:95 +#: templates/boards/posting_general.html:140 templates/boards/thread.html:105 msgid "Formatting" msgstr "Форматирование" -#: templates/boards/posting_general.html:142 templates/boards/thread.html:97 +#: templates/boards/posting_general.html:142 templates/boards/thread.html:107 msgid "quote" msgstr "цитата" -#: templates/boards/posting_general.html:143 templates/boards/thread.html:98 +#: templates/boards/posting_general.html:143 templates/boards/thread.html:108 msgid "italic" msgstr "курсив" -#: templates/boards/posting_general.html:144 templates/boards/thread.html:99 +#: templates/boards/posting_general.html:144 templates/boards/thread.html:109 msgid "bold" msgstr "полужирный" -#: templates/boards/posting_general.html:145 templates/boards/thread.html:100 +#: templates/boards/posting_general.html:145 templates/boards/thread.html:110 msgid "spoiler" msgstr "спойлер" -#: templates/boards/posting_general.html:146 templates/boards/thread.html:101 +#: templates/boards/posting_general.html:146 templates/boards/thread.html:111 msgid "comment" msgstr "комментарий" -#: templates/boards/posting_general.html:178 templates/boards/thread.html:129 +#: templates/boards/posting_general.html:178 templates/boards/thread.html:139 msgid "Post" msgstr "Отправить" @@ -238,7 +238,7 @@ msgid "Tags must be delimited by spaces. msgstr "" "Теги должны быть разделены пробелами. Текст или изображение обязательны." -#: templates/boards/posting_general.html:183 templates/boards/thread.html:131 +#: templates/boards/posting_general.html:183 templates/boards/thread.html:141 msgid "Text syntax" msgstr "Синтаксис текста" @@ -270,7 +270,7 @@ msgstr "Последний доступ: " msgid "Save" msgstr "Сохранить" -#: templates/boards/tags.html:17 +#: templates/boards/tags.html:24 msgid "threads" msgstr "тем" @@ -278,15 +278,19 @@ msgstr "тем" msgid "No tags found." msgstr "Теги не найдены." -#: templates/boards/thread.html:22 +#: templates/boards/thread.html:24 msgid "posts to bumplimit" msgstr "сообщений до бамплимита" -#: templates/boards/thread.html:87 +#: templates/boards/thread.html:71 +msgid "Replies" +msgstr "Ответы" + +#: templates/boards/thread.html:97 msgid "Reply to thread" msgstr "Ответить в тему" -#: templates/boards/thread.html:145 +#: templates/boards/thread.html:155 msgid "Last update: " msgstr "Последнее обновление: " diff --git a/boards/migrations/0012_auto.py b/boards/migrations/0012_auto.py new file mode 100644 --- /dev/null +++ b/boards/migrations/0012_auto.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding M2M table for field referenced_posts on 'Post' + m2m_table_name = db.shorten_name(u'boards_post_referenced_posts') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('from_post', models.ForeignKey(orm[u'boards.post'], null=False)), + ('to_post', models.ForeignKey(orm[u'boards.post'], null=False)) + )) + db.create_unique(m2m_table_name, ['from_post_id', 'to_post_id']) + + + def backwards(self, orm): + # Removing M2M table for field referenced_posts on 'Post' + db.delete_table(db.shorten_name(u'boards_post_referenced_posts')) + + + models = { + u'boards.ban': { + 'Meta': {'object_name': 'Ban'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}) + }, + u'boards.post': { + 'Meta': {'object_name': 'Post'}, + '_text_rendered': ('django.db.models.fields.TextField', [], {}), + 'bump_time': ('django.db.models.fields.DateTimeField', [], {}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('boards.thumbs.ImageWithThumbsField', [], {'max_length': '100', 'blank': 'True'}), + 'image_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'image_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}), + 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}), + 'poster_user_agent': ('django.db.models.fields.TextField', [], {}), + 'pub_time': ('django.db.models.fields.DateTimeField', [], {}), + 'referenced_posts': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'rfp+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}), + 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'re+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['boards.Tag']", 'symmetrical': 'False'}), + 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}), + 'text_markup_type': ('django.db.models.fields.CharField', [], {'default': "'markdown'", 'max_length': '30'}), + 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['boards.Post']", 'null': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['boards.User']", 'null': 'True'}) + }, + u'boards.setting': { + 'Meta': {'object_name': 'Setting'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['boards.User']"}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'boards.tag': { + 'Meta': {'object_name': 'Tag'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'linked': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['boards.Tag']", 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'tag+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}) + }, + u'boards.user': { + 'Meta': {'object_name': 'User'}, + 'fav_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['boards.Tag']", 'null': 'True', 'blank': 'True'}), + 'fav_threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'rank': ('django.db.models.fields.IntegerField', [], {}), + 'registration_time': ('django.db.models.fields.DateTimeField', [], {}), + 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + } + } + + complete_apps = ['boards'] \ No newline at end of file diff --git a/boards/models.py b/boards/models.py --- a/boards/models.py +++ b/boards/models.py @@ -12,6 +12,8 @@ from markupfield.fields import MarkupFie from neboard import settings import thumbs +import re + IMAGE_THUMB_SIZE = (200, 150) TITLE_MAX_LENGTH = 50 @@ -28,10 +30,12 @@ FILE_EXTENSION_DELIMITER = '.' RANK_ADMIN = 0 RANK_MODERATOR = 10 -RANK_USER = 100 \ +RANK_USER = 100 SETTING_MODERATE = "moderate" +REGEX_REPLY = re.compile('>>(\d+)') + class PostManager(models.Manager): @@ -61,6 +65,8 @@ class PostManager(models.Manager): else: self._delete_old_threads() + self.connect_replies(post) + return post def delete_post(self, post): @@ -147,6 +153,15 @@ class PostManager(models.Manager): map(self.delete_post, old_threads) + def connect_replies(self, post): + """Connect replies to a post to show them as a refmap""" + + for reply_number in re.finditer(REGEX_REPLY, post.text.raw): + id = reply_number.group(1) + ref_post = self.filter(id=id) + if ref_post.count() > 0: + ref_post[0].referenced_posts.add(post) + class TagManager(models.Manager): @@ -248,6 +263,8 @@ class Post(models.Model): replies = models.ManyToManyField('Post', symmetrical=False, null=True, blank=True, related_name='re+') + referenced_posts = models.ManyToManyField('Post', symmetrical=False, null=True, + blank=True, related_name='rfp+') def __unicode__(self): return '#' + str(self.id) + ' ' + self.title + ' (' + \ diff --git a/boards/static/js/main.js b/boards/static/js/main.js --- a/boards/static/js/main.js +++ b/boards/static/js/main.js @@ -5,9 +5,9 @@ }); addImgPreview(); - addRefLinkMap(); // TODO Rewrite popups module and reenable it //addPopups(); + addMarkPanel(); }); diff --git a/boards/static/js/refmaps.js b/boards/static/js/refmaps.js deleted file mode 100644 --- a/boards/static/js/refmaps.js +++ /dev/null @@ -1,39 +0,0 @@ -function addRefLinkMap() { - var postByNum = [], refMap = []; - - $('.post').each(function() { - var self = $(this); - - var postNum = self.attr('id'); - //add post by id - postByNum[postNum] = self; - //add ref link - self.find('p').children('a').each(function() { - if($(this).text().indexOf('>>') == 0) { - var refNum = $(this).text().match(/\d+/); - - if(postByNum[refNum]) { - if(!refMap[refNum]) - refMap[refNum] = []; - - //if !exist - if((',' + refMap[refNum].toString() + ',').indexOf(',' + postNum + ',') < 0) { - refMap[refNum].push(postNum); - }; - } - } - }); - }); - - var label_replies = gettext('Replies') + ':'; - for(var pNum in refMap) { - if(typeof refMap[pNum] === 'object') { - //append refmap panel - if(!$("#refmap_"+pNum).length) { - $('#'+pNum+'').find('.message').after( - $('
'+label_replies + refMap[pNum].toString().replace(/(\d+)/g, ' >>$1')+'
') - ); - } - } - } -} \ No newline at end of file diff --git a/boards/static/js/thread.js b/boards/static/js/thread.js --- a/boards/static/js/thread.js +++ b/boards/static/js/thread.js @@ -52,5 +52,4 @@ function addQuickReply(postId) { $(document).ready(function(){ addGalleryPanel(); - addRefLinkMap(); }); diff --git a/boards/templates/boards/base.html b/boards/templates/boards/base.html --- a/boards/templates/boards/base.html +++ b/boards/templates/boards/base.html @@ -25,7 +25,6 @@ - diff --git a/boards/templates/boards/posting_general.html b/boards/templates/boards/posting_general.html --- a/boards/templates/boards/posting_general.html +++ b/boards/templates/boards/posting_general.html @@ -83,6 +83,14 @@ {% endif %} + {% if thread.thread.referenced_posts.all %} +
+ {% trans "Replies" %}: + {% for ref_post in thread.thread.referenced_posts.all %} + >>{{ ref_post.id }} + {% endfor %} +
+ {% endif %} {% if thread.thread.get_last_replies.exists %}
@@ -115,6 +123,14 @@ {{ post.text.rendered|truncatewords_html:50 }} {% endautoescape %}
+ {% if post.referenced_posts.all %} +
+ {% trans "Replies" %}: + {% for ref_post in post.referenced_posts.all %} + >>{{ ref_post.id }} + {% endfor %} +
+ {% endif %} {% endfor %} diff --git a/boards/templates/boards/thread.html b/boards/templates/boards/thread.html --- a/boards/templates/boards/thread.html +++ b/boards/templates/boards/thread.html @@ -66,6 +66,14 @@ {% autoescape off %} {{ post.text.rendered }} {% endautoescape %} + {% if post.referenced_posts.all %} +
+ {% trans "Replies" %}: + {% for ref_post in post.referenced_posts.all %} + >>{{ ref_post.id }} + {% endfor %} +
+ {% endif %} {% if post.id == posts.0.id %}