aboutsummaryrefslogtreecommitdiffstats
path: root/bn_django/photos
diff options
context:
space:
mode:
Diffstat (limited to 'bn_django/photos')
-rw-r--r--bn_django/photos/__init__.py1
-rw-r--r--bn_django/photos/admin.py6
-rw-r--r--bn_django/photos/manual_import.py64
-rw-r--r--bn_django/photos/models.py272
-rw-r--r--bn_django/photos/templates/photos/base.html5
-rw-r--r--bn_django/photos/templates/photos/gallery_detail.html45
-rw-r--r--bn_django/photos/templates/photos/gallery_list.html57
-rw-r--r--bn_django/photos/templates/photos/import_form.html62
-rw-r--r--bn_django/photos/templates/photos/photo_detail.html111
-rw-r--r--bn_django/photos/urls.py23
-rw-r--r--bn_django/photos/views.py185
11 files changed, 0 insertions, 831 deletions
diff --git a/bn_django/photos/__init__.py b/bn_django/photos/__init__.py
deleted file mode 100644
index 52af441..0000000
--- a/bn_django/photos/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"""Strongly based on code from the stockphoto project (google it?)"""
diff --git a/bn_django/photos/admin.py b/bn_django/photos/admin.py
deleted file mode 100644
index a32ae7e..0000000
--- a/bn_django/photos/admin.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from bn_django.photos.models import Photo, Gallery
-from django.contrib import admin
-
-admin.site.register(Photo)
-admin.site.register(Gallery)
-
diff --git a/bn_django/photos/manual_import.py b/bn_django/photos/manual_import.py
deleted file mode 100644
index 8311445..0000000
--- a/bn_django/photos/manual_import.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Create your views here.
-
-# django imports
-from django.conf import settings
-
-# other imports
-import zipfile
-import os
-import stat
-import shutil
-from datetime import datetime
-from tempfile import NamedTemporaryFile, mkdtemp
-import Image
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-# Handling settings here
-STOCKPHOTO_BASE = 'photos'
-
-# models
-from bn_django.photos.models import Gallery, Photo
-
-# views
-
-
-def manual_import_photos(thezipfile, thegallery):
- # Check if the gallery is valid
- gallery = thegallery;
-
- f = file(thezipfile);
- zip = zipfile.ZipFile(f)
- #date = the_date
- #if not date:
- date = datetime.date(datetime.now())
-
- destdir= os.path.join(settings.MEDIA_ROOT, STOCKPHOTO_BASE,
- datetime.strftime(datetime.now(),
- "%Y/%m/%d/"))
- if not os.path.isdir(destdir):
- os.makedirs(destdir, 0775)
- for filename in zip.namelist():
- photopath = os.path.join(destdir, os.path.basename(filename))
- data = zip.read(filename)
- file_data = StringIO(data)
- try:
- Image.open(file_data)
- except:
- # don't save and process non Image files
- continue
- photo = file(photopath, "wb")
- photo.write(data)
-
- # Create the object
- if photopath.startswith(os.path.sep):
- photopath = photopath[len(settings.MEDIA_ROOT):]
- photo = Photo(image=photopath, date=date,
- photographer='Bryan Newbold',
- title = os.path.basename(filename),
- gallery_id = thegallery)
- # Save it -- the thumbnails etc. get created.
- photo.save()
- return
diff --git a/bn_django/photos/models.py b/bn_django/photos/models.py
deleted file mode 100644
index 4964467..0000000
--- a/bn_django/photos/models.py
+++ /dev/null
@@ -1,272 +0,0 @@
-from django.db import models
-from django.utils.translation import ugettext as _
-import django.contrib.auth.models as auth
-from django.conf import settings
-from django.dispatch import dispatcher
-from django.db.models import signals
-
-import os, os.path
-import Image
-
-# Handle settings here
-try:
- STOCKPHOTO_BASE = settings.STOCKPHOTO_BASE.strip('/')
-except AttributeError:
- STOCKPHOTO_BASE='photos'
-
-STOCKPHOTO_URL='http://media.bnewbold.net/hosted-photos'
-
-try:
- ADMIN_URL = settings.ADMIN_URL
-except AttributeError:
- ADMIN_URL='/admin'
-if ADMIN_URL[-1] == '/':
- ADMIN_URL=ADMIN_URL[:-1]
-
-# Create your models here.
-class Gallery(models.Model):
- title = models.CharField("title", max_length=80)
- slug = models.SlugField()
- date = models.DateField("publication date", auto_now_add=True)
- created = models.ForeignKey(auth.User,
- verbose_name="gallery created by"
- )
- display_width = models.IntegerField(
- "width to display full images",
- default=640)
- display_height = models.IntegerField(
- "height to display full images",
- default=480)
- thumbnail_width = models.IntegerField(
- "width to display thumbnails",
- default=150)
- thumbnail_height = models.IntegerField(
- "height to display thumbnails",
- default=100)
-
- class Meta:
- get_latest_by = 'date'
-
- class Admin:
- ordering = ['date']
- prepopulated_fields = {'slug': 'title'}
-
- def __str__(self):
- return self.title
- def get_absolute_url(self):
- return "%s/%s/" % (STOCKPHOTO_BASE, self.slug)
- def get_admin_url(self):
- return "%s/photos/gallery/%d/" % (ADMIN_URL, self.id)
- def was_published_today(self):
- return self.date.date() == datetime.date.today()
-
- def first(self):
- try:
- return self.photo_set.all()[0]
- except IndexError:
- return None
- def update_thumbs(self):
- for photo in self.photo_set.all():
- photo.create_disp()
- photo.create_thumb()
-
-class Photo(models.Model):
- # import os, os.path, Image
- image = models.ImageField("Photograph",
- upload_to= STOCKPHOTO_BASE + "/%Y/%m/%d/")
- title = models.CharField("title", max_length=80)
- desc = models.TextField("description", blank=True)
- gallery = models.ForeignKey(Gallery, blank=True, null=True)
- photographer = models.CharField("photographer", max_length=80,
- blank=True)
- date = models.DateField("date photographed", blank=True, null=True)
- extra = models.TextField("any extra information about the photo",
- blank=True)
- class META:
- get_latest_by = ['date']
-
- class Admin:
- list_display = ('title', 'date', 'gallery', 'id')
- ordering = ['id']
- list_filter = ['gallery']
- search_fields = ['title']
-
- def __str__(self):
- return self.title
-
- def delete_thumbnails(self):
- """Remove thumbnail and display-sized images when deleting.
-
- This may fail if, for example, they don't exist, so it should
- fail silently. It may not be a good idea to delete the
- original, as the user may not understand that deleting it from
- the gallery deletes it from the filesystem, so currently we
- don't do that.
-
- """
- try:
- os.unlink(self.thumbpath())
- except (IOError, OSError):
- pass
- try:
- os.unlink(self.disppath())
- except (IOError, OSError):
- pass
- # Deleting the original might be a bad thing.
- #os.unlink(self.fullpath())
-
- def get_absolute_url(self):
- return "%s/detail/%d/" % (STOCKPHOTO_BASE, self.id)
-
- def get_admin_url(self):
- return "%s/photos/photos/%d/" % (ADMIN_URL, self.id)
-
- def thumbpath(self):
- """Path to the thumbnail
- """
- photobase = self.image.name[len(STOCKPHOTO_BASE)+1:]
- return os.path.join( settings.MEDIA_ROOT, STOCKPHOTO_BASE,
- "cache", "thumbs", photobase)
-
- def thumburl(self):
- """URL to the thumbnail
- """
- photobase = self.image.name[len(STOCKPHOTO_BASE)+1:]
- return STOCKPHOTO_URL + "/cache/thumbs/" + photobase
-
- def disppath(self):
- photobase = self.image.name[len(STOCKPHOTO_BASE)+1:]
- return os.path.join( settings.MEDIA_ROOT, STOCKPHOTO_BASE,
- "cache", photobase)
-
- def dispurl(self):
- photobase = self.image.name[len(STOCKPHOTO_BASE)+1:]
- return STOCKPHOTO_URL + "/cache/" + photobase
-
- def fullpath(self):
- if self.image.name.startswith(os.path.sep):
- return self.image.name
- return os.path.join(settings.MEDIA_ROOT, self.image.name)
-
- def fullurl(self):
- if(self.image.name.startswith("photos/")):
- return STOCKPHOTO_URL + '/' + self.image.name[7:]
- else:
- return STOCKPHOTO_URL + '/' + self.image.name
-
-
- def next(self):
- '''Return id of 'next' photo in the same gallery or None if at
- the end.'''
- # we could probably be more clever here by using the new nifty
- # db access filters and queries, but for now, this is good enough
- photo_list = [x for x in self.gallery.photo_set.all()]
- ind = photo_list.index(self)
- if (ind +1) == len(photo_list):
- return None
- else:
- return photo_list[ind + 1]
-
- def prev(self):
- """Return id of 'previous' photo in the same gallery or None
- if at the beginning
- """
- photo_list = [x for x in self.gallery.photo_set.all()]
- ind = photo_list.index(self)
- if ind == 0:
- return False
- else:
- return photo_list[ind - 1]
-
- def full_exists(self):
- return os.path.exists( self.fullpath() )
-
- def disp_exists(self):
- return os.path.exists( self.disppath() )
-
- def thumb_exists(self):
- return os.path.exists( self.thumbpath() )
-
- def create_disp(self):
- im = Image.open( self.fullpath() )
- format = im.format
- # create the path for the display image
- disp_path = self.disppath()
- disp_dir = os.path.dirname(disp_path)
- if not os.path.exists(disp_dir):
- os.makedirs(disp_dir, 0775)
-
- # Make a copy of the image, scaled, if needed.
- maxwidth = self.gallery.display_width
- maxheight = self.gallery.display_height
- width, height = im.size
- if (width > maxwidth) and width > height:
- scale = float(maxwidth)/width
- width = int(width * scale)
- height = int(height * scale)
- newim = im.resize( (width, height), Image.ANTIALIAS )
- elif (height > maxheight) and height >= width:
- scale = float(maxheight)/height
- width = int(width * scale)
- height = int(height * scale)
- newim = im.resize( (width, height), Image.ANTIALIAS )
- else:
- newim = im
- newim.save(disp_path, format)
-
- def create_thumb(self):
- im = Image.open( self.fullpath() )
- format = im.format
- # create the path for the thumbnail image
- thumb_path = self.thumbpath()
- thumb_dir = os.path.dirname(thumb_path)
- if not os.path.exists(thumb_dir):
- os.makedirs(thumb_dir, 0775)
-
- # Make a copy of the image, scaled, if needed.
- maxwidth = self.gallery.thumbnail_width
- maxheight = self.gallery.thumbnail_height
- width, height = im.size
- if (width > maxwidth) and (width > height):
- scale = float(maxwidth)/width
- width = int(width * scale)
- height = int(height * scale)
- newim = im.resize( (width, height), Image.ANTIALIAS )
- elif (height > maxheight):
- scale = float(maxheight)/height
- width = int(width * scale)
- height = int(height * scale)
- newim = im.resize( (width, height), Image.ANTIALIAS )
- else:
- newim = im
- newim.save(thumb_path, format)
-
- def build_display_images(self):
- """Make thumbnail and display-sized images after saving.
-
- For some reason, this may fail on a first pass (self.image may
- be empty when this is called), but if we just let it fail
- silently, it will apparently get called again and succeed.
- """
- if self.image:
- if not self.thumb_exists():
- self.create_thumb()
- if not self.disp_exists():
- self.create_disp()
-
-def build_display_images(sender, instance, signal, *args, **kwargs):
- """Simple hook for save-after trigger
- """
- instance.build_display_images()
-def delete_thumbnails(sender, instance, signal, *args, **kwargs):
- """Simple hook for pre-delete trigger.
- """
- instance.delete_thumbnails()
-
-signals.post_save.connect(build_display_images, sender=Photo)
-signals.pre_delete.connect(delete_thumbnails, sender=Photo)
-
-#dispatcher.connect(build_display_images, signal=signals.post_save,
-# sender=Photo)
-#dispatcher.connect(delete_thumbnails, signal=signals.pre_delete,
-# sender=Photo)
diff --git a/bn_django/photos/templates/photos/base.html b/bn_django/photos/templates/photos/base.html
deleted file mode 100644
index d229057..0000000
--- a/bn_django/photos/templates/photos/base.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends "base.html" %}
-
-{% block path %}
- <a href="/photos/">photos</a>
-{% endblock %}
diff --git a/bn_django/photos/templates/photos/gallery_detail.html b/bn_django/photos/templates/photos/gallery_detail.html
deleted file mode 100644
index 0b3a4af..0000000
--- a/bn_django/photos/templates/photos/gallery_detail.html
+++ /dev/null
@@ -1,45 +0,0 @@
-{% extends "photos/base.html" %}
-{# {% load markup %} #}
-{% block path %}
-{{ block.super }}
-{% if object %}
- &raquo;
- <a href="../{{ object.slug }}/">{{ object.title }}</a>
-{% endif %} {% endblock %}
-{% block title %}
-{% if object %}Photo Set: {{ object.title }} {% endif %}
-{% endblock %}
-{% block content %}
-{% if object %}
-{% if object.photo_set.count %}
-<table width="100%" class="thumbs">
-{% for item in object.photo_set.all %} {% cycle <tr/>,&nbsp;,&nbsp;,&nbsp; %}
- <td class="photo_thumb">
- <a href="../detail/{{ item.id }}/">
- <img src="{{ item.thumburl }}"
- alt="{{ item.title }}" />
- </td> {% endfor %}
-</table>
-{% else %}
-<p>There are no photos in this gallery. If you just uploaded a batch
-of photos, try hitting your browser's reload button to see if they
-show up.</p> {% endif %}
-&nbsp;
-<!--
-{% if not user.is_anonymous %}
-<p>
- <a href="{{ object.get_admin_url }}">Edit this gallery.</a><br/>
- <a href="{{ admin_url }}/photos/photo/add/">Add a photo to
- this gallery.</a><br/>
- <a href="{{photos_url}}/import/{{ object.id }}/">Add a bunch
- of photos to this gallery.</a>
-</p>
-{% else %}
-<p>
- <a href="/accounts/login/?next={{ request.path }}">
- Login</a> to add or edit photos
-</p>
-{% endif %}
--->
-{% else %} <p>This is not the gallery you are looking for.</p> {% endif %}
-{% endblock %}
diff --git a/bn_django/photos/templates/photos/gallery_list.html b/bn_django/photos/templates/photos/gallery_list.html
deleted file mode 100644
index 11c7289..0000000
--- a/bn_django/photos/templates/photos/gallery_list.html
+++ /dev/null
@@ -1,57 +0,0 @@
-{% extends "photos/base.html" %}
-{# {% load markup %} #}
-
-{% block title %}Photo Sets{% endblock %}
-
-{% block content %}
-{% if object_list %}
- <table width="100%">
- {% for item in object_list %}
- <tr>
- <td class="photo_thumb">
- <a href="{{ item.slug }}/">
- {% if item.first %}
- <img src="{{ item.first.thumburl }}"
- alt="{{ item.first.title }}" />
- {% else %}
- (No photo available)
- {% endif %}
- </a>
- </td><td style="vertical-align: top; padding-left: 14px;" >
- <h3 style="font-size: 150%;">
- <a href="{{ item.slug }}/">{{ item.title }}</a></h3>
- {{ item.photo_set.count }} photo{{ item.photo_set.count|pluralize}}
- {% if item.first.date %}
- starting in {{ item.first.date|date:"M, Y" }}{% endif %}
- </td></tr>
- {% endfor %}
- </table>
-{% else %}
- <p>No galleries have been set up yet.</p>
-{% endif %}
-
-
-{% if is_paginated %}
-
-{% if has_previous %}
-<a href="./?page={{ previous }}">&laquo; previous</a> |
-{% endif %}
-{% if has_next %}
-<a href="./?page={{ next }}">next &raquo;</a>
-{% endif %}
-{% endif %}
-
-<!--
-{% if not user.is_anonymous %}
-<p>
- <a href="{{admin_url}}/photos/gallery/add/">Create a new gallery.</a>
-</p>
-{% else %}
-<p>
- <a href="/accounts/login/?next={{ request.path }}">
- Login</a> to create a new gallery.
-</p>
-{% endif %}
--->
-
-{% endblock %}
diff --git a/bn_django/photos/templates/photos/import_form.html b/bn_django/photos/templates/photos/import_form.html
deleted file mode 100644
index bd01a9a..0000000
--- a/bn_django/photos/templates/photos/import_form.html
+++ /dev/null
@@ -1,62 +0,0 @@
-{% extends "photos/base.html" %}
-{# {% load markup %} #}
-{% block title %}Import photos into a gallery
-{% if gallery%} ({{gallery.title}}){% endif %}{% endblock %}
-
-{% block content %}
-{% if gallery %}
-
-<form action="../../import/{{ gallery.id }}/" method="post"
- enctype="multipart/form-data">
- <div>
- {%if form.zipfile.errors %}
- <span style="color: red;">
- {{ form.zipfile.errors|join:", " }}
- </span><br/>
- {% endif %}
-
- <label class="fortextinput" for="id_zipfile">
- ZIP archive to upload:
- </label>
- {{ form.zipfile }}<br/><br/>
-
- {%if form.photographer.errors %}
- <span style="color: red;">
- {{ form.photographer.errors|join:", " }}
- </span><br/>
- {% endif %}
-
- <label class="fortextinput" for="id_photographer">
- Name of photographer:
- </label>
- {{ form.photographer }}<br/><br/>
-
- {%if form.date.errors %}
- <span style="color: red;">
- {{ form.date.errors|join:", " }}
- </span><br/>
- {% endif %}
-
- <label class="fortextinput" for="id_date">
- Date photos were taken:
- </label>
- {{ form.date }}<br/><br/>
- <input type="submit" value="Upload"/>
- </div>
-</form>
-<p>
- When you upload a batch of photos in a zipfile, it will give each of
- them a title based on its filename, and assigns them all the same
- photographer and date. That's probably not always what you want, so
- you can change any of these settings on a per-photo basis
- <em>after</em> you upload the images.
-</p>
-<p>
- <b>UPDATE:</b> The title and rotation will be guessed from EXIF data...
-</p>
-
-{% else %}
-<p>Oops! No gallery here!</p>
-{% endif %}
-
-{% endblock %}
diff --git a/bn_django/photos/templates/photos/photo_detail.html b/bn_django/photos/templates/photos/photo_detail.html
deleted file mode 100644
index 78b95fe..0000000
--- a/bn_django/photos/templates/photos/photo_detail.html
+++ /dev/null
@@ -1,111 +0,0 @@
-{% extends "photos/base.html" %}
-{# {% load markup %} #}
-
-{% load comments %}
-
-{% block path %}
- {{ block.super }}
- &raquo;
- <a href="../../{{ object.gallery.slug }}/">{{ object.gallery.title }}</a>
- &raquo;
- <a href="../{{ object.id }}">{{ object.title }}</a>
-{% endblock %}
-
-{% block title %}
-{% if object %}
-{{ object.title }}
-{% endif %}
-{% endblock %}
-
-{% block content %}
-
-{% if object %}
-<div class="right_stuff">
-{% if object.date %}
-<p class="photodate">Photo taken {{ object.date }}{% if object.photographer %}
-by {{ object.photographer }}.</p>
-{% else %}.</p>
-{% endif %}
-{% else %}
-{% if object.photographer %}
-<p class="photographer">Photo by {{ object.photographer }}.</p>
-{% endif %}
-{% endif %}
-</div>
-{% if object.next %}
-<div class="right_stuff" style="clear: right;">
-<div class="small-image-box">
-<br /><br /><br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /><br />
- <a href="../{{ object.next.id }}/">
- Next:<br/>
- <img src="{{ object.next.thumburl}}" alt="{{ object.next.title }}"/>
- </a>
-</div></div>
-
-{% endif %}
-{% if object.prev %}
-<div class="right_stuff" style="clear: right;">
-<div class="small-image-box">
-<br /> <br /><br /> <br />
- <a href="../{{ object.prev.id }}/">
- Previous:<br />
- <img src="{{ object.prev.thumburl}}" alt="{{ object.prev.title }}"/>
- </a>
-</div>
-</div>
-{% endif %}
-
-<center>
-<div id="centerize">
- <a href="{{ object.fullurl }}">
- <img src="{{ object.dispurl }}"
- alt="{{ object.title }}" />
- </a>
- <div>
- <p class="photodesc"> {{ object.desc|safe }} </p>
- {% if object.extra %}
- <h3 class="photoextra">More information</h3>
- <p class="photoextra">{{ object.extra|safe }}</p>
- {% endif %}
- </div>
-</div>
-</center>
-{% if object.prev %}
- <a href="../{{ object.prev.id }}/" class="lefty">
- &laquo; previous
- </a>
-{% endif %}
-{% if object.next %}
- <a href="../{{ object.next.id }}/" class="righty">
- next &raquo;
- </a>
-{% endif %}
-<br />
-
-<!--
-{% if not user.is_anonymous %}
-<p>
- <a href="{{ admin_url }}/photos/photo/{{ object.id }}/">
- Edit this image.
- </a>
-</p>
-{%else %}
-<p>
- <a href="/accounts/login/?next={{ request.path }}">
- Login</a> to edit this image.
-</p>
-{% endif %}
--->
-{% else %}
-<p>This is not the photo you are looking for.</p>
-{% endif %}
-{% endblock %}
-
-{% block commentary %}
-<div class='content' id='commentary'>
-<h3>Post a comment</h3>
-{% render_comment_form for object %}
-{% get_comment_list for object as comments %}
-{% include "comment_list" %}
-</div>
-{% endblock %}
diff --git a/bn_django/photos/urls.py b/bn_django/photos/urls.py
deleted file mode 100644
index 233ccc4..0000000
--- a/bn_django/photos/urls.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from django.conf.urls.defaults import *
-from django.conf import settings
-
-from models import Gallery, Photo, ADMIN_URL, STOCKPHOTO_URL
-
-info_dict = { 'extra_context': { 'admin_url': ADMIN_URL,
- 'stockphoto_url': STOCKPHOTO_URL} }
-
-urlpatterns = patterns('django.views.generic.list_detail',
- (r'^$', 'object_list',
- dict(info_dict, queryset=Gallery.objects.order_by('-date'),
- paginate_by=35, allow_empty= True)),
- (r'^(?P<slug>[\d\w-]+)/$', 'object_detail',
- dict(info_dict, queryset=Gallery.objects.all(), slug_field='slug')),
- (r'^(?P<object_id>\d+)/$', 'object_detail',
- dict(info_dict, queryset=Gallery.objects.all())),
- (r'^detail/(?P<object_id>\d+)/$', 'object_detail',
- dict(info_dict, queryset=Photo.objects.all())),
-)
-urlpatterns += patterns('bn_django.photos.views',
- (r'^import/(?P<thegallery>\d+)/$', 'import_photos'),
- #(r'^export/(\d+)/$', 'export'),
-)
diff --git a/bn_django/photos/views.py b/bn_django/photos/views.py
deleted file mode 100644
index a6459f6..0000000
--- a/bn_django/photos/views.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# Create your views here.
-
-# django imports
-from django.conf import settings
-from django import forms, http, template
-from django.contrib.auth.decorators import login_required
-from django.shortcuts import get_object_or_404, render_to_response
-from django.http import HttpResponse
-
-# other imports
-import zipfile
-import os
-import stat
-import shutil
-from datetime import datetime
-from tempfile import NamedTemporaryFile, mkdtemp
-import Image
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-# Handling settings here
-try:
- STOCKPHOTO_BASE = settings.STOCKPHOTO_BASE.strip('/')
-except AttributeError:
- STOCKPHOTO_BASE = 'photos'
-
-# models
-from bn_django.photos.models import Gallery, Photo
-
-# views
-
-class ImportForm(forms.Form):
- zipfile = forms.FileField()
- photographer = forms.CharField()
- date = forms.DateField()
-
- def valid_zipfile(self, field_data, all_data):
- zip_file = StringIO(field_data['content'])
- zip = zipfile.ZipFile(zip_file)
- return not zip.testzip()
-
-@login_required
-def import_photos(request, thegallery):
- """Import a batch of photographs uploaded by the user.
-
- Import a batch of photographs uploaded by the user, all with
- the same information for gallery, photographer and date. The
- title will be set from the filename, and the description will be
- blank. Self-respecting photographers will edit the fields for
- each photograph; this is just a way to get a bunch of photographs
- uploaded quickly.
-
- The photographs should be wrapped up in a zip archive. The
- archive will be unpacked (and flattened) in a temporary directory,
- and all image files will be identified and imported into the
- gallery. Other files in the archive will be silently ignored.
-
- After importing the images, the view will display a page which may
- contain the number of images imported, and a link to the gallery
- into which the images were imported.
- """
- # Check if the gallery is valid
- gallery = get_object_or_404(Gallery, pk=thegallery)
- # And that the user has permission to add photos
- if not request.user.has_perm('gallery.add_photo'):
- return http.HttpResponseForbidden("No permission to add photos")
-
- if request.POST:
- #new_data = request.POST.copy()
- #new_data.update(request.FILES)
- form = ImportForm(request.POST, request.FILES)
- if not form.is_valid():
- return render_to_response('photos/import_form.html',
- dict(form=form, gallery=gallery))
- # So now everything is okay
- f = request.FILES['zipfile'] # the zip"file"
- zip = zipfile.ZipFile(f)
- date = request.POST['date']
- if not date:
- date = datetime.date(datetime.now())
- destdir= os.path.join(settings.MEDIA_ROOT, STOCKPHOTO_BASE,
- datetime.strftime(datetime.now(), "%Y/%m/%d/"))
-
- if not os.path.isdir(destdir):
- os.makedirs(destdir, 0775)
- for filename in zip.namelist():
- photopath = os.path.join(destdir, os.path.basename(filename))
- data = zip.read(filename)
- file_data = StringIO(data)
- try:
- Image.open(file_data)
- except:
- # don't save and process non Image files
- continue
- photo = file(photopath, "wb")
- photo.write(data)
- f = photo
-
- # Create the object
- if photopath.startswith(os.path.sep):
- photopath = photopath[len(settings.MEDIA_ROOT):]
- photo = Photo(image=photopath, date=date,
- photographer=request.POST['photographer'],
- title = 'untitled',
- gallery_id = thegallery)
-
- # Save it -- the thumbnails etc. get created.
- photo.save()
-
- # Try to harvest EXIF data
- try:
- import EXIF
- tags = EXIF.process_file(open(photo.image.path))
- try:
- if tags.has_key('Image DateTime'):
- exifdate = tags['Image DateTime'].printable
- photo.date = apply(datetime, map(int, exifdate.split(' ')[0].split(':')))
- except Exception, E:
- print E
- pass
- try:
- if tags.has_key('EXIF UserComment'):
- exiftitle = tags['EXIF UserComment'].printable
- if not exiftitle == []:
- photo.title = exiftitle
-
- except Exception, E:
- print E
- pass
- try:
- if tags.has_key('Image Orientation'):
- exifrot = tags['EXIF UserComment'].printable
- if exifrot == 'Rotated 90 CCW':
- #DO ROTATION
- pass
- except Exception, E:
- print E
- pass
- except Exception, E:
- print E
- pass
- finally:
- photo.save()
-
- # And jump to the directory for this gallery
- response = http.HttpResponseRedirect(gallery.get_absolute_url())
- response['Pragma'] = 'no cache'
- response['Cache-Control'] = 'no-cache'
- return response
- else:
- form = ImportForm()
- return render_to_response('photos/import_form.html',
- dict(form=form, gallery=gallery))
- # request,
-
-#@login_required
-#def export(request, thegallery):
- #"""Export a gallery to a zip file and send it to the user.
- #"""
- ## Check if the gallery is valid
- #gallery = get_object_or_404(Gallery, pk=thegallery)
- #
- ## gather up the photos into a new directory
- #tmpdir = mkdtemp()
- #for photo in gallery.photo_set.all():
- #shutil.copy(photo.get_image_filename(),
- #tmpdir)
- #files = [ os.path.join(tmpdir, ff) for ff in os.listdir(tmpdir) ]
- #outfile = NamedTemporaryFile()
- #zf = zipfile.ZipFile(outfile, "w",
- #compression=zipfile.ZIP_DEFLATED)
- #for filename in files:
- #zf.write(filename, arcname=os.path.basename(filename))
- #zf.close()
- ##outfile.flush()
- #outfile.seek(0)
- #shutil.rmtree(tmpdir)
- #response = HttpResponse(outfile)
- #response['Content-Type'] = "application/zip"
- #response['Content-Length'] = str(os.stat(outfile.name)[stat.ST_SIZE])
- #response['Content-Disposition'] = "attachment; filename=photos.zip"
- #return response
- #