Add upload page
This commit is contained in:
parent
583a1ffce8
commit
727387566d
5 changed files with 185 additions and 33 deletions
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-10-13 13:52+0000\n"
|
"POT-Creation-Date: 2021-10-15 08:52+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|
@ -42,19 +42,19 @@ msgstr ""
|
||||||
msgid "hash"
|
msgid "hash"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/settings.py:153
|
#: photo21/settings.py:163
|
||||||
msgid "German"
|
msgid "German"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/settings.py:154
|
#: photo21/settings.py:164
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/settings.py:155
|
#: photo21/settings.py:165
|
||||||
msgid "Spanish"
|
msgid "Spanish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/settings.py:156
|
#: photo21/settings.py:166
|
||||||
msgid "French"
|
msgid "French"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -108,7 +108,7 @@ msgstr ""
|
||||||
msgid "E-mail Addresses"
|
msgid "E-mail Addresses"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/account/email.html:9 photo21/templates/base.html:51
|
#: photo21/templates/account/email.html:9 photo21/templates/base.html:58
|
||||||
#: photo21/templates/socialaccount/connections.html:9
|
#: photo21/templates/socialaccount/connections.html:9
|
||||||
msgid "Account"
|
msgid "Account"
|
||||||
msgstr "Compte"
|
msgstr "Compte"
|
||||||
|
|
@ -225,27 +225,34 @@ msgstr ""
|
||||||
msgid "The ENS Paris-Saclay pictures server."
|
msgid "The ENS Paris-Saclay pictures server."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/base.html:35
|
#: photo21/templates/base.html:36
|
||||||
msgid "Galleries"
|
msgid "Galleries"
|
||||||
msgstr "Galeries"
|
msgstr "Galeries"
|
||||||
|
|
||||||
#: photo21/templates/base.html:39
|
#: photo21/templates/base.html:41
|
||||||
|
#: photologue_custom/templates/photologue/upload.html:6
|
||||||
|
#: photologue_custom/templates/photologue/upload.html:54
|
||||||
|
#: photologue_custom/templates/photologue/upload.html:65
|
||||||
|
msgid "Upload"
|
||||||
|
msgstr "Téléversement"
|
||||||
|
|
||||||
|
#: photo21/templates/base.html:46
|
||||||
msgid "Manage"
|
msgid "Manage"
|
||||||
msgstr "Gestion"
|
msgstr "Gestion"
|
||||||
|
|
||||||
#: photo21/templates/base.html:60
|
#: photo21/templates/base.html:67
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/base.html:70
|
#: photo21/templates/base.html:77
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photo21/templates/base.html:79
|
#: photo21/templates/base.html:86
|
||||||
msgid "Sign up"
|
msgid "Sign up"
|
||||||
msgstr "Inscription"
|
msgstr "Inscription"
|
||||||
|
|
||||||
#: photo21/templates/index.html:50
|
#: photo21/templates/index.html:49
|
||||||
msgid "Connected as"
|
msgid "Connected as"
|
||||||
msgstr "Connecté en tant que"
|
msgstr "Connecté en tant que"
|
||||||
|
|
||||||
|
|
@ -268,6 +275,24 @@ msgstr ""
|
||||||
msgid "Add a 3rd Party Account"
|
msgid "Add a 3rd Party Account"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: photologue_custom/admin.py:45 photologue_custom/models.py:51
|
||||||
|
msgid "owner"
|
||||||
|
msgstr "propriétaire"
|
||||||
|
|
||||||
|
#: photologue_custom/forms.py:13
|
||||||
|
msgid "Gallery"
|
||||||
|
msgstr "Galerie"
|
||||||
|
|
||||||
|
#: photologue_custom/forms.py:15
|
||||||
|
msgid ""
|
||||||
|
"Select a gallery to add these images to. Leave this empty to create a new "
|
||||||
|
"gallery from the supplied title."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: photologue_custom/forms.py:19
|
||||||
|
msgid "New gallery title"
|
||||||
|
msgstr "Titre de la nouvelle galerie"
|
||||||
|
|
||||||
#: photologue_custom/models.py:23
|
#: photologue_custom/models.py:23
|
||||||
msgid "start date"
|
msgid "start date"
|
||||||
msgstr "date de début"
|
msgstr "date de début"
|
||||||
|
|
@ -276,53 +301,57 @@ msgstr "date de début"
|
||||||
msgid "end date"
|
msgid "end date"
|
||||||
msgstr "date de fin"
|
msgstr "date de fin"
|
||||||
|
|
||||||
#: photologue_custom/models.py:51
|
#: photologue_custom/templates/photologue/gallery_archive.html:7
|
||||||
msgid "owner"
|
#: photologue_custom/templates/photologue/gallery_archive.html:12
|
||||||
msgstr "propriétaire"
|
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_archive.html:4
|
|
||||||
#: photologue_custom/templates/photologue/gallery_archive.html:9
|
|
||||||
msgid "Latest photo galleries"
|
msgid "Latest photo galleries"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_archive.html:15
|
#: photologue_custom/templates/photologue/gallery_archive.html:18
|
||||||
msgid "Filter by year"
|
msgid "Filter by year"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_archive.html:32
|
#: photologue_custom/templates/photologue/gallery_archive.html:35
|
||||||
msgid "No galleries were found"
|
msgid "No galleries were found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_archive_year.html:4
|
#: photologue_custom/templates/photologue/gallery_archive_year.html:7
|
||||||
#: photologue_custom/templates/photologue/gallery_archive_year.html:9
|
#: photologue_custom/templates/photologue/gallery_archive_year.html:12
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Galleries for %(show_year)s"
|
msgid "Galleries for %(show_year)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_archive_year.html:14
|
#: photologue_custom/templates/photologue/gallery_archive_year.html:17
|
||||||
msgid "View all galleries"
|
msgid "View all galleries"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_archive_year.html:26
|
#: photologue_custom/templates/photologue/gallery_archive_year.html:29
|
||||||
msgid "No galleries were found."
|
msgid "No galleries were found."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_detail.html:35
|
#: photologue_custom/templates/photologue/gallery_detail.html:38
|
||||||
msgid "to"
|
msgid "to"
|
||||||
msgstr "au"
|
msgstr "au"
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_detail.html:49
|
#: photologue_custom/templates/photologue/gallery_detail.html:54
|
||||||
msgid "All pictures"
|
msgid "All pictures"
|
||||||
msgstr "Toutes les photos"
|
msgstr "Toutes les photos"
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/gallery_detail.html:63
|
#: photologue_custom/templates/photologue/gallery_detail.html:75
|
||||||
msgid "Download all gallery"
|
msgid "Download all gallery"
|
||||||
msgstr "Télécharger toute la galerie"
|
msgstr "Télécharger toute la galerie"
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/photo_detail.html:10
|
#: photologue_custom/templates/photologue/photo_detail.html:13
|
||||||
msgid "Published"
|
msgid "Published"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: photologue_custom/templates/photologue/photo_detail.html:22
|
#: photologue_custom/templates/photologue/photo_detail.html:25
|
||||||
msgid "This photo is found in the following galleries"
|
msgid "This photo is found in the following galleries"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: photologue_custom/templates/photologue/upload.html:59
|
||||||
|
msgid "Drag and drop photos here"
|
||||||
|
msgstr "Glissez et déposez les photos ici"
|
||||||
|
|
||||||
|
#: photologue_custom/templates/photologue/upload.html:63
|
||||||
|
msgid "Owner will be"
|
||||||
|
msgstr "Le propriétaire sera"
|
||||||
|
|
|
||||||
22
photologue_custom/forms.py
Normal file
22
photologue_custom/forms.py
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
from django import forms
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from photologue.models import Gallery
|
||||||
|
|
||||||
|
|
||||||
|
class UploadForm(forms.Form):
|
||||||
|
file_field = forms.FileField(
|
||||||
|
label="",
|
||||||
|
widget=forms.ClearableFileInput(attrs={'multiple': True}),
|
||||||
|
)
|
||||||
|
gallery = forms.ModelChoiceField(
|
||||||
|
Gallery.objects.all(),
|
||||||
|
label=_('Gallery'),
|
||||||
|
required=False,
|
||||||
|
help_text=_('Select a gallery to add these images to. Leave this empty to '
|
||||||
|
'create a new gallery from the supplied title.')
|
||||||
|
)
|
||||||
|
new_gallery_title = forms.CharField(
|
||||||
|
label=_('New gallery title'),
|
||||||
|
max_length=250,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
69
photologue_custom/templates/photologue/upload.html
Normal file
69
photologue_custom/templates/photologue/upload.html
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% comment %}
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
{% endcomment %}
|
||||||
|
{% load i18n crispy_forms_tags %}
|
||||||
|
{% block title %}{% trans "Upload" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block extracss %}
|
||||||
|
<style>
|
||||||
|
.upload-drop-zone {
|
||||||
|
height: 10em;
|
||||||
|
line-height: 10em;
|
||||||
|
border-width: 2px;
|
||||||
|
color: #a3a3a3;
|
||||||
|
border-style: dashed;
|
||||||
|
border-color: #a3a3a3;
|
||||||
|
border-radius: 0.5em;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.upload-drop-zone.drop {
|
||||||
|
color: #222;
|
||||||
|
border-color: #222;
|
||||||
|
background-color: rgba(163, 163, 163, 0.274);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extrajs %}
|
||||||
|
<script>
|
||||||
|
const dropZone = document.getElementById('drop-zone');
|
||||||
|
const uploadInput = document.getElementById('id_file_field');
|
||||||
|
|
||||||
|
dropZone.ondrop = function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.className = 'upload-drop-zone';
|
||||||
|
console.log(e.dataTransfer.files)
|
||||||
|
uploadInput.files = e.dataTransfer.files;
|
||||||
|
}
|
||||||
|
|
||||||
|
dropZone.ondragover = function() {
|
||||||
|
this.className = 'upload-drop-zone drop';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dropZone.ondragleave = function() {
|
||||||
|
this.className = 'upload-drop-zone';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{% trans "Upload" %}</h1>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="post">{% csrf_token %}
|
||||||
|
<div class="upload-drop-zone" id="drop-zone">
|
||||||
|
{% trans "Drag and drop photos here" %}
|
||||||
|
</div>
|
||||||
|
{{ form|crispy }}
|
||||||
|
<p class="mt-3">
|
||||||
|
{% trans "Owner will be" %} <code>{{ request.user.get_full_name }} ({{ request.user.username}})</code>.
|
||||||
|
</p>
|
||||||
|
<button type="submit" class="btn btn-success">{% trans "Upload" %}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
from django.urls import path, re_path
|
from django.urls import path, re_path
|
||||||
|
|
||||||
from .views import (CustomGalleryArchiveIndexView,
|
from .views import (CustomGalleryArchiveIndexView, CustomGalleryDetailView,
|
||||||
CustomGalleryYearArchiveView, CustomGalleryDetailView,
|
CustomGalleryYearArchiveView, GalleryDownload,
|
||||||
GalleryDownload, TagDetail)
|
GalleryUpload, TagDetail)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('tag/<slug:slug>/', TagDetail.as_view(), name='tag-detail'),
|
path('tag/<slug:slug>/', TagDetail.as_view(), name='tag-detail'),
|
||||||
|
|
@ -11,4 +11,5 @@ urlpatterns = [
|
||||||
path('gallery/<slug:slug>/', CustomGalleryDetailView.as_view(), name='pl-gallery'),
|
path('gallery/<slug:slug>/', CustomGalleryDetailView.as_view(), name='pl-gallery'),
|
||||||
path('gallery/<slug:slug>/<int:owner>/', CustomGalleryDetailView.as_view(), name='pl-gallery-owner'),
|
path('gallery/<slug:slug>/<int:owner>/', CustomGalleryDetailView.as_view(), name='pl-gallery-owner'),
|
||||||
path('gallery/<slug:slug>/download/', GalleryDownload.as_view(), name='gallery-download'),
|
path('gallery/<slug:slug>/download/', GalleryDownload.as_view(), name='gallery-download'),
|
||||||
|
path('upload/', GalleryUpload.as_view(), name='gallery-upload'),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,16 @@ import zipfile
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
from django.core.mail import mail_managers
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.views.generic import DetailView
|
from django.views.generic.detail import DetailView
|
||||||
|
from django.views.generic.edit import FormView
|
||||||
from photologue.models import Gallery
|
from photologue.models import Gallery
|
||||||
from photologue.views import GalleryArchiveIndexView, GalleryYearArchiveView
|
from photologue.views import GalleryArchiveIndexView, GalleryYearArchiveView
|
||||||
from taggit.models import Tag
|
from taggit.models import Tag
|
||||||
|
|
||||||
|
from .forms import UploadForm
|
||||||
|
|
||||||
|
|
||||||
class TagDetail(LoginRequiredMixin, DetailView):
|
class TagDetail(LoginRequiredMixin, DetailView):
|
||||||
model = Tag
|
model = Tag
|
||||||
|
|
@ -89,3 +93,30 @@ class GalleryDownload(LoginRequiredMixin, DetailView):
|
||||||
response = HttpResponse(byte_data.getvalue(), content_type='application/x-zip-compressed')
|
response = HttpResponse(byte_data.getvalue(), content_type='application/x-zip-compressed')
|
||||||
response['Content-Disposition'] = f"attachment; filename={gallery.slug}.zip"
|
response['Content-Disposition'] = f"attachment; filename={gallery.slug}.zip"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class GalleryUpload(FormView):
|
||||||
|
form_class = UploadForm
|
||||||
|
template_name = "photologue/upload.html"
|
||||||
|
# success_url = '...' # Replace with your URL or reverse().
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
form_class = self.get_form_class()
|
||||||
|
form = self.get_form(form_class)
|
||||||
|
files = request.FILES.getlist('file_field')
|
||||||
|
if form.is_valid():
|
||||||
|
for f in files:
|
||||||
|
print("upload", f)
|
||||||
|
return self.form_valid(form)
|
||||||
|
else:
|
||||||
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
"""
|
||||||
|
Notify moderators about successful upload
|
||||||
|
"""
|
||||||
|
mail_managers(
|
||||||
|
subject="New upload",
|
||||||
|
message="", # TODO: put username, gallery and photo names
|
||||||
|
)
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue