Commit 9e328405 authored by Skia's avatar Skia
Browse files

Add file moderation tool

parent 02be5e16
Pipeline #420 passed with stage
in 2 minutes and 9 seconds
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
<h2>{% trans %}Edit operation{% endtrans %}</h2> <h2>{% trans %}Edit operation{% endtrans %}</h2>
<form action="" method="post"> <form action="" method="post">
{% csrf_token %} {% csrf_token %}
{{ form.non_field_errors() }}
{{ form.journal }} {{ form.journal }}
{{ form.target_id }} {{ form.target_id }}
<p>{{ form.amount.errors }}<label for="{{ form.amount.name }}">{{ form.amount.label }}</label> {{ form.amount }}</p> <p>{{ form.amount.errors }}<label for="{{ form.amount.name }}">{{ form.amount.label }}</label> {{ form.amount }}</p>
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0005_auto_20161105_1035'),
]
operations = [
migrations.AddField(
model_name='sithfile',
name='is_moderated',
field=models.BooleanField(verbose_name='is moderated', default=False),
),
]
...@@ -483,7 +483,7 @@ class Preferences(models.Model): ...@@ -483,7 +483,7 @@ class Preferences(models.Model):
) )
def get_directory(instance, filename): def get_directory(instance, filename):
return './{0}/{1}'.format(instance.get_parent_path(), filename) return '.{0}/{1}'.format(instance.get_parent_path(), filename)
class SithFile(models.Model): class SithFile(models.Model):
name = models.CharField(_('file name'), max_length=256, blank=False) name = models.CharField(_('file name'), max_length=256, blank=False)
...@@ -496,6 +496,7 @@ class SithFile(models.Model): ...@@ -496,6 +496,7 @@ class SithFile(models.Model):
mime_type = models.CharField(_('mime type'), max_length=30) mime_type = models.CharField(_('mime type'), max_length=30)
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)
class Meta: class Meta:
verbose_name = _("file") verbose_name = _("file")
...@@ -503,6 +504,8 @@ class SithFile(models.Model): ...@@ -503,6 +504,8 @@ class SithFile(models.Model):
def is_owned_by(self, user): def is_owned_by(self, user):
if hasattr(self, 'profile_of') and user.is_in_group(settings.SITH_MAIN_BOARD_GROUP): if hasattr(self, 'profile_of') and user.is_in_group(settings.SITH_MAIN_BOARD_GROUP):
return True return True
if user.is_in_group(settings.SITH_GROUPS['communication-admin']['id']):
return True
return user.id == self.owner.id return user.id == self.owner.id
def can_be_viewed_by(self, user): def can_be_viewed_by(self, user):
...@@ -590,7 +593,7 @@ class SithFile(models.Model): ...@@ -590,7 +593,7 @@ class SithFile(models.Model):
return l return l
def get_parent_path(self): def get_parent_path(self):
return '/'.join([p.name for p in self.get_parent_list()]) return '/' + '/'.join([p.name for p in self.get_parent_list()])
def get_display_name(self): def get_display_name(self):
return self.name return self.name
......
...@@ -42,7 +42,8 @@ ...@@ -42,7 +42,8 @@
{% if not file.home_of and not file.home_of_club and file.parent %} {% if not file.home_of and not file.home_of_club and file.parent %}
<p><a href="{{ url('core:file_delete', file_id=file.id, popup=popup) }}">{% trans %}Delete{% endtrans %}</a></p> <p><a href="{{ url('core:file_delete', file_id=file.id, popup=popup) }}">{% trans %}Delete{% endtrans %}</a></p>
{% endif %} {% endif %}
{% if popup %} {% if user.is_in_group(settings.SITH_GROUPS['communication-admin']['id']) %}
<p><a href="{{ url('core:file_moderate', file_id=file.id) }}">{% trans %}Moderate{% endtrans %}</a></p>
{% endif %} {% endif %}
{% endblock %} {% endblock %}
......
{% extends "core/base.jinja" %}
{% block title %}
{% trans %}File moderation{% endtrans %}
{% endblock %}
{% block content %}
<h3>{% trans %}File moderation{% endtrans %}</h3>
<div>
{% for f in files %}
<div style="margin: 2px; padding: 2px; border: solid 1px red; text-align: center">
{% if f.is_folder %}
<strong>Folder</strong>
{% else %}
<strong>File</strong>
{% endif %}
<p>
<a href="{{ url("core:file_detail", file_id=f.id) }}">{{ f.name }}</a><br/>
{% trans %}Full name: {% endtrans %}{{ f.get_parent_path()+'/'+f.name }}<br/>
{% trans %}Owner: {% endtrans %}{{ f.owner.get_display_name() }}<br/>
{% trans %}Date: {% endtrans %}{{ f.date|date(DATE_FORMAT) }} {{ f.date|time(TIME_FORMAT) }}<br/>
</p>
<p><a href="{{ url('core:file_moderate', file_id=f.id) }}">{% trans %}Moderate{% endtrans %}</a> -
<a href="{{ url('core:file_delete', file_id=f.id) }}?next={{ url('core:file_moderation') }}">{% trans %}Delete{% endtrans %}</a></p>
</div>
{% endfor %}
</div>
{% endblock %}
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<h2>{% trans %}Edit user profile{% endtrans %}</h2> <h2>{% trans %}Edit user profile{% endtrans %}</h2>
<form action="" method="post" enctype="multipart/form-data" id="user_edit"> <form action="" method="post" enctype="multipart/form-data" id="user_edit">
{% csrf_token %} {% csrf_token %}
{{ form.non_field_errors() }}
{% for field in form %} {% for field in form %}
<p>{{ field.errors }}<label for="{{ field.name }}">{{ field.label }} <p>{{ field.errors }}<label for="{{ field.name }}">{{ field.label }}
{%- if field.name == "profile_pict" -%} {%- if field.name == "profile_pict" -%}
......
...@@ -58,6 +58,15 @@ ...@@ -58,6 +58,15 @@
{%- endfor %} {%- endfor %}
</ul> </ul>
{% if user.is_in_group(settings.SITH_GROUPS['communication-admin']['id']) %}
<hr>
<h4>{% trans %}Communication{% endtrans %}</h4>
<ul>
<li><a href="{{ url('core:file_moderation') }}">{% trans %}Moderate files{% endtrans %}</a></li>
</ul>
{% endif %}
<hr> <hr>
<h4>{% trans %}Club tools{% endtrans %}</h4> <h4>{% trans %}Club tools{% endtrans %}</h4>
<ul> <ul>
......
...@@ -50,6 +50,8 @@ urlpatterns = [ ...@@ -50,6 +50,8 @@ urlpatterns = [
url(r'^file/(?P<file_id>[0-9]+)/edit/(?P<popup>popup)?$', FileEditView.as_view(), name='file_edit'), url(r'^file/(?P<file_id>[0-9]+)/edit/(?P<popup>popup)?$', FileEditView.as_view(), name='file_edit'),
url(r'^file/(?P<file_id>[0-9]+)/prop/(?P<popup>popup)?$', FileEditPropView.as_view(), name='file_prop'), url(r'^file/(?P<file_id>[0-9]+)/prop/(?P<popup>popup)?$', FileEditPropView.as_view(), name='file_prop'),
url(r'^file/(?P<file_id>[0-9]+)/delete/(?P<popup>popup)?$', FileDeleteView.as_view(), name='file_delete'), url(r'^file/(?P<file_id>[0-9]+)/delete/(?P<popup>popup)?$', FileDeleteView.as_view(), name='file_delete'),
url(r'^file/moderation$', FileModerationView.as_view(), name='file_moderation'),
url(r'^file/(?P<file_id>[0-9]+)/moderate?$', FileModerateView.as_view(), name='file_moderate'),
url(r'^file/(?P<file_id>[0-9]+)/download$', send_file, name='download'), url(r'^file/(?P<file_id>[0-9]+)/download$', send_file, name='download'),
# Page views # Page views
......
# 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 render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.views.generic import ListView, DetailView from django.views.generic import ListView, DetailView, TemplateView
from django.views.generic.edit import UpdateView, CreateView, FormMixin, DeleteView from django.views.generic.edit import UpdateView, CreateView, FormMixin, DeleteView
from django.views.generic.detail import SingleObjectMixin
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.forms.models import modelform_factory from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple from django.forms import CheckboxSelectMultiple
...@@ -86,7 +87,7 @@ class FileEditView(CanEditMixin, UpdateView): ...@@ -86,7 +87,7 @@ class FileEditView(CanEditMixin, UpdateView):
context_object_name = "file" context_object_name = "file"
def get_form_class(self): def get_form_class(self):
fields = ['name'] fields = ['name', 'is_moderated']
if self.object.is_file: if self.object.is_file:
fields = ['file'] + fields fields = ['file'] + fields
return modelform_factory(SithFile, fields=fields) return modelform_factory(SithFile, fields=fields)
...@@ -166,6 +167,8 @@ class FileDeleteView(CanEditPropMixin, DeleteView): ...@@ -166,6 +167,8 @@ class FileDeleteView(CanEditPropMixin, DeleteView):
def get_success_url(self): def get_success_url(self):
self.object.file.delete() # Doing it here or overloading delete() is the same, so let's do it here self.object.file.delete() # Doing it here or overloading delete() is the same, so let's do it here
if 'next' in self.request.GET.keys():
return self.request.GET['next']
if self.object.parent is None: if self.object.parent is None:
return reverse('core:file_list', kwargs={'popup': self.kwargs['popup'] or ""}) return reverse('core:file_list', kwargs={'popup': self.kwargs['popup'] or ""})
return reverse('core:file_detail', kwargs={'file_id': self.object.parent.id, 'popup': self.kwargs['popup'] or ""}) return reverse('core:file_detail', kwargs={'file_id': self.object.parent.id, 'popup': self.kwargs['popup'] or ""})
...@@ -177,3 +180,23 @@ class FileDeleteView(CanEditPropMixin, DeleteView): ...@@ -177,3 +180,23 @@ class FileDeleteView(CanEditPropMixin, DeleteView):
kwargs['popup'] = 'popup' kwargs['popup'] = 'popup'
return kwargs return kwargs
class FileModerationView(TemplateView):
template_name = "core/file_moderation.jinja"
def get_context_data(self, **kwargs):
kwargs = super(FileModerationView, self).get_context_data(**kwargs)
kwargs['files'] = SithFile.objects.filter(is_moderated=False).all()
return kwargs
class FileModerateView(CanEditPropMixin, SingleObjectMixin):
model = SithFile
pk_url_kwarg = "file_id"
def get(self, request, *args, **kwargs):
self.object = self.get_object()
self.object.is_moderated = True
self.object.save()
if 'next' in self.request.GET.keys():
return redirect(self.request.GET['next'])
return redirect('core:file_moderation')
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment