urlfeed admin: custom image import form
authorTero Marttila <terom@fixme.fi>
Mon, 19 Aug 2013 02:11:16 +0300
changeset 49 7c0dcf6603f5
parent 48 5df9ed6b5976
child 50 b8a8269d7214
urlfeed admin: custom image import form
qrurls/admin.py
qrurls/templates/admin/qrurls_import_images.html
--- a/qrurls/admin.py	Sun Aug 18 23:24:54 2013 +0300
+++ b/qrurls/admin.py	Mon Aug 19 02:11:16 2013 +0300
@@ -1,7 +1,10 @@
 import datetime
+import urllib
 
-from django.conf import settings
+from django import http, shortcuts, forms
+from django.conf import settings, urls
 from django.contrib import admin
+from django.core.urlresolvers import reverse
 from django.utils import timezone, formats
 import django.utils.html
 import django.forms.models
@@ -16,33 +19,13 @@
 
     def __init__ (self, *args, **kwargs) :
         urlfeed = kwargs.get('instance')
+        extra = kwargs.get('extra', 5)
 
-        publishing_date = None
-        publishing_time = datetime.time()
-        
-        # hack to get at the URLFeed to determine our initial values..
-        if urlfeed and isinstance(urlfeed, URL) :
-            publishing_date = urlfeed.last_item().published.date()
-            publishing_time = urlfeed.publishing_time
-        
-        def publishing_schedule (count) :
-            if not publishing_date :
-                # starting today
-                start_date = datetime.date.today()
-                offset = 0
-            else :
-                # starting from the following day
-                start_date = publishing_date
-                offset = 1
-
-            for days in xrange(offset, count + offset) :
-                yield datetime.datetime.combine(
-                        start_date + datetime.timedelta(days=days),
-                        publishing_time
-                )
-
+        publishing_date, publishing_time = URLAdmin.publish_scheduling(urlfeed)
+    
         kwargs.update(initial=[
-                dict(published=publish) for publish in publishing_schedule(count=5)
+                dict(published=publish) for publish in URLAdmin.publishing_schedule(
+                    publishing_date, publishing_time, count=extra)
         ])
         super(URLItemFormset, self).__init__(*args, **kwargs)
 
@@ -55,6 +38,29 @@
     formset = URLItemFormset
 
 class URLAdmin (admin.ModelAdmin) :
+    @classmethod
+    def publish_scheduling (cls, urlfeed) :
+        """Calculate initial URLItem.published values for feed, or defaults."""
+        # hack to get at the URLFeed to determine our initial values..
+        if urlfeed and isinstance(urlfeed, URL) :
+            # starting from the following day
+            return (
+                    urlfeed.last_item().published.date() + datetime.timedelta(days=1),
+                    urlfeed.publishing_time,
+            )
+        else:
+            # no data...
+            datetime.date.today(), datetime.time()
+       
+    @classmethod
+    def publishing_schedule (cls, publishing_date, publishing_time, count) :
+        """Yield URLItem.published values."""
+        for days in xrange(0, count) :
+            yield datetime.datetime.combine(
+                    publishing_date + datetime.timedelta(days=days),
+                    publishing_time
+            )
+
     def timezone (self, obj) :
         now = timezone.localtime(obj.now())
         tz = now.tzinfo
@@ -141,6 +147,70 @@
     )
     inlines = (URLItemInline, )
 
