Django 1.7, working version.
authorRadek Czajka <radekczajka@nowoczesnapolska.org.pl>
Mon, 8 Sep 2014 07:50:15 +0000 (09:50 +0200)
committerRadek Czajka <radekczajka@nowoczesnapolska.org.pl>
Mon, 8 Sep 2014 07:50:15 +0000 (09:50 +0200)
38 files changed:
README.md
apps/ajaxable/utils.py
apps/catalogue/management/commands/importbooks.py
apps/catalogue/migrations/0001_initial.py
apps/catalogue/models/book.py
apps/catalogue/models/bookmedia.py
apps/catalogue/models/fragment.py
apps/catalogue/models/listeners.py
apps/catalogue/models/tag.py
apps/catalogue/templates/catalogue/related_books.html
apps/catalogue/templatetags/catalogue_tags.py
apps/catalogue/views.py
apps/lesmianator/models.py
apps/newtagging/managers.py
apps/newtagging/models.py
apps/opds/tests/__init__.py
apps/pdcounter/models.py
apps/picture/models.py
apps/picture/views.py
apps/search/__init__.py
apps/search/management/commands/reindex.py
apps/search/management/commands/snippets.py
apps/search/tests/index.py
apps/search/views.py
apps/social/views.py
doc/conf.py
doc/installation.rst
requirements-dev.txt
requirements.txt
wolnelektury/migrations/getpaid/0001_initial.py
wolnelektury/migrations/getpaid/0002_auto__add_field_payment_external_id__add_field_payment_description.py [deleted file]
wolnelektury/migrations/getpaid_payu/0001_initial.py [deleted file]
wolnelektury/migrations/getpaid_payu/__init__.py [deleted file]
wolnelektury/settings/__init__.py
wolnelektury/settings/cache.py
wolnelektury/settings/celery.py
wolnelektury/settings/contrib.py
wolnelektury/wsgi.py

index 863593e..340ae04 100644 (file)
--- a/README.md
+++ b/README.md
@@ -23,6 +23,7 @@ License
 Dependencies
 ============
 
 Dependencies
 ============
 
+ * Python 2.7
  * All packages listed in requirements.txt
  * Sass>=3.2
 
  * All packages listed in requirements.txt
  * Sass>=3.2
 
@@ -38,7 +39,6 @@ How to deploy (development version)
 3. Setup your local configuration based on settings.py. You need to generate a new SECRET_KEY, database stuff and domain related stuff.
 4. Populate database:
     
 3. Setup your local configuration based on settings.py. You need to generate a new SECRET_KEY, database stuff and domain related stuff.
 4. Populate database:
     
-    ./manage.py syncdb
     ./manage.py migrate
 
 5. Run the server
     ./manage.py migrate
 
 5. Run the server
index 456c2b4..89b5622 100755 (executable)
@@ -23,16 +23,6 @@ class LazyEncoder(json.JSONEncoder):
             return force_unicode(obj)
         return obj
 
             return force_unicode(obj)
         return obj
 
-# shortcut for JSON reponses
-class JSONResponse(HttpResponse):
-    def __init__(self, data={}, callback=None, **kwargs):
-        # get rid of mimetype
-        kwargs.pop('mimetype', None)
-        data = json.dumps(data)
-        if callback:
-            data = callback + "(" + data + ");"
-        super(JSONResponse, self).__init__(data, content_type="application/json", **kwargs)
-
 
 def method_decorator(function_decorator):
     """Converts a function decorator to a method decorator.
 
 def method_decorator(function_decorator):
     """Converts a function decorator to a method decorator.
index d0d2f22..a15faa0 100644 (file)
@@ -17,7 +17,7 @@ from wolnelektury_core.management.profile import profile
 from catalogue.models import Book
 from picture.models import Picture
 
 from catalogue.models import Book
 from picture.models import Picture
 
-from search import Index
+from search.index import Index
 
 
 class Command(BaseCommand):
 
 
 class Command(BaseCommand):
index ad83d1c..661fde8 100644 (file)
@@ -38,13 +38,13 @@ class Migration(migrations.Migration):
                 ('cover', catalogue.fields.EbookField(b'cover', upload_to=catalogue.models.book._cover_upload_to, storage=fnpdjango.storage.BofhFileSystemStorage(), max_length=255, blank=True, null=True, verbose_name='cover')),
                 ('cover_thumb', catalogue.fields.EbookField(b'cover_thumb', max_length=255, upload_to=catalogue.models.book._cover_thumb_upload_to, null=True, verbose_name='cover thumbnail', blank=True)),
                 ('_related_info', jsonfield.fields.JSONField(null=True, editable=False, blank=True)),
                 ('cover', catalogue.fields.EbookField(b'cover', upload_to=catalogue.models.book._cover_upload_to, storage=fnpdjango.storage.BofhFileSystemStorage(), max_length=255, blank=True, null=True, verbose_name='cover')),
                 ('cover_thumb', catalogue.fields.EbookField(b'cover_thumb', max_length=255, upload_to=catalogue.models.book._cover_thumb_upload_to, null=True, verbose_name='cover thumbnail', blank=True)),
                 ('_related_info', jsonfield.fields.JSONField(null=True, editable=False, blank=True)),
