+++ /dev/null
-# combo - content management system
-# Copyright (C) 2015 Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import django.apps
-
-class AppConfig(django.apps.AppConfig):
- name = 'gallery'
-
- def get_after_manager_urls(self):
- from . import urls
- return urls.manager_urlpatterns
-
-default_app_config = 'gallery.AppConfig'
+++ /dev/null
-# combo - content management system
-# Copyright (C) 2015 Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from django import forms
-from django.utils.translation import ugettext_lazy as _
-
-from .models import Image
-
-class ImageAddForm(forms.ModelForm):
- class Meta:
- model = Image
- fields = ('image', 'title',)
-
-
-class ImageEditForm(forms.ModelForm):
- class Meta:
- model = Image
- fields = ('title',)
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('auth', '0001_initial'),
- ('data', '0005_auto_20150226_0903'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='GalleryCell',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('placeholder', models.CharField(max_length=20)),
- ('order', models.PositiveIntegerField()),
- ('slug', models.SlugField(verbose_name='Slug', blank=True)),
- ('public', models.BooleanField(default=True, verbose_name='Public')),
- ('groups', models.ManyToManyField(to='auth.Group', verbose_name='Groups', blank=True)),
- ('page', models.ForeignKey(to='data.Page')),
- ],
- options={
- 'verbose_name': 'Gallery',
- },
- bases=(models.Model,),
- ),
- migrations.CreateModel(
- name='Image',
- fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('image', models.ImageField(upload_to=b'uploads/gallery/%Y/%m/', verbose_name='Image')),
- ('order', models.PositiveIntegerField()),
- ('gallery', models.ForeignKey(verbose_name='Gallery', to='gallery.GalleryCell')),
- ],
- options={
- 'ordering': ['order'],
- },
- bases=(models.Model,),
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('gallery', '0001_initial'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='image',
- name='title',
- field=models.CharField(max_length=50, verbose_name='Title', blank=True),
- preserve_default=True,
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('gallery', '0002_image_title'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='gallerycell',
- name='title',
- field=models.CharField(max_length=50, null=True, verbose_name='Title', blank=True),
- preserve_default=True,
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('gallery', '0003_gallerycell_title'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='gallerycell',
- name='restricted_to_unlogged',
- field=models.BooleanField(default=False, verbose_name='Restrict to unlogged users'),
- preserve_default=True,
- ),
- ]
+++ /dev/null
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import datetime
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('gallery', '0004_gallerycell_restricted_to_unlogged'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='gallerycell',
- name='extra_css_class',
- field=models.CharField(max_length=100, verbose_name='Extra classes for CSS styling', blank=True),
- ),
- migrations.AddField(
- model_name='gallerycell',
- name='last_update_timestamp',
- field=models.DateTimeField(default=datetime.datetime(2017, 4, 18, 11, 54, 53, 442573), auto_now=True),
- preserve_default=False,
- ),
- ]
+++ /dev/null
-# combo - content management system
-# Copyright (C) 2015 Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from django import template
-from django.db import models
-from django.forms import models as model_forms
-from django.utils.translation import ugettext_lazy as _
-
-from combo.data.models import CellBase
-from combo.data.library import register_cell_class
-
-@register_cell_class
-class GalleryCell(CellBase):
- title = models.CharField(_('Title'), max_length=50, blank=True, null=True)
- manager_form_template = 'combo/gallery_manager.html'
-
- class Meta:
- verbose_name = _('Gallery')
-
- def render(self, context):
- gallery_template = template.loader.get_template('combo/gallery.html')
- return gallery_template.render(context)
-
- def get_additional_label(self):
- if self.title:
- return self.title
- return ''
-
-
-class Image(models.Model):
- gallery = models.ForeignKey(GalleryCell, verbose_name=_('Gallery'))
- image = models.ImageField(_('Image'),
- upload_to='uploads/gallery/%Y/%m/')
- order = models.PositiveIntegerField()
- title = models.CharField(_('Title'), max_length=50, blank=True)
-
- class Meta:
- ordering = ['order']
+++ /dev/null
-function gallery(element) {
- var element_id = '#' + $(element).attr('id');
- $(element).sortable({
- items: '> li',
- containment: 'parent',
- placeholder: 'empty-image',
- update: function(event, ui) {
- var new_order = $(element).find('> li').map(function() { return $(this).data('object-id'); }).get().join();
- $.ajax({
- url: $(element).data('order-url'),
- data: {'new-order': new_order},
- success: function(data, status) {
- $(element).replaceWith($(data).find(element_id));
- gallery($(element_id));
- }
- });
- }
- });
- $('.image-delete').on('click', function() {
- $.ajax({
- url: $(this).attr('href'),
- success: function(data, status) {
- $(element).replaceWith($(data).find(element_id));
- gallery($(element_id));
- }
- });
- return false;
- });
-};
+++ /dev/null
-{% load thumbnail %}
-<div class="gallery" id="gallery-{{cell.id}}">
-{% for image in cell.image_set.all %}
- {% if forloop.first %}
-{% thumbnail image.image "640x480" crop="50% 25%" as im %}
-<div class="first">
-<img src="{{ im.url }}"/>
-<span>{% if image.title %}{{ image.title }}{% endif %}</span>
-</div>
-<div> {# extra opened <div> #}
-{% endthumbnail %}
- {% endif %}
-{% thumbnail image.image "60x60" crop="50% 25%" as im %}
-{% thumbnail image.image "640x480" crop="50% 25%" as im_large %}
-<span data-image-large="{{ im_large.url }}"><img src="{{ im.url }}"
- {% if image.title %} title="{{image.title}}" {% endif %}/></span>
-{% endthumbnail %}
-{% endthumbnail %}
-
- {% if forloop.last %}
- </div> {# close extra <div> #}
- {% endif %}
-{% endfor %}
-</div>
-<script type="text/javascript">
-$(function() {
- var $gallery = $('#gallery-{{cell.id}}');
- $gallery.find('span').on('click', function() {
- $gallery.find('div.first img').attr('src', $(this).data('image-large'));
- });
-});
-</script>
+++ /dev/null
-{% extends "combo/manager_base.html" %}
-{% load i18n %}
-
-{% block appbar %}
-{% if object.id %}
-<h2>{% trans "Edit Image" %}</h2>
-{% else %}
-<h2>{% trans "New Image" %}</h2>
-{% endif %}
-{% endblock %}
-
-{% block content %}
-
-<form method="post" enctype="multipart/form-data">
- {% csrf_token %}
- {{ form.as_p }}
- <div class="buttons">
- <button>{% trans "Save" %}</button>
- {% if object.id %}
- <a class="cancel" href="{{ object.get_absolute_url }}">{% trans 'Cancel' %}</a>
- {% else %}
- <a class="cancel" href="{% url 'combo-manager-homepage' %}">{% trans 'Cancel' %}</a>
- {% endif %}
- </div>
-</form>
-{% endblock %}
+++ /dev/null
-{% extends 'combo/cell_form.html' %}
-{% load static thumbnail i18n %}
-
-{% block cell-form %}
-<form action="{{ url }}" method="post" data-label-url="{% url 'combo-manager-page-get-additional-label' page_pk=page.id cell_reference=cell.get_reference %}">
-{% csrf_token %}
- {{ form.as_p }}
-
-<ul class="gallery" id="gallery-{{cell.id}}" data-order-url="{% url 'combo-gallery-image-order' gallery_pk=cell.id %}">
-{% for image in cell.image_set.all %}
-<li data-object-id="{{image.id}}">
-{% thumbnail image.image "120x120" crop="50% 25%" as im %}
- <img height="120" src="{{ im.url }}"/>
-{% endthumbnail %}
- <span class="image-actions">
- <a rel="popup" class="image-edit icon-edit" href="{% url 'combo-gallery-image-edit' gallery_pk=cell.id pk=image.id %}"></a>
- <a class="image-delete icon-remove-sign" href="{% url 'combo-gallery-image-delete' gallery_pk=cell.id pk=image.id %}"></a>
- </span>
-</li>
-{% endfor %}
-</ul>
-
-<script src="{% static "js/combo.gallery.js" %}"></script>
-<script>gallery($('#gallery-{{cell.id}}'));</script>
-
-{% endblock %}
-
-
-{% block cell-buttons %}
-<a class="image-add" rel="popup" href="{% url 'combo-gallery-image-add' gallery_pk=cell.id %}">{% trans 'New Image' %}</a>
-|
-{{ block.super }}
-</form>
-{% endblock %}
+++ /dev/null
-# combo - content management system
-# Copyright (C) 2015 Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from django.conf.urls import url
-
-from . import views
-
-manager_urlpatterns = [
- url('^gallery/(?P<gallery_pk>\w+)/images/add/$', views.image_add,
- name='combo-gallery-image-add'),
- url('^gallery/(?P<gallery_pk>\w+)/order$', views.image_order,
- name='combo-gallery-image-order'),
- url('^gallery/(?P<gallery_pk>\w+)/images/(?P<pk>\w+)/edit$', views.image_edit,
- name='combo-gallery-image-edit'),
- url('^gallery/(?P<gallery_pk>\w+)/images/(?P<pk>\w+)/delete$', views.image_delete,
- name='combo-gallery-image-delete'),
-]
+++ /dev/null
-# combo - content management system
-# Copyright (C) 2015 Entr'ouvert
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU Affero General Public License as published
-# by the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from django.core.urlresolvers import reverse, reverse_lazy
-from django.shortcuts import redirect
-from django.views.generic import (TemplateView, RedirectView, DetailView,
- CreateView, UpdateView, ListView, DeleteView, FormView)
-
-from .models import Image, GalleryCell
-from .forms import ImageAddForm, ImageEditForm
-
-class ImageAddView(CreateView):
- model = Image
- template_name = 'combo/gallery_image_form.html'
- form_class = ImageAddForm
-
- def form_valid(self, form):
- form.instance.gallery_id = self.kwargs.get('gallery_pk')
- other_images = form.instance.gallery.image_set.all()
- if other_images:
- form.instance.order = max([x.order for x in other_images]) + 1
- else:
- form.instance.order = 0
- return super(ImageAddView, self).form_valid(form)
-
- def get_success_url(self):
- return reverse('combo-manager-page-view', kwargs={'pk': self.object.gallery.page.id})
-
-image_add = ImageAddView.as_view()
-
-
-class ImageEditView(UpdateView):
- model = Image
- template_name = 'combo/gallery_image_form.html'
- form_class = ImageEditForm
-
- def get_success_url(self):
- return reverse('combo-manager-page-view', kwargs={'pk': self.object.gallery.page.id})
-
-image_edit = ImageEditView.as_view()
-
-
-def image_delete(request, gallery_pk, pk):
- gallery = GalleryCell.objects.get(id=gallery_pk)
- Image.objects.get(id=pk).delete()
- return redirect(reverse('combo-manager-page-view', kwargs={'pk': gallery.page.id}))
-
-
-def image_order(request, gallery_pk):
- gallery = GalleryCell.objects.get(id=gallery_pk)
- new_order = [int(x) for x in request.GET['new-order'].split(',')]
- for image in gallery.image_set.all():
- image.order = new_order.index(image.id)+1
- image.save()
- return redirect(reverse('combo-manager-page-view', kwargs={'pk': gallery.page.id}))