##// END OF EJS Templates
Added sticker as a separate entity for the attachment aliases
neko259 -
r1937:8de7e7bd default
parent child Browse files
Show More
@@ -0,0 +1,39 b''
1 # -*- coding: utf-8 -*-
2 # Generated by Django 1.11 on 2017-10-14 13:25
3 from __future__ import unicode_literals
4
5 from django.db import migrations, models
6 import django.db.models.deletion
7 from django.db.models import Q
8
9
10 class Migration(migrations.Migration):
11
12 dependencies = [
13 ('boards', '0064_remove_post_version'),
14 ]
15
16 def attachment_alias_to_sticker(apps, schema_editor):
17 Attachment = apps.get_model('boards', 'Attachment')
18 AttachmentSticker = apps.get_model('boards', 'AttachmentSticker')
19
20 attachments = Attachment.objects.exclude(Q(alias=None) | Q(alias=''))
21 for attachment in attachments:
22 AttachmentSticker.objects.create(attachment=attachment,
23 name=attachment.alias)
24
25 operations = [
26 migrations.CreateModel(
27 name='AttachmentSticker',
28 fields=[
29 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
30 ('name', models.TextField(unique=True)),
31 ('attachment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='boards.Attachment')),
32 ],
33 ),
34 migrations.RunPython(attachment_alias_to_sticker),
35 migrations.RemoveField(
36 model_name='Attachment',
37 name='alias',
38 )
39 ]
@@ -3,7 +3,7 b' from boards.models import Attachment'
3
3
4
4
5 class AttachmentAlias:
5 class AttachmentAlias:
6 def get_image(alias):
6 def get_image(self, alias):
7 pass
7 pass
8
8
9
9
@@ -18,11 +18,12 b' class SessionAttachmentAlias(AttachmentA'
18
18
19 class ModelAttachmentAlias(AttachmentAlias):
19 class ModelAttachmentAlias(AttachmentAlias):
20 def get_image(self, alias):
20 def get_image(self, alias):
21 return Attachment.objects.filter(alias=alias).first()
21 return Attachment.objects.get_by_alias(alias)
22
22
23
23
24 def get_image_by_alias(alias, session):
24 def get_image_by_alias(alias, session):
25 image = SessionAttachmentAlias(session).get_image(alias) or ModelAttachmentAlias().get_image(alias)
25 image = SessionAttachmentAlias(session).get_image(alias)\
26 or ModelAttachmentAlias().get_image(alias)
26
27
27 if image is not None:
28 if image is not None:
28 return image
29 return image
@@ -1,4 +1,5 b''
1 from boards.models.attachment import FILE_TYPES_IMAGE
1 from boards.abstracts.attachment_alias import AttachmentAlias
2 from boards.models.attachment import FILE_TYPES_IMAGE, AttachmentSticker
2 from django.contrib import admin
3 from django.contrib import admin
3 from django.utils.translation import ugettext_lazy as _
4 from django.utils.translation import ugettext_lazy as _
4 from django.core.urlresolvers import reverse
5 from django.core.urlresolvers import reverse
@@ -157,16 +158,12 b' class BannerAdmin(admin.ModelAdmin):'
157
158
158 @admin.register(Attachment)
159 @admin.register(Attachment)
159 class AttachmentAdmin(admin.ModelAdmin):
160 class AttachmentAdmin(admin.ModelAdmin):
160 list_display = ('__str__', 'mimetype', 'file', 'url', 'alias')
161 list_display = ('__str__', 'mimetype', 'file', 'url')
161 search_fields = ('alias',)
162
162
163
163 def delete_alias(self, request, queryset):
164 @admin.register(AttachmentSticker)
164 for attachment in queryset:
165 class AttachmentStickerAdmin(admin.ModelAdmin):
165 attachment.alias = None
166 search_fields = ('name',)
166 attachment.save(update_fields=['alias'])
167 self.message_user(request, _('Aliases removed'))
168
169 actions = ['delete_alias']
170
167
171
168
172 @admin.register(GlobalId)
169 @admin.register(GlobalId)
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -610,3 +610,12 b' msgstr "\xd0\x97\xd0\xb0\xd0\xb3\xd1\x80\xd1\x83\xd0\xb7\xd0\xb8\xd1\x82\xd1\x8c \xd0\xb8\xd0\xbb\xd0\xb8 \xd0\xbe\xd1\x82\xd0\xba\xd0\xb0\xd0\xb7\xd0\xb0\xd1\x82\xd1\x8c"'
610
610
611 msgid "Insert as URLs"
611 msgid "Insert as URLs"
612 msgstr "Π’ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ ΠΊΠ°ΠΊ ссылки"
612 msgstr "Π’ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ ΠΊΠ°ΠΊ ссылки"
613
614 msgid "Help"
615 msgstr "Π‘ΠΏΡ€Π°Π²ΠΊΠ°"
616
617 msgid "View available stickers:"
618 msgstr "ΠŸΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ доступныС стикСры:"
619
620 msgid "Stickers"
621 msgstr "Π‘Ρ‚ΠΈΠΊΠ΅Ρ€Ρ‹"
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -610,3 +610,12 b' msgstr "\xd0\x97\xd0\xb0\xd0\xb2\xd0\xb0\xd0\xbd\xd1\x82\xd0\xb0\xd0\xb6\xd0\xb8\xd1\x82\xd0\xb8 \xd0\xb0\xd0\xb1\xd0\xbe \xd0\xb2\xd1\x96\xd0\xb4\xd0\xbc\xd0\xbe\xd0\xb2\xd0\xb8\xd1\x82\xd0\xb8"'
610
610
611 msgid "Insert as URLs"
611 msgid "Insert as URLs"
612 msgstr "Вставляти як посилання"
612 msgstr "Вставляти як посилання"
613
614 msgid "Help"
615 msgstr "Π‘ΠΏΡ€Π°Π²ΠΊΠ°"
616
617 msgid "View available stickers:"
618 msgstr "ΠŸΠ΅Ρ€Π΅Π΄ΠΈΠ²ΠΈΡ‚ΠΈΡΡ доступні стікСри:"
619
620 msgid "Stickers"
621 msgstr "Π‘Ρ‚Ρ–ΠΊΠ΅Ρ€ΠΈ"
@@ -54,6 +54,9 b' class AttachmentManager(models.Manager):'
54 attachment = existing_attachment
54 attachment = existing_attachment
55 return attachment
55 return attachment
56
56
57 def get_by_alias(self, name):
58 return AttachmentSticker.objects.get(name=name).attachment
59
57 def _compare_chunks(self, chunks1, chunks2):
60 def _compare_chunks(self, chunks1, chunks2):
58 """
61 """
59 Compares 2 chunks of different sizes (e.g. first chunk array contains
62 Compares 2 chunks of different sizes (e.g. first chunk array contains
@@ -108,7 +111,6 b' class Attachment(models.Model):'
108 file = models.FileField(upload_to=get_upload_filename, null=True)
111 file = models.FileField(upload_to=get_upload_filename, null=True)
109 mimetype = models.CharField(max_length=200, null=True)
112 mimetype = models.CharField(max_length=200, null=True)
110 hash = models.CharField(max_length=36, null=True)
113 hash = models.CharField(max_length=36, null=True)
111 alias = models.TextField(unique=True, null=True)
112 url = models.TextField(blank=True, default='')
114 url = models.TextField(blank=True, default='')
113
115
114 def get_view(self):
116 def get_view(self):
@@ -120,8 +122,7 b' class Attachment(models.Model):'
120 if file_viewer is None:
122 if file_viewer is None:
121 file_viewer = AbstractViewer
123 file_viewer = AbstractViewer
122
124
123 return file_viewer(self.file, self.mimetype, self.hash, self.url,
125 return file_viewer(self.file, self.mimetype, self.hash, self.url).get_view()
124 self.alias).get_view()
125
126
126 def __str__(self):
127 def __str__(self):
127 return self.url or self.file.url
128 return self.url or self.file.url
@@ -157,3 +158,11 b' class Attachment(models.Model):'
157
158
158 def is_internal(self):
159 def is_internal(self):
159 return self.url is None or len(self.url) == 0
160 return self.url is None or len(self.url) == 0
161
162
163 class AttachmentSticker(models.Model):
164 attachment = models.ForeignKey('Attachment')
165 name = models.TextField(unique=True)
166
167 def __str__(self):
168 return self.name
@@ -56,7 +56,7 b" CSS_CLASS_THUMB = 'thumb'"
56
56
57 ABSTRACT_VIEW = '<div class="image">'\
57 ABSTRACT_VIEW = '<div class="image">'\
58 '{}'\
58 '{}'\
59 '<div class="image-metadata">{}<a href="{}" download >{}, {}</a>'\
59 '<div class="image-metadata"><a href="{}" download >{}, {}</a>'\
60 ' <a class="file-menu" href="#" data-type="{}" data-search-url="{}" data-filename="{}">πŸ” </a></div>'\
60 ' <a class="file-menu" href="#" data-type="{}" data-search-url="{}" data-filename="{}">πŸ” </a></div>'\
61 '</div>'
61 '</div>'
62 URL_VIEW = '<div class="image">' \
62 URL_VIEW = '<div class="image">' \
@@ -100,13 +100,12 b' def file_exists(filename):'
100
100
101
101
102 class AbstractViewer:
102 class AbstractViewer:
103 def __init__(self, file, file_type, hash, url, alias):
103 def __init__(self, file, file_type, hash, url):
104 self.file = file
104 self.file = file
105 self.file_type = file_type
105 self.file_type = file_type
106 self.hash = hash
106 self.hash = hash
107 self.url = url
107 self.url = url
108 self.extension = get_extension(self.file.name)
108 self.extension = get_extension(self.file.name)
109 self.alias = alias
110
109
111 @staticmethod
110 @staticmethod
112 def supports(file_type):
111 def supports(file_type):
@@ -121,9 +120,7 b' class AbstractViewer:'
121 else:
120 else:
122 search_url = ''
121 search_url = ''
123
122
124 alias = self.alias + '<br />' if self.alias else ''
123 return ABSTRACT_VIEW.format(self.get_format_view(), self.file.url,
125
126 return ABSTRACT_VIEW.format(self.get_format_view(), alias, self.file.url,
127 self.file_type, filesizeformat(self.file.size),
124 self.file_type, filesizeformat(self.file.size),
128 self.file_type, search_url, self.file.name)
125 self.file_type, search_url, self.file.name)
129
126
@@ -5,13 +5,16 b''
5
5
6 {% block head %}
6 {% block head %}
7 <meta name="robots" content="noindex">
7 <meta name="robots" content="noindex">
8 <title>{% trans 'Aliases' %} - {{ site_name }}</title>
8 <title>{% trans "Stickers" %} - {{ site_name }}</title>
9 {% endblock %}
9 {% endblock %}
10
10
11 {% block content %}
11 {% block content %}
12 <div class="post">
12 <div id="posts-table">
13 {% for image in image_aliases %}
13 {% for sticker in stickers %}
14 <div>{{ image.alias }}: {{ image.get_view|safe }}</div>
14 <div class="gallery_image">
15 {{ sticker.attachment.get_view|safe }}
16 <div>{{ sticker.name }}</div>
17 </div>
15 {% endfor %}
18 {% endfor %}
16 </div>
19 </div>
17 {% endblock %}
20 {% endblock %}
@@ -177,7 +177,7 b''
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 'Text syntax' %}</a></div>
180 <div><a href="{% url "staticpage" name="help" %}">{% trans 'Help' %}</a></div>
181 </div>
181 </div>
182 </div>
182 </div>
183
183
@@ -124,13 +124,6 b''
124 </script>
124 </script>
125 {% endif %}
125 {% endif %}
126 </div>
126 </div>
127 {% comment %}
128 Post images. Currently only 1 image can be posted and shown, but post model
129 supports multiple.
130 {% endcomment %}
131 {% for image in post.images.all %}
132 {{ image.get_view|safe }}
133 {% endfor %}
134 {% for file in post.attachments.all %}
127 {% for file in post.attachments.all %}
135 {{ file.get_view|safe }}
128 {{ file.get_view|safe }}
136 {% endfor %}
129 {% endfor %}
@@ -7,7 +7,9 b''
7 {% endblock %}
7 {% endblock %}
8
8
9 {% block staticcontent %}
9 {% block staticcontent %}
10 <h2>{% trans 'Syntax' %}</h2>
10 <h2>{% trans 'Help' %}</h2>
11 <p>{% trans 'View available stickers:' %} <a href="{% url 'stickers' %}">{% trans 'Stickers' %}</a></p>
12 <hr />
11 <p>[i]<i>{% trans 'Italic text' %}</i>[/i]</p>
13 <p>[i]<i>{% trans 'Italic text' %}</i>[/i]</p>
12 <p>[b]<b>{% trans 'Bold text' %}</b>[/b]</p>
14 <p>[b]<b>{% trans 'Bold text' %}</b>[/b]</p>
13 <p>[spoiler]<span class="spoiler">{% trans 'Spoiler' %}</span>[/spoiler]</p>
15 <p>[spoiler]<span class="spoiler">{% trans 'Spoiler' %}</span>[/spoiler]</p>
@@ -17,6 +19,6 b''
17 <p>[quote]<span class="quote">&gt;{% trans 'Quote' %}</span>[/quote]</p>
19 <p>[quote]<span class="quote">&gt;{% trans 'Quote' %}</span>[/quote]</p>
18 <p>[quote=src]<div class="multiquote"><div class="quote-header">src</div><div class="quote-text">{% trans 'Quote' %}</div></div><br />[/quote]</p>
20 <p>[quote=src]<div class="multiquote"><div class="quote-header">src</div><div class="quote-text">{% trans 'Quote' %}</div></div><br />[/quote]</p>
19 <p>[tag]<a class="tag">tag</a>[/tag]</p>
21 <p>[tag]<a class="tag">tag</a>[/tag]</p>
20 <br/>
22 <hr/>
21 <p>{% trans 'You can try pasting the text and previewing the result here:' %} <a href="{% url 'preview' %}">{% trans 'Preview' %}</a></p>
23 <p>{% trans 'You can try pasting the text and previewing the result here:' %} <a href="{% url 'preview' %}">{% trans 'Preview' %}</a></p>
22 {% endblock %}
24 {% endblock %}
@@ -74,9 +74,7 b''
74 <div id="posts-table">
74 <div id="posts-table">
75 {% for image in images %}
75 {% for image in images %}
76 <div class="gallery_image">
76 <div class="gallery_image">
77 {% autoescape off %}
77 {{ image.get_view|safe }}
78 {{ image.get_view }}
79 {% endautoescape %}
80 <div class="gallery_image_metadata">
78 <div class="gallery_image_metadata">
81 {{ image.get_size.0 }}x{{ image.get_size.1 }}
79 {{ image.get_size.0 }}x{{ image.get_size.1 }}
82 </div>
80 </div>
@@ -65,7 +65,7 b''
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 'Text syntax' %}</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>
@@ -5,7 +5,7 b' import neboard'
5 from boards import views
5 from boards import views
6 from boards.rss import AllThreadsFeed, TagThreadsFeed, ThreadPostsFeed
6 from boards.rss import AllThreadsFeed, TagThreadsFeed, ThreadPostsFeed
7 from boards.views import api, tag_threads, all_threads, \
7 from boards.views import api, tag_threads, all_threads, \
8 settings, all_tags, feed, alias
8 settings, all_tags, feed, stickers
9 from boards.views.authors import AuthorsView
9 from boards.views.authors import AuthorsView
10 from boards.views.notifications import NotificationView
10 from boards.views.notifications import NotificationView
11 from boards.views.static import StaticPageView
11 from boards.views.static import StaticPageView
@@ -42,7 +42,8 b' urlpatterns = ['
42 url(r'^feed/$', views.feed.FeedView.as_view(), name='feed'),
42 url(r'^feed/$', views.feed.FeedView.as_view(), name='feed'),
43
43
44 url(r'^settings/$', settings.SettingsView.as_view(), name='settings'),
44 url(r'^settings/$', settings.SettingsView.as_view(), name='settings'),
45 url(r'^aliases/(?P<category>\w+)/$', alias.AliasesView.as_view(), name='aliases'),
45 url(r'^stickers/$', stickers.AliasesView.as_view(), name='stickers'),
46 url(r'^stickers/(?P<category>\w+)/$', stickers.AliasesView.as_view(), name='stickers'),
46 url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'),
47 url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'),
47 url(r'^authors/$', AuthorsView.as_view(), name='authors'),
48 url(r'^authors/$', AuthorsView.as_view(), name='authors'),
48
49
@@ -3,7 +3,7 b' import logging'
3
3
4 from django.core import serializers
4 from django.core import serializers
5 from django.db import transaction
5 from django.db import transaction
6 from django.http import HttpResponse
6 from django.http import HttpResponse, HttpResponseBadRequest
7 from django.shortcuts import get_object_or_404
7 from django.shortcuts import get_object_or_404
8 from django.views.decorators.csrf import csrf_protect
8 from django.views.decorators.csrf import csrf_protect
9
9
@@ -11,6 +11,7 b' from boards.abstracts.settingsmanager im'
11 from boards.forms import PostForm, PlainErrorList
11 from boards.forms import PostForm, PlainErrorList
12 from boards.mdx_neboard import Parser
12 from boards.mdx_neboard import Parser
13 from boards.models import Post, Thread, Tag, Attachment, TagAlias
13 from boards.models import Post, Thread, Tag, Attachment, TagAlias
14 from boards.models.attachment import AttachmentSticker
14 from boards.models.thread import STATUS_ARCHIVE
15 from boards.models.thread import STATUS_ARCHIVE
15 from boards.models.user import Notification
16 from boards.models.user import Notification
16 from boards.utils import datetime_to_epoch
17 from boards.utils import datetime_to_epoch
@@ -190,16 +191,15 b' def api_get_tags(request):'
190
191
191
192
192 def api_get_stickers(request):
193 def api_get_stickers(request):
193 attachments = Attachment.objects.filter(mimetype__in=FILE_TYPES_IMAGE)\
194 term = request.GET.get('term')
194 .exclude(alias='').exclude(alias=None)
195 if not term:
196 return HttpResponseBadRequest()
197
198 stickers = AttachmentSticker.objects.filter(name__contains=term)
195
199
196 term = request.GET.get('term')
200 image_dict = [{'thumb': sticker.attachment.get_thumb_url(),
197 if term:
201 'alias': sticker.name}
198 attachments = attachments.filter(alias__contains=term)
202 for sticker in stickers]
199
200 image_dict = [{'thumb': attachment.get_thumb_url(),
201 'alias': attachment.alias}
202 for attachment in attachments]
203
203
204 return HttpResponse(content=json.dumps(image_dict))
204 return HttpResponse(content=json.dumps(image_dict))
205
205
@@ -1,32 +1,25 b''
1 from django.db import transaction
1 from django.shortcuts import render
2 from django.shortcuts import render, redirect
3 from django.utils import timezone
4 from django.utils.decorators import method_decorator
2 from django.utils.decorators import method_decorator
5 from django.views.decorators.csrf import csrf_protect
3 from django.views.decorators.csrf import csrf_protect
6
4
7 from boards.abstracts.settingsmanager import get_settings_manager, \
5 from boards.models.attachment import AttachmentSticker
8 SETTING_USERNAME, SETTING_LAST_NOTIFICATION_ID, SETTING_IMAGE_VIEWER
6 from boards.views.base import BaseBoardView
9 from boards.middlewares import SESSION_TIMEZONE
10 from boards.views.base import BaseBoardView, CONTEXT_FORM
11 from boards.forms import SettingsForm, PlainErrorList
12 from boards import settings
13 from boards.models import Attachment
14
7
15 CONTEXT_IMAGE_ALIASES = 'image_aliases'
8 CONTEXT_STICKERS = 'stickers'
16
9
17 TEMPLATE = 'boards/aliases.html'
10 TEMPLATE = 'boards/aliases.html'
18
11
19
12
20 class AliasesView(BaseBoardView):
13 class AliasesView(BaseBoardView):
21 @method_decorator(csrf_protect)
14 @method_decorator(csrf_protect)
22 def get(self, request, category):
15 def get(self, request, category=None):
23 params = dict()
16 params = dict()
24 settings_manager = get_settings_manager(request)
25
17
26 selected_theme = settings_manager.get_theme()
18 if category:
27
19 params[CONTEXT_STICKERS] = AttachmentSticker.objects.filter(
28 params[CONTEXT_IMAGE_ALIASES] = Attachment.objects.exclude(alias='')\
20 name__startswith=(category + '/'))
29 .exclude(alias=None).filter(alias__startswith=(category + '/'))
21 else:
22 params[CONTEXT_STICKERS] = AttachmentSticker.objects.all()
30
23
31 return render(request, TEMPLATE, params)
24 return render(request, TEMPLATE, params)
32
25
General Comments 0
You need to be logged in to leave comments. Login now