Lots of stuff
- Imagestore gallery - remember me fixed - youtube filter - password change option
This commit is contained in:
19
imagestore/models/__init__.py
Normal file
19
imagestore/models/__init__.py
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
__author__ = 'zeus'
|
||||
from imagestore.utils import load_class, get_model_string
|
||||
from django.conf import settings
|
||||
|
||||
Album = load_class(getattr(settings, 'IMAGESTORE_ALBUM_MODEL', 'imagestore.models.album.Album'))
|
||||
Image = load_class(getattr(settings, 'IMAGESTORE_IMAGE_MODEL', 'imagestore.models.image.Image'))
|
||||
|
||||
# This labels and classnames used to generate permissons labels
|
||||
image_applabel = Image._meta.app_label
|
||||
image_classname = Image.__name__.lower()
|
||||
|
||||
album_applabel = Album._meta.app_label
|
||||
album_classname = Album.__name__.lower()
|
||||
|
||||
|
||||
from upload import AlbumUpload
|
||||
16
imagestore/models/album.py
Normal file
16
imagestore/models/album.py
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
__author__ = 'zeus'
|
||||
|
||||
from bases.album import BaseAlbum
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from imagestore.utils import load_class, get_model_string
|
||||
|
||||
class Album(BaseAlbum):
|
||||
|
||||
class Meta(BaseAlbum.Meta):
|
||||
abstract = False
|
||||
verbose_name = _('Album')
|
||||
verbose_name_plural = _('Albums')
|
||||
app_label = 'imagestore'
|
||||
5
imagestore/models/bases/__init__.py
Normal file
5
imagestore/models/bases/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
__author__ = 'zeus'
|
||||
|
||||
75
imagestore/models/bases/album.py
Normal file
75
imagestore/models/bases/album.py
Normal file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
__author__ = 'zeus'
|
||||
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import permalink
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf import settings
|
||||
from sorl.thumbnail import get_thumbnail
|
||||
|
||||
try:
|
||||
from django.contrib.auth import get_user_model
|
||||
User = get_user_model()
|
||||
except ImportError:
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
try:
|
||||
import Image as PILImage
|
||||
except ImportError:
|
||||
from PIL import Image as PILImage
|
||||
|
||||
from imagestore.utils import get_model_string
|
||||
|
||||
|
||||
SELF_MANAGE = getattr(settings, 'IMAGESTORE_SELF_MANAGE', True)
|
||||
|
||||
|
||||
class BaseAlbum(models.Model):
|
||||
class Meta(object):
|
||||
abstract = True
|
||||
ordering = ('order', 'created', 'name')
|
||||
permissions = (
|
||||
('moderate_albums', 'View, update and delete any album'),
|
||||
)
|
||||
|
||||
user = models.ForeignKey(User, verbose_name=_('User'), null=True, blank=True, related_name='albums')
|
||||
name = models.CharField(_('Name'), max_length=100, blank=False, null=False)
|
||||
created = models.DateTimeField(_('Created'), auto_now_add=True)
|
||||
updated = models.DateTimeField(_('Updated'), auto_now=True)
|
||||
is_public = models.BooleanField(_('Is public'), default=True)
|
||||
head = models.ForeignKey(get_model_string('Image'), related_name='head_of', null=True, blank=True, on_delete=models.SET_NULL)
|
||||
|
||||
order = models.IntegerField(_('Order'), default=0)
|
||||
|
||||
def get_head(self):
|
||||
if self.head:
|
||||
return self.head
|
||||
else:
|
||||
if self.images.all().count()>0:
|
||||
self.head = self.images.all()[0]
|
||||
self.save()
|
||||
return self.head
|
||||
else:
|
||||
return None
|
||||
|
||||
@permalink
|
||||
def get_absolute_url(self):
|
||||
return 'imagestore:album', (), {'album_id': self.id}
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def admin_thumbnail(self):
|
||||
img = self.get_head()
|
||||
if img:
|
||||
try:
|
||||
return '<img src="%s">' % get_thumbnail(img.image, '100x100', crop='center').url
|
||||
except IOError:
|
||||
return 'IOError'
|
||||
return _('Empty album')
|
||||
|
||||
admin_thumbnail.short_description = _('Head')
|
||||
admin_thumbnail.allow_tags = True
|
||||
104
imagestore/models/bases/image.py
Normal file
104
imagestore/models/bases/image.py
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
__author__ = 'zeus'
|
||||
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import permalink
|
||||
from sorl.thumbnail.helpers import ThumbnailError
|
||||
from tagging.fields import TagField
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf import settings
|
||||
from sorl.thumbnail import ImageField, get_thumbnail
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.db.models.signals import post_save
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
try:
|
||||
from django.contrib.auth import get_user_model
|
||||
User = get_user_model()
|
||||
except ImportError:
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
try:
|
||||
import Image as PILImage
|
||||
except ImportError:
|
||||
from PIL import Image as PILImage
|
||||
|
||||
from imagestore.utils import get_file_path, get_model_string
|
||||
|
||||
SELF_MANAGE = getattr(settings, 'IMAGESTORE_SELF_MANAGE', True)
|
||||
|
||||
|
||||
class BaseImage(models.Model):
|
||||
class Meta(object):
|
||||
abstract = True
|
||||
ordering = ('order', 'id')
|
||||
permissions = (
|
||||
('moderate_images', 'View, update and delete any image'),
|
||||
)
|
||||
|
||||
title = models.CharField(_('Title'), max_length=100, blank=True, null=True)
|
||||
description = models.TextField(_('Description'), blank=True, null=True)
|
||||
tags = TagField(_('Tags'), blank=True)
|
||||
order = models.IntegerField(_('Order'), default=0)
|
||||
image = ImageField(verbose_name = _('File'), upload_to=get_file_path)
|
||||
user = models.ForeignKey(User, verbose_name=_('User'), null=True, blank=True, related_name='images')
|
||||
created = models.DateTimeField(_('Created'), auto_now_add=True, null=True)
|
||||
updated = models.DateTimeField(_('Updated'), auto_now=True, null=True)
|
||||
album = models.ForeignKey(get_model_string('Album'), verbose_name=_('Album'), null=True, blank=True, related_name='images')
|
||||
|
||||
@permalink
|
||||
def get_absolute_url(self):
|
||||
return 'imagestore:image', (), {'pk': self.id}
|
||||
|
||||
def __unicode__(self):
|
||||
return '%s'% self.id
|
||||
|
||||
def admin_thumbnail(self):
|
||||
try:
|
||||
return '<img src="%s">' % get_thumbnail(self.image, '100x100', crop='center').url
|
||||
except IOError:
|
||||
return 'IOError'
|
||||
except ThumbnailError, ex:
|
||||
return 'ThumbnailError, %s' % ex.message
|
||||
|
||||
admin_thumbnail.short_description = _('Thumbnail')
|
||||
admin_thumbnail.allow_tags = True
|
||||
|
||||
|
||||
#noinspection PyUnusedLocal
|
||||
def setup_imagestore_permissions(instance, created, **kwargs):
|
||||
if not created:
|
||||
return
|
||||
try:
|
||||
from imagestore.models import Album, Image
|
||||
album_type = ContentType.objects.get(
|
||||
#app_label=load_class('imagestore.models.Album')._meta.app_label,
|
||||
app_label = Album._meta.app_label,
|
||||
name='Album'
|
||||
)
|
||||
image_type = ContentType.objects.get(
|
||||
#app_label=load_class('imagestore.models.Image')._meta.app_label,
|
||||
app_label = Image._meta.app_label,
|
||||
name='Image'
|
||||
)
|
||||
add_image_permission = Permission.objects.get(codename='add_image', content_type=image_type)
|
||||
add_album_permission = Permission.objects.get(codename='add_album', content_type=album_type)
|
||||
change_image_permission = Permission.objects.get(codename='change_image', content_type=image_type)
|
||||
change_album_permission = Permission.objects.get(codename='change_album', content_type=album_type)
|
||||
delete_image_permission = Permission.objects.get(codename='delete_image', content_type=image_type)
|
||||
delete_album_permission = Permission.objects.get(codename='delete_album', content_type=album_type)
|
||||
instance.user_permissions.add(add_image_permission, add_album_permission,)
|
||||
instance.user_permissions.add(change_image_permission, change_album_permission,)
|
||||
instance.user_permissions.add(delete_image_permission, delete_album_permission,)
|
||||
except ObjectDoesNotExist:
|
||||
# Permissions are not yet installed or conten does not created yet
|
||||
# probaly this is first
|
||||
pass
|
||||
|
||||
|
||||
if SELF_MANAGE:
|
||||
post_save.connect(setup_imagestore_permissions, User)
|
||||
15
imagestore/models/image.py
Normal file
15
imagestore/models/image.py
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
|
||||
__author__ = 'zeus'
|
||||
|
||||
from bases.image import BaseImage
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from imagestore.utils import load_class, get_model_string
|
||||
|
||||
class Image(BaseImage):
|
||||
class Meta(BaseImage.Meta):
|
||||
abstract = False
|
||||
verbose_name = _('Image')
|
||||
verbose_name_plural = _('Images')
|
||||
app_label = 'imagestore'
|
||||
112
imagestore/models/upload.py
Normal file
112
imagestore/models/upload.py
Normal file
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.utils.importlib import import_module
|
||||
|
||||
__author__ = 'zeus'
|
||||
|
||||
import os
|
||||
import zipfile
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf import settings
|
||||
from django.core.files.base import ContentFile
|
||||
try:
|
||||
import Image as PILImage
|
||||
except ImportError:
|
||||
from PIL import Image as PILImage
|
||||
|
||||
from imagestore.models import Album, Image
|
||||
|
||||
TEMP_DIR = getattr(settings, 'TEMP_DIR', 'temp/')
|
||||
|
||||
|
||||
def process_zipfile(uploaded_album):
|
||||
if os.path.isfile(uploaded_album.zip_file.path):
|
||||
# TODO: implement try-except here
|
||||
zip = zipfile.ZipFile(uploaded_album.zip_file.path)
|
||||
bad_file = zip.testzip()
|
||||
if bad_file:
|
||||
raise Exception('"%s" in the .zip archive is corrupt.' % bad_file)
|
||||
|
||||
if not uploaded_album.album:
|
||||
uploaded_album.album = Album.objects.create(name=uploaded_album.new_album_name)
|
||||
|
||||
from cStringIO import StringIO
|
||||
for filename in sorted(zip.namelist()):
|
||||
if filename.startswith('__'): # do not process meta files
|
||||
continue
|
||||
print filename
|
||||
data = zip.read(filename)
|
||||
if len(data):
|
||||
try:
|
||||
# the following is taken from django.forms.fields.ImageField:
|
||||
# load() could spot a truncated JPEG, but it loads the entire
|
||||
# image in memory, which is a DoS vector. See #3848 and #18520.
|
||||
# verify() must be called immediately after the constructor.
|
||||
PILImage.open(StringIO(data)).verify()
|
||||
except Exception, ex:
|
||||
# if a "bad" file is found we just skip it.
|
||||
print('Error verify image: %s' % ex.message)
|
||||
continue
|
||||
if hasattr(data, 'seek') and callable(data.seek):
|
||||
print 'seeked'
|
||||
data.seek(0)
|
||||
try:
|
||||
img = Image(album=uploaded_album.album)
|
||||
img.image.save(filename, ContentFile(data))
|
||||
img.save()
|
||||
except Exception, ex:
|
||||
print('error create Image: %s' % ex.message)
|
||||
zip.close()
|
||||
uploaded_album.delete()
|
||||
|
||||
|
||||
upload_processor_function = getattr(settings, 'IMAGESTORE_UPLOAD_ALBUM_PROCESSOR', None)
|
||||
upload_processor = process_zipfile
|
||||
if upload_processor_function:
|
||||
i = upload_processor_function.rfind('.')
|
||||
module, attr = upload_processor_function[:i], upload_processor_function[i+1:]
|
||||
try:
|
||||
mod = import_module(module)
|
||||
except ImportError as e:
|
||||
raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e))
|
||||
try:
|
||||
upload_processor = getattr(mod, attr)
|
||||
except AttributeError:
|
||||
raise ImproperlyConfigured('Module "%s" does not define a "%s" callable request processor' % (module, attr))
|
||||
|
||||
|
||||
class AlbumUpload(models.Model):
|
||||
"""
|
||||
Just re-written django-photologue GalleryUpload method
|
||||
"""
|
||||
zip_file = models.FileField(_('images file (.zip)'), upload_to=TEMP_DIR,
|
||||
help_text=_('Select a .zip file of images to upload into a new Gallery.'))
|
||||
album = models.ForeignKey(
|
||||
Album,
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_('Select an album to add these images to. leave this empty to create a new album from the supplied title.')
|
||||
)
|
||||
new_album_name = models.CharField(
|
||||
max_length=255,
|
||||
blank=True,
|
||||
verbose_name=_('New album name'),
|
||||
help_text=_('If not empty new album with this name will be created and images will be upload to this album')
|
||||
)
|
||||
tags = models.CharField(max_length=255, blank=True, verbose_name=_('tags'))
|
||||
|
||||
class Meta(object):
|
||||
verbose_name = _('Album upload')
|
||||
verbose_name_plural = _('Album uploads')
|
||||
app_label = 'imagestore'
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super(AlbumUpload, self).save(*args, **kwargs)
|
||||
upload_processor(self)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
storage, path = self.zip_file.storage, self.zip_file.path
|
||||
super(AlbumUpload, self).delete(*args, **kwargs)
|
||||
storage.delete(path)
|
||||
Reference in New Issue
Block a user