diff --git a/core/admin.py b/core/admin.py
index 3d1d86c7..5742d460 100644
--- a/core/admin.py
+++ b/core/admin.py
@@ -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
+ })
diff --git a/core/lookups.py b/core/lookups.py
index dc62eb0a..20dd7113 100644
--- a/core/lookups.py
+++ b/core/lookups.py
@@ -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
diff --git a/core/migrations/0011_auto_20161124_0848.py b/core/migrations/0011_auto_20161124_0848.py
new file mode 100644
index 00000000..8baba108
--- /dev/null
+++ b/core/migrations/0011_auto_20161124_0848.py
@@ -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),
+ ),
+ ]
diff --git a/core/models.py b/core/models.py
index 57e0aa09..c13c57f3 100644
--- a/core/models.py
+++ b/core/models.py
@@ -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
diff --git a/core/static/core/style.css b/core/static/core/style.css
index e09009c0..187664b7 100644
--- a/core/static/core/style.css
+++ b/core/static/core/style.css
@@ -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 {
diff --git a/core/templates/core/user_pictures.jinja b/core/templates/core/user_pictures.jinja
index df54dd0c..5ee4a51e 100644
--- a/core/templates/core/user_pictures.jinja
+++ b/core/templates/core/user_pictures.jinja
@@ -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() %}
- {% 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 %}
{{ album.name }}
- {% 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') %}
diff --git a/migrate.py b/migrate.py
index f5976322..97d952bf 100644
--- a/migrate.py
+++ b/migrate.py
@@ -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))
diff --git a/sas/admin.py b/sas/admin.py
index aec06f37..c49ee007 100644
--- a/sas/admin.py
+++ b/sas/admin.py
@@ -4,5 +4,7 @@ from sas.models import *
admin.site.register(Album)
-admin.site.register(Picture)
+# admin.site.register(Picture)
+admin.site.register(PeoplePictureRelation)
+
diff --git a/sas/models.py b/sas/models.py
index 64c49543..18483e61 100644
--- a/sas/models.py
+++ b/sas/models.py
@@ -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)
diff --git a/sas/templates/sas/album.jinja b/sas/templates/sas/album.jinja
index 38aa67c9..2bf2f48a 100644
--- a/sas/templates/sas/album.jinja
+++ b/sas/templates/sas/album.jinja
@@ -15,6 +15,7 @@
{% block content %}
SAS > {{ print_path(album.parent) }} {{ album.get_display_name() }}
{{ album.get_display_name() }}
+
{% trans %}Edit{% endtrans %}
{% for a in album.children.filter(is_folder=True, is_moderated=True).all() %}
@@ -33,7 +34,7 @@
{% endfor %}
- {% 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) %}
diff --git a/sas/templates/sas/picture.jinja b/sas/templates/sas/picture.jinja
index 1877928d..cc2eed9c 100644
--- a/sas/templates/sas/picture.jinja
+++ b/sas/templates/sas/picture.jinja
@@ -35,7 +35,8 @@
{% block content %}
SAS > {{ print_path(picture.parent) }} {{ picture.get_display_name() }}
-
{{ picture.get_display_name() }}
+({{ picture.parent.children.filter(id__lte=picture.id).count() }} / {{ picture.parent.children.count() }})
+
{{ picture.get_display_name() }}
+
+
{% trans %}Infos{% endtrans %}
+
{% trans %}Date: {% endtrans %}{{ picture.date|date(DATETIME_FORMAT) }}
+
{{ picture.parent.children.filter(id__lte=picture.id).count() }} / {{ picture.parent.children.count() }}
+
{% trans %}Tools{% endtrans %}
{% trans %}HD version{% endtrans %}
+ {% trans %}Edit{% endtrans %}
{% trans %}Rotate left{% endtrans %}
{% trans %}Rotate right{% endtrans %}
{% trans %}Ask for removal{% endtrans %}
diff --git a/sas/urls.py b/sas/urls.py
index 23464227..ac90d432 100644
--- a/sas/urls.py
+++ b/sas/urls.py
@@ -6,7 +6,9 @@ urlpatterns = [
url(r'^$', SASMainView.as_view(), name='main'),
url(r'^moderation$', ModerationView.as_view(), name='moderation'),
url(r'^album/(?P[0-9]+)$', AlbumView.as_view(), name='album'),
+ url(r'^album/(?P[0-9]+)/edit$', AlbumEditView.as_view(), name='album_edit'),
url(r'^picture/(?P[0-9]+)$', PictureView.as_view(), name='picture'),
+ url(r'^picture/(?P[0-9]+)/edit$', PictureEditView.as_view(), name='picture_edit'),
url(r'^picture/(?P[0-9]+)/download$', send_pict, name='download'),
url(r'^picture/(?P[0-9]+)/download/compressed$', send_compressed, name='download_compressed'),
url(r'^picture/(?P[0-9]+)/download/thumb$', send_thumb, name='download_thumb'),
diff --git a/sas/views.py b/sas/views.py
index 33b74fba..6ad04439 100644
--- a/sas/views.py
+++ b/sas/views.py
@@ -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"