From 8154c30318127e0491786b65975bee808cd8e27b Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 10 Mar 2021 21:52:59 +0100 Subject: tinymce: upgrade and disable drag&drop for images diff --git a/program/urls.py b/program/urls.py index 776b9c0..78b9af4 100644 --- a/program/urls.py +++ b/program/urls.py @@ -4,10 +4,6 @@ from django.views.decorators.cache import cache_page import views -import os - -PROGRAM_SITE_MEDIA = os.path.join(os.path.dirname(__file__), '../site_media') - urlpatterns = patterns('', url(r'^today/?$', views.DayScheduleView.as_view()), url(r'^week/?$', views.WeekScheduleView.as_view()), @@ -36,4 +32,4 @@ urlpatterns = patterns('', if settings.DEBUG: urlpatterns += \ patterns('', - url(r'^static/(?P.*)$', 'django.views.static.serve', {'document_root': PROGRAM_SITE_MEDIA})) + url(r'^site_media/(?P.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT})) diff --git a/pv/settings.py b/pv/settings.py index 47b9d2e..41da596 100644 --- a/pv/settings.py +++ b/pv/settings.py @@ -90,11 +90,16 @@ INSTALLED_APPS = ( 'tinymce', ) -TINYMCE_JS_URL = '/static/js/tiny_mce/tiny_mce.js' TINYMCE_DEFAULT_CONFIG = { - 'plugins': 'contextmenu', + 'plugins': 'advimage,advlink,advlist,autoresize,contextmenu,paste', 'theme': 'advanced', 'theme_advanced_toolbar_location': 'top', + 'theme_advanced_toolbar_align': 'center', + 'theme_advanced_statusbar_location': 'bottom', + 'theme_advanced_resizing': 'true', + 'theme_advanced_path': 'false', + 'theme_advanced_buttons3_add': 'separator,pastetext,pasteword,selectall', + 'paste_block_drop': 'true', } CACHE_BACKEND = 'locmem://' diff --git a/requirements.txt b/requirements.txt index ce6754c..e4bc92f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,5 +2,5 @@ Django==1.8.14 MySQL-python==1.2.5 Pillow==3.3.0 PyYAML==3.11 -django-tinymce==2.3.0 +django-tinymce==2.6.1 python-dateutil==2.5.3 -- cgit v0.10.2 From dde04a95dcb76b765b8c66775a6ee242d3c316c4 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Mon, 29 Mar 2021 14:22:19 +0200 Subject: add show and note images based on S3 storage diff --git a/program/admin.py b/program/admin.py index 16d6973..b186c3e 100644 --- a/program/admin.py +++ b/program/admin.py @@ -154,7 +154,7 @@ class ShowAdmin(admin.ModelAdmin): prepopulated_fields = {'slug': ('name',)} search_fields = ('name', 'short_description', 'description') fields = ( - 'predecessor', 'broadcastformat', 'name', 'slug', 'image', 'image_enabled', 'short_description', 'description', + 'predecessor', 'broadcastformat', 'name', 'slug', 'image', 'short_description', 'description', 'email', 'website', 'hosts', 'owners', 'showinformation', 'showtopic', 'language', 'musicfocus', ) diff --git a/program/migrations/0013_show_and_note_images.py b/program/migrations/0013_show_and_note_images.py new file mode 100644 index 0000000..2cf8d1a --- /dev/null +++ b/program/migrations/0013_show_and_note_images.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import program.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('program', '0012_add_language'), + ] + + operations = [ + migrations.RemoveField( + model_name='show', + name='image_enabled', + ), + migrations.AlterField( + model_name='show', + name='image', + field=models.ImageField(upload_to=program.models.show_image_filename, null=True, verbose_name='Image', blank=True), + ), + migrations.AddField( + model_name='note', + name='image', + field=models.ImageField(upload_to=program.models.note_image_filename, null=True, verbose_name='Image', blank=True), + ), + ] diff --git a/program/models.py b/program/models.py index b5123cb..048e51b 100644 --- a/program/models.py +++ b/program/models.py @@ -1,3 +1,4 @@ +import os from django.contrib.auth.models import User from django.core.exceptions import ObjectDoesNotExist, ValidationError, MultipleObjectsReturned from django.core.urlresolvers import reverse @@ -11,7 +12,7 @@ from datetime import date, datetime, time, timedelta from dateutil.relativedelta import relativedelta from dateutil.rrule import rrule -from utils import get_automation_id_choices +from utils import get_automation_id_choices, hash_file class BroadcastFormat(models.Model): @@ -243,6 +244,12 @@ class Host(models.Model): return self.shows.filter(programslots__until__gt=datetime.today).distinct() +def show_image_filename(instance, filename): + instance.image.open() + filename_base, filename_ext = os.path.splitext(filename) + return "shows/%s/%s%s" % (instance.slug, hash_file(instance.image.file), filename_ext) + + class Show(models.Model): predecessor = models.ForeignKey('self', blank=True, null=True, related_name='successors', verbose_name=_("Predecessor")) hosts = models.ManyToManyField(Host, blank=True, related_name='shows', verbose_name=_("Hosts")) @@ -254,8 +261,7 @@ class Show(models.Model): musicfocus = models.ManyToManyField(MusicFocus, blank=True, related_name='shows', verbose_name=_("Music focus")) name = models.CharField(_("Name"), max_length=255) slug = models.CharField(_("Slug"), max_length=255, unique=True) - image = models.ImageField(_("Image"), blank=True, null=True, upload_to='show_images') - image_enabled = models.BooleanField(_("show Image"), default=True) + image = models.ImageField(_("Image"), blank=True, null=True, upload_to=show_image_filename) short_description = models.CharField(_("Short description"), max_length=64) description = tinymce_models.HTMLField(_("Description"), blank=True, null=True) email = models.EmailField(_("E-Mail"), blank=True, null=True) @@ -492,7 +498,14 @@ class TimeSlot(models.Model): return reverse('timeslot-detail', args=[str(self.id)]) +def note_image_filename(instance, filename): + instance.image.open() + filename_base, filename_ext = os.path.splitext(filename) + return "notes/%s/%s%s" % (instance.show.slug, hash_file(instance.image.file), filename_ext) + + class Note(models.Model): + STATUS_CHOICES = ( (0, _("Cancellation")), (1, _("Recommendation")), @@ -500,6 +513,7 @@ class Note(models.Model): ) timeslot = models.OneToOneField(TimeSlot, verbose_name=_("Time slot")) title = models.CharField(_("Title"), max_length=128) + image = models.ImageField(_("Image"), blank=True, null=True, upload_to=note_image_filename) content = tinymce_models.HTMLField(_("Content")) status = models.IntegerField(_("Status"), choices=STATUS_CHOICES, default=1) start = models.DateTimeField(editable=False) diff --git a/program/templates/v2/show_detail.html b/program/templates/v2/show_detail.html index 55f7f3b..7b2e07e 100644 --- a/program/templates/v2/show_detail.html +++ b/program/templates/v2/show_detail.html @@ -43,8 +43,8 @@
{{ show.description|safe }}
{% endif %} -{% if show.image and show.image_enabled %} -
image
+{% if show.image %} +
{% endif %}

@@ -69,7 +69,7 @@

{{ note.title }}
{% endfor %} -{% if show.predecessor and show.predecessor.notes.all %} +{% if show.predecessor and show.predecessor.notes.all %}p {% if show.name != show.predecessor.name %}

Davor als {{ show.predecessor.name }}

{% endif %} diff --git a/program/templates/v2/timeslot_detail.html b/program/templates/v2/timeslot_detail.html index ab3b429..f1e65b4 100644 --- a/program/templates/v2/timeslot_detail.html +++ b/program/templates/v2/timeslot_detail.html @@ -32,6 +32,10 @@ {% if timeslot.note %}
{{ timeslot.note.content|safe }}
+ +{% if timeslot.note.image %} +
+{% endif %} {% endif %} diff --git a/program/utils.py b/program/utils.py index 1a81766..3bfecc4 100644 --- a/program/utils.py +++ b/program/utils.py @@ -3,8 +3,10 @@ from django.conf import settings import json import urllib import bisect +import hashlib from os.path import join from datetime import datetime, date, timedelta +from functools import partial def get_automation_id_choices(): @@ -56,3 +58,11 @@ def tofirstdayinisoweek(year, week): if date(year, 1, 4).isoweekday() > 4: ret -= timedelta(days=7) return ret + + +def hash_file(file, block_size=65536): + hasher = hashlib.sha256() + for buf in iter(partial(file.read, block_size), b''): + hasher.update(buf) + + return hasher.hexdigest() diff --git a/pv/settings.py b/pv/settings.py index 41da596..18a1e5e 100644 --- a/pv/settings.py +++ b/pv/settings.py @@ -104,6 +104,14 @@ TINYMCE_DEFAULT_CONFIG = { CACHE_BACKEND = 'locmem://' + +DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' +# AWS_ACCESS_KEY_ID = 'django' +# AWS_SECRET_ACCESS_KEY = 'changeme' +# AWS_S3_ENDPOINT_URL = 'http://172.17.0.1:9000' +# AWS_STORAGE_BUCKET_NAME = 'program' + + MUSIKPROG_IDS = ( 1, # unmodieriertes musikprogramm ) diff --git a/requirements.txt b/requirements.txt index e4bc92f..7c8535c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,5 @@ Pillow==3.3.0 PyYAML==3.11 django-tinymce==2.6.1 python-dateutil==2.5.3 +django-storages=1.6.5 +boto3=1.4.8 -- cgit v0.10.2 From 02093ba844d0f2b303c519c8c49316bd45d11229 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 28 May 2021 22:34:15 +0200 Subject: fix note image urls diff --git a/program/templates/v2/timeslot_detail.html b/program/templates/v2/timeslot_detail.html index f1e65b4..81c40c7 100644 --- a/program/templates/v2/timeslot_detail.html +++ b/program/templates/v2/timeslot_detail.html @@ -34,7 +34,7 @@
{{ timeslot.note.content|safe }}
{% if timeslot.note.image %} -
+
{% endif %} {% endif %} -- cgit v0.10.2 From ed13a183a0011b3cf648a1d0533b83c86ec79467 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 2 Jun 2021 12:04:45 +0200 Subject: fix typo diff --git a/program/templates/v2/show_detail.html b/program/templates/v2/show_detail.html index 7b2e07e..73ec5b1 100644 --- a/program/templates/v2/show_detail.html +++ b/program/templates/v2/show_detail.html @@ -69,7 +69,7 @@
{{ note.title }}
{% endfor %} -{% if show.predecessor and show.predecessor.notes.all %}p +{% if show.predecessor and show.predecessor.notes.all %} {% if show.name != show.predecessor.name %}

Davor als {{ show.predecessor.name }}

{% endif %} -- cgit v0.10.2 From fda29b207fe3627445319386fd75b8da8860cee6 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 2 Jun 2021 17:58:43 +0200 Subject: fix size of imagefiel ind show and note model diff --git a/program/migrations/0013_show_and_note_images.py b/program/migrations/0013_show_and_note_images.py index 2cf8d1a..91a08b0 100644 --- a/program/migrations/0013_show_and_note_images.py +++ b/program/migrations/0013_show_and_note_images.py @@ -19,11 +19,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='show', name='image', - field=models.ImageField(upload_to=program.models.show_image_filename, null=True, verbose_name='Image', blank=True), + field=models.ImageField(max_length=350, upload_to=program.models.show_image_filename, null=True, verbose_name='Image', blank=True), ), migrations.AddField( model_name='note', name='image', - field=models.ImageField(upload_to=program.models.note_image_filename, null=True, verbose_name='Image', blank=True), + field=models.ImageField(max_length=350, upload_to=program.models.note_image_filename, null=True, verbose_name='Image', blank=True), ), ] diff --git a/program/models.py b/program/models.py index 048e51b..ecebda8 100644 --- a/program/models.py +++ b/program/models.py @@ -261,7 +261,7 @@ class Show(models.Model): musicfocus = models.ManyToManyField(MusicFocus, blank=True, related_name='shows', verbose_name=_("Music focus")) name = models.CharField(_("Name"), max_length=255) slug = models.CharField(_("Slug"), max_length=255, unique=True) - image = models.ImageField(_("Image"), blank=True, null=True, upload_to=show_image_filename) + image = models.ImageField(_("Image"), max_length=350, blank=True, null=True, upload_to=show_image_filename) short_description = models.CharField(_("Short description"), max_length=64) description = tinymce_models.HTMLField(_("Description"), blank=True, null=True) email = models.EmailField(_("E-Mail"), blank=True, null=True) @@ -513,7 +513,7 @@ class Note(models.Model): ) timeslot = models.OneToOneField(TimeSlot, verbose_name=_("Time slot")) title = models.CharField(_("Title"), max_length=128) - image = models.ImageField(_("Image"), blank=True, null=True, upload_to=note_image_filename) + image = models.ImageField(_("Image"), max_length=350, blank=True, null=True, upload_to=note_image_filename) content = tinymce_models.HTMLField(_("Content")) status = models.IntegerField(_("Status"), choices=STATUS_CHOICES, default=1) start = models.DateTimeField(editable=False) -- cgit v0.10.2 From 88fb9a1d5bc7dc5f22d96fcee970f4ec9f88b289 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 9 Jun 2021 20:02:18 +0200 Subject: no more S3 diff --git a/pv/settings.py b/pv/settings.py index 18a1e5e..5e251df 100644 --- a/pv/settings.py +++ b/pv/settings.py @@ -105,13 +105,6 @@ TINYMCE_DEFAULT_CONFIG = { CACHE_BACKEND = 'locmem://' -DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' -# AWS_ACCESS_KEY_ID = 'django' -# AWS_SECRET_ACCESS_KEY = 'changeme' -# AWS_S3_ENDPOINT_URL = 'http://172.17.0.1:9000' -# AWS_STORAGE_BUCKET_NAME = 'program' - - MUSIKPROG_IDS = ( 1, # unmodieriertes musikprogramm ) diff --git a/requirements.txt b/requirements.txt index 7c8535c..e4bc92f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,5 +4,3 @@ Pillow==3.3.0 PyYAML==3.11 django-tinymce==2.6.1 python-dateutil==2.5.3 -django-storages=1.6.5 -boto3=1.4.8 -- cgit v0.10.2