Add picture-people relation and ask for removal thing

This commit is contained in:
Skia 2016-11-19 17:19:00 +01:00
parent b619619b85
commit 22ab21e4e1
9 changed files with 221 additions and 18 deletions

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0007_auto_20161108_1703'),
]
operations = [
migrations.AddField(
model_name='sithfile',
name='asked_for_removal',
field=models.BooleanField(default=False, verbose_name='asked for removal'),
),
]

View File

@ -503,6 +503,7 @@ class SithFile(models.Model):
size = models.IntegerField(_("size"), default=0) size = models.IntegerField(_("size"), default=0)
date = models.DateTimeField(_('date'), auto_now=True) date = models.DateTimeField(_('date'), auto_now=True)
is_moderated = models.BooleanField(_("is moderated"), default=False) is_moderated = models.BooleanField(_("is moderated"), default=False)
asked_for_removal = models.BooleanField(_("asked for removal"), default=False)
class Meta: class Meta:
verbose_name = _("file") verbose_name = _("file")

View File

@ -58,6 +58,8 @@ class CanEditPropMixin(View):
""" """
def dispatch(self, request, *arg, **kwargs): def dispatch(self, request, *arg, **kwargs):
res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs) res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
if res.__class__.status_code == 302:
return res
if hasattr(self, 'object'): if hasattr(self, 'object'):
obj = self.object obj = self.object
elif hasattr(self, 'object_list'): elif hasattr(self, 'object_list'):
@ -76,6 +78,8 @@ class CanEditMixin(View):
""" """
def dispatch(self, request, *arg, **kwargs): def dispatch(self, request, *arg, **kwargs):
res = super(CanEditMixin, self).dispatch(request, *arg, **kwargs) res = super(CanEditMixin, self).dispatch(request, *arg, **kwargs)
if res.__class__.status_code == 302:
return res
if hasattr(self, 'object'): if hasattr(self, 'object'):
obj = self.object obj = self.object
elif hasattr(self, 'object_list'): elif hasattr(self, 'object_list'):
@ -94,6 +98,8 @@ class CanViewMixin(View):
""" """
def dispatch(self, request, *arg, **kwargs): def dispatch(self, request, *arg, **kwargs):
res = super(CanViewMixin, self).dispatch(request, *arg, **kwargs) res = super(CanViewMixin, self).dispatch(request, *arg, **kwargs)
if res.__class__.status_code == 302:
return res
if hasattr(self, 'object'): if hasattr(self, 'object'):
obj = self.object obj = self.object
elif hasattr(self, 'object_list'): elif hasattr(self, 'object_list'):

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('sas', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='PeoplePictureRelation',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('picture', models.ForeignKey(related_name='people', to='sas.Picture', verbose_name='picture')),
('user', models.ForeignKey(related_name='pictures', to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
),
migrations.AlterUniqueTogether(
name='peoplepicturerelation',
unique_together=set([('user', 'picture')]),
),
]

View File

@ -1,6 +1,7 @@
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from core.models import SithFile, User from core.models import SithFile, User
@ -23,6 +24,12 @@ class Picture(SithFile):
def get_download_url(self): def get_download_url(self):
return reverse('sas:download', kwargs={'picture_id': self.id}) return reverse('sas:download', kwargs={'picture_id': self.id})
def get_next(self):
return self.parent.children.exclude(is_moderated=False, asked_for_removal=True).filter(id__gt=self.id).order_by('id').first()
def get_previous(self):
return self.parent.children.exclude(is_moderated=False, asked_for_removal=True).filter(id__lt=self.id).order_by('id').last()
class Album(SithFile): class Album(SithFile):
class Meta: class Meta:
proxy = True proxy = True
@ -42,3 +49,13 @@ class Album(SithFile):
def get_absolute_url(self): def get_absolute_url(self):
return reverse('sas:album', kwargs={'album_id': self.id}) return reverse('sas:album', kwargs={'album_id': self.id})
class PeoplePictureRelation(models.Model):
"""
The PeoplePictureRelation class makes the connection between User and Picture
"""
user = models.ForeignKey(User, verbose_name=_('user'), related_name="pictures", null=False, blank=False)
picture = models.ForeignKey(Picture, verbose_name=_('picture'), related_name="people", null=False, blank=False)
class Meta:
unique_together = ['user', 'picture']

View File

@ -6,11 +6,6 @@
{% block content %} {% block content %}
<h3>{{ album.get_display_name() }}</h3> <h3>{{ album.get_display_name() }}</h3>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p() }}
<p><input type="submit" value="{% trans %}Upload{% endtrans %}" /></p>
</form>
<div> <div>
{% for a in album.children.filter(is_folder=True, is_moderated=True).all() %} {% for a in album.children.filter(is_folder=True, is_moderated=True).all() %}
<div style="display: inline-block; border: solid 1px black;"> <div style="display: inline-block; border: solid 1px black;">
@ -22,13 +17,18 @@
{# for a in album.children.filter(mime_type__in=['image/jpeg', 'image/png']).all() #} {# for a in album.children.filter(mime_type__in=['image/jpeg', 'image/png']).all() #}
{% for p in album.children.filter(is_folder=False, is_moderated=True).all() %} {% for p in album.children.filter(is_folder=False, is_moderated=True).all() %}
{% if p.as_picture.can_be_viewed_by(user) %} {% if p.as_picture.can_be_viewed_by(user) %}
<div style="display: inline-block; border: solid 1px black;"> <div style="display: inline-block; border: solid 1px black; width: 9%; margin: 0.1%">
<a href="{{ url("sas:picture", picture_id=p.id) }}"> <a href="{{ url("sas:picture", picture_id=p.id) }}#pict">
<img src="{{ p.as_picture.get_download_url() }}" alt="{{ p.get_display_name() }}" style="width: 50px"/> <img src="{{ p.as_picture.get_download_url() }}" alt="{{ p.get_display_name() }}" style="max-width: 100%"/>
</a> </a>
</div> </div>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p() }}
<p><input type="submit" value="{% trans %}Upload{% endtrans %}" /></p>
</form>
{% endblock %} {% endblock %}

