Ebooks are now named after the book's slug and overwrite old versions.
authorRadek Czajka <radekczajka@nowoczesnapolska.org.pl>
Fri, 14 Feb 2014 11:57:55 +0000 (12:57 +0100)
committerRadek Czajka <radekczajka@nowoczesnapolska.org.pl>
Fri, 14 Feb 2014 13:20:53 +0000 (14:20 +0100)
Also:
avoid hitting DB just by importing modules,
update Feedparser and django-pipeline.

12 files changed:
apps/catalogue/management/commands/checkcovers.py
apps/catalogue/migrations/0017_auto__chg_field_book_pdf_file__chg_field_book_html_file__chg_field_boo.py [new file with mode: 0644]
apps/catalogue/models/book.py
apps/catalogue/models/bookmedia.py
apps/catalogue/templatetags/catalogue_tags.py
apps/catalogue/tests/book_import.py
apps/catalogue/utils.py
apps/oai/views.py
apps/opds/views.py
requirements.txt
wolnelektury/settings/static.py
wolnelektury/utils.py

index 1af39e1..7535dd4 100644 (file)
@@ -6,6 +6,7 @@ from optparse import make_option
 from django.contrib.sites.models import Site
 from django.core.management.base import BaseCommand
 from catalogue import app_settings
 from django.contrib.sites.models import Site
 from django.core.management.base import BaseCommand
 from catalogue import app_settings
+from django.utils.functional import lazy
 
 
 def ancestor_has_cover(book):
 
 
 def ancestor_has_cover(book):
@@ -16,7 +17,7 @@ def ancestor_has_cover(book):
     return False
 
 
     return False
 
 