-                ('txt_file', catalogue.fields.EbookField(b'txt', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=None, max_length=255, blank=True, verbose_name='TXT file')),
-                ('fb2_file', catalogue.fields.EbookField(b'fb2', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=None, max_length=255, blank=True, verbose_name='FB2 file')),
-                ('pdf_file', catalogue.fields.EbookField(b'pdf', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=None, max_length=255, blank=True, verbose_name='PDF file')),
-                ('epub_file', catalogue.fields.EbookField(b'epub', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=None, max_length=255, blank=True, verbose_name='EPUB file')),
-                ('mobi_file', catalogue.fields.EbookField(b'mobi', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=None, max_length=255, blank=True, verbose_name='MOBI file')),
-                ('html_file', catalogue.fields.EbookField(b'html', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=None, max_length=255, blank=True, verbose_name='HTML file')),
-                ('xml_file', catalogue.fields.EbookField(b'xml', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=None, max_length=255, blank=True, verbose_name='XML file')),
+                ('txt_file', catalogue.fields.EbookField(b'txt', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._txt_upload_to, max_length=255, blank=True, verbose_name='TXT file')),
+                ('fb2_file', catalogue.fields.EbookField(b'fb2', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._fb2_upload_to, max_length=255, blank=True, verbose_name='FB2 file')),
+                ('pdf_file', catalogue.fields.EbookField(b'pdf', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._pdf_upload_to, max_length=255, blank=True, verbose_name='PDF file')),
+                ('epub_file', catalogue.fields.EbookField(b'epub', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._epub_upload_to, max_length=255, blank=True, verbose_name='EPUB file')),
+                ('mobi_file', catalogue.fields.EbookField(b'mobi', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._mobi_upload_to, max_length=255, blank=True, verbose_name='MOBI file')),
+                ('html_file', catalogue.fields.EbookField(b'html', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._html_upload_to, max_length=255, blank=True, verbose_name='HTML file')),
+                ('xml_file', catalogue.fields.EbookField(b'xml', default=b'', storage=fnpdjango.storage.BofhFileSystemStorage(), upload_to=catalogue.models.book._xml_upload_to, max_length=255, blank=True, verbose_name='XML file')),
                 ('parent', models.ForeignKey(related_name=b'children', blank=True, to='catalogue.Book', null=True)),
             ],
             options={
                 ('parent', models.ForeignKey(related_name=b'children', blank=True, to='catalogue.Book', null=True)),
             ],
             options={
index bab6f58..8f5f107 100644 (file)
@@ -2,14 +2,15 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
+from collections import OrderedDict
 import re
 from django.conf import settings
 import re
 from django.conf import settings
-from django.core.cache import get_cache
+from django.core.cache import caches
 from django.db import models
 from django.db.models import permalink
 import django.dispatch
 from django.db import models
 from django.db.models import permalink
 import django.dispatch
+from django.contrib.contenttypes.fields import GenericRelation
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
-from django.utils.datastructures import SortedDict
 from django.utils.translation import ugettext_lazy as _
 import jsonfield
 from fnpdjango.storage import BofhFileSystemStorage
 from django.utils.translation import ugettext_lazy as _
 import jsonfield
 from fnpdjango.storage import BofhFileSystemStorage
@@ -23,13 +24,15 @@ from newtagging import managers
 
 bofh_storage = BofhFileSystemStorage()
 
 
 bofh_storage = BofhFileSystemStorage()
 
-permanent_cache = get_cache('permanent')
+permanent_cache = caches['permanent']
 
 
 def _cover_upload_to(i, n):
     return 'book/cover/%s.jpg' % i.slug
 
 
 def _cover_upload_to(i, n):
     return 'book/cover/%s.jpg' % i.slug
+
 def _cover_thumb_upload_to(i, n):
     return 'book/cover_thumb/%s.jpg' % i.slug,
 def _cover_thumb_upload_to(i, n):
     return 'book/cover_thumb/%s.jpg' % i.slug,
+
 def _ebook_upload_to(upload_path):
     def _upload_to(i, n):
         return upload_path % i.slug
 def _ebook_upload_to(upload_path):
     def _upload_to(i, n):
         return upload_path % i.slug
@@ -75,6 +78,7 @@ class Book(models.Model):
     objects  = models.Manager()
     tagged   = managers.ModelTaggedItemManager(Tag)
     tags     = managers.TagDescriptor(Tag)
     objects  = models.Manager()
     tagged   = managers.ModelTaggedItemManager(Tag)
     tags     = managers.TagDescriptor(Tag)
+    tag_relations = GenericRelation(Tag.intermediary_table_model)
 
     html_built = django.dispatch.Signal()
     published = django.dispatch.Signal()
 
     html_built = django.dispatch.Signal()
     published = django.dispatch.Signal()
@@ -231,9 +235,9 @@ class Book(models.Model):
         return create_zip(paths, "%s_%s" % (self.slug, format_))
 
     def search_index(self, book_info=None, index=None, index_tags=True, commit=True):
         return create_zip(paths, "%s_%s" % (self.slug, format_))
 
     def search_index(self, book_info=None, index=None, index_tags=True, commit=True):
-        import search
         if index is None:
         if index is None:
-            index = search.Index()
+            from search.index import Index
+            index = Index()
         try:
             index.index_book(self, book_info)
             if index_tags:
         try:
             index.index_book(self, book_info)
             if index_tags:
@@ -593,7 +597,7 @@ class Book(models.Model):
                 books_by_parent.setdefault(book.parent_id, []).append(book)
 
         orphans = []
                 books_by_parent.setdefault(book.parent_id, []).append(book)
 
         orphans = []
-        books_by_author = SortedDict()
+        books_by_author = OrderedDict()
         for tag in Tag.objects.filter(category='author').iterator():
             books_by_author[tag] = []
 
         for tag in Tag.objects.filter(category='author').iterator():
             books_by_author[tag] = []
 
@@ -639,13 +643,16 @@ class Book(models.Model):
         else:
             return None
 
         else:
             return None
 
-
 # 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 = _ebook_upload_to('book/%s/%%s.%s' % (format_, format_))
+    # This weird globals() assignment makes Django migrations comfortable.
+    _upload_to = _ebook_upload_to('book/%s/%%s.%s' % (format_, format_))
+    _upload_to.__name__ = '_%s_upload_to' % format_
+    globals()[_upload_to.__name__] = _upload_to
+
     EbookField(format_, _("%s file" % format_.upper()),
     EbookField(format_, _("%s file" % format_.upper()),
-        upload_to=upload_to,
+        upload_to=_upload_to,
         storage=bofh_storage,
         max_length=255,
         blank=True,
         storage=bofh_storage,
         max_length=255,
         blank=True,
index 9688e86..607f4cd 100644 (file)
@@ -2,11 +2,11 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
+from collections import OrderedDict
 import json
 from collections import namedtuple
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
 import json
 from collections import namedtuple
 from django.db import models
 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
 import jsonfield
 from fnpdjango.utils.text.slughifi import slughifi
 from catalogue.fields import OverwritingFileField
@@ -19,7 +19,7 @@ def _file_upload_to(i, _n):
 class BookMedia(models.Model):
     """Represents media attached to a book."""
     FileFormat = namedtuple("FileFormat", "name ext")
 class BookMedia(models.Model):
     """Represents media attached to a book."""
     FileFormat = namedtuple("FileFormat", "name ext")
-    formats = SortedDict([
+    formats = OrderedDict([
         ('mp3', FileFormat(name='MP3', ext='mp3')),
         ('ogg', FileFormat(name='Ogg Vorbis', ext='ogg')),
         ('daisy', FileFormat(name='DAISY', ext='daisy.zip')),
         ('mp3', FileFormat(name='MP3', ext='mp3')),
         ('ogg', FileFormat(name='Ogg Vorbis', ext='ogg')),
         ('daisy', FileFormat(name='DAISY', ext='daisy.zip')),
index c9131aa..283a7d9 100644 (file)
@@ -3,7 +3,8 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.conf import settings
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.conf import settings
-from django.core.cache import get_cache
+from django.contrib.contenttypes.fields import GenericRelation
+from django.core.cache import caches
 from django.core.urlresolvers import reverse
 from django.db import models
 from django.template.loader import render_to_string
 from django.core.urlresolvers import reverse
 from django.db import models
 from django.template.loader import render_to_string
@@ -13,7 +14,7 @@ from newtagging import managers
 from catalogue.models import Tag
 
 
 from catalogue.models import Tag
 
 
-permanent_cache = get_cache('permanent')
+permanent_cache = caches['permanent']
 
 
 class Fragment(models.Model):
 
 
 class Fragment(models.Model):
@@ -26,6 +27,7 @@ class Fragment(models.Model):
     objects = models.Manager()
     tagged = managers.ModelTaggedItemManager(Tag)
     tags = managers.TagDescriptor(Tag)
     objects = models.Manager()
     tagged = managers.ModelTaggedItemManager(Tag)
     tags = managers.TagDescriptor(Tag)
+    tag_relations = GenericRelation(Tag.intermediary_table_model)
 
     class Meta:
         ordering = ('book', 'anchor',)
 
     class Meta:
         ordering = ('book', 'anchor',)
index 5ef7e9e..b7c5d55 100644 (file)
@@ -3,7 +3,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.conf import settings
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.conf import settings
-from django.core.cache import get_cache
+from django.core.cache import caches
 from django.db.models.signals import post_save, pre_delete, post_delete
 import django.dispatch
 from catalogue.models import Tag, BookMedia, Book, Fragment, Collection
 from django.db.models.signals import post_save, pre_delete, post_delete
 import django.dispatch
 from catalogue.models import Tag, BookMedia, Book, Fragment, Collection
@@ -12,7 +12,7 @@ from catalogue.utils import delete_from_cache_by_language
 from newtagging.models import tags_updated
 
 
 from newtagging.models import tags_updated
 
 
-permanent_cache = get_cache('permanent')
+permanent_cache = caches['permanent']
 
 
 def _tags_updated_handler(sender, affected_tags, **kwargs):
 
 
 def _tags_updated_handler(sender, affected_tags, **kwargs):
@@ -71,7 +71,7 @@ if not settings.NO_SEARCH_INDEX:
     @django.dispatch.receiver(post_delete, sender=Book)
     def _remove_book_from_index_handler(sender, instance, **kwargs):
         """ remove the book from search index, when it is deleted."""
     @django.dispatch.receiver(post_delete, sender=Book)
     def _remove_book_from_index_handler(sender, instance, **kwargs):
         """ remove the book from search index, when it is deleted."""
-        import search
-        idx = search.Index()
+        from search.index import Index
+        idx = Index()
         idx.remove_book(instance)
         idx.index_tags()
         idx.remove_book(instance)
         idx.index_tags()
index ba219fc..b1e3d69 100644 (file)
@@ -212,3 +212,7 @@ class Tag(TagBase):
                     else:
                         meta_tags.append(tag)
         return meta_tags
                     else:
                         meta_tags.append(tag)
         return meta_tags
+
+
+# Pickle complains about not having this.
+TagRelation = Tag.intermediary_table_model
\ No newline at end of file
index aad9742..219876e 100755 (executable)
@@ -4,4 +4,7 @@
 {% for book in books %}
     {% book_mini book %}
 {% endfor %}
 {% for book in books %}
     {% book_mini book %}
 {% endfor %}
+{% for book in random_related %}
+    {% book_mini book %}
+{% endfor %}
 {% endspaceless %}
\ No newline at end of file
 {% endspaceless %}
\ No newline at end of file
index fd8c8c4..1cc0bb7 100644 (file)
@@ -399,8 +399,8 @@ def related_books(book, limit=6, random=1, taken=0):
     related = cache.get(cache_key)
     if related is None:
         related = Book.tagged.related_to(book,
     related = cache.get(cache_key)
     if related is None:
         related = Book.tagged.related_to(book,
-                Book.objects.exclude(common_slug=book.common_slug),
-                ignore_by_tag=book.book_tag())[:limit-random]
+                Book.objects.exclude(common_slug=book.common_slug)
+                ).exclude(tag_relations__tag=book.book_tag())[:limit-random]
         cache.set(cache_key, related, 1800)
     if random:
         random_books = Book.objects.exclude(
         cache.set(cache_key, related, 1800)
     if random:
         random_books = Book.objects.exclude(
@@ -408,11 +408,14 @@ def related_books(book, limit=6, random=1, taken=0):
         if random == 1:
             count = random_books.count()
             if count:
         if random == 1:
             count = random_books.count()
             if count:
-                related.append(random_books[randint(0, count - 1)])
+                random_related = [random_books[randint(0, count - 1)]]
         else:
         else:
-            related += list(random_books.order_by('?')[:random])
+            random_related = list(random_books.order_by('?')[:random])
+    else:
+        random_related = []
     return {
         'books': related,
     return {
         'books': related,
+        'random_related': random_related,
     }
 
 
     }
 
 
index 92469d7..0026b0a 100644 (file)
@@ -2,6 +2,7 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
+from collections import OrderedDict
 import re
 import itertools
 
 import re
 import itertools
 
@@ -10,17 +11,16 @@ from django.core.cache import get_cache
 from django.template import RequestContext
 from django.template.loader import render_to_string
 from django.shortcuts import render_to_response, get_object_or_404
 from django.template import RequestContext
 from django.template.loader import render_to_string
 from django.shortcuts import render_to_response, get_object_or_404
-from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect
+from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect, JsonResponse
 from django.core.urlresolvers import reverse
 from django.db.models import Q
 from django.contrib.auth.decorators import login_required, user_passes_test
 from django.core.urlresolvers import reverse
 from django.db.models import Q
 from django.contrib.auth.decorators import login_required, user_passes_test
-from django.utils.datastructures import SortedDict
 from django.utils.http import urlquote_plus
 from django.utils import translation
 from django.utils.translation import get_language, ugettext as _, ugettext_lazy
 from django.views.decorators.vary import vary_on_headers
 
 from django.utils.http import urlquote_plus
 from django.utils import translation
 from django.utils.translation import get_language, ugettext as _, ugettext_lazy
 from django.views.decorators.vary import vary_on_headers
 
-from ajaxable.utils import JSONResponse, AjaxableFormView
+from ajaxable.utils import AjaxableFormView
 from catalogue import models
 from catalogue import forms
 from catalogue.utils import split_tags, MultiQuerySet, SortedMultiQuerySet
 from catalogue import models
 from catalogue import forms
 from catalogue.utils import split_tags, MultiQuerySet, SortedMultiQuerySet
@@ -76,7 +76,7 @@ def catalogue(request):
             'catalogue/collection_list.html', collection_list(collections))
         permanent_cache.set(cache_key, output)
     if request.is_ajax():
             'catalogue/collection_list.html', collection_list(collections))
         permanent_cache.set(cache_key, output)
     if request.is_ajax():
-        return JSONResponse(output)
+        return JsonResponse(output)
     else:
         return render_to_response('catalogue/catalogue.html', locals(),
             context_instance=RequestContext(request))
     else:
         return render_to_response('catalogue/catalogue.html', locals(),
             context_instance=RequestContext(request))
@@ -98,7 +98,7 @@ def book_list(request, filter=None, get_filter=None,
         if get_filter:
             filter = get_filter()
         books_by_author, orphans, books_by_parent = models.Book.book_list(filter)
         if get_filter:
             filter = get_filter()
         books_by_author, orphans, books_by_parent = models.Book.book_list(filter)
-        books_nav = SortedDict()
+        books_nav = OrderedDict()
         for tag in books_by_author:
             if books_by_author[tag]:
                 books_nav.setdefault(tag.sort_key[0], []).append(tag)
         for tag in books_by_author:
             if books_by_author[tag]:
                 books_nav.setdefault(tag.sort_key[0], []).append(tag)
@@ -212,8 +212,8 @@ def tagged_object_list(request, tags=''):
         fragment_keys = [fragment.pk for fragment in fragments.iterator()]
         if fragment_keys:
             related_tags = models.Fragment.tags.usage(counts=True,
         fragment_keys = [fragment.pk for fragment in fragments.iterator()]
         if fragment_keys:
             related_tags = models.Fragment.tags.usage(counts=True,
-                                filters={'pk__in': fragment_keys},
-                                extra={'where': ["catalogue_tag.category != 'book'"]})
+                                filters={'pk__in': fragment_keys}).exclude(
+                                category='book')
             related_tags = (tag for tag in related_tags if tag not in fragment_tags)
             categories = split_tags(related_tags, categories)
 
             related_tags = (tag for tag in related_tags if tag not in fragment_tags)
             categories = split_tags(related_tags, categories)
 
@@ -564,7 +564,7 @@ def json_tags_starting_with(request, callback=None):
         result = [prefix, tags_list]
     else:
         result = {"matches": tags_list}
         result = [prefix, tags_list]
     else:
         result = {"matches": tags_list}
-    return JSONResponse(result, callback)
+    return JsonResponse(result, callback)
 
 
 # =========
 
 
 # =========
index 83e8213..3482e08 100644 (file)
@@ -14,7 +14,7 @@ from django.utils.translation import ugettext_lazy as _
 from django.core.urlresolvers import reverse
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
 from django.core.urlresolvers import reverse
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
-from django.contrib.contenttypes import generic
+from django.contrib.contenttypes.fields import GenericForeignKey
 from django.conf import settings
 
 from jsonfield import JSONField
 from django.conf import settings
 
 from jsonfield import JSONField
@@ -103,7 +103,7 @@ class Continuations(models.Model):
     pickle = models.FileField(_('Continuations file'), upload_to='lesmianator')
     content_type = models.ForeignKey(ContentType)
     object_id = models.PositiveIntegerField()
     pickle = models.FileField(_('Continuations file'), upload_to='lesmianator')
     content_type = models.ForeignKey(ContentType)
     object_id = models.PositiveIntegerField()
-    content_object = generic.GenericForeignKey('content_type', 'object_id')
+    content_object = GenericForeignKey('content_type', 'object_id')
 
     class Meta:
         unique_together = (('content_type', 'object_id'), )
 
     class Meta:
         unique_together = (('content_type', 'object_id'), )
index f802aa1..0bfec54 100644 (file)
@@ -15,7 +15,7 @@ class ModelTagManager(models.Manager):
         super(ModelTagManager, self).__init__()
         self.tag_model = tag_model
 
         super(ModelTagManager, self).__init__()
         self.tag_model = tag_model
 
-    def get_query_set(self):
+    def get_queryset(self):
         content_type = ContentType.objects.get_for_model(self.model)
         return self.tag_model.objects.filter(
             items__content_type__pk=content_type.pk).distinct()
         content_type = ContentType.objects.get_for_model(self.model)
         return self.tag_model.objects.filter(
             items__content_type__pk=content_type.pk).distinct()
@@ -35,13 +35,13 @@ class ModelTaggedItemManager(models.Manager):
         super(ModelTaggedItemManager, self).__init__()
         self.intermediary_table_model = tag_model.objects.intermediary_table_model
 
         super(ModelTaggedItemManager, self).__init__()
         self.intermediary_table_model = tag_model.objects.intermediary_table_model
 
-    def related_to(self, obj, queryset=None, num=None, ignore_by_tag=None):
+    def related_to(self, obj, queryset=None):
         if queryset is None:
             return self.intermediary_table_model.objects.get_related(
         if queryset is None:
             return self.intermediary_table_model.objects.get_related(
-                obj, self.model, num=num, ignore_by_tag=ignore_by_tag)
+                obj, self.model)
         else:
             return self.intermediary_table_model.objects.get_related(
         else:
             return self.intermediary_table_model.objects.get_related(
-                obj, queryset, num=num, ignore_by_tag=ignore_by_tag)
+                obj, queryset)
 
     def with_all(self, tags, queryset=None):
         if queryset is None:
 
     def with_all(self, tags, queryset=None):
         if queryset is None:
index 71cae93..3f66681 100644 (file)
@@ -3,12 +3,11 @@
 Models and managers for generic tagging.
 """
 
 Models and managers for generic tagging.
 """
 
-from django.contrib.contenttypes import generic
+from django.contrib.contenttypes.fields import GenericForeignKey
 from django.contrib.contenttypes.models import ContentType
 from django.db import connection, models
 from django.utils.translation import ugettext_lazy as _
 from django.db.models.base import ModelBase
 from django.contrib.contenttypes.models import ContentType
 from django.db import connection, models
 from django.utils.translation import ugettext_lazy as _
 from django.db.models.base import ModelBase
-from django.db.models.loading import get_model # D1.7: apps?
 from django.core.exceptions import ObjectDoesNotExist
 from django.dispatch import Signal
 
 from django.core.exceptions import ObjectDoesNotExist
 from django.dispatch import Signal
 
@@ -162,7 +161,7 @@ class TaggedItemManager(models.Manager):
         tag_count = len(tags)
         if not tag_count:
             # No existing tags were given
         tag_count = len(tags)
         if not tag_count:
             # No existing tags were given
-            return queryset
+            return queryset.none()
         elif tag_count == 1:
             # Optimisation for single tag - fall through to the simpler
             # query below.
         elif tag_count == 1:
             # Optimisation for single tag - fall through to the simpler
             # query below.
@@ -180,7 +179,7 @@ class TaggedItemManager(models.Manager):
         queryset, model = get_queryset_and_model(queryset_or_model)
         tags = self.tag_model.get_tag_list(tags)
         if not tags:
         queryset, model = get_queryset_and_model(queryset_or_model)
         tags = self.tag_model.get_tag_list(tags)
         if not tags:
-            return queryset
+            return queryset.none()
         # TODO: presumes reverse generic relation
         return queryset.filter(tag_relations__tag__in=tags)
 
         # TODO: presumes reverse generic relation
         return queryset.filter(tag_relations__tag__in=tags)
 
@@ -194,7 +193,7 @@ class TaggedItemManager(models.Manager):
         # TODO: presumes reverse generic relation.
         # Do we know it's 'tags'?
         return queryset.filter(tag_relations__tag__in=obj.tags).annotate(
         # TODO: presumes reverse generic relation.
         # Do we know it's 'tags'?
         return queryset.filter(tag_relations__tag__in=obj.tags).annotate(
-            count=models.Count('pk')).order_by('-count').exclude(obj=obj.pk)
+            count=models.Count('pk')).order_by('-count').exclude(pk=obj.pk)
 
 
 ##########
 
 
 ##########
@@ -222,7 +221,7 @@ def create_intermediary_table_model(model):
         'tag': models.ForeignKey(model, verbose_name=_('tag'), related_name='items'),
         'content_type': models.ForeignKey(ContentType, verbose_name=_('content type')),
         'object_id': models.PositiveIntegerField(_('object id'), db_index=True),
         'tag': models.ForeignKey(model, verbose_name=_('tag'), related_name='items'),
         'content_type': models.ForeignKey(ContentType, verbose_name=_('content type')),
         'object_id': models.PositiveIntegerField(_('object id'), db_index=True),
-        'content_object': generic.GenericForeignKey('content_type', 'object_id'),
+        'content_object': GenericForeignKey('content_type', 'object_id'),
         '__unicode__': obj_unicode,
     }
 
         '__unicode__': obj_unicode,
     }
 
index ea72f06..b1399ae 100755 (executable)
@@ -11,7 +11,7 @@ from catalogue.test_utils import (BookInfoStub, PersonStub, info_args,
         WLTestCase, get_fixture)
 from catalogue.models import Book
 from librarian import WLURI, XMLNamespace
         WLTestCase, get_fixture)
 from catalogue.models import Book
 from librarian import WLURI, XMLNamespace
-from search import Index, Search
+from search.index import Index, Search
 
 AtomNS = XMLNamespace("http://www.w3.org/2005/Atom")
 
 
 AtomNS = XMLNamespace("http://www.w3.org/2005/Atom")
 
index 4dce99e..7c10f1e 100644 (file)
@@ -90,8 +90,8 @@ class BookStub(models.Model):
 
 if not settings.NO_SEARCH_INDEX:
     def update_index(sender, instance, **kwargs):
 
 if not settings.NO_SEARCH_INDEX:
     def update_index(sender, instance, **kwargs):
-        import search
-        idx = search.Index()
+        from search.index import Index
+        idx = Index()
         idx.index_tags(instance, remove_only=not 'created' in kwargs)
 
     post_delete.connect(update_index, Author)
         idx.index_tags(instance, remove_only=not 'created' in kwargs)
 
     post_delete.connect(update_index, Author)
index 2707e08..74d8631 100644 (file)
@@ -7,11 +7,12 @@ import catalogue.models
 from django.db.models import permalink
 from sorl.thumbnail import ImageField
 from django.conf import settings
 from django.db.models import permalink
 from sorl.thumbnail import ImageField
 from django.conf import settings
+from django.contrib.contenttypes.fields import GenericRelation
 from django.core.files.storage import FileSystemStorage
 from django.utils.datastructures import SortedDict
 from django.template.loader import render_to_string
 from django.utils.safestring import mark_safe
 from django.core.files.storage import FileSystemStorage
 from django.utils.datastructures import SortedDict
 from django.template.loader import render_to_string
 from django.utils.safestring import mark_safe
-from django.core.cache import get_cache
+from django.core.cache import caches
 from catalogue.utils import split_tags
 from fnpdjango.utils.text.slughifi import slughifi
 from picture import tasks
 from catalogue.utils import split_tags
 from fnpdjango.utils.text.slughifi import slughifi
 from picture import tasks
@@ -27,7 +28,7 @@ from newtagging import managers
 from os import path
 
 
 from os import path
 
 
-permanent_cache = get_cache('permanent')
+permanent_cache = caches['permanent']
 
 picture_storage = FileSystemStorage(location=path.join(
         settings.MEDIA_ROOT, 'pictures'),
 
 picture_storage = FileSystemStorage(location=path.join(
         settings.MEDIA_ROOT, 'pictures'),
@@ -45,6 +46,7 @@ class PictureArea(models.Model):
     objects     = models.Manager()
     tagged      = managers.ModelTaggedItemManager(catalogue.models.Tag)
     tags        = managers.TagDescriptor(catalogue.models.Tag)
     objects     = models.Manager()
     tagged      = managers.ModelTaggedItemManager(catalogue.models.Tag)
     tags        = managers.TagDescriptor(catalogue.models.Tag)
+    tag_relations = GenericRelation(catalogue.models.Tag.intermediary_table_model)
 
     @classmethod
     def rectangle(cls, picture, kind, coords):
 
     @classmethod
     def rectangle(cls, picture, kind, coords):
@@ -112,6 +114,7 @@ class Picture(models.Model):
     objects     = models.Manager()
     tagged      = managers.ModelTaggedItemManager(catalogue.models.Tag)
     tags        = managers.TagDescriptor(catalogue.models.Tag)
     objects     = models.Manager()
     tagged      = managers.ModelTaggedItemManager(catalogue.models.Tag)
     tags        = managers.TagDescriptor(catalogue.models.Tag)
+    tag_relations = GenericRelation(catalogue.models.Tag.intermediary_table_model)
 
     class AlreadyExists(Exception):
         pass
 
     class AlreadyExists(Exception):
         pass
index 832877e..11b08bc 100644 (file)
@@ -2,8 +2,8 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
+from collections import OrderedDict
 from django.contrib.auth.decorators import permission_required
 from django.contrib.auth.decorators import permission_required
-from django.utils.datastructures import SortedDict
 from django.shortcuts import render_to_response, get_object_or_404
 from django.template import RequestContext
 from picture.models import Picture
 from django.shortcuts import render_to_response, get_object_or_404
 from django.template import RequestContext
 from picture.models import Picture
@@ -16,7 +16,7 @@ def picture_list(request, filter=None, get_filter=None, template_name='catalogue
     if get_filter:
         filt = get_filter()
     pictures_by_author, orphans = Picture.picture_list(filt)
     if get_filter:
         filt = get_filter()
     pictures_by_author, orphans = Picture.picture_list(filt)
-    books_nav = SortedDict()
+    books_nav = OrderedDict()
     for tag in pictures_by_author:
         if pictures_by_author[tag]:
             books_nav.setdefault(tag.sort_key[0], []).append(tag)
     for tag in pictures_by_author:
         if pictures_by_author[tag]:
             books_nav.setdefault(tag.sort_key[0], []).append(tag)
index 6253c9d..d384124 100644 (file)
@@ -2,4 +2,3 @@
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from index import Index, Search, SearchResult
index 4a17acd..4941354 100755 (executable)
@@ -51,8 +51,8 @@ class Command(BaseCommand):
     )
     def handle(self, *args, **opts):
         from catalogue.models import Book
     )
     def handle(self, *args, **opts):
         from catalogue.models import Book
-        import search
-        idx = search.Index()
+        from search.index import Index
+        idx = Index()
         
         if not opts['just_tags']:
             if args:
         
         if not opts['just_tags']:
             if args:
index 7706547..40310ed 100755 (executable)
@@ -24,7 +24,7 @@ class Command(BaseCommand):
 
     def handle(self, *args, **opts):
         from catalogue.models import Book
 
     def handle(self, *args, **opts):
         from catalogue.models import Book
-        import search
+        from search.index import Search
 
         if opts['check']:
             sfn = glob(settings.SEARCH_INDEX+'snippets/*')
 
         if opts['check']:
             sfn = glob(settings.SEARCH_INDEX+'snippets/*')
@@ -39,7 +39,7 @@ class Command(BaseCommand):
                     except UnicodeDecodeError, ude:
                         print "error in snippets %d" % bkid
         if opts['check2']:
                     except UnicodeDecodeError, ude:
                         print "error in snippets %d" % bkid
         if opts['check2']:
-            s = search.Search()
+            s = Search()
             reader = s.searcher.getIndexReader()
             numdocs = reader.numDocs()
             for did in range(numdocs):
             reader = s.searcher.getIndexReader()
             numdocs = reader.numDocs()
             for did in range(numdocs):
index fc2da1e..b8d4472 100644 (file)
@@ -9,7 +9,7 @@ from catalogue.test_utils import WLTestCase, get_fixture
 from os import path
 import tempfile
 from catalogue.models import Book, Tag
 from os import path
 import tempfile
 from catalogue.models import Book, Tag
-from search import Index, Search, SearchResult
+from search.index import Index, Search, SearchResult
 import catalogue
 import opds
 
 import catalogue
 import opds
 
index dc9e27b..514dc6e 100644 (file)
@@ -6,14 +6,13 @@ from django.conf import settings
 from django.shortcuts import render_to_response, get_object_or_404
 from django.template import RequestContext
 from django.views.decorators import cache
 from django.shortcuts import render_to_response, get_object_or_404
 from django.template import RequestContext
 from django.views.decorators import cache
-from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect
+from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect, JsonResponse
 from django.utils.translation import ugettext as _
 
 from catalogue.utils import split_tags
 from catalogue.models import Book, Tag, Fragment
 from pdcounter.models import Author as PDCounterAuthor, BookStub as PDCounterBook
 from django.utils.translation import ugettext as _
 
 from catalogue.utils import split_tags
 from catalogue.models import Book, Tag, Fragment
 from pdcounter.models import Author as PDCounterAuthor, BookStub as PDCounterBook
-from catalogue.views import JSONResponse
-from search import Search, SearchResult
+from search.index import Search, SearchResult
 from suggest.forms import PublishingSuggestForm
 import re
 #import enchant
 from suggest.forms import PublishingSuggestForm
 import re
 #import enchant
@@ -63,7 +62,7 @@ def did_you_mean(query, tokens):
 def hint(request):
     prefix = request.GET.get('term', '')
     if len(prefix) < 2:
 def hint(request):
     prefix = request.GET.get('term', '')
     if len(prefix) < 2:
-        return JSONResponse([])
+        return JsonResponse([])
 
     prefix = remove_query_syntax_chars(prefix)
 
 
     prefix = remove_query_syntax_chars(prefix)
 
@@ -107,7 +106,7 @@ def hint(request):
         return HttpResponse("%s(%s);" % (callback, json.dumps(data)),
                             content_type="application/json; charset=utf-8")
     else:
         return HttpResponse("%s(%s);" % (callback, json.dumps(data)),
                             content_type="application/json; charset=utf-8")
     else:
-        return JSONResponse(data)
+        return JsonResponse(data)
 
 
 def main(request):
 
 
 def main(request):
index e5a8270..446c5c4 100644 (file)
@@ -3,11 +3,11 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.shortcuts import render, get_object_or_404, redirect
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.shortcuts import render, get_object_or_404, redirect
-from django.http import HttpResponseForbidden
+from django.http import HttpResponseForbidden, JsonResponse
 from django.contrib.auth.decorators import login_required
 from django.views.decorators.http import require_POST
 
 from django.contrib.auth.decorators import login_required
 from django.views.decorators.http import require_POST
 
-from ajaxable.utils import JSONResponse, AjaxableFormView
+from ajaxable.utils import AjaxableFormView
 
 from catalogue.models import Book
 from social import forms
 
 from catalogue.models import Book
 from social import forms
@@ -29,7 +29,7 @@ def like_book(request, slug):
         set_sets(request.user, book, [tag])
 
     if request.is_ajax():
         set_sets(request.user, book, [tag])
 
     if request.is_ajax():
-        return JSONResponse({"success": True, "msg": "ok", "like": True})
+        return JsonResponse({"success": True, "msg": "ok", "like": True})
     else:
         return redirect(book)
 
     else:
         return redirect(book)
 
@@ -66,6 +66,6 @@ def unlike_book(request, slug):
         set_sets(request.user, book, [])
 
     if request.is_ajax():
         set_sets(request.user, book, [])
 
     if request.is_ajax():
-        return JSONResponse({"success": True, "msg": "ok", "like": False})
+        return JsonResponse({"success": True, "msg": "ok", "like": False})
     else:
         return redirect(book)
     else:
         return redirect(book)
index edbc49f..6563265 100644 (file)
@@ -18,15 +18,13 @@ import sys, os
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #sys.path.insert(0, os.path.abspath('.'))
 sys.path += [
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #sys.path.insert(0, os.path.abspath('.'))
 sys.path += [
-    os.path.abspath('../wolnelektury'),
+    os.path.abspath('..'),
     os.path.abspath('../apps'),
     os.path.abspath('../lib'),
     os.path.abspath('../lib/librarian'),
 ]
 
     os.path.abspath('../apps'),
     os.path.abspath('../lib'),
     os.path.abspath('../lib/librarian'),
 ]
 
-from django.core.management import setup_environ
-import settings
-setup_environ(settings)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wolnelektury.settings")
 
 
 
 
 
 
@@ -53,7 +51,7 @@ master_doc = 'index'
 
 # General information about the project.
 project = u'Wolne Lektury'
 
 # General information about the project.
 project = u'Wolne Lektury'
-copyright = u'2007-2012, Fundacja Nowoczesna Polska'
+copyright = u'2007-2014, Fundacja Nowoczesna Polska'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
index 32e46e5..3b16bbb 100644 (file)
@@ -5,7 +5,7 @@ Setup
 Requirements
 ------------
 
 Requirements
 ------------
 
-* `Python 2.6+ <http://python.org>`_
+* `Python 2.7 <http://python.org>`_
 * Python requiremets: ``pip install -r requirements.txt``
 * a library for your database of choice
   (see `DBs supported by Django <http://docs.djangoproject.com/en/dev/topics/install/#get-your-database-running>`_)
 * Python requiremets: ``pip install -r requirements.txt``
 * a library for your database of choice
   (see `DBs supported by Django <http://docs.djangoproject.com/en/dev/topics/install/#get-your-database-running>`_)
@@ -29,7 +29,7 @@ Run the dev server with::
 Some tasks (like generating e-books) run in a seperate
 Celery process by default, so you'll also need to run::
 
 Some tasks (like generating e-books) run in a seperate
 Celery process by default, so you'll also need to run::
 
-    ./manage.py celeryd --loglevel=INFO
+    celery -A wolnelektury worker --loglevel=INFO
 
 Or, if you don't want to run a separate Celery daemon, set this
 in your ``localsettings.py``::
 
 Or, if you don't want to run a separate Celery daemon, set this
 in your ``localsettings.py``::
index 739b6bf..219ba0e 100644 (file)
@@ -5,3 +5,4 @@ polib
 BabelDjango
 Fabric
 sphinx
 BabelDjango
 Fabric
 sphinx
+pyinotify
index 8a208a3..cdab158 100644 (file)
@@ -7,7 +7,7 @@ South>=0.7 # migrations for django
 django-pipeline>=1.3,<1.4
 django-pagination>=1.0
 django-maintenancemode>=0.10
 django-pipeline>=1.3,<1.4
 django-pagination>=1.0
 django-maintenancemode>=0.10
-django-piston>=0.2.2.1,<0.2.3
+django-piston==0.2.2.1.2
 jsonfield>=0.9.20
 django-picklefield
 django-modeltranslation==0.8b2
 jsonfield>=0.9.20
 django-picklefield
 django-modeltranslation==0.8b2
@@ -39,7 +39,8 @@ lxml>=2.2.2
 # MySQL-python>=1.2,<2.0
 
 # celery tasks
 # MySQL-python>=1.2,<2.0
 
 # celery tasks
-django-celery>=3.1,<3.2
+celery>=3.1.12,<3.2
+-e git+git://github.com/rczajka/kombu.git@4ed3622d1e801811410eda503e3eb8a6efd7f86f#egg=kombu
 
 # spell checking
 pyenchant
 
 # spell checking
 pyenchant
index a4a5280..2ab2d3f 100644 (file)
 # -*- coding: utf-8 -*-
 # -*- 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):
-        # Adding model 'Payment'
-        db.create_table(u'getpaid_payment', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('amount', self.gf('django.db.models.fields.DecimalField')(max_digits=20, decimal_places=4)),
-            ('currency', self.gf('django.db.models.fields.CharField')(max_length=3)),
-            ('status', self.gf('django.db.models.fields.CharField')(default='new', max_length=20, db_index=True)),
-            ('backend', self.gf('django.db.models.fields.CharField')(max_length=50)),
-            ('created_on', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, db_index=True, blank=True)),
-            ('paid_on', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True, db_index=True, blank=True)),
-            ('amount_paid', self.gf('django.db.models.fields.DecimalField')(default=0, max_digits=20, decimal_places=4)),
-            ('order', self.gf('django.db.models.fields.related.ForeignKey')(related_name='payment', to=orm['funding.Funding'])),
-        ))
-        db.send_create_signal(u'getpaid', ['Payment'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Payment'
-        db.delete_table(u'getpaid_payment')
-
-
-    models = {
-        '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': '100', 'null': 'True', 'format_name': "'cover'", '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': '100', 'format_name': "'epub'", 'blank': 'True'}),
-            'extra_info': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'fb2_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', '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': '100', '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': '100', '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': '100', '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'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}),
-            'txt_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', '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': '100', 'format_name': "'xml'", 'blank': 'True'})
-        },
-        u'funding.funding': {
-            'Meta': {'ordering': "['-payed_at']", 'object_name': 'Funding'},
-            'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'}),
-            'anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '127', 'blank': 'True'}),
-            'offer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['funding.Offer']"}),
-            'payed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'perks': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['funding.Perk']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'funding.offer': {
-            'Meta': {'ordering': "['-end']", 'object_name': 'Offer'},
-            'author': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Book']", 'null': 'True', 'blank': 'True'}),
-            'due': ('django.db.models.fields.DateField', [], {}),
-            'end': ('django.db.models.fields.DateField', [], {}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'redakcja_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'start': ('django.db.models.fields.DateField', [], {}),
-            'target': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'funding.perk': {
-            'Meta': {'ordering': "['-price']", 'object_name': 'Perk'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'offer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['funding.Offer']", 'null': 'True', 'blank': 'True'}),
-            'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'})
-        },
-        u'getpaid.payment': {
-            'Meta': {'ordering': "('-created_on',)", 'object_name': 'Payment'},
-            'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '4'}),
-            'amount_paid': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '20', 'decimal_places': '4'}),
-            'backend': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
-            'currency': ('django.db.models.fields.CharField', [], {'max_length': '3'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'payment'", 'to': u"orm['funding.Funding']"}),
-            'paid_on': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'db_index': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': '20', 'db_index': 'True'})
-        }
-    }
-
-    complete_apps = ['getpaid']
\ No newline at end of file
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import getpaid.abstract_mixin
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('funding', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Payment',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('amount', models.DecimalField(verbose_name='amount', max_digits=20, decimal_places=4)),
+                ('currency', models.CharField(max_length=3, verbose_name='currency')),
+                ('status', models.CharField(default=b'new', max_length=20, verbose_name='status', db_index=True, choices=[(b'new', 'new'), (b'in_progress', 'in progress'), (b'partially_paid', 'partially paid'), (b'paid', 'paid'), (b'failed', 'failed')])),
+                ('backend', models.CharField(max_length=50, verbose_name='backend')),
+                ('created_on', models.DateTimeField(auto_now_add=True, verbose_name='created on', db_index=True)),
+                ('paid_on', models.DateTimeField(default=None, null=True, verbose_name='paid on', db_index=True, blank=True)),
+                ('amount_paid', models.DecimalField(default=0, verbose_name='amount paid', max_digits=20, decimal_places=4)),
+                ('external_id', models.CharField(max_length=64, null=True, verbose_name='external id', blank=True)),
+                ('description', models.CharField(max_length=128, null=True, verbose_name='Description', blank=True)),
+                ('order', models.ForeignKey(related_name=b'payment', to='funding.Funding')),
+            ],
+            options={
+                'ordering': ('-created_on',),
+                'verbose_name': 'Payment',
+                'verbose_name_plural': 'Payments',
+            },
+            bases=(models.Model, getpaid.abstract_mixin.AbstractMixin),
+        ),
+    ]
diff --git a/wolnelektury/migrations/getpaid/0002_auto__add_field_payment_external_id__add_field_payment_description.py b/wolnelektury/migrations/getpaid/0002_auto__add_field_payment_external_id__add_field_payment_description.py
deleted file mode 100644 (file)
index c017e3c..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-# -*- 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):
-        # Adding field 'Payment.external_id'
-        db.add_column(u'getpaid_payment', 'external_id',
-                      self.gf('django.db.models.fields.CharField')(max_length=64, null=True, blank=True),
-                      keep_default=False)
-
-        # Adding field 'Payment.description'
-        db.add_column(u'getpaid_payment', 'description',
-                      self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Payment.external_id'
-        db.delete_column(u'getpaid_payment', 'external_id')
-
-        # Deleting field 'Payment.description'
-        db.delete_column(u'getpaid_payment', 'description')
-
-
-    models = {
-        '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': '100', 'null': 'True', 'format_name': "'cover'", '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': '100', 'format_name': "'epub'", 'blank': 'True'}),
-            'extra_info': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'fb2_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', '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': '100', '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': '100', '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': '100', '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'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}),
-            'txt_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', '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': '100', 'format_name': "'xml'", 'blank': 'True'})
-        },
-        u'funding.funding': {
-            'Meta': {'ordering': "['-payed_at']", 'object_name': 'Funding'},
-            'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '127', 'blank': 'True'}),
-            'offer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['funding.Offer']"}),
-            'payed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'perks': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['funding.Perk']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'funding.offer': {
-            'Meta': {'ordering': "['-end']", 'object_name': 'Offer'},
-            'author': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Book']", 'null': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'due': ('django.db.models.fields.DateField', [], {}),
-            'end': ('django.db.models.fields.DateField', [], {}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'redakcja_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'start': ('django.db.models.fields.DateField', [], {}),
-            'target': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'funding.perk': {
-            'Meta': {'ordering': "['-price']", 'object_name': 'Perk'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'offer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['funding.Offer']", 'null': 'True', 'blank': 'True'}),
-            'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'})
-        },
-        u'getpaid.payment': {
-            'Meta': {'ordering': "('-created_on',)", 'object_name': 'Payment'},
-            'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '20', 'decimal_places': '4'}),
-            'amount_paid': ('django.db.models.fields.DecimalField', [], {'default': '0', 'max_digits': '20', 'decimal_places': '4'}),
-            'backend': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
-            'currency': ('django.db.models.fields.CharField', [], {'max_length': '3'}),
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}),
-            'external_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'payment'", 'to': u"orm['funding.Funding']"}),
-            'paid_on': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'db_index': 'True', 'blank': 'True'}),
-            'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': '20', 'db_index': 'True'})
-        }
-    }
-
-    complete_apps = ['getpaid']
\ No newline at end of file
diff --git a/wolnelektury/migrations/getpaid_payu/0001_initial.py b/wolnelektury/migrations/getpaid_payu/0001_initial.py
deleted file mode 100644 (file)
index b8b2b79..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- 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):
-        pass
-
-    def backwards(self, orm):
-        pass
-
-    models = {
-        
-    }
-
-    complete_apps = ['payu']
\ No newline at end of file
diff --git a/wolnelektury/migrations/getpaid_payu/__init__.py b/wolnelektury/migrations/getpaid_payu/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
index 7c3787c..58fbc42 100644 (file)
@@ -30,7 +30,7 @@ MIDDLEWARE_CLASSES = [
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
-    'django.middleware.doc.XViewMiddleware',
+    'django.contrib.admindocs.middleware.XViewMiddleware',
     'pagination.middleware.PaginationMiddleware',
     'django.middleware.locale.LocaleMiddleware',
     'maintenancemode.middleware.MaintenanceModeMiddleware',
     'pagination.middleware.PaginationMiddleware',
     'django.middleware.locale.LocaleMiddleware',
     'maintenancemode.middleware.MaintenanceModeMiddleware',
@@ -92,7 +92,6 @@ INSTALLED_APPS_CONTRIB = [
     #'rosetta',
     #'south',
     'sorl.thumbnail',
     #'rosetta',
     #'south',
     'sorl.thumbnail',
-    'djcelery',
     'kombu.transport.django',
     'honeypot',
     #'django_nose',
     'kombu.transport.django',
     'honeypot',
     #'django_nose',
index 3e27b5f..d4beab3 100644 (file)
@@ -10,7 +10,7 @@ CACHES = {
     },
     'permanent': {
         'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
     },
     'permanent': {
         'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
-        'TIMEOUT': 2419200,
+        'TIMEOUT': None,
         'LOCATION': [
             '127.0.0.1:11211',
         ]
         'LOCATION': [
             '127.0.0.1:11211',
         ]
index e4286ce..77abfa6 100644 (file)
@@ -1,5 +1,4 @@
 BROKER_URL = 'django://'
 BROKER_URL = 'django://'
-CELERY_RESULT_BACKEND='djcelery.backends.database:DatabaseBackend'
 
 CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
 CELERY_SEND_TASK_ERROR_EMAILS = True
 
 CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
 CELERY_SEND_TASK_ERROR_EMAILS = True
index b480cd9..3645c1d 100644 (file)
@@ -5,9 +5,8 @@ THUMBNAIL_QUALITY = 95
 MODELTRANSLATION_DEFAULT_LANGUAGE = 'pl'
 MODELTRANSLATION_PREPOPULATE_LANGUAGE = 'pl'
 
 MODELTRANSLATION_DEFAULT_LANGUAGE = 'pl'
 MODELTRANSLATION_PREPOPULATE_LANGUAGE = 'pl'
 
-SOUTH_MIGRATION_MODULES = {
+MIGRATION_MODULES = {
     'getpaid' : 'wolnelektury.migrations.getpaid',
     'getpaid' : 'wolnelektury.migrations.getpaid',
-    'payu': 'wolnelektury.migrations.getpaid_payu',
 }
 
 GETPAID_ORDER_DESCRIPTION = "{% load funding_tags %}{{ order|sanitize_payment_title }}"
 }
 
 GETPAID_ORDER_DESCRIPTION = "{% load funding_tags %}{{ order|sanitize_payment_title }}"
index 46ea2fd..d688df0 100644 (file)
@@ -7,14 +7,13 @@ ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 # Add apps and lib directories to PYTHONPATH
 sys.path = [
     ROOT,
 # Add apps and lib directories to PYTHONPATH
 sys.path = [
     ROOT,
-    os.path.join(ROOT, 'wolnelektury'),
     os.path.join(ROOT, 'apps'),
     os.path.join(ROOT, 'lib'),
     os.path.join(ROOT, 'lib/librarian'),
 ] + sys.path
 
 
     os.path.join(ROOT, 'apps'),
     os.path.join(ROOT, 'lib'),
     os.path.join(ROOT, 'lib/librarian'),
 ] + sys.path
 
 
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wolnelektury.settings")
 
 # This application object is used by the development server
 # as well as any WSGI server configured to use this file.
 
 # This application object is used by the development server
 # as well as any WSGI server configured to use this file.