mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-18 20:23:23 +00:00
Merge branch 'download-all-my-pictures' into 'master'
Add feature to download all of your pictures as a user See merge request ae-utbm/Sith!319
This commit is contained in:
commit
effed9c760
@ -22,7 +22,7 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.urls import re_path, include
|
from django.urls import re_path, path, include
|
||||||
|
|
||||||
from api.views import *
|
from api.views import *
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
@ -54,4 +54,5 @@ urlpatterns = [
|
|||||||
re_path(r"^markdown$", RenderMarkdown, name="api_markdown"),
|
re_path(r"^markdown$", RenderMarkdown, name="api_markdown"),
|
||||||
re_path(r"^mailings$", FetchMailingLists, name="mailings_fetch"),
|
re_path(r"^mailings$", FetchMailingLists, name="mailings_fetch"),
|
||||||
re_path(r"^uv$", uv_endpoint, name="uv_endpoint"),
|
re_path(r"^uv$", uv_endpoint, name="uv_endpoint"),
|
||||||
|
path("sas/<int:user>", all_pictures_of_user_endpoint, name="all_pictures_of_user"),
|
||||||
]
|
]
|
||||||
|
@ -78,3 +78,4 @@ from .club import *
|
|||||||
from .group import *
|
from .group import *
|
||||||
from .launderette import *
|
from .launderette import *
|
||||||
from .uv import *
|
from .uv import *
|
||||||
|
from .sas import *
|
||||||
|
42
api/views/sas.py
Normal file
42
api/views/sas.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from typing import List
|
||||||
|
from rest_framework.decorators import api_view, renderer_classes
|
||||||
|
from rest_framework.exceptions import PermissionDenied
|
||||||
|
from rest_framework.generics import get_object_or_404
|
||||||
|
from rest_framework.renderers import JSONRenderer
|
||||||
|
from rest_framework.request import Request
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from core.views import can_edit_prop
|
||||||
|
from core.models import User
|
||||||
|
from sas.models import Picture
|
||||||
|
|
||||||
|
|
||||||
|
def all_pictures_of_user(user: User) -> List[Picture]:
|
||||||
|
return [
|
||||||
|
relation.picture
|
||||||
|
for relation in user.pictures.exclude(picture=None)
|
||||||
|
.order_by("-picture__parent__date", "id")
|
||||||
|
.select_related("picture__parent")
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@api_view(["GET"])
|
||||||
|
@renderer_classes((JSONRenderer,))
|
||||||
|
def all_pictures_of_user_endpoint(request: Request, user: int):
|
||||||
|
requested_user: User = get_object_or_404(User, pk=user)
|
||||||
|
if not can_edit_prop(requested_user, request.user):
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": f"{picture.parent.name} - {picture.name}",
|
||||||
|
"date": picture.date,
|
||||||
|
"author": str(picture.owner),
|
||||||
|
"full_size_url": picture.get_download_url(),
|
||||||
|
"compressed_url": picture.get_download_compressed_url(),
|
||||||
|
"thumb_url": picture.get_download_thumb_url(),
|
||||||
|
}
|
||||||
|
for picture in all_pictures_of_user(requested_user)
|
||||||
|
]
|
||||||
|
)
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% for a in albums %}
|
{% for a in albums %}
|
||||||
|
<button id="download_all_pictures", onclick=download_pictures()>{% trans %}Download all my pictures{% endtrans %}</button>
|
||||||
<div style="padding: 10px">
|
<div style="padding: 10px">
|
||||||
<h4>{{ a.name }}</h4>
|
<h4>{{ a.name }}</h4>
|
||||||
<hr>
|
<hr>
|
||||||
@ -20,3 +21,67 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block script %}
|
||||||
|
{{ super() }}
|
||||||
|
<script type="text/javascript">
|
||||||
|
/**
|
||||||
|
* Download a list of files.
|
||||||
|
* @author speedplane
|
||||||
|
*/
|
||||||
|
function download_files(files) {
|
||||||
|
function download_next(i) {
|
||||||
|
if (i >= files.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var a = document.createElement('a');
|
||||||
|
a.href = files[i].download;
|
||||||
|
a.target = '_parent';
|
||||||
|
// Use a.download if available, it prevents plugins from opening.
|
||||||
|
if ('download' in a) {
|
||||||
|
a.download = files[i].filename;
|
||||||
|
}
|
||||||
|
// Add a to the doc for click to work.
|
||||||
|
(document.body || document.documentElement).appendChild(a);
|
||||||
|
if (a.click) {
|
||||||
|
a.click(); // The click method is supported by most browsers.
|
||||||
|
} else {
|
||||||
|
$(a).click(); // Backup using jquery
|
||||||
|
}
|
||||||
|
// Delete the temporary link.
|
||||||
|
a.parentNode.removeChild(a);
|
||||||
|
// Download the next file with a small timeout. The timeout is necessary
|
||||||
|
// for IE, which will otherwise only download the first file.
|
||||||
|
setTimeout(function() {
|
||||||
|
download_next(i + 1);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
// Initiate the first download.
|
||||||
|
download_next(0);
|
||||||
|
}
|
||||||
|
function download_pictures() {
|
||||||
|
$("#download_all_pictures").prop("disabled", true);
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: "{{ url('api:all_pictures_of_user', user=object.id) }}",
|
||||||
|
tryCount: 0,
|
||||||
|
xhr: function(){
|
||||||
|
return xhr;
|
||||||
|
},
|
||||||
|
success: function(data){
|
||||||
|
$("#download_all_pictures").prop("disabled", false);
|
||||||
|
to_download = [];
|
||||||
|
data.forEach(picture =>
|
||||||
|
to_download.push({ download: picture["full_size_url"], filename: picture["name"] })
|
||||||
|
);
|
||||||
|
download_files(to_download);
|
||||||
|
},
|
||||||
|
error: function(data){
|
||||||
|
console.log("Error retrieving data from url: " + data);
|
||||||
|
$("#download_all_pictures").text("{% trans %}Error downloading your pictures{% endtrans %}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
# This file contains all the views that concern the page model
|
# This file contains all the views that concern the page model
|
||||||
from django.shortcuts import redirect, get_object_or_404
|
from django.shortcuts import redirect, get_object_or_404
|
||||||
|
from django.utils.http import http_date
|
||||||
from django.views.generic import ListView, DetailView, TemplateView
|
from django.views.generic import ListView, DetailView, TemplateView
|
||||||
from django.views.generic.edit import UpdateView, FormMixin, DeleteView
|
from django.views.generic.edit import UpdateView, FormMixin, DeleteView
|
||||||
from django.views.generic.detail import SingleObjectMixin
|
from django.views.generic.detail import SingleObjectMixin
|
||||||
@ -68,6 +69,7 @@ def send_file(request, file_id, file_class=SithFile, file_attr="file"):
|
|||||||
with open(filepath.encode("utf-8"), "rb") as filename:
|
with open(filepath.encode("utf-8"), "rb") as filename:
|
||||||
wrapper = FileWrapper(filename)
|
wrapper = FileWrapper(filename)
|
||||||
response = HttpResponse(wrapper, content_type=f.mime_type)
|
response = HttpResponse(wrapper, content_type=f.mime_type)
|
||||||
|
response["Last-Modified"] = http_date(f.date.timestamp())
|
||||||
response["Content-Length"] = os.path.getsize(filepath.encode("utf-8"))
|
response["Content-Length"] = os.path.getsize(filepath.encode("utf-8"))
|
||||||
response["Content-Disposition"] = ('inline; filename="%s"' % f.name).encode(
|
response["Content-Disposition"] = ('inline; filename="%s"' % f.name).encode(
|
||||||
"utf-8"
|
"utf-8"
|
||||||
|
@ -48,6 +48,7 @@ from django.views.generic.dates import YearMixin, MonthMixin
|
|||||||
|
|
||||||
from datetime import timedelta, date
|
from datetime import timedelta, date
|
||||||
import logging
|
import logging
|
||||||
|
from api.views.sas import all_pictures_of_user
|
||||||
|
|
||||||
from core.views import (
|
from core.views import (
|
||||||
CanViewMixin,
|
CanViewMixin,
|
||||||
@ -325,19 +326,15 @@ class UserPicturesView(UserTabsMixin, CanViewMixin, DetailView):
|
|||||||
kwargs = super(UserPicturesView, self).get_context_data(**kwargs)
|
kwargs = super(UserPicturesView, self).get_context_data(**kwargs)
|
||||||
kwargs["albums"] = []
|
kwargs["albums"] = []
|
||||||
kwargs["pictures"] = {}
|
kwargs["pictures"] = {}
|
||||||
picture_qs = (
|
picture_qs = all_pictures_of_user(self.object)
|
||||||
self.object.pictures.exclude(picture=None)
|
|
||||||
.order_by("-picture__parent__date", "id")
|
|
||||||
.select_related("picture__parent")
|
|
||||||
)
|
|
||||||
last_album = None
|
last_album = None
|
||||||
for pict_relation in picture_qs:
|
for picture in picture_qs:
|
||||||
album = pict_relation.picture.parent
|
album = picture.parent
|
||||||
if album.id != last_album:
|
if album.id != last_album:
|
||||||
kwargs["albums"].append(album)
|
kwargs["albums"].append(album)
|
||||||
kwargs["pictures"][album.id] = []
|
kwargs["pictures"][album.id] = []
|
||||||
last_album = album.id
|
last_album = album.id
|
||||||
kwargs["pictures"][album.id].append(pict_relation.picture)
|
kwargs["pictures"][album.id].append(picture)
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ La traduction se fait en trois étapes. Il faut d'abord générer un fichier de
|
|||||||
|
|
||||||
.. sourcecode:: bash
|
.. sourcecode:: bash
|
||||||
|
|
||||||
./manage.py makemessages --ignore "env/*" -e py,jinja
|
./manage.py makemessages --locale=fr --ignore "env/*" -e py,jinja
|
||||||
|
|
||||||
Éditer le fichier django.po
|
Éditer le fichier django.po
|
||||||
---------------------------
|
---------------------------
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user