Compare commits

..

No commits in common. 'mprofiag' and 'standalone' have entirely different histories.

@ -1,6 +1,6 @@
*.pyc
*.pyo
/.env
/docker
/data
/static_collected
/node_modules
.git

@ -1,13 +1,5 @@
SECRET_KEY=TEST---asdg4hr63453452542h4sdf25g42s3df54hj38rd4sg3f2d54h3sd5f4g53
DEBUG=True
DEBUG=False
SENTRY_DSN=https://460e310d034c49a794941e087c4fcc6e@sentry.io/1196285
DEFAULT_HAYSTACK_URL=es+https://tcjf1ngoog:qj70l67kk2@tagesschule-elementa-8329801232.eu-west-1.bonsaisearch.net/index-*
DATABASE_URL=postgres://django:MuzQzD6yLyaksfw9f6NUDLsK6Tp7gD7f8uX@postgres:5432/db
HTTP_PORT=8009
POSTGRES_PASSWORD=MuzQzD6yLyaksfw9f6NUDLsK6Tp7gD7f8uX
POSTGRES_USER=django
POSTGRES_DB=db
POSTGRES_DATA_DIR=./docker/pgdata
MEDIA_DIR=./docker/data/media
DATA_DIR=./docker/data
STATIC_DIR=./docker/static_collected
DATABASE_URL=postgres://django:MuzQzD6yLyaksfw9f6NUDLsK6Tp7gD7f8uX@postgres:5432/db

@ -1,2 +1,2 @@
DATABASE_URL=postgres://django@MuzQzD6yLyaksfw9f6NUDLsK6Tp7gD7f8uX:5432/db
DEFAULT_HAYSTACK_URL=es+https://tcjf1ngoog:qj70l67kk2@tagesschule-elementa-8329801232.eu-west-1.bonsaisearch.net/test-*
DATABASE_URL=postgres://postgres@postgres:5432/db
DEFAULT_HAYSTACK_URL=es+https://tcjf1ngoog:qj70l67kk2@tagesschule-elementa-8329801232.eu-west-1.bonsaisearch.net/test-*

17
.gitignore vendored