View File

@ -23,6 +23,9 @@
{% trans %}Owner: {% endtrans %}{{ p.owner.get_display_name() }}<br/> {% trans %}Owner: {% endtrans %}{{ p.owner.get_display_name() }}<br/>
{% trans %}Date: {% endtrans %}{{ p.date|date(DATE_FORMAT) }} {{ p.date|time(TIME_FORMAT) }}<br/> {% trans %}Date: {% endtrans %}{{ p.date|date(DATE_FORMAT) }} {{ p.date|time(TIME_FORMAT) }}<br/>
</p> </p>
{% if p.asked_for_removal %}
<p class="important">{% trans %}Asked for removal{% endtrans %}</p>
{% endif %}
<p> <p>
<input type="radio" name="action_{{ p.id }}" id="m_{{ p.id }}" value="moderate"/> <input type="radio" name="action_{{ p.id }}" id="m_{{ p.id }}" value="moderate"/>
<a href="{{ url('core:file_moderate', file_id=p.id) }}?next={{ url('sas:moderation') }}">{% trans %}Moderate{% endtrans %}</a> <a href="{{ url('core:file_moderate', file_id=p.id) }}?next={{ url('sas:moderation') }}">{% trans %}Moderate{% endtrans %}</a>

View File

@ -1,16 +1,97 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% block head %}
{{ super() }}
<style>
#prev, #next {
display: inline-block;
width: 42%;
margin: 0.5%;
border: solid 1px grey;
overflow: auto;
background: #333;
}
#prev img, #next img {
display: block;
margin: auto;
max-width: 100%;
max-height: 100%;
}
</style>
{% endblock %}
{% block title %} {% block title %}
{% trans %}SAS{% endtrans %} {% trans %}SAS{% endtrans %}
{% endblock %} {% endblock %}
{% macro print_path(file) %}
{% if file %}
{{ print_path(file.parent) }}
<a href="{{ url('sas:album', album_id=file.id) }}">{{ file.get_display_name() }}</a> >
{% endif %}
{% endmacro %}
{% block content %} {% block content %}
{{ print_path(picture.parent) }} {{ picture.get_display_name() }}
<h3>{{ picture.get_display_name() }}</h3> <h3>{{ picture.get_display_name() }}</h3>
<div style="float: right"> <div style="display: inline-block; width: 89%; background: #333;" id="pict">
PREV / NEXT <img src="{{ picture.get_download_url() }}" alt="{{ picture.get_display_name() }}" style="width: 90%; display: block; margin: auto"/>
</div> </div>
<div> <div style="display: inline-block; width: 10%; vertical-align: top;">
<img src="{{ picture.get_download_url() }}" alt="{{ picture.get_display_name() }}" style="width: 90%"/> <div>
<div id="prev">
{% if picture.get_previous() %}
<a href="{{ url("sas:picture", picture_id=picture.get_previous().id) }}#pict">
<img src="{{ picture.get_previous().as_picture.get_download_url() }}" alt="{{ picture.get_previous().get_display_name() }}" />
</a>
{% endif %}
</div>
<div id="next">
{% if picture.get_next() %}
<a href="{{ url("sas:picture", picture_id=picture.get_next().id) }}#pict">
<img src="{{ picture.get_next().as_picture.get_download_url() }}" alt="{{ picture.get_next().get_display_name() }}" />
</a>
{% endif %}
</div>
</div>
<div>
<ul>
{% for r in picture.people.all() %}
<li>
<a href="{{ r.user.get_absolute_url() }}">{{ r.user.get_display_name() }}</a>
{% if user == r.user or user.is_in_group(settings.SITH_SAS_ADMIN_GROUP_ID) %}
<a href="?remove_user={{ r.user.id }}">{% trans %}Delete{% endtrans %}</a>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
<div>
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p() }}
<p><input type="submit" value="{% trans %}Go{% endtrans %}" /></p>
</form>
</div>
<p style="font-size: smaller;">
<a href="?ask_removal">{% trans %}Ask for removal{% endtrans %}</a>
</p>
</div> </div>
{% endblock %} {% endblock %}
{% block script %}
{{ super() }}
<script>
$( function() {
$(document).keydown(function (e) {
if (e.keyCode == 37) {
console.log("prev");
$('#prev a')[0].click();
} else if (e.keyCode == 39) {
console.log("next");
$('#next a')[0].click();
}
});
} );
</script>
{% endblock %}

