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
@@ -1,5 +1,6 @@
from boards.abstracts.settingsmanager import SessionSettingsManager
-from boards.models import PostImage
+from boards.models import Attachment
+
class AttachmentAlias:
def get_image(alias):
@@ -17,7 +18,7 @@ class SessionAttachmentAlias(AttachmentA
class ModelAttachmentAlias(AttachmentAlias):
def get_image(self, alias):
- return PostImage.objects.filter(alias=alias).first()
+ return Attachment.objects.filter(alias=alias).first()
def get_image_by_alias(alias, session):
diff --git a/boards/abstracts/constants.py b/boards/abstracts/constants.py
new file mode 100644
--- /dev/null
+++ b/boards/abstracts/constants.py
@@ -0,0 +1,1 @@
+FILE_DIRECTORY = 'files/'
diff --git a/boards/admin.py b/boards/admin.py
--- a/boards/admin.py
+++ b/boards/admin.py
@@ -1,8 +1,8 @@
+from boards.models.attachment import FILE_TYPES_IMAGE
from django.contrib import admin
from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
-from django.db.models import F
-from boards.models import Post, Tag, Ban, Thread, Banner, PostImage, KeyPair, GlobalId
+from boards.models import Post, Tag, Ban, Thread, Banner, Attachment, KeyPair, GlobalId
@admin.register(Post)
@@ -40,11 +40,11 @@ class PostAdmin(admin.ModelAdmin):
self.message_user(request, _('{} posters were banned, {} messages were hidden').format(bans, hidden))
def linked_images(self, obj: Post):
- images = obj.images.all()
+ images = obj.attachments.filter(mimetype__in=FILE_TYPES_IMAGE)
image_urls = [''.format(
reverse('admin:%s_%s_change' % (image._meta.app_label,
image._meta.model_name),
- args=[image.id]), image.image.url_200x150) for image in images]
+ args=[image.id]), image.file.url_200x150) for image in images]
return ', '.join(image_urls)
linked_images.allow_tags = True
@@ -142,8 +142,8 @@ class BannerAdmin(admin.ModelAdmin):
list_display = ('title', 'text')
-@admin.register(PostImage)
-class PostImageAdmin(admin.ModelAdmin):
+@admin.register(Attachment)
+class AttachmentAdmin(admin.ModelAdmin):
search_fields = ('alias',)
diff --git a/boards/management/commands/cleanfiles.py b/boards/management/commands/cleanfiles.py
--- a/boards/management/commands/cleanfiles.py
+++ b/boards/management/commands/cleanfiles.py
@@ -1,46 +1,36 @@
import os
+from boards.abstracts.constants import FILE_DIRECTORY
from django.core.management import BaseCommand
from django.db import transaction
from boards.models import Attachment
-from boards.models.attachment import FILES_DIRECTORY
-from boards.models.image import IMAGES_DIRECTORY, PostImage, IMAGE_THUMB_SIZE
from neboard.settings import MEDIA_ROOT
__author__ = 'neko259'
+THUMB_SIZE = (200, 150)
+
class Command(BaseCommand):
help = 'Remove files whose models were deleted'
@transaction.atomic
def handle(self, *args, **options):
- count = 0
- thumb_prefix = '.{}x{}'.format(*IMAGE_THUMB_SIZE)
-
- model_files = os.listdir(MEDIA_ROOT + IMAGES_DIRECTORY)
- for file in model_files:
- image_name = file if thumb_prefix not in file else file.replace(thumb_prefix, '')
- found = PostImage.objects.filter(
- image=IMAGES_DIRECTORY + image_name).exists()
-
- if not found:
- print('Missing {}'.format(image_name))
- os.remove(MEDIA_ROOT + IMAGES_DIRECTORY + file)
- count += 1
- print('Deleted {} image files.'.format(count))
+ thumb_prefix = '.{}x{}'.format(*THUMB_SIZE)
count = 0
- model_files = os.listdir(MEDIA_ROOT + FILES_DIRECTORY)
+ model_files = os.listdir(MEDIA_ROOT + FILE_DIRECTORY)
for file in model_files:
- found = Attachment.objects.filter(file=FILES_DIRECTORY + file)\
+ model_filename = file if thumb_prefix not in file else file.replace(
+ thumb_prefix, '')
+ found = Attachment.objects.filter(file=FILE_DIRECTORY + model_filename)\
.exists()
if not found:
print('Missing {}'.format(file))
- os.remove(MEDIA_ROOT + FILES_DIRECTORY + file)
+ os.remove(MEDIA_ROOT + FILE_DIRECTORY + file)
count += 1
print('Deleted {} attachment files.'.format(count))
diff --git a/boards/migrations/0001_initial.py b/boards/migrations/0001_initial.py
--- a/boards/migrations/0001_initial.py
+++ b/boards/migrations/0001_initial.py
@@ -2,7 +2,6 @@
from __future__ import unicode_literals
from django.db import models, migrations
-import boards.models.image
import boards.models.base
import boards.thumbs
diff --git a/boards/migrations/0047_attachment_alias.py b/boards/migrations/0047_attachment_alias.py
new file mode 100644
--- /dev/null
+++ b/boards/migrations/0047_attachment_alias.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.5 on 2016-05-21 07:43
+from __future__ import unicode_literals
+
+from boards.signals import generate_thumb
+from boards.utils import get_extension
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ def images_to_attachments(apps, schema_editor):
+ PostImage = apps.get_model('boards', 'PostImage')
+ Attachment = apps.get_model('boards', 'Attachment')
+
+ count = 0
+ images = PostImage.objects.all()
+ for image in images:
+ file_type = get_extension(image.image.name)
+ attachment = Attachment.objects.create(
+ file=image.image.file, mimetype=file_type, hash=image.hash,
+ alias=image.alias)
+ generate_thumb(attachment)
+ count += 1
+ print('Processed {} of {} images'.format(count, len(images)))
+ for post in image.post_images.all():
+ post.attachments.add(attachment)
+
+ image.image.close()
+
+ dependencies = [
+ ('boards', '0046_auto_20160520_2307'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='attachment',
+ name='alias',
+ field=models.TextField(blank=True, null=True, unique=True),
+ ),
+ migrations.RunPython(images_to_attachments),
+ ]
diff --git a/boards/migrations/0048_remove_post_images.py b/boards/migrations/0048_remove_post_images.py
new file mode 100644
--- /dev/null
+++ b/boards/migrations/0048_remove_post_images.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.5 on 2016-05-21 08:25
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('boards', '0047_attachment_alias'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='post',
+ name='images',
+ ),
+ ]
diff --git a/boards/migrations/0049_delete_postimage.py b/boards/migrations/0049_delete_postimage.py
new file mode 100644
--- /dev/null
+++ b/boards/migrations/0049_delete_postimage.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.5 on 2016-05-21 08:29
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('boards', '0048_remove_post_images'),
+ ]
+
+ operations = [
+ migrations.DeleteModel(
+ name='PostImage',
+ ),
+ ]
diff --git a/boards/models/__init__.py b/boards/models/__init__.py
--- a/boards/models/__init__.py
+++ b/boards/models/__init__.py
@@ -5,7 +5,6 @@ STATUS_ARCHIVE = 'archived'
from boards.models.sync_key import KeyPair
from boards.models.signature import GlobalId, Signature
-from boards.models.image import PostImage
from boards.models.attachment import Attachment
from boards.models.thread import Thread
from boards.models.post import Post
diff --git a/boards/models/attachment/__init__.py b/boards/models/attachment/__init__.py
--- a/boards/models/attachment/__init__.py
+++ b/boards/models/attachment/__init__.py
@@ -1,8 +1,12 @@
+import boards
+from boards.models import STATUS_ARCHIVE
+from django.core.files.images import get_image_dimensions
from django.db import models
from boards import utils
-from boards.models.attachment.viewers import get_viewers, AbstractViewer
-from boards.utils import get_upload_filename, get_file_mimetype, get_extension
+from boards.models.attachment.viewers import get_viewers, AbstractViewer, \
+ FILE_TYPES_IMAGE
+from boards.utils import get_upload_filename, get_extension, cached_result
class AttachmentManager(models.Manager):
@@ -19,6 +23,13 @@ class AttachmentManager(models.Manager):
return attachment
+ def get_random_images(self, count, tags=None):
+ images = self.filter(mimetype__in=FILE_TYPES_IMAGE).exclude(
+ post_attachments__thread__status=STATUS_ARCHIVE)
+ if tags is not None:
+ images = images.filter(post_attachments__threads__tags__in=tags)
+ return images.order_by('?')[:count]
+
class Attachment(models.Model):
objects = AttachmentManager()
@@ -26,6 +37,7 @@ class Attachment(models.Model):
file = models.FileField(upload_to=get_upload_filename)
mimetype = models.CharField(max_length=50)
hash = models.CharField(max_length=36)
+ alias = models.TextField(unique=True, null=True, blank=True)
def get_view(self):
file_viewer = None
@@ -40,3 +52,27 @@ class Attachment(models.Model):
def __str__(self):
return self.file.url
+
+ def get_random_associated_post(self):
+ posts = boards.models.Post.objects.filter(attachments__in=[self])
+ return posts.order_by('?').first()
+
+ @cached_result()
+ def get_size(self):
+ if self.mimetype in FILE_TYPES_IMAGE:
+ return get_image_dimensions(self.file)
+ else:
+ return 200, 150
+
+ def get_thumb_url(self):
+ split = self.file.url.rsplit('.', 1)
+ w, h = 200, 150
+ return '%s.%sx%s.%s' % (split[0], w, h, split[1])
+
+ @cached_result()
+ def get_preview_size(self):
+ if self.mimetype in FILE_TYPES_IMAGE:
+ preview_path = self.file.path.replace('.', '.200x150.')
+ return get_image_dimensions(preview_path)
+ else:
+ return 200, 150
diff --git a/boards/models/attachment/viewers.py b/boards/models/attachment/viewers.py
--- a/boards/models/attachment/viewers.py
+++ b/boards/models/attachment/viewers.py
@@ -1,3 +1,4 @@
+from django.core.files.images import get_image_dimensions
from django.template.defaultfilters import filesizeformat
from django.contrib.staticfiles.templatetags.staticfiles import static
@@ -15,6 +16,13 @@ FILE_TYPES_AUDIO = (
'mp3',
'opus',
)
+FILE_TYPES_IMAGE = (
+ 'jpeg',
+ 'jpg',
+ 'png',
+ 'bmp',
+ 'gif',
+)
PLAIN_FILE_FORMATS = {
'pdf': 'pdf',
@@ -22,6 +30,9 @@ PLAIN_FILE_FORMATS = {
'txt': 'txt',
}
+CSS_CLASS_IMAGE = 'image'
+CSS_CLASS_THUMB = 'thumb'
+
def get_viewers():
return AbstractViewer.__subclasses__()
@@ -83,3 +94,35 @@ class SvgViewer(AbstractViewer):
return ''\
''\
''.format(self.file.url, self.file.url)
+
+
+class ImageViewer(AbstractViewer):
+ @staticmethod
+ def supports(file_type):
+ return file_type in FILE_TYPES_IMAGE
+
+ def get_format_view(self):
+ metadata = '{}, {}'.format(self.file.name.split('.')[-1],
+ filesizeformat(self.file.size))
+ width, height = get_image_dimensions(self.file.file)
+ preview_path = self.file.path.replace('.', '.200x150.')
+ pre_width, pre_height = get_image_dimensions(preview_path)
+
+ split = self.file.url.rsplit('.', 1)
+ w, h = 200, 150
+ thumb_url = '%s.%sx%s.%s' % (split[0], w, h, split[1])
+
+ return '' \
+ '' \
+ '' \
+ .format(CSS_CLASS_THUMB,
+ thumb_url,
+ str(pre_width),
+ str(pre_height), str(width), str(height),
+ full=self.file.url, image_meta=metadata)
+
diff --git a/boards/models/image.py b/boards/models/image.py
deleted file mode 100644
--- a/boards/models/image.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from django.core.files.images import get_image_dimensions
-from django.db import models
-from django.template.defaultfilters import filesizeformat
-
-from boards import thumbs, utils
-import boards
-from boards.models.base import Viewable
-from boards.models import STATUS_ARCHIVE
-from boards.utils import get_upload_filename
-
-
-__author__ = 'neko259'
-
-
-IMAGE_THUMB_SIZE = (200, 150)
-HASH_LENGTH = 36
-
-CSS_CLASS_IMAGE = 'image'
-CSS_CLASS_THUMB = 'thumb'
-
-
-class PostImageManager(models.Manager):
- def create_with_hash(self, image):
- image_hash = utils.get_file_hash(image)
- existing = self.filter(hash=image_hash)
- if len(existing) > 0:
- post_image = existing[0]
- else:
- post_image = PostImage.objects.create(image=image)
-
- return post_image
-
- def get_random_images(self, count, tags=None):
- images = self.exclude(post_images__thread__status=STATUS_ARCHIVE)
- if tags is not None:
- images = images.filter(post_images__threads__tags__in=tags)
- return images.order_by('?')[:count]
-
-
-class PostImage(models.Model, Viewable):
- objects = PostImageManager()
-
- class Meta:
- app_label = 'boards'
- ordering = ('id',)
-
- image = thumbs.ImageWithThumbsField(upload_to=get_upload_filename,
- blank=True, sizes=(IMAGE_THUMB_SIZE,))
- hash = models.CharField(max_length=HASH_LENGTH)
- alias = models.TextField(unique=True, null=True, blank=True)
-
- def save(self, *args, **kwargs):
- """
- Saves the model and computes the image hash for deduplication purposes.
- """
-
- if not self.pk and self.image:
- self.hash = utils.get_file_hash(self.image)
- super(PostImage, self).save(*args, **kwargs)
-
- def __str__(self):
- return self.image.url
-
- def get_view(self):
- metadata = '{}, {}'.format(self.image.name.split('.')[-1],
- filesizeformat(self.image.size))
- width, height = get_image_dimensions(self.image.file)
- preview_path = self.image.path.replace('.', '.200x150.')
- pre_width, pre_height = get_image_dimensions(preview_path)
- return '
'\
- .format(CSS_CLASS_IMAGE, CSS_CLASS_THUMB,
- self.image.url_200x150,
- str(self.hash), str(pre_width),
- str(pre_height), str(width), str(height),
- full=self.image.url, image_meta=metadata)
-
- def get_random_associated_post(self):
- posts = boards.models.Post.objects.filter(images__in=[self])
- return posts.order_by('?').first()
diff --git a/boards/models/post/__init__.py b/boards/models/post/__init__.py
--- a/boards/models/post/__init__.py
+++ b/boards/models/post/__init__.py
@@ -3,7 +3,8 @@ import uuid
import re
from boards import settings
from boards.abstracts.tripcode import Tripcode
-from boards.models import PostImage, Attachment, KeyPair, GlobalId
+from boards.models import Attachment, KeyPair, GlobalId
+from boards.models.attachment import FILE_TYPES_IMAGE
from boards.models.base import Viewable
from boards.models.post.export import get_exporter, DIFF_TYPE_JSON
from boards.models.post.manager import PostManager
@@ -27,8 +28,6 @@ APP_LABEL_BOARDS = 'boards'
BAN_REASON_AUTO = 'Auto'
-IMAGE_THUMB_SIZE = (200, 150)
-
TITLE_MAX_LENGTH = 200
REGEX_REPLY = re.compile(r'\[post\](\d+)\[/post\]')
@@ -74,8 +73,6 @@ class Post(models.Model, Viewable):
text = TextField(blank=True, null=True)
_text_rendered = TextField(blank=True, null=True, editable=False)
- images = models.ManyToManyField(PostImage, null=True, blank=True,
- related_name='post_images', db_index=True)
attachments = models.ManyToManyField(Attachment, null=True, blank=True,
related_name='attachment_posts')
@@ -212,8 +209,8 @@ class Post(models.Model, Viewable):
def get_search_view(self, *args, **kwargs):
return self.get_view(need_op_data=True, *args, **kwargs)
- def get_first_image(self) -> PostImage:
- return self.images.earliest('id')
+ def get_first_image(self) -> Attachment:
+ return self.attachments.filter(mimetype__in=FILE_TYPES_IMAGE).earliest('id')
def set_global_id(self, key_pair=None):
"""
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
@@ -11,19 +11,11 @@ import boards
from boards.models.user import Ban
from boards.mdx_neboard import Parser
-from boards.models import PostImage, Attachment
+from boards.models import Attachment
from boards import utils
__author__ = 'neko259'
-IMAGE_TYPES = (
- 'jpeg',
- 'jpg',
- 'png',
- 'bmp',
- 'gif',
-)
-
POSTS_PER_DAY_RANGE = 7
NO_IP = '0.0.0.0'
@@ -186,8 +178,4 @@ class PostManager(models.Manager):
list(map(thread.tags.add, tags))
def _add_file_to_post(self, file, post):
- file_type = file.name.split('.')[-1].lower()
- if file_type in IMAGE_TYPES:
- post.images.add(PostImage.objects.create_with_hash(file))
- else:
- post.attachments.add(Attachment.objects.create_with_hash(file))
+ post.attachments.add(Attachment.objects.create_with_hash(file))
diff --git a/boards/models/post/sync.py b/boards/models/post/sync.py
--- a/boards/models/post/sync.py
+++ b/boards/models/post/sync.py
@@ -72,16 +72,11 @@ class SyncManager:
global_id = post.global_id
- images = post.images.all()
attachments = post.attachments.all()
if global_id.content:
model.append(et.fromstring(global_id.content))
- if len(images) > 0 or len(attachments) > 0:
+ if len(attachments) > 0:
attachment_refs = et.SubElement(model, TAG_ATTACHMENT_REFS)
- for image in images:
- SyncManager._attachment_to_xml(
- None, attachment_refs, image.image.file,
- image.hash, image.image.url)
for file in attachments:
SyncManager._attachment_to_xml(
None, attachment_refs, file.file.file,
@@ -116,14 +111,10 @@ class SyncManager:
tripcode = et.SubElement(content_tag, TAG_TRIPCODE)
tripcode.text = post.tripcode
- if len(images) > 0 or len(attachments) > 0:
+ if len(attachments) > 0:
attachments_tag = et.SubElement(content_tag, TAG_ATTACHMENTS)
attachment_refs = et.SubElement(model, TAG_ATTACHMENT_REFS)
- for image in images:
- SyncManager._attachment_to_xml(
- attachments_tag, attachment_refs, image.image.file,
- image.hash, image.image.url)
for file in attachments:
SyncManager._attachment_to_xml(
attachments_tag, attachment_refs, file.file.file,
diff --git a/boards/models/tag.py b/boards/models/tag.py
--- a/boards/models/tag.py
+++ b/boards/models/tag.py
@@ -1,10 +1,11 @@
import hashlib
+from boards.models.attachment import FILE_TYPES_IMAGE
from django.template.loader import render_to_string
from django.db import models
from django.db.models import Count
from django.core.urlresolvers import reverse
-from boards.models import PostImage
+from boards.models import Attachment
from boards.models.base import Viewable
from boards.models.thread import STATUS_ACTIVE, STATUS_BUMPLIMIT, STATUS_ARCHIVE
from boards.utils import cached_result
@@ -107,8 +108,9 @@ class Tag(models.Model, Viewable):
return self.description
def get_random_image_post(self, status=[STATUS_ACTIVE, STATUS_BUMPLIMIT]):
- posts = boards.models.Post.objects.annotate(images_count=Count(
- 'images')).filter(images_count__gt=0, threads__tags__in=[self])
+ posts = boards.models.Post.objects.filter(attachments__mimetype__in=FILE_TYPES_IMAGE)\
+ .annotate(images_count=Count(
+ 'attachments')).filter(images_count__gt=0, threads__tags__in=[self])
if status is not None:
posts = posts.filter(thread__status__in=status)
return posts.order_by('?').first()
@@ -143,5 +145,6 @@ class Tag(models.Model, Viewable):
return self.children
def get_images(self):
- return PostImage.objects.filter(post_images__thread__tags__in=[self])\
- .order_by('-post_images__pub_time')
\ No newline at end of file
+ return Attachment.objects.filter(
+ post_attachments__thread__tags__in=[self]).filter(
+ mimetype__in=FILE_TYPES_IMAGE).order_by('-post_images__pub_time')
\ No newline at end of file
diff --git a/boards/models/thread.py b/boards/models/thread.py
--- a/boards/models/thread.py
+++ b/boards/models/thread.py
@@ -1,5 +1,6 @@
import logging
from adjacent import Client
+from boards.models.attachment import FILE_TYPES_IMAGE
from django.db.models import Count, Sum, QuerySet, Q
from django.utils import timezone
@@ -138,8 +139,10 @@ class Thread(models.Model):
@cached_result(key_method=_get_cache_key)
def get_images_count(self) -> int:
- return self.get_replies().annotate(images_count=Count(
- 'images')).aggregate(Sum('images_count'))['images_count__sum']
+ return self.get_replies().filter(
+ attachments__mimetype__in=FILE_TYPES_IMAGE)\
+ .annotate(images_count=Count(
+ 'attachments')).aggregate(Sum('images_count'))['images_count__sum']
def can_bump(self) -> bool:
"""
@@ -181,7 +184,7 @@ class Thread(models.Model):
"""
query = self.multi_replies.order_by('pub_time').prefetch_related(
- 'images', 'thread', 'attachments')
+ 'thread', 'attachments')
if view_fields_only:
query = query.defer('poster_ip')
return query
@@ -193,9 +196,9 @@ class Thread(models.Model):
"""
Gets replies that have at least one image attached
"""
-
- return self.get_replies(view_fields_only).annotate(images_count=Count(
- 'images')).filter(images_count__gt=0)
+ return self.get_replies(view_fields_only).filter(
+ attachments__mimetype__in=FILE_TYPES_IMAGE).annotate(images_count=Count(
+ 'attachments')).filter(images_count__gt=0)
def get_opening_post(self, only_id=False) -> Post:
"""
diff --git a/boards/signals.py b/boards/signals.py
--- a/boards/signals.py
+++ b/boards/signals.py
@@ -1,7 +1,9 @@
import re
+from boards import thumbs
from boards.mdx_neboard import get_parser
-from boards.models import Post, GlobalId
+from boards.models import Post, GlobalId, Attachment
+from boards.models.attachment.viewers import FILE_TYPES_IMAGE
from boards.models.post import REGEX_NOTIFICATION, REGEX_REPLY,\
REGEX_GLOBAL_REPLY
from boards.models.post.manager import post_import_deps
@@ -12,6 +14,9 @@ from django.dispatch import receiver
from django.utils import timezone
+THUMB_SIZES = ((200, 150),)
+
+
@receiver(post_save, sender=Post)
def connect_replies(instance, **kwargs):
for reply_number in re.finditer(REGEX_REPLY, instance.get_raw_text()):
@@ -90,3 +95,22 @@ def update_thread_on_delete(instance, **
def delete_global_id(instance, **kwargs):
if instance.global_id and instance.global_id.id:
instance.global_id.delete()
+
+
+@receiver(post_save, sender=Attachment)
+def generate_thumb(instance, **kwargs):
+ if instance.mimetype in FILE_TYPES_IMAGE:
+ for size in THUMB_SIZES:
+ (w, h) = size
+ split = instance.file.name.rsplit('.', 1)
+ thumb_name = '%s.%sx%s.%s' % (split[0], w, h, split[1])
+
+ if not instance.file.storage.exists(thumb_name):
+ # you can use another thumbnailing function if you like
+ thumb_content = thumbs.generate_thumb(instance.file, size, split[1])
+
+ thumb_name_ = instance.file.storage.save(thumb_name, thumb_content)
+
+ if not thumb_name == thumb_name_:
+ raise ValueError(
+ 'There is already a file named %s' % thumb_name_)
diff --git a/boards/templates/boards/all_threads.html b/boards/templates/boards/all_threads.html
--- a/boards/templates/boards/all_threads.html
+++ b/boards/templates/boards/all_threads.html
@@ -40,11 +40,11 @@
{% if random_image_post %}
- {% with image=random_image_post.images.first %}
+ {% with image=random_image_post.get_first_image %}
{% endwith %}
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
@@ -26,7 +26,7 @@
{% endif %}
{% for image in image_aliases %}
- {{ image.alias }}:
+
{{ image.alias }}: {{ image.get_view|safe }}
{% endfor %}
diff --git a/boards/templates/boards/thread_gallery.html b/boards/templates/boards/thread_gallery.html
--- a/boards/templates/boards/thread_gallery.html
+++ b/boards/templates/boards/thread_gallery.html
@@ -23,7 +23,7 @@
{% autoescape off %}
{{ image.get_view }}
- {{ image.width }}x{{ image.height }}
+ {{ image.get_size.0 }}x{{ image.get_size.1 }}
{% image_actions image.image.url request.get_host %}
>>{{ post.id }}
diff --git a/boards/utils.py b/boards/utils.py
--- a/boards/utils.py
+++ b/boards/utils.py
@@ -2,6 +2,7 @@
This module contains helper functions and helper classes.
"""
import hashlib
+from boards.abstracts.constants import FILE_DIRECTORY
from random import random
import time
import hmac
@@ -29,10 +30,6 @@ SETTING_ANON_MODE = 'AnonymousMode'
ANON_IP = '127.0.0.1'
-UPLOAD_DIRS ={
- 'PostImage': 'images/',
- 'Attachment': 'files/',
-}
FILE_EXTENSION_DELIMITER = '.'
@@ -136,9 +133,7 @@ def get_upload_filename(model_instance,
str(int(random() * 1000)),
extension)
- directory = UPLOAD_DIRS[type(model_instance).__name__]
-
- return os.path.join(directory, new_name)
+ return os.path.join(FILE_DIRECTORY, new_name)
def get_file_mimetype(file) -> str:
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
@@ -5,7 +5,6 @@ from django.core.paginator import EmptyP
from django.db import transaction
from django.http import Http404
from django.shortcuts import render, redirect
-import requests
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
@@ -13,7 +12,7 @@ from boards import utils, settings
from boards.abstracts.paginator import get_paginator
from boards.abstracts.settingsmanager import get_settings_manager
from boards.forms import ThreadForm, PlainErrorList
-from boards.models import Post, Thread, Ban, Tag, PostImage, Banner
+from boards.models import Post, Thread, Ban, Banner
from boards.views.banned import BannedView
from boards.views.base import BaseBoardView, CONTEXT_FORM
from boards.views.posting_mixin import PostMixin
diff --git a/boards/views/random.py b/boards/views/random.py
--- a/boards/views/random.py
+++ b/boards/views/random.py
@@ -1,7 +1,7 @@
from django.shortcuts import render
from django.views.generic import View
-from boards.models import PostImage
+from boards.models import Attachment
__author__ = 'neko259'
@@ -16,7 +16,7 @@ class RandomImageView(View):
def get(self, request):
params = dict()
- params[CONTEXT_IMAGES] = PostImage.objects.get_random_images(
+ params[CONTEXT_IMAGES] = Attachment.objects.get_random_images(
RANDOM_POST_COUNT)
return render(request, TEMPLATE, params)
diff --git a/boards/views/settings.py b/boards/views/settings.py
--- a/boards/views/settings.py
+++ b/boards/views/settings.py
@@ -8,7 +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
+from boards.models import Attachment
FORM_THEME = 'theme'
FORM_USERNAME = 'username'
@@ -43,7 +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)
+ params[CONTEXT_IMAGE_ALIASES] = Attachment.objects.exclude(alias='').exclude(alias=None)
return render(request, TEMPLATE, params)
diff --git a/boards/views/tag_threads.py b/boards/views/tag_threads.py
--- a/boards/views/tag_threads.py
+++ b/boards/views/tag_threads.py
@@ -3,8 +3,8 @@ from django.core.urlresolvers import rev
from boards.abstracts.settingsmanager import get_settings_manager, \
SETTING_FAVORITE_TAGS, SETTING_HIDDEN_TAGS
-from boards.models import Tag, PostImage
-from boards.views.all_threads import AllThreadsView, DEFAULT_PAGE
+from boards.models import Tag
+from boards.views.all_threads import AllThreadsView
from boards.views.mixins import DispatcherMixin, PARAMETER_METHOD
from boards.forms import ThreadForm, PlainErrorList