Lot of small improvement in SAS

This commit is contained in:
Skia 2016-11-25 13:47:09 +01:00
parent 0b23d39e15
commit cfbb6f4e1f
13 changed files with 170 additions and 43 deletions

View File

@ -1,4 +1,5 @@
from django.contrib import admin
from ajax_select import make_ajax_form
from core.models import User, Page, RealGroup, SithFile
from django.contrib.auth.models import Group as AuthGroup
@ -7,5 +8,9 @@ admin.site.register(User)
admin.site.unregister(AuthGroup)
admin.site.register(RealGroup)
admin.site.register(Page)
admin.site.register(SithFile)
@admin.register(SithFile)
class SithFileAdmin(admin.ModelAdmin):
form = make_ajax_form(SithFile, {
'parent': 'files', # ManyToManyField
})

View File

@ -2,7 +2,7 @@ from django.core.exceptions import PermissionDenied
from ajax_select import register, LookupChannel
from core.views.site import search_user
from core.models import User, Group
from core.models import User, Group, SithFile
from club.models import Club
from counter.models import Product, Counter
from accounting.models import ClubAccount, Company
@ -77,6 +77,13 @@ class ProductsLookup(RightManagedLookupChannel):
def format_item_display(self, item):
return "%s (%s)" % (item.name, item.code)
@register('files')
class SithFileLookup(RightManagedLookupChannel):
model = SithFile
def get_query(self, q, request):
return self.model.objects.filter(name__icontains=q)[:50]
@register('club_accounts')
class ClubAccountLookup(RightManagedLookupChannel):
model = ClubAccount

