# HG changeset patch # User neko259 # Date 2016-04-22 08:39:39 # Node ID 9178427eb3553fb7f09759fd2c455e0a5fb22a03 # Parent a55d11eb0edeb6002d46e2236b450889d7594805 Added image aliases to upload the same images (like "fake" or "gtfo") diff --git a/boards/abstracts/attachment_alias.py b/boards/abstracts/attachment_alias.py new file mode 100644 --- /dev/null +++ b/boards/abstracts/attachment_alias.py @@ -0,0 +1,27 @@ +from boards.abstracts.settingsmanager import SessionSettingsManager +from boards.models import PostImage + +class AttachmentAlias: + def get_image(alias): + pass + + +class SessionAttachmentAlias(AttachmentAlias): + def __init__(self, session): + self.session = session + + def get_image(self, alias): + settings_manager = SessionSettingsManager(self.session) + return settings_manager.get_image_by_alias(alias) + + +class ModelAttachmentAlias(AttachmentAlias): + def get_image(self, alias): + return PostImage.objects.filter(alias=alias).first() + + +def get_image_by_alias(alias, session): + image = SessionAttachmentAlias(session).get_image(alias) or ModelAttachmentAlias().get_image(alias) + + if image is not None: + return image diff --git a/boards/abstracts/settingsmanager.py b/boards/abstracts/settingsmanager.py --- a/boards/abstracts/settingsmanager.py +++ b/boards/abstracts/settingsmanager.py @@ -19,6 +19,7 @@ SETTING_USERNAME = 'username' SETTING_LAST_NOTIFICATION_ID = 'last_notification' SETTING_IMAGE_VIEWER = 'image_viewer' SETTING_TRIPCODE = 'tripcode' +SETTING_IMAGES = 'images_aliases' DEFAULT_THEME = 'md' @@ -153,6 +154,17 @@ class SettingsManager: names = set(name.strip() for name in names) return names + def get_image_by_alias(self, alias): + images = self.get_setting(SETTING_IMAGES) + if images is not None and len(images) > 0: + return images.get(alias) + + def add_image_alias(self, alias, image): + images = self.get_setting(SETTING_IMAGES) + if images is None: + images = dict() + images.put(alias, image) + class SessionSettingsManager(SettingsManager): """ diff --git a/boards/admin.py b/boards/admin.py --- a/boards/admin.py +++ b/boards/admin.py @@ -1,16 +1,17 @@ from django.contrib import admin -from boards.models import Post, Tag, Ban, Thread, Banner from django.utils.translation import ugettext_lazy as _ +from django.core.urlresolvers import reverse +from boards.models import Post, Tag, Ban, Thread, Banner, PostImage @admin.register(Post) class PostAdmin(admin.ModelAdmin): - list_display = ('id', 'title', 'text', 'poster_ip') + list_display = ('id', 'title', 'text', 'poster_ip', 'linked_images') list_filter = ('pub_time',) search_fields = ('id', 'title', 'text', 'poster_ip') exclude = ('referenced_posts', 'refmap') - readonly_fields = ('poster_ip', 'threads', 'thread', 'images', + readonly_fields = ('poster_ip', 'threads', 'thread', 'linked_images', 'attachments', 'uid', 'url', 'pub_time', 'opening') def ban_poster(self, request, queryset): @@ -35,6 +36,12 @@ class PostAdmin(admin.ModelAdmin): posts.update(hidden=True) self.message_user(request, _('{} posters were banned, {} messages were hidden').format(bans, hidden)) + def linked_images(self, obj: Post): + images = obj.images.all() + image_urls = ['{}'.format(reverse('admin:%s_%s_change' %(image._meta.app_label, image._meta.model_name), args=[image.id]), image.hash) for image in images] + return ', '.join(image_urls) + linked_images.allow_tags = True + actions = ['ban_poster', 'ban_with_hiding'] @@ -97,3 +104,8 @@ class BanAdmin(admin.ModelAdmin): @admin.register(Banner) class BannerAdmin(admin.ModelAdmin): list_display = ('title', 'text') + + +@admin.register(PostImage) +class PostImageAdmin(admin.ModelAdmin): + search_fields = ('alias',) diff --git a/boards/forms.py b/boards/forms.py --- a/boards/forms.py +++ b/boards/forms.py @@ -13,6 +13,7 @@ from django.utils.translation import uge from django.utils import timezone from boards.abstracts.settingsmanager import get_settings_manager +from boards.abstracts.attachment_alias import get_image_by_alias from boards.mdx_neboard import formatters from boards.models.attachment.downloaders import Downloader from boards.models.post import TITLE_MAX_LENGTH @@ -183,6 +184,7 @@ class PostForm(NeboardForm): session = None need_to_ban = False + image = None def _update_file_extension(self, file): if file: @@ -229,13 +231,20 @@ class PostForm(NeboardForm): url = self.cleaned_data['file_url'] file = None + if url: - file = self._get_file_from_url(url) + file = get_image_by_alias(url, self.session) + self.image = file - if not file: - raise forms.ValidationError(_('Invalid URL')) - else: - validate_file_size(file.size) + if file is not None: + return + + if file is None: + file = self._get_file_from_url(url) + if not file: + raise forms.ValidationError(_('Invalid URL')) + else: + validate_file_size(file.size) self._update_file_extension(file) return file @@ -312,11 +321,18 @@ class PostForm(NeboardForm): else: return title + def get_images(self): + if self.image: + return [self.image] + else: + return [] + def _clean_text_file(self): text = self.cleaned_data.get('text') file = self.get_file() + images = self.get_images() - if (not text) and (not file): + if (not text) and (not file) and len(images) == 0: error_message = _('Either text or file must be entered.') self._errors['text'] = self.error_class([error_message]) diff --git a/boards/migrations/0041_auto_20160124_2341.py b/boards/migrations/0041_auto_20160124_2341.py new file mode 100644 --- /dev/null +++ b/boards/migrations/0041_auto_20160124_2341.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('boards', '0040_thread_monochrome'), + ] + + operations = [ + migrations.AddField( + model_name='attachment', + name='original_filename', + field=models.TextField(null=True), + ), + migrations.AddField( + model_name='postimage', + name='original_filename', + field=models.TextField(null=True), + ), + ] diff --git a/boards/migrations/0042_auto_20160422_1053.py b/boards/migrations/0042_auto_20160422_1053.py new file mode 100644 --- /dev/null +++ b/boards/migrations/0042_auto_20160422_1053.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.5 on 2016-04-22 07:53 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('boards', '0041_auto_20160124_2341'), + ] + + operations = [ + migrations.RemoveField( + model_name='attachment', + name='original_filename', + ), + migrations.RemoveField( + model_name='postimage', + name='original_filename', + ), + migrations.AddField( + model_name='postimage', + name='alias', + field=models.TextField(blank=True, null=True, unique=True), + ), + ] diff --git a/boards/models/attachment/downloaders.py b/boards/models/attachment/downloaders.py --- a/boards/models/attachment/downloaders.py +++ b/boards/models/attachment/downloaders.py @@ -67,3 +67,4 @@ class YouTubeDownloader(Downloader): @staticmethod def handles(url: str) -> bool: return YOUTUBE_URL.match(url) + diff --git a/boards/models/image.py b/boards/models/image.py --- a/boards/models/image.py +++ b/boards/models/image.py @@ -56,6 +56,7 @@ class PostImage(models.Model, Viewable): preview_width_field='pre_width', preview_height_field='pre_height') hash = models.CharField(max_length=HASH_LENGTH) + alias = models.TextField(unique=True, null=True, blank=True) def save(self, *args, **kwargs): """ diff --git a/boards/models/post/manager.py b/boards/models/post/manager.py --- a/boards/models/post/manager.py +++ b/boards/models/post/manager.py @@ -31,7 +31,7 @@ class PostManager(models.Manager): @transaction.atomic def create_post(self, title: str, text: str, file=None, thread=None, ip=NO_IP, tags: list=None, opening_posts: list=None, - tripcode='', monochrome=False): + tripcode='', monochrome=False, images=[]): """ Creates new post """ @@ -87,6 +87,8 @@ class PostManager(models.Manager): post.images.add(PostImage.objects.create_with_hash(file)) else: post.attachments.add(Attachment.objects.create_with_hash(file)) + for image in images: + post.images.add(image) post.connect_threads(opening_posts) 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,10 @@ {% else %}