View File

@ -1,5 +1,5 @@
from django.shortcuts import render from django.shortcuts import render, redirect
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy, reverse
from django.views.generic import ListView, DetailView, RedirectView, TemplateView from django.views.generic import ListView, DetailView, RedirectView, TemplateView
from django.views.generic.edit import UpdateView, CreateView, DeleteView, ProcessFormView, FormMixin, FormView from django.views.generic.edit import UpdateView, CreateView, DeleteView, ProcessFormView, FormMixin, FormView
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
@ -8,14 +8,14 @@ from django.conf import settings
from django import forms from django import forms
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField from ajax_select import make_ajax_form, make_ajax_field
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin, TabedViewMixin
from core.views.forms import SelectUser, LoginForm, SelectDate, SelectDateTime from core.views.forms import SelectUser, LoginForm, SelectDate, SelectDateTime
from core.views.files import send_file from core.views.files import send_file
from core.models import SithFile, User from core.models import SithFile, User
from sas.models import Picture, Album from sas.models import Picture, Album, PeoplePictureRelation
class SASForm(forms.Form): class SASForm(forms.Form):
album_name = forms.CharField(label=_("Add a new album"), max_length=30, required=False) album_name = forms.CharField(label=_("Add a new album"), max_length=30, required=False)
@ -41,6 +41,13 @@ class SASForm(forms.Form):
except Exception as e: except Exception as e:
self.add_error(None, _("Error uploading file %(file_name)s: %(msg)s") % {'file_name': f, 'msg': repr(e)}) self.add_error(None, _("Error uploading file %(file_name)s: %(msg)s") % {'file_name': f, 'msg': repr(e)})
class RelationForm(forms.ModelForm):
class Meta:
model = PeoplePictureRelation
fields = ['picture', 'user']
widgets = {'picture': forms.HiddenInput}
user = make_ajax_field(PeoplePictureRelation, 'user', 'users', help_text="")
class SASMainView(FormView): class SASMainView(FormView):
form_class = SASForm form_class = SASForm
template_name = "sas/main.jinja" template_name = "sas/main.jinja"
@ -65,11 +72,51 @@ class SASMainView(FormView):
kwargs['root_file'] = SithFile.objects.filter(id=settings.SITH_SAS_ROOT_DIR_ID).first() kwargs['root_file'] = SithFile.objects.filter(id=settings.SITH_SAS_ROOT_DIR_ID).first()
return kwargs return kwargs
class PictureView(DetailView, CanViewMixin): class PictureView(CanViewMixin, DetailView, FormMixin):
model = Picture model = Picture
form_class = RelationForm
pk_url_kwarg = "picture_id" pk_url_kwarg = "picture_id"
template_name = "sas/picture.jinja" template_name = "sas/picture.jinja"
def get_initial(self):
return {'picture': self.object}
def get(self, request, *args, **kwargs):
self.object = self.get_object()
self.form = self.get_form()
if 'remove_user' in request.GET.keys():
try:
user = User.objects.filter(id=int(request.GET['remove_user'])).first()
if user.id == request.user.id or request.user.is_in_group(settings.SITH_SAS_ADMIN_GROUP_ID):
r = PeoplePictureRelation.objects.filter(user=user, picture=self.object).delete()
except: pass
if 'ask_removal' in request.GET.keys():
self.object.is_moderated = False
self.object.asked_for_removal = True
self.object.save()
return redirect("sas:album", album_id=self.object.parent.id)
return super(PictureView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
self.form = self.get_form()
if request.user.is_authenticated() and request.user.is_in_group('ae-membres'):
if self.form.is_valid():
PeoplePictureRelation(user=self.form.cleaned_data['user'],
picture=self.form.cleaned_data['picture']).save()
return super(PictureView, self).form_valid(self.form)
else:
self.form.add_error(None, _("You do not have the permission to do that"))
return self.form_invalid(self.form)
def get_context_data(self, **kwargs):
kwargs = super(PictureView, self).get_context_data(**kwargs)
kwargs['form'] = self.form
return kwargs
def get_success_url(self):
return reverse('sas:picture', kwargs={'picture_id': self.object.id})
def send_pict(request, picture_id): def send_pict(request, picture_id):
return send_file(request, picture_id, Picture) return send_file(request, picture_id, Picture)
@ -98,7 +145,7 @@ class AlbumView(CanViewMixin, DetailView, FormMixin):
return self.form_invalid(self.form) return self.form_invalid(self.form)
def get_success_url(self): def get_success_url(self):
return reverse_lazy('sas:album', kwargs={'album_id': self.object.id}) return reverse('sas:album', kwargs={'album_id': self.object.id})
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
kwargs = super(AlbumView, self).get_context_data(**kwargs) kwargs = super(AlbumView, self).get_context_data(**kwargs)
@ -120,6 +167,7 @@ class ModerationView(TemplateView):
pict.delete() pict.delete()
elif v == "moderate": elif v == "moderate":
pict.is_moderated = True pict.is_moderated = True
pict.asked_for_removal = False
pict.save() pict.save()
except: pass except: pass
return super(ModerationView, self).get(request, *args, **kwargs) return super(ModerationView, self).get(request, *args, **kwargs)