View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
import core.models
class Migration(migrations.Migration):
dependencies = [
('core', '0010_sithfile_is_in_sas'),
]
operations = [
migrations.AlterField(
model_name='sithfile',
name='compressed',
field=models.FileField(verbose_name='compressed file', upload_to=core.models.get_compressed_directory, null=True, blank=True, max_length=256),
),
migrations.AlterField(
model_name='sithfile',
name='date',
field=models.DateTimeField(verbose_name='date', default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='sithfile',
name='file',
field=models.FileField(verbose_name='file', upload_to=core.models.get_directory, null=True, blank=True, max_length=256),
),
migrations.AlterField(
model_name='sithfile',
name='thumbnail',
field=models.FileField(verbose_name='thumbnail', upload_to=core.models.get_thumbnail_directory, null=True, blank=True, max_length=256),
),
]

View File

@ -317,7 +317,9 @@ class User(AbstractBaseUser):
def get_short_name(self):
"Returns the short name for the user."
return self.first_name
if self.nick_name:
return self.nick_name
return self.first_name + " " + self.last_name
def get_display_name(self):
"""
@ -501,16 +503,16 @@ def get_thumbnail_directory(instance, filename):
class SithFile(models.Model):
name = models.CharField(_('file name'), max_length=256, blank=False)
parent = models.ForeignKey('self', related_name="children", verbose_name=_("parent"), null=True, blank=True)
file = models.FileField(upload_to=get_directory, verbose_name=_("file"), null=True, blank=True)
compressed = models.FileField(upload_to=get_compressed_directory, verbose_name=_("compressed file"), null=True, blank=True)
thumbnail = models.FileField(upload_to=get_thumbnail_directory, verbose_name=_("thumbnail"), null=True, blank=True)
file = models.FileField(upload_to=get_directory, verbose_name=_("file"), max_length=256, null=True, blank=True)
compressed = models.FileField(upload_to=get_compressed_directory, verbose_name=_("compressed file"), max_length=256, null=True, blank=True)
thumbnail = models.FileField(upload_to=get_thumbnail_directory, verbose_name=_("thumbnail"), max_length=256, null=True, blank=True)
owner = models.ForeignKey(User, related_name="owned_files", verbose_name=_("owner"))
edit_groups = models.ManyToManyField(Group, related_name="editable_files", verbose_name=_("edit group"), blank=True)
view_groups = models.ManyToManyField(Group, related_name="viewable_files", verbose_name=_("view group"), blank=True)
is_folder = models.BooleanField(_("is folder"), default=True)
mime_type = models.CharField(_('mime type'), max_length=30)
size = models.IntegerField(_("size"), default=0)
date = models.DateTimeField(_('date'), auto_now=True)
date = models.DateTimeField(_('date'), default=timezone.now)
is_moderated = models.BooleanField(_("is moderated"), default=False)
asked_for_removal = models.BooleanField(_("asked for removal"), default=False)
is_in_sas = models.BooleanField(_("is in the SAS"), default=False)
@ -629,6 +631,9 @@ class SithFile(models.Model):
def get_download_url(self):
return reverse('core:download', kwargs={'file_id': self.id})
def __str__(self):
return self.get_parent_path() + "/" + self.name
class LockError(Exception):
"""There was a lock error on the object"""
pass

View File

@ -314,10 +314,11 @@ textarea {
text-align: center;
padding: 5px;
width: 200px;
height: 133px;
height: 140px;
background: #eee;
box-shadow: black 2px 2px 10px;
margin: 10px;
vertical-align: top;
}
.album img {

View File

@ -6,12 +6,12 @@
{% endblock %}
{% block content %}
{% for r in user.pictures.exclude(picture=None).values('user__pictures__picture__parent').distinct() %}
{% for r in profile.pictures.exclude(picture=None).values('user__pictures__picture__parent').distinct() %}
<div style="padding: 10px">
{% set album = user.pictures.filter(picture__parent=r['user__pictures__picture__parent']).first().picture.parent %}
{% set album = profile.pictures.filter(picture__parent=r['user__pictures__picture__parent']).first().picture.parent %}
<h4>{{ album.name }}</h4>
<hr>
{% for r in user.pictures.exclude(picture=None).filter(picture__parent=album) %}
{% for r in profile.pictures.exclude(picture=None).filter(picture__parent=album).order_by('id') %}
<div class="picture">
<a href="{{ url("sas:picture", picture_id=r.picture.id) }}#pict">
<img src="{{ r.picture.as_picture.get_download_thumb_url() }}" alt="{{ r.picture.get_display_name() }}" style="max-width: 100%"/>

View File

@ -25,7 +25,7 @@ from counter.models import Customer, Counter, Selling, Refilling, Product, Produ
from subscription.models import Subscription, Subscriber
from eboutic.models import Invoice, InvoiceItem
from accounting.models import BankAccount, ClubAccount, GeneralJournal, Operation, AccountingType, Company, SimplifiedAccountingType, Label
from sas.models import Album, Picture
from sas.models import Album, Picture, PeoplePictureRelation
db = MySQLdb.connect(**settings.OLD_MYSQL_INFOS)
start = datetime.datetime.now()
@ -1029,7 +1029,7 @@ def migrate_sas():
album_link = {}
picture_link = {}
FILE_ROOT = "/data/sas/"
Album.objects.filter(is_in_sas=True).delete()
SithFile.objects.filter(id__gt=18886).delete()
print("Album/Pictures deleted")
cur = db.cursor(MySQLdb.cursors.SSDictCursor)
cur.execute("""
@ -1044,44 +1044,74 @@ def migrate_sas():
album_link[str(r['id_catph'])] = a.id
except Exception as e:
print("FAIL to migrate Album: %s" % (repr(e)))
print("Album moved, need to make the tree")
cur.execute("""
SELECT *
FROM sas_cat_photos
""")
for r in cur:
try:
p = Album.objects.filter(id=album_link[r['id_catph_parent']]).first()
a = Album.objects.filter(id=album_link[r['id_catph']]).first()
p = Album.objects.filter(id=album_link[str(r['id_catph_parent'])]).first()
a = Album.objects.filter(id=album_link[str(r['id_catph'])]).first()
a.parent = p
a.save()
except: pass
print("Album migrated at %s" % datetime.datetime.now())
print("Running time: %s" % (datetime.datetime.now()-start))
# cur.execute("""
# SELECT *
# FROM sas_photos
# """)
# for r in cur:
# try:
# user = User.objects.filter(id=r['id_utilisateur']).first() or root
# parent = Album.objects.filter(id=album_link[str(r['id_catph'])]).first()
cur.execute("""
SELECT *
FROM sas_photos
""")
for r in cur:
try:
user = User.objects.filter(id=r['id_utilisateur']).first() or root
parent = Album.objects.filter(id=album_link[str(r['id_catph'])]).first()
# p = Picture(
# name=to_unicode(str(r['id_photo'])),
# owner=user,
# is_moderated=True,
# is_folder=False,
# mime_type="image/jpeg",
# parent=parent
# )
# for f in p._meta.local_fields:
# if f.name == "date":
# f.auto_now = False
# p.date = r['date_ajout_ph'].replace(tzinfo=timezone('Europe/Paris'))
# p.save()
# picture_link[str(r['id_photo'])] = p.id
# except Exception as e:
# print("FAIL to migrate Picture: %s" % (repr(e)))
file_name = FILE_ROOT
if r['date_prise_vue']:
file_name += r['date_prise_vue'].strftime("%Y/%m/%d")
else:
file_name += '/'.join(["1970", "01", "01"])
file_name += "/" + str(r['id_photo']) + ".jpg"
file = File(open(file_name, "rb"))
file.name = str(r['id_photo']) + ".jpg"
p = Picture(
name=to_unicode(str(r['id_photo'])) + ".jpg",
owner=user,
is_moderated=True,
is_folder=False,
mime_type="image/jpeg",
parent=parent,
file=file,
)
if r['date_prise_vue']:
p.date = r['date_prise_vue'].replace(tzinfo=timezone('Europe/Paris'))
else:
p.date = r['date_ajout_ph'].replace(tzinfo=timezone('Europe/Paris'))
for f in p._meta.local_fields:
if f.name == "date":
f.auto_now = False
p.generate_thumbnails()
db2 = MySQLdb.connect(**settings.OLD_MYSQL_INFOS)
cur2 = db2.cursor(MySQLdb.cursors.SSDictCursor)
cur2.execute("""
SELECT *
FROM sas_personnes_photos
WHERE id_photo = %s
""", (r['id_photo'], ))
for r2 in cur2:
try:
u = User.objects.filter(id=r2['id_utilisateur']).first()
if u:
PeoplePictureRelation(user=u, picture=p).save()
except:
print("Fail to associate user %d to picture %d" % (r2['id_utilisateur'], p.id))
picture_link[str(r['id_photo'])] = p.id
except Exception as e:
pass
print("FAIL to migrate Picture: %s" % (repr(e)))
cur.close()
print("SAS migrated at %s" % datetime.datetime.now())
print("Running time: %s" % (datetime.datetime.now()-start))

View File

@ -4,5 +4,7 @@ from sas.models import *
admin.site.register(Album)
admin.site.register(Picture)
# admin.site.register(Picture)
admin.site.register(PeoplePictureRelation)

View File

@ -1,4 +1,5 @@
from django.db import models
from django.core.urlresolvers import reverse_lazy, reverse
from django.conf import settings
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
@ -36,6 +37,9 @@ class Picture(SithFile):
def get_download_thumb_url(self):
return reverse('sas:download_thumb', kwargs={'picture_id': self.id})
def get_absolute_url(self):
return reverse('sas:picture', kwargs={'picture_id': self.id})
def generate_thumbnails(self):
im = Image.open(BytesIO(self.file.read()))
try:
@ -94,3 +98,6 @@ class PeoplePictureRelation(models.Model):
class Meta:
unique_together = ['user', 'picture']
def __str__(self):
return self.user.get_display_name() + " - " + str(self.picture)

View File

@ -15,6 +15,7 @@
{% block content %}
<a href="{{ url('sas:main') }}">SAS</a> > {{ print_path(album.parent) }} {{ album.get_display_name() }}
<h3>{{ album.get_display_name() }}</h3>
<a href="{{ url('sas:album_edit', album_id=album.id) }}">{% trans %}Edit{% endtrans %}</a><br>
<hr>
<div>
{% for a in album.children.filter(is_folder=True, is_moderated=True).all() %}
@ -33,7 +34,7 @@
{% endfor %}
</div>
<div>
{% 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).order_by('id') %}
{% if p.as_picture.can_be_viewed_by(user) %}
<div class="picture">
<a href="{{ url("sas:picture", picture_id=p.id) }}#pict">

