From: Radek Czajka Date: Fri, 13 Jan 2012 16:05:36 +0000 (+0100) Subject: Merge branch 'production' into pretty X-Git-Url: https://git.mdrn.pl/wolnelektury.git/commitdiff_plain/73ce961f14509aabfa26536f847afd28111029c6 Merge branch 'production' into pretty Conflicts: apps/catalogue/models.py wolnelektury/settings.py wolnelektury/templates/catalogue/main_page.html wolnelektury/urls.py --- 73ce961f14509aabfa26536f847afd28111029c6 diff --cc apps/catalogue/migrations/0024_auto__add_collection.py index 000000000,000000000..e2e21007d new file mode 100644 --- /dev/null +++ b/apps/catalogue/migrations/0024_auto__add_collection.py @@@ -1,0 -1,0 +1,138 @@@ ++# encoding: 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 'Collection' ++ db.create_table('catalogue_collection', ( ++ ('title', self.gf('django.db.models.fields.CharField')(max_length=120, db_index=True)), ++ ('slug', self.gf('django.db.models.fields.SlugField')(max_length=120, primary_key=True, db_index=True)), ++ ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), ++ ('book_slugs', self.gf('django.db.models.fields.TextField')()), ++ )) ++ db.send_create_signal('catalogue', ['Collection']) ++ ++ ++ def backwards(self, orm): ++ ++ # Deleting model 'Collection' ++ db.delete_table('catalogue_collection') ++ ++ ++ models = { ++ 'auth.group': { ++ 'Meta': {'object_name': 'Group'}, ++ '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': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) ++ }, ++ 'auth.permission': { ++ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, ++ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), ++ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), ++ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) ++ }, ++ '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', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), ++ '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', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), ++ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) ++ }, ++ 'catalogue.book': { ++ 'Meta': {'ordering': "('sort_key',)", 'object_name': 'Book'}, ++ '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', 'db_index': 'True'}), ++ 'cover': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', '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': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), ++ 'extra_info': ('catalogue.fields.JSONField', [], {'default': "'{}'"}), ++ 'gazeta_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), ++ 'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), ++ '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': ('django.db.models.fields.files.FileField', [], {'max_length': '100', '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': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), ++ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '120', 'db_index': 'True'}), ++ 'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), ++ 'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}), ++ 'txt_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'blank': 'True'}), ++ 'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), ++ 'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', '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': ('catalogue.fields.JSONField', [], {'default': "'{}'"}), ++ 'file': ('catalogue.fields.OverwritingFileField', [], {'max_length': '100'}), ++ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'name': ('django.db.models.fields.CharField', [], {'max_length': "'100'"}), ++ 'source_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), ++ 'type': ('django.db.models.fields.CharField', [], {'max_length': "'100'"}), ++ 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': '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'}), ++ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '120', 'primary_key': 'True', 'db_index': 'True'}), ++ 'title': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': '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']"}), ++ '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'}), ++ 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), ++ 'gazeta_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}), ++ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), ++ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}), ++ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '120', 'db_index': 'True'}), ++ 'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}), ++ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}), ++ 'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}) ++ }, ++ 'catalogue.tagrelation': { ++ 'Meta': {'unique_together': "(('tag', 'content_type', 'object_id'),)", 'object_name': 'TagRelation', 'db_table': "'catalogue_tag_relation'"}, ++ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), ++ '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']"}) ++ }, ++ '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'}), ++ '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'] diff --cc apps/catalogue/models.py index fbae111ea,1417519f7..9a1e71ad0 --- a/apps/catalogue/models.py +++ b/apps/catalogue/models.py @@@ -1022,6 -947,39 +1022,24 @@@ class Fragment(models.Model) return mark_safe(short_html) -class FileRecord(models.Model): - slug = models.SlugField(_('slug'), max_length=120, db_index=True) - type = models.CharField(_('type'), max_length=20, db_index=True) - sha1 = models.CharField(_('sha-1 hash'), max_length=40) - time = models.DateTimeField(_('time'), auto_now_add=True) - - class Meta: - ordering = ('-time','-slug', '-type') - verbose_name = _('file record') - verbose_name_plural = _('file records') - - def __unicode__(self): - return "%s %s.%s" % (self.sha1, self.slug, self.type) - - + class Collection(models.Model): + """A collection of books, which might be defined before publishing them.""" + title = models.CharField(_('title'), max_length=120, db_index=True) + slug = models.SlugField(_('slug'), max_length=120, primary_key=True) + description = models.TextField(_('description'), null=True, blank=True) + + models.SlugField(_('slug'), max_length=120, unique=True, db_index=True) + book_slugs = models.TextField(_('book slugs')) + + class Meta: + ordering = ('title',) + verbose_name = _('collection') + verbose_name_plural = _('collections') + + def __unicode__(self): + return self.title + + ########### # # SIGNALS diff --cc apps/catalogue/urls.py index 4baf225a5,0e0da4b4a..db044fc1c --- a/apps/catalogue/urls.py +++ b/apps/catalogue/urls.py @@@ -23,10 -13,11 +23,11 @@@ urlpatterns = patterns('picture.views' url(r'^polki/$', 'user_shelves', name='user_shelves'), url(r'^polki/(?P[a-zA-Z0-9-]+)/usun/$', 'delete_shelf', name='delete_shelf'), url(r'^polki/(?P[a-zA-Z0-9-]+)\.zip$', 'download_shelf', name='download_shelf'), - url(r'^lektury/', 'book_list', name='book_list'), + url(r'^lektury/$', 'book_list', name='book_list'), + url(r'^lektury/(?P[a-zA-Z0-9-]+)/$', 'collection', name='collection'), url(r'^audiobooki/$', 'audiobook_list', name='audiobook_list'), url(r'^daisy/$', 'daisy_list', name='daisy_list'), - url(r'^lektura/(?P[a-zA-Z0-9-]+)/polki/', 'book_sets', name='book_shelves'), + url(r'^lektura/(?P%s)/polki/' % SLUG, 'book_sets', name='book_shelves'), url(r'^polki/nowa/$', 'new_set', name='new_set'), url(r'^tags/$', 'tags_starting_with', name='hint'), url(r'^jtags/$', 'json_tags_starting_with', name='jhint'), diff --cc apps/catalogue/views.py index 34c9c1f1f,bf0c42f70..f57797da1 --- a/apps/catalogue/views.py +++ b/apps/catalogue/views.py @@@ -53,9 -70,12 +53,10 @@@ def catalogue(request) context_instance=RequestContext(request)) - def book_list(request, filter=None, template_name='catalogue/book_list.html'): + def book_list(request, filter=None, template_name='catalogue/book_list.html', + context=None): """ generates a listing of all books, optionally filtered with a test function """ - form = forms.SearchForm() - books_by_author, orphans, books_by_parent = models.Book.book_list(filter) books_nav = SortedDict() for tag in books_by_author: diff --cc wolnelektury/settings.py index afd42e96c,e34b9052b..a69b0508e --- a/wolnelektury/settings.py +++ b/wolnelektury/settings.py @@@ -58,9 -58,8 +58,9 @@@ USE_I18N = Tru # Absolute path to the directory that holds media. # Example: "/home/media/media.lawrence.com/" - MEDIA_ROOT = path.join(PROJECT_DIR, '../media') - STATIC_ROOT = path.join(PROJECT_DIR, 'static') - SEARCH_INDEX = path.join(MEDIA_ROOT, 'search') + MEDIA_ROOT = path.join(PROJECT_DIR, '../media/') + STATIC_ROOT = path.join(PROJECT_DIR, 'static/') ++SEARCH_INDEX = path.join(MEDIA_ROOT, 'search/') # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash if there is a path component (optional in other cases). @@@ -154,13 -151,22 +154,24 @@@ INSTALLED_APPS = 'sponsors', 'stats', 'suggest', + 'picture', + 'search', ] - #CACHE_BACKEND = 'locmem:///?max_entries=3000' - CACHE_BACKEND = 'memcached://127.0.0.1:11211/' - #CACHE_BACKEND = None + CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', + 'LOCATION': [ + '127.0.0.1:11211', + ] + }, + 'api': { + 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', + 'LOCATION': path.join(PROJECT_DIR, 'django_cache/'), + 'KEY_PREFIX': 'api', + 'TIMEOUT': 86400, + }, + } CACHE_MIDDLEWARE_ANONYMOUS_ONLY=True # CSS and JavaScript file groups diff --cc wolnelektury/templates/catalogue/collection.html index 000000000,113f7b76d..4bb12c938 mode 000000,100755..100755 --- a/wolnelektury/templates/catalogue/collection.html +++ b/wolnelektury/templates/catalogue/collection.html @@@ -1,0 -1,10 +1,10 @@@ + {% extends "catalogue/book_list.html" %} + {% load i18n %} + -{% block title %}{{ context.collection.title }} {% trans "in WolneLektury.pl" %}{% endblock %} ++{% block titleextra %}{{ context.collection.title }}{% endblock %} + + {% block book_list_header %}{{ context.collection.title }}{% endblock %} + + {% block book_list_info %} + {{ context.collection.description|safe }} + {% endblock %}