From 674686233fb4167657c96f62b8ee42917ba07a1b Mon Sep 17 00:00:00 2001 From: Ed Summers Date: Fri, 9 Sep 2011 01:38:28 -0400 Subject: [PATCH] lots of changes to support dynamically loading from openlibrary based on an isbn...which still needs some work to prevent duplication --- core/books.py | 144 +++++++------- core/management/commands/load_books.py | 3 +- ...ition_year__add_field_edition_descripti.py | 175 ++++++++++++++++++ .../0005_auto__add_field_edition_language.py | 119 ++++++++++++ ..._language__del_field_edition_page_count.py | 123 ++++++++++++ ...__del_identifier__add_editionidentifier.py | 137 ++++++++++++++ .../0008_auto__add_workidentifier.py | 132 +++++++++++++ .../migrations/0009_auto__add_editioncover.py | 136 ++++++++++++++ core/models.py | 45 ++++- core/tests.py | 36 ++-- settings/common.py | 2 + 11 files changed, 956 insertions(+), 96 deletions(-) create mode 100644 core/migrations/0004_auto__add_subject__del_field_edition_year__add_field_edition_descripti.py create mode 100644 core/migrations/0005_auto__add_field_edition_language.py create mode 100644 core/migrations/0006_auto__del_field_edition_language__del_field_edition_page_count.py create mode 100644 core/migrations/0007_auto__del_identifier__add_editionidentifier.py create mode 100644 core/migrations/0008_auto__add_workidentifier.py create mode 100644 core/migrations/0009_auto__add_editioncover.py diff --git a/core/books.py b/core/books.py index a514ba66..4bac2cd2 100755 --- a/core/books.py +++ b/core/books.py @@ -1,101 +1,99 @@ -from django.conf import settings +""" +The module handles fetching books from OpenLibrary and adding them +to the local database. +""" import json import logging import requests +from django.conf import settings -def get_edition(isbn): +from regluit.core import models - # lookup the isbn at googlebooks - results = googlebooks_search("isbn:%s" % isbn) - if results['totalItems'] == 0: - return None - elif results['totalItems'] > 1: - return LookupFailure("multiple results for isbn %s" % isbn) - # get the edition detail from google - google_id = results['items'][0]['id'] - i = googlebooks_volume(google_id) +def add_book(isbn): + url = "http://openlibrary.org/api/books" + bibkeys = "ISBN:%s" % isbn + params = {"bibkeys": bibkeys, "jscmd": "details", "format": "json"} + results = get_json(url, params) + if results.has_key(bibkeys): + return save_edition(results[bibkeys]['details']) + return None - # normalize some of the googlebooks data - edition = { - 'title': i['volumeInfo']['title'], - 'authors': i['volumeInfo']['authors'], - 'description': i['volumeInfo']['description'], - 'categories': i['volumeInfo']['categories'], - 'language': i['volumeInfo']['language'], - 'publisher': i['volumeInfo']['publisher'], - 'publication_date': i['volumeInfo']['publishedDate'], - 'page_count': i['volumeInfo']['pageCount'], - 'google_books_id': i['id'], - 'cover_image_url': i['volumeInfo']['imageLinks']['thumbnail'], - 'isbn_10': [], - 'isbn_13': [] - } - for identifier in i['volumeInfo'].get('industryIdentifiers', []): - if identifier['type'] == 'ISBN_10': - edition['isbn_10'].append(identifier['identifier']) - elif identifier['type'] == 'ISBN_13': - edition['isbn_13'].append(identifier['identifier']) +def save_edition(edition_data): + edition = models.Edition() + edition.title = edition_data.get('title') + edition.description = edition_data.get('description') + edition.publisher = first(edition_data, 'publishers') + edition.publication_date = edition_data.get('publish_date') + edition.save() + + for work_data in edition_data.get('works', []): + save_work(work_data['key'], edition) + + for isbn_10 in edition_data.get('isbn_10', []): + models.EditionIdentifier.objects.get_or_create(name='isbn_10', value=isbn_10, edition=edition) + + for isbn_13 in edition_data.get('isbn_13', []): + models.EditionIdentifier.objects.get_or_create(name='isbn_13', value=isbn_13, edition=edition) + + for cover_id in edition_data.get('covers', []): + models.EditionCover.objects.get_or_create(openlibrary_id=cover_id, edition=edition) return edition -def get_work(isbn): - return {'title': 'Neuromancer'} +def save_work(work_key, edition): + url = "http://openlibrary.org" + work_key + work_data = get_json(url) + + work = models.Work() + work.title = work_data.get('title') + work.openlibrary_id = work_key + work.save() + + for author_data in work_data.get('authors', []): + save_author(author_data['author']['key'], work) + + for subject_name in work_data.get('subjects', []): + subject, created = models.Subject.objects.get_or_create(name=subject_name) + work.subjects.add(subject) + + work.editions.add(edition) + + return work -def googlebooks_search(q): - params = {"q": q, "key": settings.GOOGLE_BOOKS_API_KEY} - url = 'https://www.googleapis.com/books/v1/volumes' - return _get_json(url, params) +def save_author(author_key, work): + url = "http://openlibrary.org" + author_key + author_data = get_json(url) + + author = models.Author() + author.name = author_data['name'] + author.save() + + author.works.add(work) + + return author -def googlebooks_volume(google_books_id): - params = {"key": settings.GOOGLE_BOOKS_API_KEY} - url = "https://www.googleapis.com/books/v1/volumes/%s" % google_books_id - return _get_json(url, params) +def first(dictionary, key): + l = dictionary.get(key, []) + if len(l) == 0: return None + return l[0] -def _get_json(url, params): - response = requests.get(url, params=params) +def get_json(url, params={}): + headers = {'User-Agent': 'unglue.it bot', 'Accept': 'application/json'} + response = requests.get(url, params=params, headers=headers) if response.status_code == 200: return json.loads(response.content) else: logging.error("unexpected HTTP response: %s" % response) raise LookupFailure("GET failed: url=%s and params=%s" % (url, params)) + class LookupFailure(Exception): pass - - -if __name__ == "__main__": - # list of books from Amanda - isbns = [ - # amanda's first list - "0811216993", "0811216713", "1564780880", "0156709902", - "0803260970", "0231145365", "0745647863", "0393302318", - "1590171101", "015602909X", "0156576813", "0156982900", - "0156189798", "0553380834", "0375706682", "055380491X", - "0553378589", "0684831074", "0761148574", "1563053381", - "0520256093", "0679442707", "0375754741", - - # amanda's second list - "0547773986", "0719595800", "1582432104", "0156372088", - "0139391401", "0300022867", "0300084587", "0691063184", - "0691004765", "0940242753", "0671240773", "0060852240", - "0307270807", "0520047834", "0471609978", "0030839939", - "0465027822", "0465028381", "0716760355", "1597261076", - "1559638583", "0393014886", "0452011752", "0151400563", - "0812536363", "0441007465", "0441569595", "0441012035", - "0393311198", "0525200150", "0375704078", "0773723749", - "0760759146", "0441478123", "0553383043", "006076029X", - "0802714544", "0743442539", "0743431677", - ] - - for isbn in isbns: - print get_edition(isbn) - - diff --git a/core/management/commands/load_books.py b/core/management/commands/load_books.py index 8ff53544..f287f3fa 100644 --- a/core/management/commands/load_books.py +++ b/core/management/commands/load_books.py @@ -9,4 +9,5 @@ class Command(BaseCommand): def handle(self, filename, **options): for isbn in open(filename): isbn = isbn.strip() - print books.get_edition(isbn) + edition = books.add_book(isbn) + print edition.title diff --git a/core/migrations/0004_auto__add_subject__del_field_edition_year__add_field_edition_descripti.py b/core/migrations/0004_auto__add_subject__del_field_edition_year__add_field_edition_descripti.py new file mode 100644 index 00000000..504ffa77 --- /dev/null +++ b/core/migrations/0004_auto__add_subject__del_field_edition_year__add_field_edition_descripti.py @@ -0,0 +1,175 @@ +# 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 'Subject' + db.create_table('core_subject', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=500)), + )) + db.send_create_signal('core', ['Subject']) + + # Adding M2M table for field works on 'Subject' + db.create_table('core_subject_works', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('subject', models.ForeignKey(orm['core.subject'], null=False)), + ('work', models.ForeignKey(orm['core.work'], null=False)) + )) + db.create_unique('core_subject_works', ['subject_id', 'work_id']) + + # Deleting field 'Edition.year' + db.delete_column('core_edition', 'year') + + # Adding field 'Edition.description' + db.add_column('core_edition', 'description', self.gf('django.db.models.fields.TextField')(default=''), keep_default=False) + + # Adding field 'Edition.publication_date' + db.add_column('core_edition', 'publication_date', self.gf('django.db.models.fields.CharField')(default=datetime.datetime(2011, 9, 9, 0, 23, 21, 713964), max_length=50), keep_default=False) + + # Adding field 'Edition.page_count' + db.add_column('core_edition', 'page_count', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False) + + # Deleting field 'Author.edition' + db.delete_column('core_author', 'edition_id') + + # Adding M2M table for field works on 'Author' + db.create_table('core_author_works', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('author', models.ForeignKey(orm['core.author'], null=False)), + ('work', models.ForeignKey(orm['core.work'], null=False)) + )) + db.create_unique('core_author_works', ['author_id', 'work_id']) + + + def backwards(self, orm): + + # Deleting model 'Subject' + db.delete_table('core_subject') + + # Removing M2M table for field works on 'Subject' + db.delete_table('core_subject_works') + + # User chose to not deal with backwards NULL issues for 'Edition.year' + raise RuntimeError("Cannot reverse this migration. 'Edition.year' and its values cannot be restored.") + + # Deleting field 'Edition.description' + db.delete_column('core_edition', 'description') + + # Deleting field 'Edition.publication_date' + db.delete_column('core_edition', 'publication_date') + + # Deleting field 'Edition.page_count' + db.delete_column('core_edition', 'page_count') + + # User chose to not deal with backwards NULL issues for 'Author.edition' + raise RuntimeError("Cannot reverse this migration. 'Author.edition' and its values cannot be restored.") + + # Removing M2M table for field works on 'Author' + db.delete_table('core_author_works') + + + 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'}) + }, + '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'}) + }, + 'core.author': { + 'Meta': {'object_name': 'Author'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.campaign': { + 'Meta': {'object_name': 'Campaign'}, + 'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'deadline': ('django.db.models.fields.DateTimeField', [], {}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '10000'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'target': ('django.db.models.fields.FloatField', [], {}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaign'", 'to': "orm['core.Work']"}) + }, + 'core.edition': { + 'Meta': {'object_name': 'Edition'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'page_count': ('django.db.models.fields.IntegerField', [], {}), + 'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'to': "orm['core.Work']"}) + }, + 'core.identifier': { + 'Meta': {'object_name': 'Identifier'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Edition']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + }, + 'core.subject': { + 'Meta': {'object_name': 'Subject'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.wishlist': { + 'Meta': {'object_name': 'Wishlist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.work': { + 'Meta': {'object_name': 'Work'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}) + } + } + + complete_apps = ['core'] diff --git a/core/migrations/0005_auto__add_field_edition_language.py b/core/migrations/0005_auto__add_field_edition_language.py new file mode 100644 index 00000000..8b492627 --- /dev/null +++ b/core/migrations/0005_auto__add_field_edition_language.py @@ -0,0 +1,119 @@ +# 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 field 'Edition.language' + db.add_column('core_edition', 'language', self.gf('django.db.models.fields.CharField')(default='eng', max_length=5), keep_default=False) + + + def backwards(self, orm): + + # Deleting field 'Edition.language' + db.delete_column('core_edition', 'language') + + + 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'}) + }, + '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'}) + }, + 'core.author': { + 'Meta': {'object_name': 'Author'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.campaign': { + 'Meta': {'object_name': 'Campaign'}, + 'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'deadline': ('django.db.models.fields.DateTimeField', [], {}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '10000'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'target': ('django.db.models.fields.FloatField', [], {}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaign'", 'to': "orm['core.Work']"}) + }, + 'core.edition': { + 'Meta': {'object_name': 'Edition'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'max_length': '5'}), + 'page_count': ('django.db.models.fields.IntegerField', [], {}), + 'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'to': "orm['core.Work']"}) + }, + 'core.identifier': { + 'Meta': {'object_name': 'Identifier'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Edition']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + }, + 'core.subject': { + 'Meta': {'object_name': 'Subject'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.wishlist': { + 'Meta': {'object_name': 'Wishlist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.work': { + 'Meta': {'object_name': 'Work'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}) + } + } + + complete_apps = ['core'] diff --git a/core/migrations/0006_auto__del_field_edition_language__del_field_edition_page_count.py b/core/migrations/0006_auto__del_field_edition_language__del_field_edition_page_count.py new file mode 100644 index 00000000..393001d8 --- /dev/null +++ b/core/migrations/0006_auto__del_field_edition_language__del_field_edition_page_count.py @@ -0,0 +1,123 @@ +# 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): + + # Deleting field 'Edition.language' + db.delete_column('core_edition', 'language') + + # Deleting field 'Edition.page_count' + db.delete_column('core_edition', 'page_count') + + + def backwards(self, orm): + + # User chose to not deal with backwards NULL issues for 'Edition.language' + raise RuntimeError("Cannot reverse this migration. 'Edition.language' and its values cannot be restored.") + + # User chose to not deal with backwards NULL issues for 'Edition.page_count' + raise RuntimeError("Cannot reverse this migration. 'Edition.page_count' and its values cannot be restored.") + + + 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'}) + }, + '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'}) + }, + 'core.author': { + 'Meta': {'object_name': 'Author'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.campaign': { + 'Meta': {'object_name': 'Campaign'}, + 'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'deadline': ('django.db.models.fields.DateTimeField', [], {}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '10000'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'target': ('django.db.models.fields.FloatField', [], {}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaign'", 'to': "orm['core.Work']"}) + }, + 'core.edition': { + 'Meta': {'object_name': 'Edition'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'to': "orm['core.Work']"}) + }, + 'core.identifier': { + 'Meta': {'object_name': 'Identifier'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Edition']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + }, + 'core.subject': { + 'Meta': {'object_name': 'Subject'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.wishlist': { + 'Meta': {'object_name': 'Wishlist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.work': { + 'Meta': {'object_name': 'Work'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}) + } + } + + complete_apps = ['core'] diff --git a/core/migrations/0007_auto__del_identifier__add_editionidentifier.py b/core/migrations/0007_auto__del_identifier__add_editionidentifier.py new file mode 100644 index 00000000..24bf5c95 --- /dev/null +++ b/core/migrations/0007_auto__del_identifier__add_editionidentifier.py @@ -0,0 +1,137 @@ +# 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): + + # Deleting model 'Identifier' + db.delete_table('core_identifier') + + # Adding model 'EditionIdentifier' + db.create_table('core_editionidentifier', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=10)), + ('value', self.gf('django.db.models.fields.CharField')(max_length=500)), + ('edition', self.gf('django.db.models.fields.related.ForeignKey')(related_name='identifiers', to=orm['core.Edition'])), + )) + db.send_create_signal('core', ['EditionIdentifier']) + + + def backwards(self, orm): + + # Adding model 'Identifier' + db.create_table('core_identifier', ( + ('name', self.gf('django.db.models.fields.CharField')(max_length=10)), + ('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('value', self.gf('django.db.models.fields.CharField')(max_length=500)), + ('edition', self.gf('django.db.models.fields.related.ForeignKey')(related_name='identifiers', to=orm['core.Edition'])), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + )) + db.send_create_signal('core', ['Identifier']) + + # Deleting model 'EditionIdentifier' + db.delete_table('core_editionidentifier') + + + 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'}) + }, + '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'}) + }, + 'core.author': { + 'Meta': {'object_name': 'Author'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.campaign': { + 'Meta': {'object_name': 'Campaign'}, + 'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'deadline': ('django.db.models.fields.DateTimeField', [], {}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '10000'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'target': ('django.db.models.fields.FloatField', [], {}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaign'", 'to': "orm['core.Work']"}) + }, + 'core.edition': { + 'Meta': {'object_name': 'Edition'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'to': "orm['core.Work']"}) + }, + 'core.editionidentifier': { + 'Meta': {'object_name': 'EditionIdentifier'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Edition']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + }, + 'core.subject': { + 'Meta': {'object_name': 'Subject'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.wishlist': { + 'Meta': {'object_name': 'Wishlist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.work': { + 'Meta': {'object_name': 'Work'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}) + } + } + + complete_apps = ['core'] diff --git a/core/migrations/0008_auto__add_workidentifier.py b/core/migrations/0008_auto__add_workidentifier.py new file mode 100644 index 00000000..9ae6686b --- /dev/null +++ b/core/migrations/0008_auto__add_workidentifier.py @@ -0,0 +1,132 @@ +# 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 'WorkIdentifier' + db.create_table('core_workidentifier', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=10)), + ('value', self.gf('django.db.models.fields.CharField')(max_length=500)), + ('work', self.gf('django.db.models.fields.related.ForeignKey')(related_name='identifiers', to=orm['core.Work'])), + )) + db.send_create_signal('core', ['WorkIdentifier']) + + + def backwards(self, orm): + + # Deleting model 'WorkIdentifier' + db.delete_table('core_workidentifier') + + + 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'}) + }, + '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'}) + }, + 'core.author': { + 'Meta': {'object_name': 'Author'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.campaign': { + 'Meta': {'object_name': 'Campaign'}, + 'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'deadline': ('django.db.models.fields.DateTimeField', [], {}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '10000'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'target': ('django.db.models.fields.FloatField', [], {}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaign'", 'to': "orm['core.Work']"}) + }, + 'core.edition': { + 'Meta': {'object_name': 'Edition'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'to': "orm['core.Work']"}) + }, + 'core.editionidentifier': { + 'Meta': {'object_name': 'EditionIdentifier'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Edition']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + }, + 'core.subject': { + 'Meta': {'object_name': 'Subject'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.wishlist': { + 'Meta': {'object_name': 'Wishlist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.work': { + 'Meta': {'object_name': 'Work'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}) + }, + 'core.workidentifier': { + 'Meta': {'object_name': 'WorkIdentifier'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Work']"}) + } + } + + complete_apps = ['core'] diff --git a/core/migrations/0009_auto__add_editioncover.py b/core/migrations/0009_auto__add_editioncover.py new file mode 100644 index 00000000..0a77e9a9 --- /dev/null +++ b/core/migrations/0009_auto__add_editioncover.py @@ -0,0 +1,136 @@ +# 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 'EditionCover' + db.create_table('core_editioncover', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('openlibrary_id', self.gf('django.db.models.fields.IntegerField')()), + ('edition', self.gf('django.db.models.fields.related.ForeignKey')(related_name='covers', to=orm['core.Edition'])), + )) + db.send_create_signal('core', ['EditionCover']) + + + def backwards(self, orm): + + # Deleting model 'EditionCover' + db.delete_table('core_editioncover') + + + 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'}) + }, + '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'}) + }, + 'core.author': { + 'Meta': {'object_name': 'Author'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.campaign': { + 'Meta': {'object_name': 'Campaign'}, + 'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'deadline': ('django.db.models.fields.DateTimeField', [], {}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '10000'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), + 'target': ('django.db.models.fields.FloatField', [], {}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaign'", 'to': "orm['core.Work']"}) + }, + 'core.edition': { + 'Meta': {'object_name': 'Edition'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editions'", 'to': "orm['core.Work']"}) + }, + 'core.editioncover': { + 'Meta': {'object_name': 'EditionCover'}, + 'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'covers'", 'to': "orm['core.Edition']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'openlibrary_id': ('django.db.models.fields.IntegerField', [], {}) + }, + 'core.editionidentifier': { + 'Meta': {'object_name': 'EditionIdentifier'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Edition']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + }, + 'core.subject': { + 'Meta': {'object_name': 'Subject'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.wishlist': { + 'Meta': {'object_name': 'Wishlist'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'wishlist'", 'unique': 'True', 'to': "orm['auth.User']"}), + 'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'wishlists'", 'symmetrical': 'False', 'to': "orm['core.Work']"}) + }, + 'core.work': { + 'Meta': {'object_name': 'Work'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}) + }, + 'core.workidentifier': { + 'Meta': {'object_name': 'WorkIdentifier'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'to': "orm['core.Work']"}) + } + } + + complete_apps = ['core'] diff --git a/core/models.py b/core/models.py index 516ec1ca..a380bfff 100755 --- a/core/models.py +++ b/core/models.py @@ -17,23 +17,56 @@ class Work(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=1000) +class WorkIdentifier(models.Model): + created = models.DateTimeField(auto_now_add=True) + name = models.CharField(max_length=10) + value = models.CharField(max_length=500) + work = models.ForeignKey("Work", related_name="identifiers") + +class Author(models.Model): + created = models.DateTimeField(auto_now_add=True) + name = models.CharField(max_length=500) + works = models.ManyToManyField("Work", related_name="authors") + + def __unicode__(self): + return self.name + +class Subject(models.Model): + created = models.DateTimeField(auto_now_add=True) + name = models.CharField(max_length=500) + works = models.ManyToManyField("Work", related_name="subjects") + class Edition(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=1000) + description = models.TextField(default='') publisher = models.CharField(max_length=255) - year = models.CharField(max_length=10) + publication_date = models.CharField(max_length=50) work = models.ForeignKey("Work", related_name="editions") -class Identifier(models.Model): + @property + def isbn_10(self): + return self._id('isbn_10') + + @property + def isbn_13(self): + return self._id('isbn_13') + + def _id(self, name): + for i in self.identifiers.all(): + if i.name == name: + return i.value + return None + +class EditionIdentifier(models.Model): created = models.DateTimeField(auto_now_add=True) name = models.CharField(max_length=10) value = models.CharField(max_length=500) edition = models.ForeignKey("Edition", related_name="identifiers") -class Author(models.Model): - created = models.DateTimeField(auto_now_add=True) - name = models.CharField(max_length=500) - edition = models.ForeignKey("Edition", related_name="authors") +class EditionCover(models.Model): + openlibrary_id = models.IntegerField() + edition = models.ForeignKey("Edition", related_name="covers") class Wishlist(models.Model): created = models.DateTimeField(auto_now_add=True) diff --git a/core/tests.py b/core/tests.py index 62cb4430..0a3083a2 100755 --- a/core/tests.py +++ b/core/tests.py @@ -4,21 +4,25 @@ from regluit.core import books class TestBooks(TestCase): - def test_get_edition(self): - edition = books.get_edition(isbn='0441012035') - self.assertEqual(edition['title'], 'Neuromancer') - self.assertEqual(edition['publication_date'], '2004') - self.assertEqual(edition['publisher'], 'Ace Books') - self.assertEqual(edition['page_count'], 371) - self.assertEqual(edition['authors'], ['William Gibson']) - self.assertEqual(edition['isbn_10'], ['0441012035']) - self.assertEqual(edition['isbn_13'], ['9780441012039']) - self.assertEqual(edition['google_books_id'], '2NyiPwAACAAJ') - self.assertTrue('Fiction / Science Fiction / General' in edition['categories']) - self.assertTrue('The future blazed into existence with each deliberate word' in edition['description']) - self.assertEqual(edition['cover_image_url'], 'http://bks3.books.google.com/books?id=2NyiPwAACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api') + def test_add_book(self): + edition = books.add_book(isbn='0441012035') + self.assertEqual(edition.title, 'Neuromancer') + self.assertEqual(edition.publication_date, '2004') + self.assertEqual(edition.publisher, 'Ace Books') + + self.assertEqual(edition.isbn_10, '0441012035') + self.assertEqual(edition.isbn_13, None) + + covers = edition.covers.all() + self.assertEqual(len(covers), 1) + self.assertEqual(covers[0].openlibrary_id, 284192) + + work = edition.work + self.assertTrue(work) + self.assertEqual(work.authors.all()[0].name, 'William F. Gibson') + + subject_names = [subject.name for subject in work.subjects.all()] + self.assertTrue(len(subject_names) > 15) + self.assertTrue('Fiction' in subject_names) - def test_get_work(self): - work = books.get_work(isbn='0441012035') - self.assertEqual(work['title'], 'Neuromancer') diff --git a/settings/common.py b/settings/common.py index 8f3bf644..5cf317a8 100644 --- a/settings/common.py +++ b/settings/common.py @@ -168,3 +168,5 @@ FACEBOOK_EXTENDED_PERMISSIONS = ['email'] LOGIN_URL = "/accounts/login/" LOGIN_REDIRECT_URL = "/" LOGOUT_URL = "/accounts/logout/" + +USER_AGENT = "unglue.it bot "