diff --git a/Dockerfile b/Dockerfile index 554f7fe..9a0da78 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,9 +6,12 @@ ENV SHELL /bin/bash # ------------------------------------------ # install necessary packages via apt-get: # ------------------------------------------ -# RUN apt-get update && \ -# apt-get install -y --no-install-recommends \ -# libsaxonhe-java +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + libsasl2-dev python-dev libldap2-dev libssl-dev + +# this is supposed to save memory: +RUN rm -rf /var/lib/apt/lists/* # ------------------------------------------ # install python dependencies: diff --git a/requirements.txt b/requirements.txt index 589c526..23737bc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,42 @@ -Django==2.2 -psycopg2-binary +Django==2.1.11 +psycopg2-binary == 2.7.7 +dj-database-url==0.5.0 +django-auth-ldap==2.0.0 +django-classy-tags==0.9.0 +django-cms==3.6.0 +django-filer==1.5.0 +django-formtools==2.1 +django-js-asset==1.2.2 +django-mptt==0.10.0 +django-polymorphic==2.0.3 +django-sekizai==1.0.0 +django-treebeard==4.3 +djangocms-admin-style==1.4.0 +djangocms-attributes-field==1.1.0 +djangocms-column==1.9.0 +djangocms-file==2.3.0 +djangocms-installer==1.1.1 +djangocms-link==2.5.0 +djangocms-picture==2.1.3 +djangocms-snippet==2.1.0 +djangocms-style==2.2.0 +djangocms-text-ckeditor==3.7.0 +djangocms-video==2.1.1 +easy-thumbnails==2.6 +html5lib==1.0.1 +lxml==4.4.1 +Pillow==6.1.0 +pyasn1==0.4.6 +pyasn1-modules==0.2.6 +python-ldap==3.2.0 +pytz==2019.2 +six==1.12.0 +sqlparse==0.3.0 +tzlocal==2.0.0 +Unidecode==1.0.23 +webencodings==0.5.1 +git+git://github.molgen.mpg.de/EditionOpenAccess/django-eoaauthors +git+git://github.molgen.mpg.de/EditionOpenAccess/django-eoaforthcoming +git+git://github.molgen.mpg.de/EditionOpenAccess/django-eoapublications +git+git://github.molgen.mpg.de/EditionOpenAccess/django-eoaseries +git+git://github.molgen.mpg.de/EditionOpenAccess/django-opds diff --git a/src/cms_plugins.py b/src/cms_plugins.py new file mode 100644 index 0000000..867d4a9 --- /dev/null +++ b/src/cms_plugins.py @@ -0,0 +1,10 @@ +from cms.plugin_base import CMSPluginBase +from cms.plugin_pool import plugin_pool +from cms.models.pluginmodel import CMSPlugin +from django.utils.translation import ugettext_lazy as _ + +@plugin_pool.register_plugin +class EOASeries(CMSPluginBase): + model = CMSPlugin + render_template = "eoaseries.html" + cache = False diff --git a/src/eoa/cms_apps.py b/src/eoa/cms_apps.py new file mode 100644 index 0000000..80032bd --- /dev/null +++ b/src/eoa/cms_apps.py @@ -0,0 +1,18 @@ +from cms.app_base import CMSApp +from cms.apphook_pool import apphook_pool + +@apphook_pool.register +class EOASeriesApphook(CMSApp): + app_name = "eoaseries" # must match the application namespace + name = "EOA Series Apphook" + + def get_urls(self, page=None, language=None, **kwargs): + return ["eoaseries.urls"] + +@apphook_pool.register +class EOAAuthorsApphook(CMSApp): + app_name = "eoaauthors" # must match the application namespace + name = "EOA Authors Apphook" + + def get_urls(self, page=None, language=None, **kwargs): + return ["eoaauthors.urls"] diff --git a/src/eoa/migrations/__init__.py b/src/eoa/migrations/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/eoa/migrations/__init__.py @@ -0,0 +1 @@ + diff --git a/src/eoa/settings.py b/src/eoa/settings.py index b551fcc..7e8ad4b 100644 --- a/src/eoa/settings.py +++ b/src/eoa/settings.py @@ -11,9 +11,16 @@ """ import os +from pathlib import Path +import ldap +from django_auth_ldap.config import LDAPSearch, PosixGroupType + +gettext = lambda s: s # Build paths inside the project like this: os.path.join(BASE_DIR, ...) -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +BASE_DIR = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +RES_DIR = Path(os.environ['RES_DIR']) # Quick-start development settings - unsuitable for production @@ -31,22 +38,53 @@ # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', + 'djangocms_admin_style', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', - 'django.contrib.messages', + 'django.contrib.admin', + 'django.contrib.sites', + 'django.contrib.sitemaps', 'django.contrib.staticfiles', + 'django.contrib.messages', + 'cms', + 'menus', + 'sekizai', + 'treebeard', + 'djangocms_text_ckeditor', + 'filer', + 'easy_thumbnails', + 'djangocms_column', + 'djangocms_file', + 'djangocms_link', + 'djangocms_picture', + 'djangocms_style', + 'djangocms_snippet', + 'djangocms_video', + + + 'eoa', + 'eoapublications', + 'eoaforthcoming', + 'eoaseries', + 'eoaauthors', + 'opds', ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', + 'cms.middleware.utils.ApphookReloadMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', + 'django.contrib.sites.middleware.CurrentSiteMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.common.CommonMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'cms.middleware.user.CurrentUserMiddleware', + 'cms.middleware.page.CurrentPageMiddleware', + 'cms.middleware.toolbar.ToolbarMiddleware', + 'cms.middleware.language.LanguageCookieMiddleware' ] ROOT_URLCONF = 'eoa.urls' @@ -54,14 +92,25 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, + 'DIRS': [os.path.join(BASE_DIR, 'eoa', 'templates'),], + # 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', + 'django.template.context_processors.i18n', + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.template.context_processors.media', + 'django.template.context_processors.csrf', + 'django.template.context_processors.tz', + 'sekizai.context_processors.sekizai', + 'django.template.context_processors.static', + 'cms.context_processors.cms_settings' + ], + 'loaders': [ + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader' ], }, }, @@ -75,8 +124,11 @@ DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'postgres', + 'USER': 'postgres', + 'HOST': 'db', + 'PORT': '5432', } } @@ -99,13 +151,37 @@ }, ] +AUTHENTICATION_BACKENDS = ( + 'django_auth_ldap.backend.LDAPBackend', + 'django.contrib.auth.backends.ModelBackend', +) + +AUTH_LDAP_SERVER_URI = "ldap://mpiwg-ldap.mpiwg-berlin.mpg.de:7389" +AUTH_LDAP_BIND_DN = "" +AUTH_LDAP_BIND_PASSWORD = "" +AUTH_LDAP_USER_SEARCH = LDAPSearch("cn=users,dc=mpiwg-berlin,dc=mpg,dc=de", + ldap.SCOPE_SUBTREE, "(uid=%(user)s)") +AUTH_LDAP_USER_ATTR_MAP = {"first_name": "givenName", "last_name": "sn"} +AUTH_LDAP_PROFILE_ATTR_MAP = {"home_directory": "homeDirectory"} +AUTH_LDAP_GROUP_SEARCH = LDAPSearch("cn=groups,dc=mpiwg-berlin,dc=mpg,dc=de", + ldap.SCOPE_SUBTREE, "(objectClass=posixGroup)") +AUTH_LDAP_GROUP_TYPE = PosixGroupType() +AUTH_LDAP_MIRROR_GROUPS = True + +# Use LDAP group membership to calculate group permissions. +AUTH_LDAP_FIND_GROUP_PERMS = True +AUTH_LDAP_USER_FLAGS_BY_GROUP = { + "is_active": "cn=mpiwg,cn=groups,dc=mpiwg-berlin,dc=mpg,dc=de", + "is_staff": "cn=mpiwg,cn=groups,dc=mpiwg-berlin,dc=mpg,dc=de" +} + # Internationalization # https://docs.djangoproject.com/en/2.2/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'en' -TIME_ZONE = 'UTC' +TIME_ZONE = 'Europe/Berlin' USE_I18N = True @@ -114,7 +190,59 @@ USE_TZ = True +LANGUAGES = ( + ## Customize this + ('en', gettext('en')), +) + +## CMS config: +CMS_LANGUAGES = { + ## Customize this + 1: [ + { + 'code': 'en', + 'name': gettext('en'), + 'redirect_on_fallback': True, + 'public': True, + 'hide_untranslated': False, + }, + ], + 'default': { + 'redirect_on_fallback': True, + 'public': True, + 'hide_untranslated': False, + }, +} + +CMS_TEMPLATES = ( + ## Customize this + ('fullwidth.html', 'Fullwidth'), +) + +CMS_PERMISSION = True + +CMS_PLACEHOLDER_CONF = {} + # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.2/howto/static-files/ STATIC_URL = '/static/' +# where all static files are collected by 'python manage.py collectstatic' +STATIC_ROOT = RES_DIR / 'all_static_files' +MEDIA_URL = '/media/' +MEDIA_ROOT = RES_DIR / 'all_media_files' + +STATICFILES_DIRS = [ + RES_DIR / "static", +] +SITE_ID = 1 + +MIGRATION_MODULES = { +} + +THUMBNAIL_PROCESSORS = ( + 'easy_thumbnails.processors.colorspace', + 'easy_thumbnails.processors.autocrop', + 'filer.thumbnail_processors.scale_and_crop_with_subject_location', + 'easy_thumbnails.processors.filters' +) diff --git a/src/eoa/templates/base.html b/src/eoa/templates/base.html new file mode 100644 index 0000000..558110d --- /dev/null +++ b/src/eoa/templates/base.html @@ -0,0 +1,79 @@ +{% load cms_tags menu_tags sekizai_tags staticfiles %} +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"/> + <title>{% block title %}Edition Open Access{% endblock title %}</title> + <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"/> + <meta name="viewport" content="width=device-width, initial-scale=1"/> + {% block metatags %}{% endblock metatags %} + {% block hyperimage %}{% endblock hyperimage %} + <link rel="shortcut icon" href="{% static 'assets/images/favicon.png' %}"/> + <link rel="apple-touch-icon" href="{% static 'assets/images/favicon-apple.png' %}"/> + <link href="{% static '852a3afcc3d6f07ad520.app.css' %}" rel="stylesheet"/> + {% render_block "css" %} + </head> + <body> + {% cms_toolbar %} + <div class="page"> + <div class="content"> + <div class="mobile-header__background"></div> + <header class="header"> + <div class="header__content"> + <div class="blocklogo container"> + <div class="blocklogo__logo"> + <a href="{% page_url 'intropage' %}"> + <img class="blocklogo__img" src="{% static 'assets/images/mprl_logo_281x165.png' %}" alt="logo" data-object-fit="cover"/> + </a> + </div> + </div> + <nav class="nav"> + <a class="nav-toggle" href="#"> + <span class="nav-toggle__item"></span> + <span class="nav-toggle__item"></span> + <span class="nav-toggle__item"></span> + </a> + <div class="nav__wrapper"> + <div class="container"> + <ul class="nav__menu"> + <!-- <li class="nav__item"> --> + {% show_menu 0 100 100 100 %} + <li class="nav__item nav-search" id="nav-search"> + <form class="nav-search-form"> + <input class="nav-search__input" placeholder="Search" type="search" value="" name="search" id="search"/> + <input class="nav-search__submit" type="submit" value=""/> + </form> + </li> + <li class="nav__item nav-footer"> + <a class="nav__link nav-footer__link" href="{% page_url 'contact' %}">Contact</a><a class="nav__link nav-footer__link" href="{% page_url 'imprint' %}">Imprint</a> + </li> + </ul> + </div> + </div> + </nav> + <nav class="breadcrumbs container"> + <ul class="breadcrumbs__items"> + {% block breadcrumb %} + {% show_breadcrumb %} + {% endblock %} + </ul> + </nav> + </div> + </header> + <!-- <main class="main"> <div class="container"> <div class="main-content"> --> + {% block content %}{% endblock content %} + <!-- </div> </div> </main> --> + </div> + <footer class="footer"> + <div class="footer__content"> + <div class="footer-menu"><a href="{% page_url 'contact' %}">Contact</a><a href="{% page_url 'imprint' %}">Imprint</a><a class="share" href="#">Share<span>this Page</span></a></div> + <div class="footer-logo"><a href="https://mpiwg-berlin.mpg.de/"> + <h2>Max Planck Institute for the History of Science</h2></a></div> + </div> + </footer> + </div> + {% block hyperimagebottom %}{% endblock hyperimagebottom %} + <script type="text/javascript" src="{% static '852a3afcc3d6f07ad520.app.js' %}"></script> + {% render_block "js" %} + </body> +</html> diff --git a/src/eoa/templates/fullwidth.html b/src/eoa/templates/fullwidth.html new file mode 100644 index 0000000..e4c4708 --- /dev/null +++ b/src/eoa/templates/fullwidth.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} +{% load cms_tags %} + +{% block title %}{% page_attribute "page_title" %}{% endblock title %} + +{% block content %} +<main class="main"> + <div class="container"> + <div class="main-content"> + {% placeholder "content" %} + </div> + </div> +</main> +{% endblock content %} diff --git a/src/eoa/templates/menu/breadcrumb.html b/src/eoa/templates/menu/breadcrumb.html new file mode 100644 index 0000000..d354e78 --- /dev/null +++ b/src/eoa/templates/menu/breadcrumb.html @@ -0,0 +1,9 @@ +{% for ance in ancestors %} +<li class="breadcrumbs__item"> + {% if not forloop.last %} + <a class="breadcrumbs__link" href="{{ ance.get_absolute_url }}">{{ ance.get_menu_title }}</a> + {% else %} + <span class="breadcrumbs__link-current">{{ ance.get_menu_title }}</span> + {% endif %} +</li> +{% endfor %} diff --git a/src/eoa/templates/menu/menu.html b/src/eoa/templates/menu/menu.html new file mode 100644 index 0000000..93b85fa --- /dev/null +++ b/src/eoa/templates/menu/menu.html @@ -0,0 +1,12 @@ +{% load menu_tags %} + +{% for child in children %} +<li class="nav__item {% if child.selected %}nav__item--active{% endif %}{% if child.ancestor %} ancestor{% endif %}{% if child.sibling %} sibling{% endif %}{% if child.descendant %} descendant{% endif %}"> + <a class="nav__link {% if child.selected %}nav__link--active{% endif %}" href="{{ child.attr.redirect_url|default:child.get_absolute_url }}">{{ child.get_menu_title }}</a> + {% if child.children %} + <ul>{{node.title}}fsf + {% show_menu from_level to_level extra_inactive extra_active template "" "" child %} + </ul> + {% endif %} +</li> +{% endfor %} diff --git a/src/eoa/urls.py b/src/eoa/urls.py index e7ddb02..80146d4 100644 --- a/src/eoa/urls.py +++ b/src/eoa/urls.py @@ -13,9 +13,33 @@ 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ +from django.urls import path, include, re_path from django.contrib import admin -from django.urls import path + +from cms.sitemaps import CMSSitemap +from django.conf import settings +from django.contrib.sitemaps.views import sitemap +from django.contrib.staticfiles.urls import staticfiles_urlpatterns +from django.views.static import serve + +admin.autodiscover() urlpatterns = [ + path('', include('eoapublications.urls')), + path('opds/', include('opds.urls')), + path(r'sitemap.xml', sitemap, + {'sitemaps': {'cmspages': CMSSitemap}}), +] + +# https://stackoverflow.com/questions/17959941/how-to-remove-the-language-identifier-from-django-cms-2-4-urls +urlpatterns += [ path('admin/', admin.site.urls), + path('', include('cms.urls')), ] + +# This is only needed when using runserver. +if settings.DEBUG: + urlpatterns = [ + re_path(r'^media/(?P<path>.*)$', serve, + {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}), + ] + staticfiles_urlpatterns() + urlpatterns