@ -15,23 +15,16 @@ Thumbs.db
# Aldryn
.aldryn
/data
/data.tar.gz
/docker/static_collected
/static_collected
/node_modules
# </DEFAULT>
/static/css/
/static/js/
/static/fonts/
/static/img/
/static/animation/
/.idea
/requirements.txt
/docker/conf/certbot/
/docker/pgdata/**
/docker/data
.env-nginx
.env-db
.env
docker/storage/**
.bash_history
.cache/
.local/
.ssh/
/conf/certbot/

@ -1,69 +0,0 @@
# This viminfo file was generated by Vim 8.0.
# You may edit it if you're careful!
# Viminfo version
|1,4
# Value of 'encoding' when this file was written
*encoding=utf-8
# hlsearch on (H) or off (h):
~h
# Command Line History (newest to oldest):
:q
|2,0,1599761890,,"q"
# Search String History (newest to oldest):
# Expression History (newest to oldest):
# Input Line History (newest to oldest):
# Debug Line History (newest to oldest):
# Registers:
# File marks:
'0 1 0 ~/restart.sh
|4,48,1,0,1599761890,"~/restart.sh"
'1 1 0 ~/restart.sh
|4,49,1,0,1599761817,"~/restart.sh"
'2 1 0 ~/restart.sh
|4,50,1,0,1599761501,"~/restart.sh"
'3 1 0 ~/restart.sh
|4,51,1,0,1599761501,"~/restart.sh"
'4 1 0 ~/restart.sh
|4,52,1,0,1599660361,"~/restart.sh"
'5 1 0 ~/restart.sh
|4,53,1,0,1599660361,"~/restart.sh"
'6 1 0 ~/restart.sh
|4,54,1,0,1599660361,"~/restart.sh"
'7 1 0 ~/restart.sh
|4,55,1,0,1599660361,"~/restart.sh"
'8 1 0 ~/restart.sh
|4,56,1,0,1599485736,"~/restart.sh"
'9 1 0 ~/restart.sh
|4,57,1,0,1599485736,"~/restart.sh"
# Jumplist (newest first):
-' 1 0 ~/restart.sh
|4,39,1,0,1599761890,"~/restart.sh"
-' 1 0 ~/restart.sh
|4,39,1,0,1599761817,"~/restart.sh"
-' 1 0 ~/restart.sh
|4,39,1,0,1599761501,"~/restart.sh"
-' 1 0 ~/restart.sh
|4,39,1,0,1599660361,"~/restart.sh"
-' 1 0 ~/restart.sh
|4,39,1,0,1599485736,"~/restart.sh"
-' 1 0 ~/restart.sh
|4,39,1,0,1599480996,"~/restart.sh"
-' 1 0 ~/restart.sh
|4,39,1,0,1599474185,"~/restart.sh"
# History of marks within files (newest to oldest):
> ~/restart.sh
* 1599761887 0
" 1 0

@ -54,8 +54,8 @@ RUN pip-reqs compile && \
COPY . /app
# </SOURCE>
RUN mkdir -p /app/static_collected
RUN mkdir -p /app/data/media
RUN mkdir /app/static_collected
RUN mkdir /app/data/media
# <GULP>
ENV GULP_MODE=production

@ -1,45 +0,0 @@
# Tagesschule elementa
ssh tagesschule@docker.mprofiag.de
sudo ./docker-update.sh
## Docker
1. Copy environment files `.env*.example` to `.env*` and make the configuration changes.
Configure database user and ports for docker.
- HTTP_PORT=8009 [.env] ...
2. Main app has several mountpoints / volumes. Point them into the appropriate location on
your filesystem
- ./docker/static_collected
- ./docker/data/media
- ./docker/data
3. To start
docker-compose up
4. Restore DB
docker exec -i tagesschule_db_1 pg_restore -U django --no-owner -d db < 41ebf901-4607-4653-9b00-54a42d877b38.dump
3. Migrate
docker-compose exec web manage.py migrate
5. Add admin user
In docker container `docker-compose exec web bash` run
python manage.py shell
In that shell create admin user (https://stackoverflow.com/questions/18503770/how-to-create-user-from-django-shell)
user@host> manage.py shell
>>> from django.contrib.auth.models import User
>>> user=User.objects.create_user('foo', password='bar')
>>> user.is_superuser=True
>>> user.is_staff=True
>>> user.save()

@ -1,2 +1,2 @@
#/bin/bash
exec docker-compose run --rm web gulp "$@" --inspect
exec docker-compose run --rm web gulp "$@" --debug

@ -2,15 +2,33 @@ upstream gunicorn {
server web:80;
}
server {
listen 80;
server_name tagesschule.mprofiag.ch;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name tagesschule.mprofiag.ch;
server_tokens off;
sendfile on;
add_header X-Frame-Options "";
ssl_certificate /etc/letsencrypt/live/tagesschule.mprofiag.ch/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tagesschule.mprofiag.ch/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
client_max_body_size 1000M;
add_header X-Frame-Options "";
gzip on;
gzip_http_version 1.1;

@ -1,2 +0,0 @@
#!/bin/bash
cd /var/www/tagesschule && git pull && docker-compose build web

@ -5,36 +5,55 @@ services:
image: nginx:1.16-alpine
restart: unless-stopped
volumes:
- ./docker/conf/nginx:/etc/nginx/conf.d
- ./docker/static_collected:/app/static_collected
- ${MEDIA_DIR}:/app/data/media
- ./conf/nginx:/etc/nginx/conf.d
- ./conf/certbot/conf:/etc/letsencrypt
- ./conf/certbot/www:/var/www/certbot
- ./static_collected:/app/static_collected
- ./data/media:/app/data/media
ports:
- ${HTTP_PORT}:80
#command: "/bin/sh -c 'while :; do sleep 1m & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
- "80:80"
- "443:443"
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
depends_on:
- web
network_mode: bridge
links:
- web
web:
networks:
- nginx_network
certbot:
image: certbot/certbot
restart: unless-stopped
volumes:
- ./conf/certbot/conf:/etc/letsencrypt
- ./conf/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
web:
build: "."
links:
- "db:postgres"
volumes:
- .:/app:rw
- ${DATA_DIR}:/data:rw
- ${STATIC_DIR}:/app/static_collected
- ${MEDIA_DIR}:/app/data/media
network_mode: bridge
- ".:/app:rw"
- "./data:/data:rw"
- ./static_collected:/app/static_collected
- ./data/media:/app/data/media
networks:
- nginx_network
- db_network
command: "/bin/sh -c '/app/wait-for-postgres.sh postgres /app/run.sh'"
env_file:
- ./.env
db:
restart: unless-stopped
image: postgres:9.6-alpine
env_file:
- ./.env-db
volumes:
- ${POSTGRES_DATA_DIR}:/var/lib/postgresql/data:rw
network_mode: bridge
- ".:/app:rw"
- "./pgdata:/var/lib/postgresql/data:rw"
networks:
- db_network
networks:
nginx_network:
driver: bridge
db_network:
driver: bridge

@ -1,2 +0,0 @@
#!/bin/bash
cd /var/www/tagesschule && docker-compose logs --tail=100 -f

@ -1,2 +0,0 @@
#!/bin/bash
cd /var/www/tagesschule && git pull && docker-compose restart web

@ -1,2 +0,0 @@
#!/bin/bash
cd /var/www/tagesschule && docker-compose up

@ -1,2 +0,0 @@
#!/bin/bash
cd /var/www/tagesschule && git pull && docker-compose build web && docker-compose up

@ -1,2 +0,0 @@
#!/bin/bash
cd /var/www/tagesschule && docker-compose exec web bash

@ -54,7 +54,6 @@ $(function() {
reveal_element($('.header__logo'));
reveal_elements($('.timetable__clock__frame'));
reveal_element($('.timetable__next'));
reveal_element($('.timetable__button'));
reveal_element($('.timetable__start__background'));
});

@ -13,14 +13,11 @@ $(function() {
url: $form.attr('action'),
data: $form.serialize(),
success: function(data) {
django_recaptcha_callbacks = [];
var $new = $(data).find('#' + id);
$new.find('.reveal').each(function() {
$(this).removeClass('reveal reveal_animation');
});
$new.removeClass('reveal reveal_animation');
$form.replaceWith($new);
djangoRecaptchaOnLoadCallback();
}
});
});

@ -1,4 +1,4 @@
$(function () {
$(function() {
var $body = $('body');
var $timetable = $('#timetable');
@ -9,7 +9,7 @@ $(function () {
$(window).scrollTop(0);
window.timetable_can_scroll = false;
window.setTimeout(function () {
window.setTimeout(function() {
window.timetable_can_scroll = true;
}, 2500);
@ -39,17 +39,17 @@ $(function () {
function init_timetable_items() {
$timetable.attr('data-active', 1);
$timetable.find('.timetable__item').each(function () {
$timetable.find('.timetable__item').each(function() {
$(this).addClass('reveal_container')
});
window.setTimeout(function () {
window.setTimeout(function() {
$timetable.addClass('active');
window.requestAnimationFrame(function () {
$timetable.find('.timetable__item').each(function () {
window.requestAnimationFrame(function() {
$timetable.find('.timetable__item').each(function() {
var index = parseInt($(this).attr('data-id'));
var elementWatcher = scrollMonitor.create(this);
elementWatcher.enterViewport(function () {
elementWatcher.enterViewport(function() {
set_timetable_item(index);
});
});
@ -76,7 +76,7 @@ $(function () {
var $timetable_progress = $('#timetable__clock__progress');
var timetable_clock_progress_max = parseFloat($timetable_progress.attr('stroke-dasharray'));
$body.on('click', '.timetable__next', function (event) {
$body.on('click', '.timetable__next', function(event) {
event.preventDefault();
if (!activated) {
$(window).scrollTop($(window).height());
@ -146,45 +146,4 @@ $(function () {
$timetable_progress.attr('stroke-dashoffset', timetable_clock_progress_max * Math.abs(total_progress - 1));
}
}
document.querySelector('.timetable__button a').addEventListener('click', function (event) {
event.preventDefault();
var player;
var vimeo_id = document.querySelector('.timetable__button').getAttribute('data-video-vimeo-id');
var pswpElement = document.querySelectorAll('.pswp')[0],
gallery,
options,
items;
options = {
showHideOpacity: true,
download: false,
fullscreenEl: false,
shareEl: false,
bgOpacity: 0.85,
mainClass: 'timetable__pswp',
};
items = [
{
html: '<div class="gallery__iframe"><div class="gallery__iframe__main"><iframe src="https://player.vimeo.com/video/' + vimeo_id + '" width="100%" height="100%" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe></div></div>',
},
];
var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
gallery.listen('close', function () {
document.querySelector('#timetable').style.height = '';
player.pause();
});
gallery.init();
document.querySelector('#timetable').style.height = '100%';
var iframe = document.querySelector('.pswp iframe');
player = new Vimeo.Player(iframe);
player.play();
});
});

@ -11,14 +11,14 @@ $(function() {
$body.on('click', '.privacy_action--accept', function(event) {
event.preventDefault();
setCookie(cookie_name, 'true', 60);
setCookie(cookie_name, true, 360);
$privacy_message.remove();
$body.trigger('enable_tracking');
});
$body.on('click', '.privacy_action--decline', function(event) {
event.preventDefault();
setCookie(cookie_name, 'false', 60);
setCookie(cookie_name, false, 360);
$privacy_message.remove();
});

@ -38,4 +38,3 @@
@import "modules/plugins/_timetable.scss";
@import "modules/plugins/_reference_list.scss";
@import "modules/plugins/_form.scss";
@import "modules/plugins/_iframe.scss";

@ -153,29 +153,6 @@
min-width: em(200px);
}
.button--icon {
white-space: nowrap;
transform: none;
transition: transform 0.4s $easeOutQuart;
.button__icon {
display: inline-block;
vertical-align: top;
position: relative;
transform: none !important;
width: auto;
padding-left: em(15px);
}
.button__text {
vertical-align: top;
transform: none !important;
padding-left: 0;
min-width: auto;
}
&:hover {
transform: scale(1.05);
}
}
.form__field {
width: 100%;
display: block;

@ -3,25 +3,6 @@
font-size: 0;
}
.gallery__iframe {
width: 100%;
max-width: 140vh;
margin: auto;
position: relative;
top: 50%;
transform: translateY(-50%);
}
.gallery__iframe__main {
width: 100%;
padding-bottom: 56.25%;
position: relative;
}
.gallery__iframe__main iframe {
position: absolute;
}
.gallery__item {
display: inline-block;
vertical-align: top;

@ -1,3 +0,0 @@
.iframe {
margin: em(50px) 0;
}

@ -6,8 +6,4 @@
width: 100%;
display: block;
height: 1px;
}
.spacer ~ .spacer {
height: em(50px);
}
}

@ -11,44 +11,9 @@ $timetable_count: 15;
}
}
.timetable__button {
opacity: 0;
position: fixed;
bottom: 150px;
left: 50%;
transform: translateX(-50%);
z-index: 1000;
transition: opacity 0.5s $easeOutQuad, transform 0.5s $easeOutQuad;
#timetable[data-active="0"] & {
opacity: 1;
}
img {
position: absolute;
top: 50%;
left: 50%;
width: 40px;
height: 20px;
margin-left: -20px;
}
&.reveal {
transform: translateX(-50%) scale(1.2);
}
@media screen and (max-width: $huge_breakpoint) {
bottom: 130px;
}
@media screen and (max-width: $large_breakpoint) {
bottom: 120px;
}
}
.timetable__pswp .pswp__top-bar {
opacity: 1;
background: transparent;
}
.timetable__clock__frame {
position: fixed;
top: 40%;
top: 50%;
transform: translateY(-50%);
width: 30%;
left: 35%;
@ -60,10 +25,10 @@ $timetable_count: 15;
left: 50%;
max-width: 40vh;
transform: translateX(-50%) translateY(14%);
// #timetable[data-active="0"] & {
// top: 50%;
// transform: translateX(-50%) translateY(-50%);
// }
#timetable[data-active="0"] & {
top: 50%;
transform: translateX(-50%) translateY(-50%);
}
}
}

@ -15,31 +15,20 @@ https://control.divio.com/api/v1/apps/serve/django-filer/1.4.1/e7e860ea-0af6-4fc
elasticsearch==6.4.0
django-spurl==0.6.5
aldryn-search==1.0.1
django-fontawesome==1.0
django-fontawesome==0.3.1
mailchimp3==2.1.0
django-image-cropping==1.2.0
django-anymail[mailgun]==1.4
django-admin-view-permission==1.9
gunicorn==19.9.0
sentry-sdk==0.14.3
aldryn-forms-recaptcha-plugin==1.0.0.2
django-recaptcha2==1.4.1
# compat versions
django-storages<1.9 # https://stackoverflow.com/questions/60297619/divio-importerror-cannot-import-name-s3boto
django-storages<1.9
psycopg2<2.8
django-parler<=2.1
django-select2<=6.3.1
django-formtools==2.2
django-sekizai<=1.1.0
django-classy-tags<=1.0.0
djangocms-attributes-field<=1.2.0
django-haystack==2.8.1
django-simple-captcha==0.5.12
django-treebeard==4.3.1
django-meta==1.7.0
tablib==0.14.0
django-simple-sso==0.14.1
easy-thumbnails==2.7.1
dj-database-url==0.5.0
django-js-asset==1.2.3
idna==3.4
cssselect==1.1.0
lxml-html-clean==0.1.1
djangocms-attributes-field<=1.2.0

@ -38,7 +38,8 @@ aldryn_addons.settings.load(locals())
INSTALLED_APPS.insert(0, 'admin_view_permission')
INSTALLED_APPS.extend([
'snowpenguin.django.recaptcha2',
'aldryn_forms_recaptcha_plugin',
'snowpenguin.django.recaptcha3',
'portal',
'project',
'fontawesome',
@ -204,13 +205,12 @@ CKEDITOR_SETTINGS_TIMETABLE_ITEM_TITLE['bodyClass'] = 'h2 timetable__item__title
CKEDITOR_SETTINGS_TIMETABLE_ITEM_TEXT = copy.deepcopy(CKEDITOR_SETTINGS_INPUT)
CKEDITOR_SETTINGS_TIMETABLE_ITEM_TEXT['bodyClass'] = 'section__text timetable__item__text'
DEFAULT_FROM_EMAIL = 'web@tagesschule-elementa.ch'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.office365.com'
EMAIL_HOST_USER = DEFAULT_FROM_EMAIL
EMAIL_HOST_PASSWORD = 'TagesschuleElementa1234'
EMAIL_PORT = 587
ANYMAIL = {
'MAILGUN_API_KEY': 'key-f6625f8850326f8774b2f587c0c41cd2',
'MAILGUN_SENDER_DOMAIN': 'mg.tagesschule-elementa.ch',
}
EMAIL_BACKEND = 'anymail.backends.mailgun.EmailBackend'
DEFAULT_FROM_EMAIL = 'system@tagesschule-elementa.ch'
FILER_ENABLE_PERMISSIONS = True
@ -255,18 +255,11 @@ if not DEBUG:
'tagesschule-elementa.ch',
'www.tagesschule-elementa.ch',
'tagesschule.mprofiag.ch',
'docker.mprofiag.de'
]
DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 1024
RECAPTCHA_PUBLIC_KEY = '6LeILd0ZAAAAAB9xO_y8kS292wv2ikl0M8s7zFn9'
RECAPTCHA_PRIVATE_KEY = '6LeILd0ZAAAAAOGF1AvxdiGcXWLjr2BzHaQ8Zush'
RECAPTCHA_PUBLIC_KEY = '6Lec78gZAAAAANc-oxXJPMi7BXmINlP-QkcS937g'
RECAPTCHA_PRIVATE_KEY = '6Lec78gZAAAAADuIppqW7cSh6iPw3TZQ9r-ogHtz'
RECAPTCHA_SCORE_THRESHOLD = 0.5
ALDRYN_FORMS_ACTION_BACKENDS = {
'default': 'project.action_backends.DefaultAction',
'email_only': 'aldryn_forms.action_backends.EmailAction',
'none': 'aldryn_forms.action_backends.NoAction',
}

@ -1,46 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.21 on 2020-03-25 16:11
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import parler.fields
class Migration(migrations.Migration):
dependencies = [
('portal', '0004_auto_20180718_1754'),
]
operations = [
migrations.AlterModelOptions(
name='announcement',
options={'ordering': ['-updated'], 'verbose_name': 'Neuigkeit', 'verbose_name_plural': 'Aktuell'},
),
migrations.AlterField(
model_name='announcementtranslation',
name='master',
field=parler.fields.TranslationsForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='portal.Announcement'),
),
migrations.AlterField(
model_name='downloadfiletranslation',
name='master',
field=parler.fields.TranslationsForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='portal.DownloadFile'),
),
migrations.AlterField(
model_name='downloadsectiontranslation',
name='master',
field=parler.fields.TranslationsForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='portal.DownloadSection'),
),
migrations.AlterField(
model_name='informationsectiontranslation',
name='master',
field=parler.fields.TranslationsForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='portal.InformationSection'),
),
migrations.AlterField(
model_name='informationtranslation',
name='master',
field=parler.fields.TranslationsForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='portal.Information'),
),
]

@ -1,13 +0,0 @@
# -*- coding: utf-8 -*-
from aldryn_forms.action_backends_base import BaseAction
class DefaultAction(BaseAction):
verbose_name = 'Default'
def form_valid(self, cmsplugin, instance, request, form):
email = form.cleaned_data.get('emailfield_1', None)
if email and email in ['eric.jones.z.mail@gmail.com']:
return
recipients = cmsplugin.send_notifications(instance, form)
form.instance.set_recipients(recipients)
form.save()

@ -2,10 +2,8 @@
from django.contrib import admin
from cms.extensions import PageExtensionAdmin
from parler.admin import TranslatableAdmin
from aldryn_forms.models import FormSubmission
from aldryn_forms.admin.base import BaseFormSubmissionAdmin
from project.models import ImageExtension, SliderItemQualification, Notification
from project.views import CustomFormExportWizardView
@admin.register(ImageExtension)
@ -21,15 +19,3 @@ class SliderItemQualificationAdmin(TranslatableAdmin):
@admin.register(Notification)
class NotificationAdmin(TranslatableAdmin):
pass
admin.site.unregister(FormSubmission)
@admin.register(FormSubmission)
class FormSubmissionAdmin(BaseFormSubmissionAdmin):
def get_form_export_view(self):
return CustomFormExportWizardView.as_view(admin=self, file_type='xls')

@ -8,14 +8,11 @@ from djangocms_picture.cms_plugins import PicturePlugin as _PicturePlugin
from djangocms_text_ckeditor.cms_plugins import TextPlugin as _TextPlugin
from django.contrib import admin
from mailchimp3 import MailChimp
from aldryn_forms.cms_plugins import Field
from snowpenguin.django.recaptcha2.fields import ReCaptchaField
from snowpenguin.django.recaptcha2.widgets import ReCaptchaWidget
from project.forms import NewsletterSubscriptionForm
from project.models import Section, Quote, SliderItem, SectionText, Video, DownloadSection, DownloadSectionFolder, \
TextSliderItem, HighlightListItem, ReferenceListItem, SocialMediaList, SocialMediaListItem, Timetable, \
TimetableItem, Partner, HighlightList, Image, TitleListItem, TitleList, IntroImage, Gallery, Iframe
TimetableItem, Partner, HighlightList, Image, TitleListItem, TitleList, IntroImage, Gallery
@plugin_pool.register_plugin
@ -29,7 +26,7 @@ class SectionPlugin(CMSPluginBase):
'SectionTextPlugin', 'VideoPlugin', 'DownloadSectionPlugin', 'TextSliderPlugin',
'HighlightListPlugin', 'ReferenceListPlugin', 'FormPlugin', 'PicturePlugin', 'SubPageListPlugin',
'PartnerPlugin', 'NewsletterSubscriptionPlugin', 'NewsletterArchivePlugin',
'SocialMediaListPlugin', 'GalleryPlugin', 'IframePlugin']
'SocialMediaListPlugin', 'GalleryPlugin']
@plugin_pool.register_plugin
@ -209,24 +206,6 @@ class FormPlugin(_FormPlugin):
'SubmitButton', 'ReCaptchaFieldPlugin']
@plugin_pool.register_plugin
class ReCaptchaFieldPlugin(Field):
name = 'ReCaptcha Field'
render_template = True
allow_children = False
form_field = ReCaptchaField
form_field_widget = ReCaptchaWidget
form_field_enabled_options = [
'error_messages',
]
fieldset_general_fields = []
fieldset_advanced_fields = []
def get_form_field_widget_kwargs(self, instance):
return {'explicit': True}
class SocialMediaListItemInlineAdmin(admin.TabularInline):
model = SocialMediaListItem
extra = 0
@ -348,11 +327,3 @@ class GalleryPlugin(CMSPluginBase):
module = 'Content'
name = 'Gallery'
render_template = 'project/plugins/content/gallery.html'
@plugin_pool.register_plugin
class IframePlugin(CMSPluginBase):
model = Iframe
module = 'Content'
name = 'Iframe'
render_template = 'project/plugins/content/iframe.html'

@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.21 on 2020-03-25 16:11
from __future__ import unicode_literals
from django.db import migrations
import django.db.models.deletion
import parler.fields
class Migration(migrations.Migration):
dependencies = [
('project', '0009_auto_20190214_1250'),
]
operations = [
migrations.AlterField(
model_name='notificationtranslation',
name='master',
field=parler.fields.TranslationsForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='project.Notification'),
),
migrations.AlterField(
model_name='slideritemqualificationtranslation',
name='master',
field=parler.fields.TranslationsForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='project.SliderItemQualification'),
),
]

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.21 on 2021-11-04 16:08
from __future__ import unicode_literals
from django.db import migrations, models
import djangocms_text_ckeditor.fields
class Migration(migrations.Migration):
dependencies = [
('project', '0010_auto_20200325_1611'),
]
operations = [
migrations.AddField(
model_name='timetable',
name='video_cta',
field=djangocms_text_ckeditor.fields.HTMLField(blank=True, null=True, verbose_name='Video CTA'),
),
migrations.AddField(
model_name='timetable',
name='video_vimeo_id',
field=models.IntegerField(blank=True, help_text='e.g. https://vimeo.com/<b>131766159</b>', null=True, verbose_name='Video Vimeo ID'),
),
]

@ -1,30 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.21 on 2024-05-23 15:51
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cms', '0020_old_tree_cleanup'),
('project', '0011_auto_20211104_1608'),
]
operations = [
migrations.CreateModel(
name='Iframe',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_iframe', serialize=False, to='cms.CMSPlugin')),
('html', models.TextField(verbose_name='HTML')),
],
options={
'verbose_name': 'Iframe',
'verbose_name_plural': 'Iframes',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
]

@ -265,8 +265,6 @@ class Timetable(CMSPlugin):
introduction = HTMLField(verbose_name='Intro', configuration='CKEDITOR_SETTINGS_INPUT')
outro = HTMLField(verbose_name='Outro', configuration='CKEDITOR_SETTINGS_INPUT', blank=True, null=True)
cta = HTMLField(verbose_name='CTA', configuration='CKEDITOR_SETTINGS_INPUT', blank=True, null=True)
video_vimeo_id = models.IntegerField(verbose_name='Video Vimeo ID', blank=True, null=True, help_text='e.g. https://vimeo.com/<b>131766159</b>')
video_cta = HTMLField(verbose_name='Video CTA', configuration='CKEDITOR_SETTINGS_INPUT', blank=True, null=True)
class Meta(CMSPlugin.Meta):
verbose_name = 'Timetable'
@ -349,14 +347,3 @@ class Gallery(CMSPlugin):
@property
def files(self):
return self.folder.files.all().order_by('name')
class Iframe(CMSPlugin):
html = models.TextField('HTML')
class Meta(CMSPlugin.Meta):
verbose_name = 'Iframe'
verbose_name_plural = 'Iframes'
def __str__(self):
return self.html

@ -1,4 +1,4 @@
{% load static i18n cms_tags sekizai_tags fontawesome menu_tags recaptcha2 %}<!DOCTYPE html>
{% load static i18n cms_tags sekizai_tags fontawesome menu_tags %}<!DOCTYPE html>
<html class="r" lang="{{ LANGUAGE_CODE }}">
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge">
@ -10,8 +10,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="google" content="notranslate">
{% recaptcha_explicit_support %}
<meta name="msvalidate.01" content="7E7A1E68251AEDF0AF320164C774E3E8"/>
{% block extra_meta %}
@ -177,14 +175,12 @@
<div id="privacy-message" style="display: none;">
<div class="privacy-message__frame">
<p>
{% page_url 'privacy' as privacy_url %}
{% if LANGUAGE_CODE == 'de' %}
{% page_url 'imprint' as privacy_url %}
{% blocktrans with privacy_url=privacy_url %}
Um diese Webseite optimal gestalten und fortlaufend verbessern zu können, verwenden wir Cookies.
Weitere Informationen finden Sie in unserer <a href="{{ privacy_url }}">Datenschutzerklärung</a>.
{% else %}
In order to optimize this website and to continuously improve it, we use cookies.
Further information can be found in our <a href="{{ privacy_url }}">data protection policy</a>.
{% endif %}
Weitere Informationen finden Sie in unserer
<a href="{{ privacy_url }}">Datenschutzerklärung im Impressum</a>.
{% endblocktrans %}
</p>
<div class="privacy-message__actions">
<a href="#" class="button button--small button--ghost privacy_action--decline">
@ -210,24 +206,32 @@
<script>
$(function() {
var init_tag_manager = function() {
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-WVRJ872');
var init_google_analytics = function() {
(function(i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function() {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-116863155-1', 'auto');
ga('set', 'anonymizeIp', true);
ga('send', 'pageview');
};
if (window.privacy_accepted) {
init_tag_manager();
init_google_analytics();
}
$('body').on('enable_tracking', function() {
init_tag_manager();
init_google_analytics();
});
});
</script>
{% recaptcha_explicit_init LANGUAGE_CODE %}
</body>
</html>

@ -1,5 +0,0 @@
<div class="iframe reveal_container">
<div class="reveal reveal_animation">
<div style="display:inline-block;vertical-align:top;width:300px;margin:20px auto;color:#333;background:#fff;border:1px solid #ddd;line-height:1.2;text-decoration:none;padding:0"><a href="https://read.bookcreator.com/Y0SYhDEKm4Wfw50K2K1EsVR6BSO2/3EzILpspTZubAkL9btIklA" style="display:block;color:#333;line-height:1.2;text-decoration:none;padding:0;font-weight:normal" target="_blank" rel="noreferrer"><img src="https://assets.api.bookcreator.com/Y0SYhDEKm4Wfw50K2K1EsVR6BSO2/books/3EzILpspTZubAkL9btIklA/cover/share" style="max-height:300px;max-width:100%;display:block;margin:0 auto;padding:0;border:none" alt="Unsere Lieblingstiere"/></a><div style="display:block;padding:20px;overflow:hidden;overflow-x:hidden;border-top:1px solid #ddd"><div style="display:block;color:#333;line-height:1.2;text-decoration:none;padding:0;font-weight:normal;font-size:21px;margin:0 0 0.25em"><a href="https://read.bookcreator.com/Y0SYhDEKm4Wfw50K2K1EsVR6BSO2/3EzILpspTZubAkL9btIklA" style="display:block;color:#333;line-height:1.2;text-decoration:none;padding:0;font-weight:normal" target="_blank" rel="noreferrer">Unsere Lieblingstiere</a></div><div style="display:block;color:#333;line-height:1.2;text-decoration:none;padding:0;font-weight:normal;font-size:16px;margin:0 0 0.5em"><a href="https://read.bookcreator.com/Y0SYhDEKm4Wfw50K2K1EsVR6BSO2/3EzILpspTZubAkL9btIklA" style="display:block;color:#333;line-height:1.2;text-decoration:none;padding:0;font-weight:normal" target="_blank" rel="noreferrer">Click to read this book, made with Book Creator</a></div><div style="display:block;color:#455a64;line-height:1.2;text-decoration:none;padding:0;font-weight:bold;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px"><a href="https://read.bookcreator.com/Y0SYhDEKm4Wfw50K2K1EsVR6BSO2/3EzILpspTZubAkL9btIklA" style="display:block;color:#333;line-height:1.2;text-decoration:none;padding:0;font-weight:normal" target="_blank" rel="noreferrer">read.bookcreator.com</a></div></div></div>
</div>
</div>

@ -1,7 +1,7 @@
{% load i18n thumbnail util_tags %}
<div class="video reveal_container">
<iframe class="video__frame" src="https://player.vimeo.com/video/{{ instance.vimeo_id }}?dnt=1" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen allow="autoplay"></iframe>
<iframe class="video__frame" src="https://player.vimeo.com/video/{{ instance.vimeo_id }}?dnt=1" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
<a href="#" class="video__thumbnail reveal reveal_animation">
<span class="video__play">
{% include 'project/assets/play.svg' %}

@ -1,15 +1,6 @@
{% load i18n cms_tags thumbnail util_tags %}
<div id="timetable" data-active="0" data-last="{{ instance.child_plugin_instances|length }}">
{% if instance.video_vimeo_id and instance.video_cta %}
<div class="timetable__button reveal reveal_animation data_delay_8" data-video-vimeo-id="{{ instance.video_vimeo_id }}">
<a href="#video" class="button button--white button--small button--icon">
<span class="button__icon">{% include 'project/assets/play.svg' %}</span>
<span class="button__text">{{ instance.video_cta }}</span>
</a>
</div>
{% endif %}
<div class="timetable__clock__frame">
<div class="timetable__clock__main">
<div class="timetable__start reveal reveal_animation data_delay_8"></div>

@ -3,7 +3,7 @@ from django.conf.urls import url, include
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateView
from project.views import SearchView, NewsletterSubscriptionView, LoginRedirectView, MediaRedirectView, ArchiveFilerPublic
from project.views import SearchView, NewsletterSubscriptionView, LoginRedirectView, MediaRedirectView
urlpatterns = [
url(_(r'^suche/'), SearchView.as_view(), kwargs={'search': True}, name='search'),
@ -13,5 +13,4 @@ urlpatterns = [
name='newsletter_subscription_success'),
url(r'^login/redirect/$', LoginRedirectView.as_view(), name='login_redirect'),
url(r'^media/bridge/$', MediaRedirectView.as_view(), name='media_bridge'),
url(r'^media/archive/$', ArchiveFilerPublic.as_view(), name='media_archive'),
]

@ -2,16 +2,10 @@
from aldryn_search.views import AldrynSearchView
from cms.models import Page
from django.core.urlresolvers import reverse_lazy
from django.views import View
from django.views.generic import RedirectView
from django.views.generic.edit import FormView
from aldryn_forms.admin.views import FormExportWizardView
from aldryn_forms.admin.exporter import Exporter
from tablib import Dataset
from django.http import HttpResponse
from project.forms import NewsletterSubscriptionForm
import os
import zipfile
class SearchView(AldrynSearchView):
@ -51,75 +45,3 @@ class MediaRedirectView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
return self.request.GET.get('url', None)
class CustomExporter(Exporter):
custom_fields = ['sent_at']
def get_dataset(self, fields):
headers = [field.rpartition('-')[0] for field in fields]
for custom_field in self.custom_fields:
headers.append(custom_field)
dataset = Dataset(headers=headers)
for submission in self.queryset.only('data').iterator():
row_data = []
form_fields = [field for field in submission.get_form_data()
if field.field_id in fields]
for header in fields:
for field in form_fields:
if field.field_id == header:
row_data.append(field.value)
break
else:
row_data.append('')
if row_data:
for custom_field in self.custom_fields:
row_data.append(getattr(submission, custom_field).strftime('%d.%m.%Y %H:%M:%S'))
dataset.append(row_data)
return dataset
class CustomFormExportWizardView(FormExportWizardView):
def done(self, form_list, **kwargs):
"""
this step only runs if all forms are valid.
"""
form_iter = iter(form_list)
step_1_form = next(form_iter)
step_2_form = next(form_iter)
fields = step_2_form.get_fields()
queryset = step_1_form.get_queryset()
dataset = CustomExporter(queryset=queryset).get_dataset(fields=fields)
filename = step_1_form.get_filename(extension=self.file_type)
content_type = self.get_content_type()
response = HttpResponse(dataset.xls, content_type=content_type)
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
class ArchiveFilerPublic(View):
def get(self, request):
path = '/app/data/media/filer_public/'
with zipfile.ZipFile('filer_public.zip', 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(path):
for file in files:
filePath = os.path.join(root, file)
try:
with open(filePath) as tempFile:
pass
zipf.write(filePath, os.path.relpath(filePath, os.path.join(path, '..')))
except IOError:
print(filePath)
return HttpResponse('success')

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,5 +1,3 @@
{% for name, value in form_data %}
{% if name %}
<p>{{ name }}: {{ value|default_if_none:"—" }}</p>
{% endif %}
<p>{{ name }}: {{ value|default_if_none:"—" }}</p>
{% endfor %}

@ -7,10 +7,10 @@ host="$1"
shift
cmd="$@"
until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c '\q'; do
until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "postgres" -c '\q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - executing command"
exec $cmd
exec $cmd
Loading…
Cancel
Save