From: Marek Stępniowski 
Date: Fri, 9 Oct 2009 15:09:14 +0000 (+0200)
Subject: Dodanie aplikacji sponsors do zarządzania logami sponsorów w stopce.
X-Git-Url: https://git.mdrn.pl/wolnelektury.git/commitdiff_plain/0d0fa7a4cd45b477e40740a8d971ec814bc6a4a9
Dodanie aplikacji sponsors do zarządzania logami sponsorów w stopce.
---
diff --git a/apps/sponsors/__init__.py b/apps/sponsors/__init__.py
new file mode 100644
index 000000000..f39d8b488
--- /dev/null
+++ b/apps/sponsors/__init__.py
@@ -0,0 +1,3 @@
+# -*- encoding: utf-8 -*-
+__author__ = u'Marek StÄpniowski, '
+__version__ = '0.1'
diff --git a/apps/sponsors/admin.py b/apps/sponsors/admin.py
new file mode 100644
index 000000000..c66a08653
--- /dev/null
+++ b/apps/sponsors/admin.py
@@ -0,0 +1,21 @@
+from django.db import models
+from django.contrib import admin
+
+from sponsors.models import Sponsor, SponsorGroup
+from sponsors.widgets import OrderedSelectMultiple
+
+class SponsorGroupAdmin(admin.ModelAdmin):
+    formfield_overrides = {
+        models.CommaSeparatedIntegerField: {'widget': OrderedSelectMultiple},
+    }   
+    list_display = ('name',)
+    search_fields = ('name',)
+    ordering = ('name',)
+
+class SponsorAdmin(admin.ModelAdmin):
+    list_display = ('name',)
+    search_fields = ('name',)
+    ordering = ('name',)
+
+admin.site.register(SponsorGroup, SponsorGroupAdmin)
+admin.site.register(Sponsor, SponsorAdmin)
diff --git a/apps/sponsors/models.py b/apps/sponsors/models.py
new file mode 100644
index 000000000..ffad8e774
--- /dev/null
+++ b/apps/sponsors/models.py
@@ -0,0 +1,35 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+
+class Sponsor(models.Model):
+    name = models.CharField(_('name'), max_length=120)
+    _description = models.CharField(_('description'), blank=True, max_length=255)
+    logo = models.ImageField(_('logo'), upload_to='sponsors/sponsor/logo')
+    url = models.URLField(_('url'), blank=True, verify_exists=False)
+    
+    def __unicode__(self):
+        return self.name
+
+    def description(self):
+        if len(self._description):
+            return self._description
+        else:
+            return self.name
+
+
+class SponsorGroup(models.Model):
+    name = models.CharField(_('name'), max_length=120)
+    order = models.IntegerField(_('order'), default=0)
+    column_width = models.PositiveIntegerField(_('column width'))
+    sponsor_ids = models.CommaSeparatedIntegerField(_('sponsors'), max_length=255)
+    
+    def sponsors(self):
+        ids = [int(pk) for pk in self.sponsor_ids.split(',')]
+        result = Sponsor.objects.in_bulk(ids)
+        return [result[pk] for pk in ids]
+    sponsors.changes_data = False
+    
+    def __unicode__(self):
+        return self.name
+
diff --git a/apps/sponsors/static/css/sponsors.css b/apps/sponsors/static/css/sponsors.css
new file mode 100644
index 000000000..f3d7ed977
--- /dev/null
+++ b/apps/sponsors/static/css/sponsors.css
@@ -0,0 +1,4 @@
+.sponsor-group {
+    float: left;
+    overflow: hidden;
+}
diff --git a/apps/sponsors/static/js/ordered_select_multiple.js b/apps/sponsors/static/js/ordered_select_multiple.js
new file mode 100644
index 000000000..e4fd74daa
--- /dev/null
+++ b/apps/sponsors/static/js/ordered_select_multiple.js
@@ -0,0 +1,63 @@
+(function($) {
+  $.fn.orderedSelectMultiple = function(options) {
+    var settings = {
+      choices: []
+    };
+    $.extend(settings, options);
+    
+    var input = $(this).hide();
+    var values = input.val().split(',');
+    
+    var container = $('').insertAfter($(this));
+    var choicesList = $('
').appendTo(container).css({
+      width: 200, float: 'left', minHeight: 200, backgroundColor: '#eee', margin: 0, padding: 0
+    });
+    var valuesList = $('
').appendTo(container).css({
+      width: 200, float: 'left', minHeight: 200, backgroundColor: '#eee', margin: 0, padding: 0
+    });
+    var choiceIds = [];
+    $.each(settings.choices, function() {
+      choiceIds.push('' + this.id);
+    });
+    
+    function createItem(hash) {
+      return $('' + hash.name + '').css({
+        backgroundColor: '#cff',
+        display: 'block',
+        border: '1px solid #cdd',
+        padding: 2,
+        margin: 0
+      }).data('obj-id', hash.id);
+    }
+    
+    $.each(settings.choices, function() {
+      if ($.inArray('' + this.id, values) == -1) {
+        choicesList.append(createItem(this));
+      }
+    });
+    
+    $.each(values, function() {
+      var index = $.inArray('' + this, choiceIds); // Why this[0]?
+      if (index != -1) {
+        valuesList.append(createItem(settings.choices[index]));
+      }
+    });
+    
+    choicesList.sortable({
+  		connectWith: '.connectedSortable'
+  	}).disableSelection();
+  	
+  	valuesList.sortable({
+  		connectWith: '.connectedSortable',
+  		update: function() {
+  		  values = [];
+  		  $('li', valuesList).each(function(index) {
+          values.push($(this).data('obj-id'));
+          console.log($(this).data('obj-id'));
+  		  });
+  		  console.log('update', values.join(','), input);
+  		  input.val(values.join(','));
+  		}
+  	}).disableSelection();
+  };
+})(jQuery);
diff --git a/apps/sponsors/templates/sponsors/sponsors.html b/apps/sponsors/templates/sponsors/sponsors.html
new file mode 100644
index 000000000..d5decae71
--- /dev/null
+++ b/apps/sponsors/templates/sponsors/sponsors.html
@@ -0,0 +1,11 @@
+
diff --git a/apps/sponsors/templatetags/__init__.py b/apps/sponsors/templatetags/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/apps/sponsors/templatetags/sponsor_tags.py b/apps/sponsors/templatetags/sponsor_tags.py
new file mode 100644
index 000000000..87289e8d5
--- /dev/null
+++ b/apps/sponsors/templatetags/sponsor_tags.py
@@ -0,0 +1,12 @@
+from django import template
+
+from sponsors import models
+
+
+register = template.Library()
+
+
+def sponsors():
+    return {'sponsor_groups': models.SponsorGroup.objects.all()}
+    
+compressed_js = register.inclusion_tag('sponsors/sponsors.html')(sponsors)
diff --git a/apps/sponsors/widgets.py b/apps/sponsors/widgets.py
new file mode 100644
index 000000000..2ed579370
--- /dev/null
+++ b/apps/sponsors/widgets.py
@@ -0,0 +1,30 @@
+from django import forms
+from django.conf import settings
+from django.utils.safestring import mark_safe
+from django.utils.translation import ugettext_lazy as _
+
+from sponsors import models
+
+
+class OrderedSelectMultiple(forms.TextInput):
+    """
+    A SelectMultiple with a JavaScript interface.
+    """
+    class Media:
+        js = (
+            'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js',
+            'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js',
+            settings.MEDIA_URL + 'js/ordered_select_multiple.js',
+        )
+
+    def render(self, name, value, attrs=None, choices=()):
+        output = [super(OrderedSelectMultiple, self).render(name, value, attrs)]
+        choices = [(unicode(obj), obj.pk) for obj in models.Sponsor.objects.all()]
+        choices_js = ', '.join('{name: "%s", id: %d}' % choice for choice in choices)
+        output.append(u'\n' % 
+            (name, choices_js))
+        return mark_safe(u''.join(output))
+
diff --git a/wolnelektury/media/css/sponsors.css b/wolnelektury/media/css/sponsors.css
new file mode 100644
index 000000000..f5497c135
--- /dev/null
+++ b/wolnelektury/media/css/sponsors.css
@@ -0,0 +1,8 @@
+.sponsor-group {
+    float: left;
+    overflow: hidden;
+}
+
+.sponsor-logo {
+    float: left;
+}
\ No newline at end of file
diff --git a/wolnelektury/media/js/ordered_select_multiple.js b/wolnelektury/media/js/ordered_select_multiple.js
new file mode 100644
index 000000000..e4fd74daa
--- /dev/null
+++ b/wolnelektury/media/js/ordered_select_multiple.js
@@ -0,0 +1,63 @@
+(function($) {
+  $.fn.orderedSelectMultiple = function(options) {
+    var settings = {
+      choices: []
+    };
+    $.extend(settings, options);
+    
+    var input = $(this).hide();
+    var values = input.val().split(',');
+    
+    var container = $('').insertAfter($(this));
+    var choicesList = $('
').appendTo(container).css({
+      width: 200, float: 'left', minHeight: 200, backgroundColor: '#eee', margin: 0, padding: 0
+    });
+    var valuesList = $('
').appendTo(container).css({
+      width: 200, float: 'left', minHeight: 200, backgroundColor: '#eee', margin: 0, padding: 0
+    });
+    var choiceIds = [];
+    $.each(settings.choices, function() {
+      choiceIds.push('' + this.id);
+    });
+    
+    function createItem(hash) {
+      return $('' + hash.name + '').css({
+        backgroundColor: '#cff',
+        display: 'block',
+        border: '1px solid #cdd',
+        padding: 2,
+        margin: 0
+      }).data('obj-id', hash.id);
+    }
+    
+    $.each(settings.choices, function() {
+      if ($.inArray('' + this.id, values) == -1) {
+        choicesList.append(createItem(this));
+      }
+    });
+    
+    $.each(values, function() {
+      var index = $.inArray('' + this, choiceIds); // Why this[0]?
+      if (index != -1) {
+        valuesList.append(createItem(settings.choices[index]));
+      }
+    });
+    
+    choicesList.sortable({
+  		connectWith: '.connectedSortable'
+  	}).disableSelection();
+  	
+  	valuesList.sortable({
+  		connectWith: '.connectedSortable',
+  		update: function() {
+  		  values = [];
+  		  $('li', valuesList).each(function(index) {
+          values.push($(this).data('obj-id'));
+          console.log($(this).data('obj-id'));
+  		  });
+  		  console.log('update', values.join(','), input);
+  		  input.val(values.join(','));
+  		}
+  	}).disableSelection();
+  };
+})(jQuery);
diff --git a/wolnelektury/settings.py b/wolnelektury/settings.py
index bdbc9923b..9e9f6a545 100644
--- a/wolnelektury/settings.py
+++ b/wolnelektury/settings.py
@@ -96,6 +96,7 @@ INSTALLED_APPS = [
     
     # external
     'south',
+    'sponsors',
     'newtagging',
     'pagination',
     'chunks',
@@ -108,7 +109,7 @@ CACHE_BACKEND = 'locmem:///?max_entries=3000'
 # CSS and JavaScript file groups
 COMPRESS_CSS = {
     'all': {
-        'source_filenames': ('css/master.css', 'css/jquery.autocomplete.css', 'css/master.plain.css',),
+        'source_filenames': ('css/master.css', 'css/jquery.autocomplete.css', 'css/master.plain.css', 'css/sponsors.css',),
         'output_filename': 'css/all.min.css',
     },
     'book': {
diff --git a/wolnelektury/templates/base.html b/wolnelektury/templates/base.html
index 4e7a6fabd..ec75d63d4 100644
--- a/wolnelektury/templates/base.html
+++ b/wolnelektury/templates/base.html
@@ -1,4 +1,4 @@
-{% load chunks compressed catalogue_tags %}
+{% load chunks compressed catalogue_tags sponsor_tags %}
 
 
@@ -55,11 +55,8 @@
                 Fundacja Nowoczesna Polska, 00-514 Warszawa, ul. MarszaÅkowska 84/92 lok. 125, tel/fax: (22) 621-30-17,
                 e-mail: fundacja@nowoczesnapolska.org.pl
             
-
-    
-
-
 
+			{% sponsors %}