added organizer color field

This commit is contained in:
Marvin Sipp
2017-10-07 18:13:06 +02:00
committed by Raphael Michel
parent 11d76656de
commit 28d074366e
5 changed files with 57 additions and 11 deletions
+11
View File
@@ -1,6 +1,7 @@
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from i18nfield.forms import I18nFormField, I18nTextarea from i18nfield.forms import I18nFormField, I18nTextarea
@@ -120,6 +121,16 @@ class OrganizerSettingsForm(SettingsForm):
help_text=_('Choose all languages that your organizer homepage should be available in.') help_text=_('Choose all languages that your organizer homepage should be available in.')
) )
organizer_primary_color = forms.CharField(
label=_("Primary color"),
required=False,
validators=[
RegexValidator(regex='^#[0-9a-fA-F]{6}$',
message=_('Please enter the hexadecimal code of a color, e.g. #990000.'))
],
widget=forms.TextInput(attrs={'class': 'colorpickerfield'})
)
organizer_homepage_text = I18nFormField( organizer_homepage_text = I18nFormField(
label=_('Homepage text'), label=_('Homepage text'),
required=False, required=False,
@@ -20,6 +20,7 @@
<legend>{% trans "Display settings" %}</legend> <legend>{% trans "Display settings" %}</legend>
{% bootstrap_form_errors sform %} {% bootstrap_form_errors sform %}
{% bootstrap_field sform.locales layout="horizontal" %} {% bootstrap_field sform.locales layout="horizontal" %}
{% bootstrap_field sform.organizer_primary_color layout="horizontal" %}
{% bootstrap_field sform.organizer_logo_image layout="horizontal" %} {% bootstrap_field sform.organizer_logo_image layout="horizontal" %}
{% bootstrap_field sform.organizer_homepage_text layout="horizontal" %} {% bootstrap_field sform.organizer_homepage_text layout="horizontal" %}
{% bootstrap_field sform.event_list_type layout="horizontal" %} {% bootstrap_field sform.event_list_type layout="horizontal" %}
+2
View File
@@ -24,6 +24,7 @@ from pretix.control.forms.organizer import (
from pretix.control.permissions import OrganizerPermissionRequiredMixin from pretix.control.permissions import OrganizerPermissionRequiredMixin
from pretix.control.signals import nav_organizer from pretix.control.signals import nav_organizer
from pretix.helpers.urls import build_absolute_uri from pretix.helpers.urls import build_absolute_uri
from pretix.presale.style import regenerate_organizer_css
class OrganizerList(ListView): class OrganizerList(ListView):
@@ -135,6 +136,7 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
user=self.request.user, user=self.request.user,
data={k: form.cleaned_data.get(k) for k in form.changed_data} data={k: form.cleaned_data.get(k) for k in form.changed_data}
) )
regenerate_organizer_css.apply_async(args=(self.request.organizer.pk,))
messages.success(self.request, _('Your changes have been saved.')) messages.success(self.request, _('Your changes have been saved.'))
return super().form_valid(form) return super().form_valid(form)
+2
View File
@@ -57,6 +57,8 @@ def contextprocessor(request):
ctx['languages'] = [get_language_info(code) for code in request.event.settings.locales] ctx['languages'] = [get_language_info(code) for code in request.event.settings.locales]
if hasattr(request, 'organizer'): if hasattr(request, 'organizer'):
if request.organizer.settings.presale_css_file and not hasattr(request, 'event'):
ctx['css_file'] = default_storage.url(request.organizer.settings.presale_css_file)
ctx['organizer_logo'] = request.organizer.settings.get('organizer_logo_image', as_type=str, default='')[7:] ctx['organizer_logo'] = request.organizer.settings.get('organizer_logo_image', as_type=str, default='')[7:]
ctx['organizer_homepage_text'] = request.organizer.settings.get('organizer_homepage_text', as_type=LazyI18nString) ctx['organizer_homepage_text'] = request.organizer.settings.get('organizer_homepage_text', as_type=LazyI18nString)
ctx['organizer'] = request.organizer ctx['organizer'] = request.organizer
+41 -11
View File
@@ -11,23 +11,22 @@ from django.core.files.storage import default_storage
from django.dispatch import Signal from django.dispatch import Signal
from django.templatetags.static import static as _static from django.templatetags.static import static as _static
from pretix.base.models import Event from pretix.base.models import Event, Event_SettingsStore, Organizer
from pretix.base.services.async import ProfiledTask from pretix.base.services.async import ProfiledTask
from pretix.celery_app import app from pretix.celery_app import app
from pretix.multidomain.urlreverse import get_domain from pretix.multidomain.urlreverse import get_domain
logger = logging.getLogger('pretix.presale.style') logger = logging.getLogger('pretix.presale.style')
affected_keys = ['primary_font', 'primary_color']
@app.task(base=ProfiledTask) def compile_scss(object):
def regenerate_css(event_id: int):
event = Event.objects.select_related('organizer').get(pk=event_id)
sassdir = os.path.join(settings.STATIC_ROOT, 'pretixpresale/scss') sassdir = os.path.join(settings.STATIC_ROOT, 'pretixpresale/scss')
def static(path): def static(path):
sp = _static(path) sp = _static(path)
if not settings.MEDIA_URL.startswith("/") and sp.startswith("/"): if not settings.MEDIA_URL.startswith("/") and sp.startswith("/"):
domain = get_domain(event.organizer) domain = get_domain(object.organizer if isinstance(object, Event) else object)
if domain: if domain:
siteurlsplit = urlsplit(settings.SITE_URL) siteurlsplit = urlsplit(settings.SITE_URL)
if siteurlsplit.port and siteurlsplit.port not in (80, 443): if siteurlsplit.port and siteurlsplit.port not in (80, 443):
@@ -38,15 +37,16 @@ def regenerate_css(event_id: int):
return '"{}"'.format(sp) return '"{}"'.format(sp)
sassrules = [] sassrules = []
if event.settings.get('primary_color'): if object.settings.get('primary_color'):
sassrules.append('$brand-primary: {};'.format(event.settings.get('primary_color'))) sassrules.append('$brand-primary: {};'.format(object.settings.get('primary_color')))
font = event.settings.get('primary_font') font = object.settings.get('primary_font')
if font != 'Open Sans': if font != 'Open Sans':
sassrules.append(get_font_stylesheet(font)) sassrules.append(get_font_stylesheet(font))
sassrules.append('$font-family-sans-serif: "{}", "Open Sans", "OpenSans", "Helvetica Neue", Helvetica, Arial, sans-serif !default'.format( sassrules.append(
font '$font-family-sans-serif: "{}", "Open Sans", "OpenSans", "Helvetica Neue", Helvetica, Arial, sans-serif !default'.format(
)) font
))
sassrules.append('@import "main.scss";') sassrules.append('@import "main.scss";')
@@ -58,6 +58,14 @@ def regenerate_css(event_id: int):
custom_functions=cf custom_functions=cf
) )
checksum = hashlib.sha1(css.encode('utf-8')).hexdigest() checksum = hashlib.sha1(css.encode('utf-8')).hexdigest()
return css, checksum
@app.task(base=ProfiledTask)
def regenerate_css(event_id: int):
event = Event.objects.select_related('organizer').get(pk=event_id)
css, checksum = compile_scss(event)
fname = '{}/{}/presale.{}.css'.format( fname = '{}/{}/presale.{}.css'.format(
event.organizer.slug, event.slug, checksum[:16] event.organizer.slug, event.slug, checksum[:16]
) )
@@ -68,6 +76,28 @@ def regenerate_css(event_id: int):
event.settings.set('presale_css_checksum', checksum) event.settings.set('presale_css_checksum', checksum)
@app.task(base=ProfiledTask)
def regenerate_organizer_css(organizer_id: int):
organizer = Organizer.objects.get(pk=organizer_id)
css, checksum = compile_scss(organizer)
fname = '{}/presale.{}.css'.format(
organizer.slug, checksum[:16]
)
if organizer.settings.get('presale_css_checksum', '') != checksum:
newname = default_storage.save(fname, ContentFile(css.encode('utf-8')))
organizer.settings.set('presale_css_file', newname)
organizer.settings.set('presale_css_checksum', checksum)
non_inherited_events = set(Event_SettingsStore.objects.filter(
event__organizer=organizer, key__in=affected_keys
).values_list('event_id', flat=True))
for event in organizer.events.all():
if event.pk not in non_inherited_events:
regenerate_css.apply_async(args=(event.pk,))
register_fonts = Signal() register_fonts = Signal()
""" """
Return a dictionaries of the following structure. Paths should be relative to static root. Return a dictionaries of the following structure. Paths should be relative to static root.