{% trans 'No hidden tags.' %}

{% endif %} + + {% for image in image_aliases %} + {{ image.alias }}:
+ {% endfor %}
diff --git a/boards/views/all_threads.py b/boards/views/all_threads.py --- a/boards/views/all_threads.py +++ b/boards/views/all_threads.py @@ -138,6 +138,7 @@ class AllThreadsView(PostMixin, FileUplo text = data[FORM_TEXT] file = form.get_file() threads = data[FORM_THREADS] + images = form.get_images() text = self._remove_invalid_links(text) @@ -147,7 +148,7 @@ class AllThreadsView(PostMixin, FileUplo post = Post.objects.create_post(title=title, text=text, file=file, ip=ip, tags=tags, opening_posts=threads, tripcode=form.get_tripcode(), - monochrome=monochrome) + monochrome=monochrome, images=images) # This is required to update the threads to which posts we have replied # when creating this one diff --git a/boards/views/settings.py b/boards/views/settings.py --- a/boards/views/settings.py +++ b/boards/views/settings.py @@ -8,6 +8,7 @@ from boards.middlewares import SESSION_T from boards.views.base import BaseBoardView, CONTEXT_FORM from boards.forms import SettingsForm, PlainErrorList from boards import settings +from boards.models import PostImage FORM_THEME = 'theme' FORM_USERNAME = 'username' @@ -15,6 +16,7 @@ FORM_TIMEZONE = 'timezone' FORM_IMAGE_VIEWER = 'image_viewer' CONTEXT_HIDDEN_TAGS = 'hidden_tags' +CONTEXT_IMAGE_ALIASES = 'image_aliases' TEMPLATE = 'boards/settings.html' @@ -41,6 +43,7 @@ class SettingsView(BaseBoardView): params[CONTEXT_FORM] = form params[CONTEXT_HIDDEN_TAGS] = settings_manager.get_hidden_tags() + params[CONTEXT_IMAGE_ALIASES] = PostImage.objects.exclude(alias='').exclude(alias=None) return render(request, TEMPLATE, params) diff --git a/boards/views/thread/thread.py b/boards/views/thread/thread.py --- a/boards/views/thread/thread.py +++ b/boards/views/thread/thread.py @@ -129,6 +129,7 @@ class ThreadView(BaseBoardView, PostMixi text = data[FORM_TEXT] file = form.get_file() threads = data[FORM_THREADS] + images = form.get_images() text = self._remove_invalid_links(text) @@ -137,7 +138,8 @@ class ThreadView(BaseBoardView, PostMixi post = Post.objects.create_post(title=title, text=text, file=file, thread=post_thread, ip=ip, opening_posts=threads, - tripcode=form.get_tripcode()) + tripcode=form.get_tripcode(), + images=images) post.notify_clients() if html_response: