diff --git a/boards/abstracts/attachment_alias.py b/boards/abstracts/attachment_alias.py --- a/boards/abstracts/attachment_alias.py +++ b/boards/abstracts/attachment_alias.py @@ -13,7 +13,7 @@ class SessionAttachmentAlias(AttachmentA def get_image(self, alias): settings_manager = SessionSettingsManager(self.session) - return settings_manager.get_image_by_alias(alias) + return settings_manager.get_attachment_by_alias(alias) class ModelAttachmentAlias(AttachmentAlias): diff --git a/boards/abstracts/settingsmanager.py b/boards/abstracts/settingsmanager.py --- a/boards/abstracts/settingsmanager.py +++ b/boards/abstracts/settingsmanager.py @@ -1,5 +1,6 @@ from boards import settings -from boards.models import Tag, TagAlias +from boards.models import Tag, TagAlias, Attachment +from boards.models.attachment import AttachmentSticker from boards.models.thread import FAV_THREAD_NO_UPDATES from boards.models.tag import DEFAULT_LOCALE @@ -164,16 +165,29 @@ class SettingsManager: names = set(name.strip() for name in names) return names - def get_image_by_alias(self, alias): + def get_attachment_by_alias(self, alias): images = self.get_setting(SETTING_IMAGES) - if images is not None and len(images) > 0: - return images.get(alias) + if images and alias in images: + return Attachment.objects.get(id=images.get(alias)) - def add_image_alias(self, alias, image): + def add_attachment_alias(self, alias, attachment): images = self.get_setting(SETTING_IMAGES) if images is None: images = dict() - images.put(alias, image) + images[alias] = attachment.id + self.set_setting(SETTING_IMAGES, images) + + def remove_attachment_alias(self, alias): + images = self.get_setting(SETTING_IMAGES) + del images[alias] + self.set_setting(SETTING_IMAGES, images) + + def get_stickers(self): + images = self.get_setting(SETTING_IMAGES) + if images: + return [AttachmentSticker(name=key, + attachment=Attachment.objects.get(id=value)) + for key, value in images.items()] class SessionSettingsManager(SettingsManager): diff --git a/boards/locale/ru/LC_MESSAGES/django.mo b/boards/locale/ru/LC_MESSAGES/django.mo index 9f4a7ac3acb87e564c1e6dd5462f23aa685d77c3..05b7597076740e7609027d1302020687531bc18f GIT binary patch literal 12483 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 diff --git a/boards/locale/ru/LC_MESSAGES/django.po b/boards/locale/ru/LC_MESSAGES/django.po --- a/boards/locale/ru/LC_MESSAGES/django.po +++ b/boards/locale/ru/LC_MESSAGES/django.po @@ -622,3 +622,12 @@ msgstr "Стикеры" msgid "Available by addresses:" msgstr "Доступно по адресам:" + +msgid "Local stickers" +msgstr "Локальные стикеры" + +msgid "Global stickers" +msgstr "Глобальные стикеры" + +msgid "Remove sticker" +msgstr "Удалить стикер" diff --git a/boards/locale/ru/LC_MESSAGES/djangojs.mo b/boards/locale/ru/LC_MESSAGES/djangojs.mo index 3219613ff9a7e149dcf8c5303f428cf78d4d9901..c48b521be23655a1d2e8f4414e48496ab3389f07 GIT binary patch literal 1175 zc${rgL2naB7@agwz$#UtT#%5M92ym&ad$%y=_aOG;tjR1W6O3x^nkRrCuZq-$C_Cq zsE``Mp{yW z$#FtH1+RdQg1;Zu55SY)CqsTSp5^)nTm&E9MaT^J5*Vw<2g95w$%nwcB;&A`%AGJw?N6CbCxl(?ICyEA_SGlBIN+Bmm&_z3YD>77#Sdp3(S9mLCr8Yay zr3ysk(3-n&&OPhV^IpACsxIZ~yeDMLDykE-*_nPvv8Hfnu2yZb1>lRa=A>G+=@r%yoy^Y&%4E9-D@;XLmGAZ_yE@Ae%GO8cj@eM5_zs%o)3e(kewY3 zqE<>3Z|D2$yp>xJQOqM;cfAKe%&)~?^g=&~W@+oPFBOjq%gseLv!hF5t#HY_s3npg z+@Uky263(y_N5=PMIpP&p;0d_RpG=e&5ni7qt9%sP_XIbBu$RiM8US{SJa|TTAwaV zjYe~Y>ExI?tU24FH*RDWXsl!K*zimpo6Qk@PjBm|dZ3@_4YOu$Q@w@8OEk93ZT-sp zqBp6zY1Z@xn(Jnj=tp{h#*gN%SsVS!^l$KNn49_~)z8f>?AuE91NgS}GotTf-|uD> zqZdg#^*qK1SDT;px_$-uIt8V#f!@^5)9yCW53%F5SxpndiZK86nLFvWhvp~jcsi0G mDfG#EFhMYQky?^1e~hksZ`<5?zj~AW|6VM3H_E%JP4X`x5U`^F diff --git a/boards/locale/ru/LC_MESSAGES/djangojs.po b/boards/locale/ru/LC_MESSAGES/djangojs.po --- a/boards/locale/ru/LC_MESSAGES/djangojs.po +++ b/boards/locale/ru/LC_MESSAGES/djangojs.po @@ -59,3 +59,5 @@ msgstr "Расчёт PoW..." msgid "Duplicates search" msgstr "Поиск дубликатов" +msgid "Add local sticker" +msgstr "Добавить локальный стикер" diff --git a/boards/locale/uk/LC_MESSAGES/django.mo b/boards/locale/uk/LC_MESSAGES/django.mo index f0b7e10e74e1d2962a50cb62f5a8ee19a88a788a..8ac9b88866d658c7cd38790346bfceb553f56a13 GIT binary patch literal 12644 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 Rhn_IWf&486bq=7Y{{^!xhI9Y` diff --git a/boards/locale/uk/LC_MESSAGES/django.po b/boards/locale/uk/LC_MESSAGES/django.po --- a/boards/locale/uk/LC_MESSAGES/django.po +++ b/boards/locale/uk/LC_MESSAGES/django.po @@ -622,3 +622,12 @@ msgstr "Стікери" msgid "Available by addresses:" msgstr "Доступно за адресами:" + +msgid "Local stickers" +msgstr "Локальні стікери" + +msgid "Global stickers" +msgstr "Глобальні стікери" + +msgid "Remove sticker" +msgstr "Видалити стікер" diff --git a/boards/locale/uk/LC_MESSAGES/djangojs.mo b/boards/locale/uk/LC_MESSAGES/djangojs.mo index 5f9713279012b06095bed1c2eb1f134cc80c4fcd..969e75f0458297132ae18f0b268270a157c673e8 GIT binary patch literal 1260 zc$}3|U2hvj6rIrWWdVYUH;}jyBBCl|cGFaZjooI6H?4&oTeedKZ(DofF06N~nRNwH zCE8S=K1AwE36Fq~cy^<>UujaQzhL$c@EhPCaK?7<3qr8c*)#XvbMHN~+TTx|{DI-g z0dE5_@G9_xO`bo1H-JBZ*MSprllaZKNzVfKHLwdl1zw$-^f$q;fWx^-UjiNh-vS>X zK6iq#cfnV{?|{DtzXkpcoCiMxFWJ4|3wF;*#tPsq@FnoCV2onVO?@I{F90uFkJFs> z_Y&|t@ZvPb{7#2r*$!jUY1IBoD7Geh{XrTfU8>8^^7%X~4f=7^4pX5?i%_+%vWg5l z5ZGc}>XZ_h(v}<~9o7_ytx!*B9d?CPG=;h*6bYrInrBfD>B(EOsp^v)^Q-@4RI~fGu`Kb-{936FZpz-=2gpQzNl>kxk{*0-cn(r z<1m%VqxH>7g*N{mn*A&sniIX&GV2Z-2pDZTO#avRPi@1Zd%KQN@X>U@=|qY z8d$BCtHJDkZr;hQ$s`pC)_v25AQfMyANJ!gN>-?SHB?%p#m&|_U!Li#tu3K=khG=! z;2tesiPBs>9;h(p>r(Z!M@fGi>f+fInjDMoC-1pVvFOsm0@*&hZ~-elkbd?d+C$OlBW+55sK#a6D&^ znIAEK4>-iip}B8H*mRiPIqt>OT^KqtPvB-+BhZM<1JKYsLe=I+|0*A1`Ayv50E_?j zINtG#y$T%QJ)VoP*5`dIoF{86*u>hO1-R!m*%`=>j%su-JX5Rl>GTUM1 M=|4OEe+3Ns3+>{}, {}'\ - ' 🔍 '\ + ' 🔍 '\ '' URL_VIEW = '
' \ '{}' \ @@ -100,10 +100,10 @@ def file_exists(filename): class AbstractViewer: - def __init__(self, file, file_type, hash, url): + def __init__(self, file, file_type, id, url): self.file = file self.file_type = file_type - self.hash = hash + self.id = id self.url = url self.extension = get_extension(self.file.name) @@ -122,7 +122,7 @@ class AbstractViewer: return ABSTRACT_VIEW.format(self.get_format_view(), self.file.url, self.file_type, filesizeformat(self.file.size), - self.file_type, search_url, self.file.name) + self.file_type, search_url, self.file.name, self.id) def get_format_view(self): image_name = PLAIN_FILE_FORMATS.get(self.extension, self.extension) @@ -193,7 +193,7 @@ class ImageViewer(AbstractViewer): return IMAGE_FORMAT_VIEW.format(CSS_CLASS_THUMB, thumb_url, - self.hash, + self.id, str(pre_width), str(pre_height), str(width), str(height), full=self.file.url, image_meta=metadata) 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 @@ -160,6 +160,7 @@ function addContextMenu() { var fileSearchUrl = $trigger.data('search-url'); var isImage = IMAGE_TYPES.indexOf($trigger.data('type')) > -1; var hasUrl = fileSearchUrl.length > 0; + var id = $trigger.data('id'); return { items: { duplicates: { @@ -188,8 +189,17 @@ function addContextMenu() { callback: function(key, opts) { window.location = 'http://tineye.com/search?url=' + fileSearchUrl; } + }, + addAlias: { + name: gettext('Add local sticker'), + callback: function(key, opts) { + var alias = prompt(gettext('Input sticker name')); + if (alias) { + window.location = '/stickers/?action=add&name=' + alias + '&id=' + id; + } + } } - }, + } }; } }); diff --git a/boards/templates/boards/aliases.html b/boards/templates/boards/aliases.html --- a/boards/templates/boards/aliases.html +++ b/boards/templates/boards/aliases.html @@ -10,11 +10,24 @@ {% block content %}
- {% for sticker in stickers %} - - {% endfor %} + {% if local_stickers %} +

{% trans "Local stickers" %}

+ {% for sticker in local_stickers %} + + {% endfor %} + {% endif %} + {% if global_stickers %} +

{% trans "Global stickers" %}

+ {% for sticker in global_stickers %} + + {% endfor %} + {% endif %}
{% endblock %} diff --git a/boards/templates/boards/settings.html b/boards/templates/boards/settings.html --- a/boards/templates/boards/settings.html +++ b/boards/templates/boards/settings.html @@ -24,6 +24,7 @@ {% else %}

{% trans 'No hidden tags.' %}

{% endif %} +

{% trans 'Stickers' %}

diff --git a/boards/views/api.py b/boards/views/api.py --- a/boards/views/api.py +++ b/boards/views/api.py @@ -195,7 +195,9 @@ def api_get_stickers(request): if not term: return HttpResponseBadRequest() - stickers = AttachmentSticker.objects.filter(name__contains=term) + global_stickers = AttachmentSticker.objects.filter(name__contains=term) + local_stickers = [sticker for sticker in get_settings_manager(request).get_stickers() if term in sticker.name] + stickers = list(global_stickers) + local_stickers image_dict = [{'thumb': sticker.attachment.get_thumb_url(), 'alias': sticker.name} diff --git a/boards/views/stickers.py b/boards/views/stickers.py --- a/boards/views/stickers.py +++ b/boards/views/stickers.py @@ -1,11 +1,13 @@ -from django.shortcuts import render +from django.shortcuts import render, redirect from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_protect -from boards.models.attachment import AttachmentSticker +from boards.abstracts.settingsmanager import get_settings_manager +from boards.models.attachment import AttachmentSticker, Attachment from boards.views.base import BaseBoardView -CONTEXT_STICKERS = 'stickers' +CONTEXT_GLOBAL_STICKERS = 'global_stickers' +CONTEXT_LOCAL_STICKERS = 'local_stickers' TEMPLATE = 'boards/aliases.html' @@ -13,13 +15,31 @@ TEMPLATE = 'boards/aliases.html' class AliasesView(BaseBoardView): @method_decorator(csrf_protect) def get(self, request, category=None): + result = self._process_creation(request) + if result: + return result + params = dict() if category: - params[CONTEXT_STICKERS] = AttachmentSticker.objects.filter( + params[CONTEXT_GLOBAL_STICKERS] = AttachmentSticker.objects.filter( name__startswith=(category + '/')) else: - params[CONTEXT_STICKERS] = AttachmentSticker.objects.all() + params[CONTEXT_GLOBAL_STICKERS] = AttachmentSticker.objects.all() + params[CONTEXT_LOCAL_STICKERS] = get_settings_manager(request).get_stickers() return render(request, TEMPLATE, params) + def _process_creation(self, request): + action = request.GET.get('action') + if action == 'add' and 'name' in request.GET and 'id' in request.GET: + name = request.GET['name'] + id = request.GET['id'] + attachment = Attachment.objects.get(id=id) + get_settings_manager(request).add_attachment_alias(name, attachment) + + return redirect('stickers') + if action == 'remove' and 'name' in request.GET: + name = request.GET['name'] + get_settings_manager(request).remove_attachment_alias(name) + return redirect('stickers')