View File

@ -35,7 +35,8 @@
{% block content %}
<a href="{{ url('sas:main') }}">SAS</a> > {{ print_path(picture.parent) }} {{ picture.get_display_name() }}
<h3>{{ picture.get_display_name() }}</h3>
({{ picture.parent.children.filter(id__lte=picture.id).count() }} / {{ picture.parent.children.count() }})
<h3> {{ picture.get_display_name() }}</h3>
<div style="display: inline-block; width: 19%; vertical-align: top; overflow: hidden; float: right">
<div>
<div id="prev">
@ -60,7 +61,7 @@
<ul>
{% for r in picture.people.all() %}
<li>
<a href="{{ r.user.get_absolute_url() }}">{{ r.user.get_display_name() }}</a>
<a href="{{ r.user.get_absolute_url() }}">{{ r.user.get_short_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 %}
@ -73,12 +74,18 @@
<p><input type="submit" value="{% trans %}Go{% endtrans %}" /></p>
</form>
</div>
<div>
<h5>{% trans %}Infos{% endtrans %}</h5>
<p>{% trans %}Date: {% endtrans %}{{ picture.date|date(DATETIME_FORMAT) }}</p>
<p>{{ picture.parent.children.filter(id__lte=picture.id).count() }} / {{ picture.parent.children.count() }}</p>
</div>
<div>
<h5>{% trans %}Tools{% endtrans %}</h5>
<p>
<a href="{{ picture.get_download_url() }}">{% trans %}HD version{% endtrans %}</a>
</p>
<p style="font-size: smaller;">
<a href="{{ url('sas:picture_edit', picture_id=picture.id) }}">{% trans %}Edit{% endtrans %}</a><br>
<a href="?rotate_left">{% trans %}Rotate left{% endtrans %}</a><br>
<a href="?rotate_right">{% trans %}Rotate right{% endtrans %}</a><br>
<a href="?ask_removal">{% trans %}Ask for removal{% endtrans %}</a><br>

View File

@ -6,7 +6,9 @@ urlpatterns = [
url(r'^$', SASMainView.as_view(), name='main'),
url(r'^moderation$', ModerationView.as_view(), name='moderation'),
url(r'^album/(?P<album_id>[0-9]+)$', AlbumView.as_view(), name='album'),
url(r'^album/(?P<album_id>[0-9]+)/edit$', AlbumEditView.as_view(), name='album_edit'),
url(r'^picture/(?P<picture_id>[0-9]+)$', PictureView.as_view(), name='picture'),
url(r'^picture/(?P<picture_id>[0-9]+)/edit$', PictureEditView.as_view(), name='picture_edit'),
url(r'^picture/(?P<picture_id>[0-9]+)/download$', send_pict, name='download'),
url(r'^picture/(?P<picture_id>[0-9]+)/download/compressed$', send_compressed, name='download_compressed'),
url(r'^picture/(?P<picture_id>[0-9]+)/download/thumb$', send_thumb, name='download_thumb'),

View File

@ -5,6 +5,7 @@ from django.views.generic.edit import UpdateView, CreateView, DeleteView, Proces
from django.utils.translation import ugettext as _
from django.utils import timezone
from django.conf import settings
from django.forms.models import modelform_factory
from django import forms
from django.core.exceptions import PermissionDenied
@ -192,4 +193,27 @@ class ModerationView(TemplateView):
kwargs['pictures'] = Picture.objects.filter(is_moderated=False, is_in_sas=True).order_by('id')
return kwargs
class PictureEditForm(forms.ModelForm):
class Meta:
model = Picture
fields=['name', 'parent']
parent = make_ajax_field(Picture, 'parent', 'files', help_text="")
class AlbumEditForm(forms.ModelForm):
class Meta:
model = Album
fields=['name', 'parent']
parent = make_ajax_field(Album, 'parent', 'files', help_text="")
class PictureEditView(UpdateView):
model=Picture
form_class=PictureEditForm
template_name='core/edit.jinja'
pk_url_kwarg = "picture_id"
class AlbumEditView(UpdateView):
model=Album
form_class=AlbumEditForm
template_name='core/edit.jinja'
pk_url_kwarg = "album_id"