-current_domain = Site.objects.get_current().domain
+current_domain = lazy(lambda: Site.objects.get_current().domain, str)()
 def full_url(obj):
     return 'http://%s%s' % (
                 current_domain,
 def full_url(obj):
     return 'http://%s%s' % (
                 current_domain,
diff --git a/apps/catalogue/migrations/0017_auto__chg_field_book_pdf_file__chg_field_book_html_file__chg_field_boo.py b/apps/catalogue/migrations/0017_auto__chg_field_book_pdf_file__chg_field_book_html_file__chg_field_boo.py
new file mode 100644 (file)
index 0000000..df96042
--- /dev/null
@@ -0,0 +1,243 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+
+        # Changing field 'Book.pdf_file'
+        db.alter_column(u'catalogue_book', 'pdf_file', self.gf('catalogue.fields.EbookField')(max_length=255, format_name='pdf'))
+
+        # Changing field 'Book.html_file'
+        db.alter_column(u'catalogue_book', 'html_file', self.gf('catalogue.fields.EbookField')(max_length=255, format_name='html'))
+
+        # Changing field 'Book.fb2_file'
+        db.alter_column(u'catalogue_book', 'fb2_file', self.gf('catalogue.fields.EbookField')(max_length=255, format_name='fb2'))
+
+        # Changing field 'Book.xml_file'
+        db.alter_column(u'catalogue_book', 'xml_file', self.gf('catalogue.fields.EbookField')(max_length=255, format_name='xml'))
+
+        # Changing field 'Book.txt_file'
+        db.alter_column(u'catalogue_book', 'txt_file', self.gf('catalogue.fields.EbookField')(max_length=255, format_name='txt'))
+
+        # Changing field 'Book.mobi_file'
+        db.alter_column(u'catalogue_book', 'mobi_file', self.gf('catalogue.fields.EbookField')(max_length=255, format_name='mobi'))
+
+        # Changing field 'Book.epub_file'
+        db.alter_column(u'catalogue_book', 'epub_file', self.gf('catalogue.fields.EbookField')(max_length=255, format_name='epub'))
+
+        # Changing field 'Book.cover_thumb'
+        db.alter_column(u'catalogue_book', 'cover_thumb', self.gf('catalogue.fields.EbookField')(max_length=255, null=True, format_name='cover_thumb'))
+
+        # Changing field 'Book.cover'
+        db.alter_column(u'catalogue_book', 'cover', self.gf('catalogue.fields.EbookField')(max_length=255, null=True, format_name='cover'))
+
+        # Changing field 'BookMedia.file'
+        db.alter_column(u'catalogue_bookmedia', 'file', self.gf('catalogue.fields.OverwritingFileField')(max_length=600))
+
+        # Changing field 'BookMedia.type'
+        db.alter_column(u'catalogue_bookmedia', 'type', self.gf('django.db.models.fields.CharField')(max_length=20))
+
+    def backwards(self, orm):
+
+        # Changing field 'Book.pdf_file'
+        db.alter_column(u'catalogue_book', 'pdf_file', self.gf('catalogue.fields.EbookField')(max_length=100, format_name='pdf'))
+
+        # Changing field 'Book.html_file'
+        db.alter_column(u'catalogue_book', 'html_file', self.gf('catalogue.fields.EbookField')(max_length=100, format_name='html'))
+
+        # Changing field 'Book.fb2_file'
+        db.alter_column(u'catalogue_book', 'fb2_file', self.gf('catalogue.fields.EbookField')(max_length=100, format_name='fb2'))
+
+        # Changing field 'Book.xml_file'
+        db.alter_column(u'catalogue_book', 'xml_file', self.gf('catalogue.fields.EbookField')(max_length=100, format_name='xml'))
+
+        # Changing field 'Book.txt_file'
+        db.alter_column(u'catalogue_book', 'txt_file', self.gf('catalogue.fields.EbookField')(max_length=100, format_name='txt'))
+
+        # Changing field 'Book.mobi_file'
+        db.alter_column(u'catalogue_book', 'mobi_file', self.gf('catalogue.fields.EbookField')(max_length=100, format_name='mobi'))
+
+        # Changing field 'Book.epub_file'
+        db.alter_column(u'catalogue_book', 'epub_file', self.gf('catalogue.fields.EbookField')(max_length=100, format_name='epub'))
+
+        # Changing field 'Book.cover_thumb'
+        db.alter_column(u'catalogue_book', 'cover_thumb', self.gf('catalogue.fields.EbookField')(max_length=100, null=True, format_name='cover_thumb'))
+
+        # Changing field 'Book.cover'
+        db.alter_column(u'catalogue_book', 'cover', self.gf('catalogue.fields.EbookField')(max_length=100, null=True, format_name='cover'))
+
+        # Changing field 'BookMedia.file'
+        db.alter_column(u'catalogue_bookmedia', 'file', self.gf('catalogue.fields.OverwritingFileField')(max_length=100))
+
+        # Changing field 'BookMedia.type'
+        db.alter_column(u'catalogue_bookmedia', 'type', self.gf('django.db.models.fields.CharField')(max_length='100'))
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'catalogue.book': {
+            'Meta': {'ordering': "('sort_key',)", 'object_name': 'Book'},
+            '_related_info': ('jsonfield.fields.JSONField', [], {'null': 'True', 'blank': 'True'}),
+            'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'common_slug': ('django.db.models.fields.SlugField', [], {'max_length': '120'}),
+            'cover': ('catalogue.fields.EbookField', [], {'max_length': '255', 'null': 'True', 'format_name': "'cover'", 'blank': 'True'}),
+            'cover_thumb': ('catalogue.fields.EbookField', [], {'max_length': '255', 'null': 'True', 'format_name': "'cover_thumb'", 'blank': 'True'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'epub_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '255', 'format_name': "'epub'", 'blank': 'True'}),
+            'extra_info': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'fb2_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '255', 'format_name': "'fb2'", 'blank': 'True'}),
+            'gazeta_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}),
+            'html_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '255', 'format_name': "'html'", 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language': ('django.db.models.fields.CharField', [], {'default': "'pol'", 'max_length': '3', 'db_index': 'True'}),
+            'mobi_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '255', 'format_name': "'mobi'", 'blank': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['catalogue.Book']"}),
+            'parent_number': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'pdf_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '255', 'format_name': "'pdf'", 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '120'}),
+            'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}),
+            'sort_key_author': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '120', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}),
+            'txt_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '255', 'format_name': "'txt'", 'blank': 'True'}),
+            'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}),
+            'xml_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '255', 'format_name': "'xml'", 'blank': 'True'})
+        },
+        'catalogue.bookmedia': {
+            'Meta': {'ordering': "('type', 'name')", 'object_name': 'BookMedia'},
+            'book': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'media'", 'to': "orm['catalogue.Book']"}),
+            'extra_info': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'file': ('catalogue.fields.OverwritingFileField', [], {'max_length': '600'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
+            'source_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '20', 'db_index': 'True'}),
+            'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'})
+        },
+        'catalogue.collection': {
+            'Meta': {'ordering': "('title',)", 'object_name': 'Collection'},
+            'book_slugs': ('django.db.models.fields.TextField', [], {}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_de': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_en': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_es': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_fr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_it': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_lt': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_ru': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_uk': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'kind': ('django.db.models.fields.CharField', [], {'default': "'book'", 'max_length': '10', 'db_index': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '120', 'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}),
+            'title_de': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
+            'title_en': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
+            'title_es': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
+            'title_fr': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
+            'title_it': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
+            'title_lt': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
+            'title_pl': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
+            'title_ru': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '120', 'null': 'True', 'blank': 'True'}),
+            'title_uk': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '120', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.fragment': {
+            'Meta': {'ordering': "('book', 'anchor')", 'object_name': 'Fragment'},
+            'anchor': ('django.db.models.fields.CharField', [], {'max_length': '120'}),
+            'book': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'fragments'", 'to': "orm['catalogue.Book']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'short_text': ('django.db.models.fields.TextField', [], {}),
+            'text': ('django.db.models.fields.TextField', [], {})
+        },
+        'catalogue.tag': {
+            'Meta': {'ordering': "('sort_key',)", 'unique_together': "(('slug', 'category'),)", 'object_name': 'Tag'},
+            'book_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'category': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
+            'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'culturepl_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'description_de': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_en': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_es': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_fr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_it': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_lt': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_ru': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'description_uk': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'gazeta_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
+            'name_de': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'name_es': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'name_fr': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'name_it': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'name_lt': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'name_ru': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'name_uk': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'picture_count': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '120'}),
+            'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}),
+            'wiki_link_de': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': 'True', 'blank': 'True'}),
+            'wiki_link_en': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': 'True', 'blank': 'True'}),
+            'wiki_link_es': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': 'True', 'blank': 'True'}),
+            'wiki_link_fr': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': 'True', 'blank': 'True'}),
+            'wiki_link_it': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': 'True', 'blank': 'True'}),
+            'wiki_link_lt': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': 'True', 'blank': 'True'}),
+            'wiki_link_pl': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': 'True', 'blank': 'True'}),
+            'wiki_link_ru': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': 'True', 'blank': 'True'}),
+            'wiki_link_uk': ('django.db.models.fields.CharField', [], {'max_length': '240', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.tagrelation': {
+            'Meta': {'unique_together': "(('tag', 'content_type', 'object_id'),)", 'object_name': 'TagRelation', 'db_table': "u'catalogue_tag_relation'"},
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'items'", 'to': "orm['catalogue.Tag']"})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
index bd7d7e4..414d1ef 100644 (file)
@@ -11,14 +11,16 @@ import django.dispatch
 from django.utils.datastructures import SortedDict
 from django.utils.translation import ugettext_lazy as _
 import jsonfield
 from django.utils.datastructures import SortedDict
 from django.utils.translation import ugettext_lazy as _
 import jsonfield
+from fnpdjango.storage import BofhFileSystemStorage
 from catalogue import constants
 from catalogue.fields import EbookField
 from catalogue.models import Tag, Fragment, BookMedia
 from catalogue import constants
 from catalogue.fields import EbookField
 from catalogue.models import Tag, Fragment, BookMedia
-from catalogue.utils import create_zip, split_tags, book_upload_path, related_tag_name
+from catalogue.utils import create_zip, split_tags, related_tag_name
 from catalogue import app_settings
 from catalogue import tasks
 from newtagging import managers
 
 from catalogue import app_settings
 from catalogue import tasks
 from newtagging import managers
 
+bofh_storage = BofhFileSystemStorage()
 
 permanent_cache = get_cache('permanent')
 
 
 permanent_cache = get_cache('permanent')
 
@@ -43,10 +45,14 @@ class Book(models.Model):
     # files generated during publication
 
     cover = EbookField('cover', _('cover'),
     # files generated during publication
 
     cover = EbookField('cover', _('cover'),
-                upload_to=book_upload_path('jpg'), null=True, blank=True)
+            null=True, blank=True,
+            upload_to=lambda i, n: 'book/cover/%s.jpg' % i.slug,
+            storage=bofh_storage, max_length=255)
     # Cleaner version of cover for thumbs
     # Cleaner version of cover for thumbs
-    cover_thumb = EbookField('cover_thumb', _('cover thumbnail'),
-                upload_to=book_upload_path('th.jpg'), null=True, blank=True)
+    cover_thumb = EbookField('cover_thumb', _('cover thumbnail'), 
+            null=True, blank=True,
+            upload_to=lambda i, n: 'book/cover_thumb/%s.jpg' % i.slug,
+            max_length=255)
     ebook_formats = constants.EBOOK_FORMATS
     formats = ebook_formats + ['html', 'xml']
 
     ebook_formats = constants.EBOOK_FORMATS
     formats = ebook_formats + ['html', 'xml']
 
@@ -620,6 +626,13 @@ class Book(models.Model):
 # add the file fields
 for format_ in Book.formats:
     field_name = "%s_file" % format_
 # add the file fields
 for format_ in Book.formats:
     field_name = "%s_file" % format_
+    upload_to = (lambda upload_path:
+            lambda i, n: upload_path % i.slug
+        )('book/%s/%%s.%s' % (format_, format_))
     EbookField(format_, _("%s file" % format_.upper()),
     EbookField(format_, _("%s file" % format_.upper()),
-            upload_to=book_upload_path(format_),
-            blank=True, default='').contribute_to_class(Book, field_name)
+        upload_to=upload_to,
+        storage=bofh_storage,
+        max_length=255,
+        blank=True,
+        default=''
+    ).contribute_to_class(Book, field_name)
index 42781e9..6291329 100644 (file)
@@ -8,8 +8,8 @@ from django.db import models
 from django.utils.translation import ugettext_lazy as _
 from django.utils.datastructures import SortedDict
 import jsonfield
 from django.utils.translation import ugettext_lazy as _
 from django.utils.datastructures import SortedDict
 import jsonfield
+from fnpdjango.utils.text.slughifi import slughifi
 from catalogue.fields import OverwritingFileField
 from catalogue.fields import OverwritingFileField
-from catalogue.utils import book_upload_path
 
 
 class BookMedia(models.Model):
 
 
 class BookMedia(models.Model):
@@ -23,11 +23,13 @@ class BookMedia(models.Model):
     format_choices = [(k, _('%s file') % t.name)
             for k, t in formats.items()]
 
     format_choices = [(k, _('%s file') % t.name)
             for k, t in formats.items()]
 
-    type        = models.CharField(_('type'), db_index=True, choices=format_choices, max_length="100")
-    name        = models.CharField(_('name'), max_length=512)
-    file        = OverwritingFileField(_('file'), upload_to=book_upload_path())
+    type = models.CharField(_('type'), db_index=True, choices=format_choices, max_length=20)
+    name = models.CharField(_('name'), max_length=512)
+    file = OverwritingFileField(_('file'), max_length=600,
+        upload_to=lambda i, _n: 'book/%(ext)s/%(name)s.%(ext)s' % {
+                    'ext': i.ext(), 'name': slughifi(i.name)})
     uploaded_at = models.DateTimeField(_('creation date'), auto_now_add=True, editable=False, db_index=True)
     uploaded_at = models.DateTimeField(_('creation date'), auto_now_add=True, editable=False, db_index=True)
-    extra_info  = jsonfield.JSONField(_('extra information'), default={}, editable=False)
+    extra_info = jsonfield.JSONField(_('extra information'), default={}, editable=False)
     book = models.ForeignKey('Book', related_name='media')
     source_sha1 = models.CharField(null=True, blank=True, max_length=40, editable=False)
 
     book = models.ForeignKey('Book', related_name='media')
     source_sha1 = models.CharField(null=True, blank=True, max_length=40, editable=False)
 
@@ -102,6 +104,9 @@ class BookMedia(models.Model):
         return {'artist_name': artist_name, 'director_name': director_name,
                 'project': project, 'funded_by': funded_by}
 
         return {'artist_name': artist_name, 'director_name': director_name,
                 'project': project, 'funded_by': funded_by}
 
+    def ext(self):
+        return self.formats[self.type].ext
+
     @staticmethod
     def read_source_sha1(filepath, filetype):
         """
     @staticmethod
     def read_source_sha1(filepath, filetype):
         """
index 95288a4..6ff60a3 100644 (file)
@@ -284,7 +284,7 @@ def latest_blog_posts(feed_url, posts_to_show=5):
         feed = feedparser.parse(str(feed_url))
         posts = []
         for i in range(posts_to_show):
         feed = feedparser.parse(str(feed_url))
         posts = []
         for i in range(posts_to_show):
-            pub_date = feed['entries'][i].updated_parsed
+            pub_date = feed['entries'][i].published_parsed
             published = datetime.date(pub_date[0], pub_date[1], pub_date[2])
             posts.append({
                 'title': feed['entries'][i].title,
             published = datetime.date(pub_date[0], pub_date[1], pub_date[2])
             posts.append({
                 'title': feed['entries'][i].title,
index 08d5243..4b01a8f 100644 (file)
@@ -435,8 +435,7 @@ class BookImportGenerateTest(WLTestCase):
 
     def test_custom_pdf(self):
         from catalogue.tasks import build_custom_pdf
 
     def test_custom_pdf(self):
         from catalogue.tasks import build_custom_pdf
-        from catalogue.utils import get_dynamic_path
-        out = get_dynamic_path(None, 'test-custom', ext='pdf')
+        out = 'test-custom.pdf'
         absoulute_path = path.join(settings.MEDIA_ROOT, out)
 
         if not path.exists(path.dirname(absoulute_path)):
         absoulute_path = path.join(settings.MEDIA_ROOT, out)
 
         if not path.exists(path.dirname(absoulute_path)):
index 98ee36c..a0e834c 100644 (file)
@@ -49,25 +49,6 @@ def split_tags(tags, initial=None):
     return result
 
 
     return result
 
 
-def get_dynamic_path(media, filename, ext=None, maxlen=100):
-    from fnpdjango.utils.text.slughifi import slughifi
-
-    # how to put related book's slug here?
-    if not ext:
-        # BookMedia case
-        ext = media.formats[media.type].ext
-    if media is None or not media.name:
-        name = slughifi(filename.split(".")[0])
-    else:
-        name = slughifi(media.name)
-    return 'book/%s/%s.%s' % (ext, name[:maxlen-len('book/%s/.%s' % (ext, ext))-4], ext)
-
-
-# TODO: why is this hard-coded ?
-def book_upload_path(ext=None, maxlen=100):
-    return lambda *args: get_dynamic_path(*args, ext=ext, maxlen=maxlen)
-
-
 class ExistingFile(UploadedFile):
 
     def __init__(self, path, *args, **kwargs):
 class ExistingFile(UploadedFile):
 
     def __init__(self, path, *args, **kwargs):
index 1002671..5bb9025 100644 (file)
@@ -6,6 +6,7 @@ from oai.handlers import Catalogue, NS_DCTERMS, nsdcterms
 from oaipmh.server import ServerBase, NS_OAIDC, NS_DC, NS_XSI, nsoaidc, nsdc
 from oaipmh.metadata import MetadataRegistry
 from django.http import HttpResponse
 from oaipmh.server import ServerBase, NS_OAIDC, NS_DC, NS_XSI, nsoaidc, nsdc
 from oaipmh.metadata import MetadataRegistry
 from django.http import HttpResponse
+from django.utils.functional import SimpleLazyObject
 from lxml.etree import SubElement
 
 
 from lxml.etree import SubElement
 
 
@@ -57,8 +58,10 @@ metadata_registry.registerWriter('oai_dc', fbc_oai_dc_writer)
 metadata_registry.registerWriter('qdc', qdc_writer)
 
 
 metadata_registry.registerWriter('qdc', qdc_writer)
 
 
-server = ServerBase(Catalogue(metadata_registry), metadata_registry,
-    {'topxsi': NS_XSI})
+server = SimpleLazyObject(lambda: 
+    ServerBase(Catalogue(metadata_registry), metadata_registry,
+        {'topxsi': NS_XSI})
+    )
 
 
 def oaipmh(request):
 
 
 def oaipmh(request):
index 4dd1ca2..d70501c 100644 (file)
@@ -12,6 +12,7 @@ from django.utils.feedgenerator import Atom1Feed
 from django.conf import settings
 from django.http import Http404
 from django.contrib.sites.models import Site
 from django.conf import settings
 from django.http import Http404
 from django.contrib.sites.models import Site
+from django.utils.functional import lazy
 
 from basicauth import logged_in_or_basicauth, factory_decorator
 from catalogue.models import Book, Tag
 
 from basicauth import logged_in_or_basicauth, factory_decorator
 from catalogue.models import Book, Tag
@@ -64,21 +65,22 @@ _root_feeds = (
 )
 
 
 )
 
 
+current_domain = lazy(lambda: Site.objects.get_current().domain, str)()
 def full_url(url):
 def full_url(url):
-    return urljoin("http://%s" % Site.objects.get_current().domain, url)
+    return urljoin("http://%s" % current_domain, url)
 
 
 class OPDSFeed(Atom1Feed):
     link_rel = u"subsection"
     link_type = u"application/atom+xml"
 
 
 
 class OPDSFeed(Atom1Feed):
     link_rel = u"subsection"
     link_type = u"application/atom+xml"
 
-    _book_parent_img = full_url(os.path.join(settings.STATIC_URL, "img/book-parent.png"))
+    _book_parent_img = lazy(lambda: full_url(os.path.join(settings.STATIC_URL, "img/book-parent.png")))()
     try:
         _book_parent_img_size = unicode(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book-parent.png")))
     except:
         _book_parent_img_size = ''
 
     try:
         _book_parent_img_size = unicode(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book-parent.png")))
     except:
         _book_parent_img_size = ''
 
-    _book_img = full_url(os.path.join(settings.STATIC_URL, "img/book.png"))
+    _book_img = lazy(lambda: full_url(os.path.join(settings.STATIC_URL, "img/book.png")))()
     try:
         _book_img_size = unicode(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book.png")))
     except:
     try:
         _book_img_size = unicode(os.path.getsize(os.path.join(settings.STATIC_ROOT, "img/book.png")))
     except:
index 143f40e..9b92efa 100644 (file)
@@ -3,9 +3,9 @@
 
 # django
 Django>=1.6,<1.7
 
 # django
 Django>=1.6,<1.7
-fnpdjango>=0.1.8,<0.2
+fnpdjango>=0.1.15,<0.2
 South>=0.7 # migrations for django
 South>=0.7 # migrations for django
-django-pipeline>=1.2.24,<1.3
+django-pipeline>=1.3,<1.4
 django-pagination>=1.0
 django-maintenancemode>=0.10
 django-piston>=0.2.2.1,<0.2.3
 django-pagination>=1.0
 django-maintenancemode>=0.10
 django-piston>=0.2.2.1,<0.2.3
@@ -29,7 +29,7 @@ django-piwik
 python-fb
 
 # Feedparser 
 python-fb
 
 # Feedparser 
-Feedparser>=4.1
+Feedparser>=5.1
 
 # PIL 
 PIL>=1.1.6
 
 # PIL 
 PIL>=1.1.6
index 45bd8d6..2bfcd25 100644 (file)
@@ -140,7 +140,7 @@ PIPELINE_JS = {
 
 }
 
 
 }
 
-STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'
+STATICFILES_STORAGE = 'wolnelektury.utils.GzipPipelineCachedStorage'
 PIPELINE_CSS_COMPRESSOR = None
 PIPELINE_JS_COMPRESSOR = None
 
 PIPELINE_CSS_COMPRESSOR = None
 PIPELINE_JS_COMPRESSOR = None
 
index 0c256e5..e06fb1d 100644 (file)
@@ -5,6 +5,8 @@
 import pytz
 from django.utils import timezone
 from django.conf import settings
 import pytz
 from django.utils import timezone
 from django.conf import settings
+from pipeline.storage import GZIPMixin
+from pipeline.storage import PipelineCachedStorage
 
 tz = pytz.timezone(settings.TIME_ZONE)
 
 
 tz = pytz.timezone(settings.TIME_ZONE)
 
@@ -15,3 +17,6 @@ def localtime_to_utc(localtime):
 
 def utc_for_js(dt):
     return dt.strftime('%Y/%m/%d %H:%M:%S UTC')
 
 def utc_for_js(dt):
     return dt.strftime('%Y/%m/%d %H:%M:%S UTC')
+
+class GzipPipelineCachedStorage(GZIPMixin, PipelineCachedStorage):
+    pass