+    ## Import
+    class ImportForm (forms.Form) :
+        shorturl = forms.ModelChoiceField(URL.objects)
+        publishing_date = forms.DateField(widget=admin.widgets.AdminDateWidget)
+        publishing_time = forms.TimeField(widget=admin.widgets.AdminTimeWidget)
+        image = forms.ImageField()
+
+    def import_images_handler (self, url_feed, data) :
+        """Custom for backend for mass-importing images into a feed."""
+        
+        images = [data['image']]
+        publishing = self.publishing_schedule(data['publishing_date'], data['publishing_time'], len(images))
+
+        for image, publish in zip(images, publishing) :
+            # XXX: move title default elsewhere
+            url_image = URLImage(image=image, title=image.name)
+            url_image.save()
+
+            url_item = URLItem(shorturl=url_feed, published=publish, image=url_image)
+            url_item.save()
+
+        return http.HttpResponseRedirect(reverse('admin:qrurls_url_change', args=(url_feed.id, )))
+
+    def import_images (self, request, shorturl_id) :
+        """Custom form frontend for mass-importing images into a feed."""
+        url_feed = URL.objects.get(id=int(shorturl_id))
+        
+        if request.method == 'POST' :
+            form = self.ImportForm(request.POST, request.FILES)
+
+            if form.is_valid() :
+                return self.import_images_handler(url_feed, form.cleaned_data)
+        else :
+            publishing_date, publishing_time = self.publish_scheduling(url_feed)
+
+            form = self.ImportForm(initial=dict(
+                shorturl        = url_feed.id,
+                publishing_date = publishing_date,
+                publishing_time = publishing_time,
+            ))
+        
+        return shortcuts.render(request, 'admin/qrurls_import_images.html', dict(
+            current_app     = self.admin_site.name,
+
+            media           = self.media + form.media,
+            form_url        = reverse('admin:qrurls_import_images', kwargs=dict(shorturl_id=url_feed.id)),
+            form            = form,
+        ))
+
+    def get_urls (self) :
+        return urls.patterns('',
+            urls.url(r'^(?P<shorturl_id>\d+)/import$', self.admin_site.admin_view(self.import_images),
+                name='qrurls_import_images'),
+        ) + super(URLAdmin, self).get_urls()
+
+    def import_images_action (self, request, queryset) :
+        url_feed, = [url_feed for url_feed in queryset]
+        return http.HttpResponseRedirect(
+                reverse('admin:qrurls_import_images', kwargs=dict(shorturl_id=url_feed.id)) # ) + '?' + urllib.urlencode(qs, doseq=True)
+        )
+    import_images_action.short_description = "Import images for selected feeds"
+    
+    actions = [import_images_action]
+
 class URLItemAdmin (admin.ModelAdmin) :
     list_display = (
         'shorturl', 'published_state', 'get_absolute_url', 'image', 'published',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qrurls/templates/admin/qrurls_import_images.html	Mon Aug 19 02:11:16 2013 +0300
@@ -0,0 +1,61 @@
+{% extends "admin/base_site.html" %}
+{% load i18n admin_static %}
+
+{% block extrahead %}{{ block.super }}
+    <script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
+    {{ media }}
+{% endblock %}
+
+{% block extrastyle %}{{ block.super }}
+    <link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />
+{% endblock %}
+
+{% block content %}
+<div id="content-main">
+    <form enctype="multipart/form-data" action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% csrf_token %}
+        <div>
+            {% if errors %}
+                <p class="errornote">
+                {% blocktrans count counter=errors|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %}
+                </p>
+                {{ adminform.form.non_field_errors }}
+            {% endif %}
+
+            <fieldset class="module aligned">
+                <h2>URL Feed</h2>
+                <div class="form-row">
+                    <div class="field-box field-shorturl">
+                        {{ form.shorturl.errors }}
+                        {{ form.shorturl.label_tag }}
+                        {{ form.shorturl }}
+                    </div>
+                </div>
+                <div class="form-row">
+                    {{ form.publishing_date.errors }}
+                    {{ form.publishing_time.errors }}
+                    <div class="field-box field-publishing_date">
+                        {{ form.publishing_date.label_tag }}
+                        {{ form.publishing_date }}
+                    </div>
+                    <div class="field-box field-publishing_time">
+                        {{ form.publishing_time.label_tag }}
+                        {{ form.publishing_time }}
+                    </div>
+                    <p class="help">Starting date/time for publishing.</p>
+                </div>
+                <div class="form-row">
+                    <div class="field-box field-image">
+                        {{ form.image.errors }}
+                        {{ form.image.label_tag }}
+                        {{ form.image }}
+                    </div>
+                </div>
+            </fieldset>
+
+            <div class="submit-row">
+                <input type="submit" value="{% trans 'Import' %}" class="default" name="_import" />
+            </div>
+        </div>
+    </form>
+</div>
+{% endblock %}