Merge branch 'master' of github.com:Gluejar/regluit into payment

pull/1/head
Raymond Yee 2011-12-19 13:23:40 -05:00
commit f1875201b3
25 changed files with 933 additions and 162 deletions

View File

@ -1,5 +1,6 @@
import json import json
import logging import logging
import datetime
import requests import requests
from xml.etree import ElementTree from xml.etree import ElementTree
@ -12,6 +13,7 @@ from regluit.core import models
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def add_by_oclc(oclc): def add_by_oclc(oclc):
logger.info("adding book by oclc %s", oclc) logger.info("adding book by oclc %s", oclc)
for edition in models.Edition.objects.filter(oclc=oclc): for edition in models.Edition.objects.filter(oclc=oclc):
@ -107,10 +109,6 @@ def add_by_googlebooks_id(googlebooks_id, work=None):
a, created = models.Author.objects.get_or_create(name=a) a, created = models.Author.objects.get_or_create(name=a)
a.editions.add(e) a.editions.add(e)
for s in d.get('categories', []):
s, created = models.Subject.objects.get_or_create(name=s)
s.editions.add(e)
access_info = item.get('accessInfo') access_info = item.get('accessInfo')
if access_info: if access_info:
e.public_domain = item.get('public_domain', None) e.public_domain = item.get('public_domain', None)
@ -192,6 +190,47 @@ def merge_works(w1, w2):
w2.delete() w2.delete()
def add_openlibrary(work):
work.openlibrary_lookup = datetime.datetime.now()
work.save()
# find the first ISBN match in OpenLibrary
logger.info("looking up openlibrary data for work %s", work.id)
found = False
e = None # openlibrary edition json
w = None # openlibrary work json
# get the 1st openlibrary match by isbn that has an associated work
url = "http://openlibrary.org/api/books"
params = {"format": "json", "jscmd": "details"}
for edition in work.editions.all():
isbn_key = "ISBN:%s" % edition.isbn_10
params['bibkeys'] = isbn_key
e = _get_json(url, params)
if e.has_key(isbn_key) and e[isbn_key]['details'].has_key('works'):
work_key = e[isbn_key]['details']['works'].pop(0)['key']
logger.info("got openlibrary work %s for isbn %s", work_key, isbn_key)
w = _get_json("http://openlibrary.org" + work_key)
if w.has_key('subjects'):
found = True
break
if not found:
logger.warn("unable to find work %s at openlibrary", work.id)
return
# add the subjects to the Work
for s in w.get('subjects', []):
logger.info("adding subject %s to work %s", s, work.id)
subject, created = models.Subject.objects.get_or_create(name=s)
work.subjects.add(subject)
work.openlibrary_id = w['key']
work.save()
# TODO: add authors here once they are moved from Edition to Work
# TODO: add LCCN, LibraryThing, GoodReads to appropriate models
def _get_json(url, params={}): def _get_json(url, params={}):
# TODO: should X-Forwarded-For change based on the request from client? # TODO: should X-Forwarded-For change based on the request from client?
headers = {'User-Agent': settings.USER_AGENT, headers = {'User-Agent': settings.USER_AGENT,

View File

@ -285,13 +285,12 @@ def load_goodreads_shelf_into_wishlist(user, shelf_name='all', goodreads_user_id
if match: if match:
edition.goodreads_id = match.group(1) edition.goodreads_id = match.group(1)
edition.save() edition.save()
regluit.core.tasks.populate_edition.delay(edition)
user.wishlist.add_work(edition.work, 'goodreads')
logger.info("Work with isbn %s added to wishlist.", isbn)
else: else:
logger.error("unable to extract goodreads id from %s", link) logger.error("unable to extract goodreads id from %s", link)
# let's not trigger too much traffic to Google books for now
# regluit.core.tasks.add_related.delay(isbn)
user.wishlist.add_work(edition.work, 'goodreads')
logger.info("Work with isbn %s added to wishlist.", isbn)
except Exception, e: except Exception, e:
logger.info ("Exception adding ISBN %s: %s", isbn, e) logger.info ("Exception adding ISBN %s: %s", isbn, e)

View File

@ -217,8 +217,7 @@ def load_librarything_into_wishlist(user, lt_username, max_books=None):
edition.work.librarything_id = book['work_id'] edition.work.librarything_id = book['work_id']
edition.work.save() edition.work.save()
# let's not trigger too much traffic to Google books for now regluit.core.tasks.populate_edition.delay(edition)
# regluit.core.tasks.add_related.delay(isbn)
user.wishlist.add_work(edition.work, 'librarything') user.wishlist.add_work(edition.work, 'librarything')
logger.info("Work with isbn %s added to wishlist.", isbn) logger.info("Work with isbn %s added to wishlist.", isbn)
except Exception, e: except Exception, e:

View File

@ -0,0 +1,10 @@
from django.core.management.base import BaseCommand
from regluit.core import models
from regluit.core import bookloader
class Command(BaseCommand):
def handle(self, *args, **options):
for work in models.Work.objects.filter(openlibrary_lookup__isnull=True):
bookloader.add_openlibrary(work)

View File

@ -1,13 +0,0 @@
from django.core.management.base import BaseCommand
from regluit.core import tasks, models
class Command(BaseCommand):
help = "queues add related books for works that have only one edition"
def handle(self, **options):
for work in models.Work.objects.all():
if work.editions.all().count() == 1:
sole_edition = work.editions.all()[0]
tasks.add_related.delay(sole_edition.isbn_10)

View File

@ -0,0 +1,220 @@
# 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):
# Removing M2M table for field editions on 'Subject'
db.delete_table('core_subject_editions')
# 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'])
def backwards(self, orm):
# Adding M2M table for field editions on 'Subject'
db.create_table('core_subject_editions', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('subject', models.ForeignKey(orm['core.subject'], null=False)),
('edition', models.ForeignKey(orm['core.edition'], null=False))
))
db.create_unique('core_subject_editions', ['subject_id', 'edition_id'])
# Removing M2M table for field works on 'Subject'
db.delete_table('core_subject_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'}),
'editions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'core.campaign': {
'Meta': {'object_name': 'Campaign'},
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'deadline': ('django.db.models.fields.DateTimeField', [], {}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'details': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True'}),
'target': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
},
'core.campaignaction': {
'Meta': {'object_name': 'CampaignAction'},
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'to': "orm['core.Campaign']"}),
'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15'})
},
'core.celerytask': {
'Meta': {'object_name': 'CeleryTask'},
'active': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2011, 12, 15, 22, 25, 4, 967842)', 'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True'}),
'function_args': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'function_name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'task_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'null': 'True', 'to': "orm['auth.User']"})
},
'core.claim': {
'Meta': {'object_name': 'Claim'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'rights_holder': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.RightsHolder']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '7'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['auth.User']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.Work']"})
},
'core.ebook': {
'Meta': {'object_name': 'Ebook'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebooks'", 'to': "orm['core.Edition']"}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'rights': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
},
'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': "''", 'null': 'True'}),
'goodreads_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'googlebooks_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'isbn_10': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True'}),
'isbn_13': ('django.db.models.fields.CharField', [], {'max_length': '13', 'null': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'oclc': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True'}),
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': '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'", 'null': 'True', 'to': "orm['core.Work']"})
},
'core.premium': {
'Meta': {'object_name': 'Premium'},
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
},
'core.rightsholder': {
'Meta': {'object_name': 'RightsHolder'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rights_holder'", 'to': "orm['auth.User']"}),
'rights_holder_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
},
'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.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'facebook_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
'goodreads_auth_secret': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_auth_token': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_user_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'goodreads_user_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'goodreads_user_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'home_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '31', 'blank': 'True'}),
'pic_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'tagline': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'twitter_id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.wishes': {
'Meta': {'object_name': 'Wishes', 'db_table': "'core_wishlist_works'"},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'wishlist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'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', 'through': "orm['core.Wishes']", 'to': "orm['core.Work']"})
},
'core.work': {
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'openlibrary_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
}
}
complete_apps = ['core']

View File

@ -0,0 +1,210 @@
# 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):
# Changing field 'Subject.name'
db.alter_column('core_subject', 'name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=200))
# Adding unique constraint on 'Subject', fields ['name']
db.create_unique('core_subject', ['name'])
def backwards(self, orm):
# Removing unique constraint on 'Subject', fields ['name']
db.delete_unique('core_subject', ['name'])
# Changing field 'Subject.name'
db.alter_column('core_subject', 'name', self.gf('django.db.models.fields.CharField')(max_length=500))
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'}),
'editions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'core.campaign': {
'Meta': {'object_name': 'Campaign'},
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'deadline': ('django.db.models.fields.DateTimeField', [], {}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'details': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True'}),
'target': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
},
'core.campaignaction': {
'Meta': {'object_name': 'CampaignAction'},
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'to': "orm['core.Campaign']"}),
'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15'})
},
'core.celerytask': {
'Meta': {'object_name': 'CeleryTask'},
'active': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2011, 12, 19, 1, 15, 14, 636254)', 'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True'}),
'function_args': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'function_name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'task_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'null': 'True', 'to': "orm['auth.User']"})
},
'core.claim': {
'Meta': {'object_name': 'Claim'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'rights_holder': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.RightsHolder']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '7'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['auth.User']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.Work']"})
},
'core.ebook': {
'Meta': {'object_name': 'Ebook'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebooks'", 'to': "orm['core.Edition']"}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'rights': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
},
'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': "''", 'null': 'True'}),
'goodreads_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'googlebooks_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'isbn_10': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True'}),
'isbn_13': ('django.db.models.fields.CharField', [], {'max_length': '13', 'null': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'oclc': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True'}),
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': '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'", 'null': 'True', 'to': "orm['core.Work']"})
},
'core.premium': {
'Meta': {'object_name': 'Premium'},
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
},
'core.rightsholder': {
'Meta': {'object_name': 'RightsHolder'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rights_holder'", 'to': "orm['auth.User']"}),
'rights_holder_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
},
'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', [], {'unique': 'True', 'max_length': '200'}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"})
},
'core.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'facebook_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
'goodreads_auth_secret': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_auth_token': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_user_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'goodreads_user_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'goodreads_user_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'home_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '31', 'blank': 'True'}),
'pic_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'tagline': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'twitter_id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.wishes': {
'Meta': {'object_name': 'Wishes', 'db_table': "'core_wishlist_works'"},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'wishlist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'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', 'through': "orm['core.Wishes']", 'to': "orm['core.Work']"})
},
'core.work': {
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'openlibrary_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
}
}
complete_apps = ['core']

View File

@ -0,0 +1,205 @@
# 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 'Work.openlibrary_lookup'
db.add_column('core_work', 'openlibrary_lookup', self.gf('django.db.models.fields.DateTimeField')(null=True), keep_default=False)
def backwards(self, orm):
# Deleting field 'Work.openlibrary_lookup'
db.delete_column('core_work', 'openlibrary_lookup')
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'}),
'editions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'authors'", 'symmetrical': 'False', 'to': "orm['core.Edition']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'core.campaign': {
'Meta': {'object_name': 'Campaign'},
'activated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'amazon_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'deadline': ('django.db.models.fields.DateTimeField', [], {}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'details': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'left': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'managers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'campaigns'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
'paypal_receiver': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'status': ('django.db.models.fields.CharField', [], {'default': "'INITIALIZED'", 'max_length': '15', 'null': 'True'}),
'target': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '14', 'decimal_places': '2'}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'campaigns'", 'to': "orm['core.Work']"})
},
'core.campaignaction': {
'Meta': {'object_name': 'CampaignAction'},
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'to': "orm['core.Campaign']"}),
'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '15'})
},
'core.celerytask': {
'Meta': {'object_name': 'CeleryTask'},
'active': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2011, 12, 19, 1, 22, 42, 254688)', 'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True'}),
'function_args': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'function_name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'task_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'null': 'True', 'to': "orm['auth.User']"})
},
'core.claim': {
'Meta': {'object_name': 'Claim'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'rights_holder': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.RightsHolder']"}),
'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '7'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['auth.User']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'claim'", 'to': "orm['core.Work']"})
},
'core.ebook': {
'Meta': {'object_name': 'Ebook'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ebooks'", 'to': "orm['core.Edition']"}),
'format': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'provider': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'rights': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
},
'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': "''", 'null': 'True'}),
'goodreads_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'googlebooks_id': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'isbn_10': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True'}),
'isbn_13': ('django.db.models.fields.CharField', [], {'max_length': '13', 'null': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'oclc': ('django.db.models.fields.CharField', [], {'max_length': '25', 'null': 'True'}),
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': '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'", 'null': 'True', 'to': "orm['core.Work']"})
},
'core.premium': {
'Meta': {'object_name': 'Premium'},
'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '0'}),
'campaign': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'premiums'", 'null': 'True', 'to': "orm['core.Campaign']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'description': ('django.db.models.fields.TextField', [], {'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '2'})
},
'core.rightsholder': {
'Meta': {'object_name': 'RightsHolder'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'email': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rights_holder'", 'to': "orm['auth.User']"}),
'rights_holder_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
},
'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', [], {'unique': 'True', 'max_length': '200'}),
'works': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subjects'", 'symmetrical': 'False', 'to': "orm['core.Work']"})
},
'core.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'facebook_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'}),
'goodreads_auth_secret': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_auth_token': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'goodreads_user_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
'goodreads_user_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'goodreads_user_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'home_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '31', 'blank': 'True'}),
'pic_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
'tagline': ('django.db.models.fields.CharField', [], {'max_length': '140', 'blank': 'True'}),
'twitter_id': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"})
},
'core.wishes': {
'Meta': {'object_name': 'Wishes', 'db_table': "'core_wishlist_works'"},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'source': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}),
'wishlist': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['core.Wishlist']"}),
'work': ('django.db.models.fields.related.ForeignKey', [], {'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', 'through': "orm['core.Wishes']", 'to': "orm['core.Work']"})
},
'core.work': {
'Meta': {'ordering': "['title']", 'object_name': 'Work'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '2'}),
'librarything_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'openlibrary_id': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
}
}
complete_apps = ['core']

View File

@ -211,6 +211,7 @@ class Work(models.Model):
openlibrary_id = models.CharField(max_length=50, null=True) openlibrary_id = models.CharField(max_length=50, null=True)
librarything_id = models.CharField(max_length=50, null=True) librarything_id = models.CharField(max_length=50, null=True)
language = models.CharField(max_length=2, default="en", null=False) language = models.CharField(max_length=2, default="en", null=False)
openlibrary_lookup = models.DateTimeField(null=True)
class Meta: class Meta:
ordering = ['title'] ordering = ['title']
@ -241,6 +242,10 @@ class Work(models.Model):
def librarything_url(self): def librarything_url(self):
return "http://www.librarything.com/work/%s" % self.librarything_id return "http://www.librarything.com/work/%s" % self.librarything_id
@property
def openlibrary_url(self):
return "http://openlibrary.org" + self.openlibrary_id
def cover_image_small(self): def cover_image_small(self):
return self.editions.all()[0].cover_image_small() return self.editions.all()[0].cover_image_small()
@ -366,8 +371,11 @@ class Author(models.Model):
class Subject(models.Model): class Subject(models.Model):
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=500) name = models.CharField(max_length=200, unique=True)
editions = models.ManyToManyField("Edition", related_name="subjects") works = models.ManyToManyField("Work", related_name="subjects")
class Meta:
ordering = ['name']
def __unicode__(self): def __unicode__(self):
return self.name return self.name

View File

@ -1,15 +1,18 @@
from celery.decorators import task
from regluit.core import bookloader
from regluit.core import goodreads, librarything
from time import sleep from time import sleep
@task from celery.decorators import task
def add_related(isbn):
return bookloader.add_related(isbn) from regluit.core import bookloader
from regluit.core import goodreads, librarything
@task @task
def add_by_isbn(isbn): def populate_edition(edition):
return bookloader.add_by_isbn(isbn) """given an edition this task will populate the database with additional
information about related editions and subjects related to this edition
"""
bookloader.add_related(edition.isbn_10)
bookloader.add_openlibrary(edition.work)
return edition
@task @task
def load_goodreads_shelf_into_wishlist(user, shelf_name='all', goodreads_user_id=None, max_books=None, def load_goodreads_shelf_into_wishlist(user, shelf_name='all', goodreads_user_id=None, max_books=None,

View File

@ -21,7 +21,7 @@ from time import sleep
from math import factorial from math import factorial
class TestBookLoader(TestCase): class BookLoaderTests(TestCase):
def test_add_by_isbn(self): def test_add_by_isbn(self):
# edition # edition
@ -33,11 +33,6 @@ class TestBookLoader(TestCase):
self.assertEqual(edition.isbn_13, '9780441012039') self.assertEqual(edition.isbn_13, '9780441012039')
self.assertEqual(edition.googlebooks_id, "2NyiPwAACAAJ") self.assertEqual(edition.googlebooks_id, "2NyiPwAACAAJ")
# subjects
subject_names = [subject.name for subject in edition.subjects.all()]
self.assertEqual(len(subject_names), 11)
self.assertTrue('Japan' in subject_names)
# authors # authors
self.assertEqual(edition.authors.all().count(), 1) self.assertEqual(edition.authors.all().count(), 1)
self.assertEqual(edition.authors.all()[0].name, 'William Gibson') self.assertEqual(edition.authors.all()[0].name, 'William Gibson')
@ -51,7 +46,6 @@ class TestBookLoader(TestCase):
self.assertEqual(models.Edition.objects.all().count(), 1) self.assertEqual(models.Edition.objects.all().count(), 1)
self.assertEqual(models.Author.objects.all().count(), 1) self.assertEqual(models.Author.objects.all().count(), 1)
self.assertEqual(models.Work.objects.all().count(), 1) self.assertEqual(models.Work.objects.all().count(), 1)
self.assertEqual(models.Subject.objects.all().count(), 11)
def test_missing_isbn(self): def test_missing_isbn(self):
e = bookloader.add_by_isbn('0139391401') e = bookloader.add_by_isbn('0139391401')
@ -79,6 +73,11 @@ class TestBookLoader(TestCase):
self.assertEqual(models.Edition.objects.count(), self.assertEqual(models.Edition.objects.count(),
edition.work.editions.count()) edition.work.editions.count())
def test_populate_edition(self):
edition = bookloader.add_by_googlebooks_id('c_dBPgAACAAJ')
edition = tasks.populate_edition.run(edition)
self.assertTrue(edition.work.editions.all().count() > 20)
self.assertTrue(edition.work.subjects.all().count() > 10)
def test_merge_works(self): def test_merge_works(self):
# add two editions and see that there are two stub works # add two editions and see that there are two stub works
@ -86,6 +85,8 @@ class TestBookLoader(TestCase):
e2 = bookloader.add_by_isbn('1458776204') e2 = bookloader.add_by_isbn('1458776204')
self.assertTrue(e1) self.assertTrue(e1)
self.assertTrue(e2) self.assertTrue(e2)
self.assertTrue(e1.work)
self.assertTrue(e2.work)
self.assertEqual(models.Work.objects.count(), 2) self.assertEqual(models.Work.objects.count(), 2)
# add the stub works to a wishlist # add the stub works to a wishlist
@ -117,10 +118,6 @@ class TestBookLoader(TestCase):
self.assertEqual(c1.work, c2.work) self.assertEqual(c1.work, c2.work)
self.assertEqual(user.wishlist.works.all().count(), 1) self.assertEqual(user.wishlist.works.all().count(), 1)
def test_oclc(self):
edition = bookloader.add_by_oclc('1246014')
self.assertEqual(edition.title, 'The Latin language')
def test_ebook(self): def test_ebook(self):
edition = bookloader.add_by_oclc('1246014') edition = bookloader.add_by_oclc('1246014')
self.assertEqual(edition.ebooks.count(), 2) self.assertEqual(edition.ebooks.count(), 2)
@ -154,6 +151,16 @@ class TestBookLoader(TestCase):
for edition in work.editions.all(): for edition in work.editions.all():
self.assertEqual(edition.title.lower(), "cat's cradle") self.assertEqual(edition.title.lower(), "cat's cradle")
def test_add_openlibrary(self):
work = bookloader.add_by_isbn('0441012035').work
bookloader.add_related('0441012035')
bookloader.add_openlibrary(work)
subjects = [s.name for s in work.subjects.all()]
self.assertTrue(len(subjects) > 10)
self.assertTrue('Science fiction' in subjects)
self.assertEqual(work.openlibrary_id, '/works/OL27258W')
class SearchTests(TestCase): class SearchTests(TestCase):
def test_basic_search(self): def test_basic_search(self):
@ -235,7 +242,6 @@ class CampaignTests(TestCase):
self.assertTrue(c4.update_success()) self.assertTrue(c4.update_success())
self.assertEqual(c4.status, 'SUCCESSFUL') self.assertEqual(c4.status, 'SUCCESSFUL')
# WITHDRAWN # WITHDRAWN
c5 = Campaign(target=D('1000.00'),deadline=datetime(2012,1,1),work=w) c5 = Campaign(target=D('1000.00'),deadline=datetime(2012,1,1),work=w)
c5.save() c5.save()
@ -243,17 +249,6 @@ class CampaignTests(TestCase):
self.assertEqual(c5.status, 'WITHDRAWN') self.assertEqual(c5.status, 'WITHDRAWN')
class SettingsTest(TestCase):
def test_dev_me_alignment(self):
from regluit.settings import me, dev
self.assertEqual(set(me.__dict__.keys()) ^ set(dev.__dict__.keys()), set([]))
def test_prod_me_alignment(self):
from regluit.settings import me, prod
self.assertEqual(set(me.__dict__.keys()) ^ set(prod.__dict__.keys()), set([]))
class WishlistTest(TestCase): class WishlistTest(TestCase):
def test_add_remove(self): def test_add_remove(self):
@ -266,20 +261,6 @@ class WishlistTest(TestCase):
user.wishlist.remove_work(work) user.wishlist.remove_work(work)
self.assertEqual(user.wishlist.works.count(), 0) self.assertEqual(user.wishlist.works.count(), 0)
class SettingsTest(TestCase):
def test_dev_me_alignment(self):
try:
from regluit.settings import me, dev
except:
return
self.assertEqual(set(me.__dict__.keys()) ^ set(dev.__dict__.keys()), set([]))
def test_prod_me_alignment(self):
from regluit.settings import me, prod
self.assertEqual(set(me.__dict__.keys()) ^ set(prod.__dict__.keys()), set([]))
class CeleryTaskTest(TestCase): class CeleryTaskTest(TestCase):
def test_single_fac(self): def test_single_fac(self):
@ -384,10 +365,3 @@ class ISBNTest(TestCase):
self.assertEqual(len(set([str(isbn.ISBN(milosz_10)), str(isbn.ISBN(milosz_13))])),2) self.assertEqual(len(set([str(isbn.ISBN(milosz_10)), str(isbn.ISBN(milosz_13))])),2)
self.assertEqual(len(set([isbn.ISBN(milosz_10).to_string(), isbn.ISBN(milosz_13).to_string()])),1) self.assertEqual(len(set([isbn.ISBN(milosz_10).to_string(), isbn.ISBN(milosz_13).to_string()])),1)
def suite():
testcases = [TestBookLoader, SearchTests, CampaignTests, WishlistTest, CeleryTaskTest, GoodreadsTest, LibraryThingTest, ISBNTest]
suites = unittest.TestSuite([unittest.TestLoader().loadTestsFromTestCase(testcase) for testcase in testcases])
suites.addTest(SettingsTest('test_dev_me_alignment')) # give option to test this alignment
return suites

View File

@ -2,12 +2,16 @@
import re import re
import json import json
import time import fileinput
import urllib
import requests import requests
from oaipmh.client import Client
from oaipmh.metadata import MetadataRegistry, oai_dc_reader def match():
for line in fileinput.input():
j = json.loads(line)
authors = j['authors']
title = j['title']
print googlebooks_id(title, authors)
def google_search(title, authors, no_matches): def google_search(title, authors, no_matches):
headers = {'X-Forwarded-For': '69.243.24.29'} headers = {'X-Forwarded-For': '69.243.24.29'}
@ -78,6 +82,4 @@ def norm_author(a):
return a return a
if __name__ == "__main__": if __name__ == "__main__":
results = open("results.txt", "w") googlebooks_ids()
no_matches = open("no-matches.log", "w")
lookup(results, no_matches)

View File

@ -101,7 +101,7 @@ class MyZotero(Zotero2):
if isbn: if isbn:
edition = bookloader.add_by_isbn(isbn) edition = bookloader.add_by_isbn(isbn)
# let's not trigger too much traffic to Google books for now # let's not trigger too much traffic to Google books for now
# regluit.core.tasks.add_related.delay(isbn) regluit.core.tasks.populate_edition.delay(edition)
user.wishlist.add_work(edition.work, 'zotero') user.wishlist.add_work(edition.work, 'zotero')
logger.info("Work with isbn %s added to wishlist.", isbn) logger.info("Work with isbn %s added to wishlist.", isbn)
except Exception, e: except Exception, e:

View File

@ -10,14 +10,14 @@
wishlists. It is here primarily to show what subjects are present wishlists. It is here primarily to show what subjects are present
in the database to guide further development. You can order by the in the database to guide further development. You can order by the
<a href="{% url subjects %}">subject name</a> or by the <a href="{% url subjects %}">subject name</a> or by the
<a href="{% url subjects %}?order=count">number</a> of editions <a href="{% url subjects %}?order=count">number</a> of works
with that subject. with that subject.
</p> </p>
<p> <p>
<ul> <ul>
{% for subject in subjects %} {% for subject in subjects %}
<li>{{ subject.name }} ({{ subject.editions__count }})</li> <li>{{ subject.name }} ({{ subject.works__count }})</li>
{% endfor %} {% endfor %}
</ul> </ul>
</p> </p>

View File

@ -196,6 +196,15 @@ jQuery(document).ready(function(){
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if work.subjects.all.count > 0 %}
<h4>Subjects</h4>
<ul>
{% for subject in work.subjects.all %}
<li>{{ subject.name }}</li>
{% endfor %}
</ul>
{% endif %}
<h4>Editions</h4> <h4>Editions</h4>
{% for edition in editions %} {% for edition in editions %}
<div class="editions"><div><img src="http://bks{% cycle '1' '2' '3' '4' '5' '6' '7' '8' '9' %}.books.google.com/books?id={{ edition.googlebooks_id }}&printsec=frontcover&img=1&zoom=5" /></div><div class="metadata">{{edition.publisher}}<br />{{edition.publication_date}}<br /><a href="http://bks{% cycle '1' '2' '3' '4' '5' '6' '7' '8' '9' %}.books.google.com/books?id={{ edition.googlebooks_id }}">This edition on Google Books</a></div></div> <div class="editions"><div><img src="http://bks{% cycle '1' '2' '3' '4' '5' '6' '7' '8' '9' %}.books.google.com/books?id={{ edition.googlebooks_id }}&printsec=frontcover&img=1&zoom=5" /></div><div class="metadata">{{edition.publisher}}<br />{{edition.publication_date}}<br /><a href="http://bks{% cycle '1' '2' '3' '4' '5' '6' '7' '8' '9' %}.books.google.com/books?id={{ edition.googlebooks_id }}">This edition on Google Books</a></div></div>
@ -213,10 +222,10 @@ jQuery(document).ready(function(){
<h3 class="jsmod-title"><span>Share</span></h3> <h3 class="jsmod-title"><span>Share</span></h3>
<div class="jsmod-content"> <div class="jsmod-content">
<ul class="social menu"> <ul class="social menu">
<li class="facebook first"><a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2F{{ request.META.HTTP_HOST|urlencode:"" }}{{ request.path|urlencode:"" }}"><span>Facebook</span></a></li> <a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2F{{ request.META.HTTP_HOST|urlencode:"" }}{{ request.path|urlencode:"" }}"><li class="facebook first"><span>Facebook</span></li></a>
<li class="twitter"><a href="https://twitter.com/intent/tweet?url=http%3A%2F%2F{{ request.META.HTTP_HOST|urlencode:"" }}{{ request.path|urlencode:"" }}&text=I'm%20ungluing%20{{ work.title|urlencode }}%20at%20%40unglueit"><span>Twitter</span></a></li> <a href="https://twitter.com/intent/tweet?url=http%3A%2F%2F{{ request.META.HTTP_HOST|urlencode:"" }}{{ request.path|urlencode:"" }}&text=I'm%20ungluing%20{{ work.title|urlencode }}%20at%20%40unglueit"><li class="twitter"><span>Twitter</span></li></a>
<li class="lasts email"><a href="#"<span>Email</span></a></li> <a href="#"><li class="email"><span>Email</span></li></a>
<li><a href="#" id="embed"><span>Embed</span></a></li> <a href="#" id="embed"><li class="embed"><span>Embed</span></li></a>
<div id="widgetcode">Copy/paste this into your site:<br /><textarea rows="7" cols="22">&lt;iframe src="{{base_url}}/api/widget/{{work.editions.all.0.isbn_13}}/" width="152" height="325" frameborder="0"&gt;&lt;/iframe&gt;</textarea></div> <div id="widgetcode">Copy/paste this into your site:<br /><textarea rows="7" cols="22">&lt;iframe src="{{base_url}}/api/widget/{{work.editions.all.0.isbn_13}}/" width="152" height="325" frameborder="0"&gt;&lt;/iframe&gt;</textarea></div>
</ul> </ul>
</div> </div>

View File

@ -4,9 +4,12 @@ import json
import urllib import urllib
import logging import logging
import datetime import datetime
from decimal import Decimal as D
from re import sub from re import sub
from itertools import islice
from decimal import Decimal as D
import requests
import oauth2 as oauth
from django import forms from django import forms
from django.db.models import Q, Count, Sum from django.db.models import Q, Count, Sum
from django.conf import settings from django.conf import settings
@ -26,10 +29,6 @@ from django.contrib.auth.decorators import login_required
from django.shortcuts import render, render_to_response, get_object_or_404 from django.shortcuts import render, render_to_response, get_object_or_404
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import requests
import oauth2 as oauth
from itertools import islice
from regluit.core import tasks from regluit.core import tasks
from regluit.core import models, bookloader, librarything from regluit.core import models, bookloader, librarything
from regluit.core import userlists from regluit.core import userlists
@ -40,13 +39,13 @@ from regluit.frontend.forms import RightsHolderForm, UserClaimForm, LibraryThin
from regluit.frontend.forms import ManageCampaignForm, DonateForm from regluit.frontend.forms import ManageCampaignForm, DonateForm
from regluit.payment.manager import PaymentManager from regluit.payment.manager import PaymentManager
from regluit.payment.parameters import TARGET_TYPE_CAMPAIGN, TARGET_TYPE_DONATION from regluit.payment.parameters import TARGET_TYPE_CAMPAIGN, TARGET_TYPE_DONATION
from regluit.core import goodreads from regluit.core import goodreads
from tastypie.models import ApiKey from tastypie.models import ApiKey
from regluit.payment.models import Transaction
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
from regluit.payment.models import Transaction
def home(request): def home(request):
if request.user.is_authenticated(): if request.user.is_authenticated():
@ -136,19 +135,21 @@ def googlebooks(request, googlebooks_id):
edition = models.Edition.objects.get(googlebooks_id=googlebooks_id) edition = models.Edition.objects.get(googlebooks_id=googlebooks_id)
except models.Edition.DoesNotExist: except models.Edition.DoesNotExist:
edition = bookloader.add_by_googlebooks_id(googlebooks_id) edition = bookloader.add_by_googlebooks_id(googlebooks_id)
# we could populate_edition(edition) to pull in related editions here
# but it is left out for now to lower the amount of traffic on
# googlebooks, librarything and openlibrary
if not edition: if not edition:
return HttpResponseNotFound("invalid googlebooks id") return HttpResponseNotFound("invalid googlebooks id")
tasks.add_related.delay(edition.isbn_10)
work_url = reverse('work', kwargs={'work_id': edition.work.id}) work_url = reverse('work', kwargs={'work_id': edition.work.id})
return HttpResponseRedirect(work_url) return HttpResponseRedirect(work_url)
def subjects(request): def subjects(request):
order = request.GET.get('order') order = request.GET.get('order')
subjects = models.Subject.objects.all() subjects = models.Subject.objects.all()
subjects = subjects.annotate(Count('editions')) subjects = subjects.annotate(Count('works'))
if request.GET.get('order') == 'count': if request.GET.get('order') == 'count':
subjects = subjects.order_by('-editions__count') subjects = subjects.order_by('-works__count')
else: else:
subjects = subjects.order_by('name') subjects = subjects.order_by('name')
@ -558,7 +559,7 @@ def wishlist(request):
if googlebooks_id: if googlebooks_id:
edition = bookloader.add_by_googlebooks_id(googlebooks_id) edition = bookloader.add_by_googlebooks_id(googlebooks_id)
# add related editions asynchronously # add related editions asynchronously
tasks.add_related.delay(edition.isbn_10) tasks.populate_edition.delay(edition)
request.user.wishlist.add_work(edition.work,'user') request.user.wishlist.add_work(edition.work,'user')
# TODO: redirect to work page, when it exists # TODO: redirect to work page, when it exists
return HttpResponseRedirect('/') return HttpResponseRedirect('/')

View File

@ -192,9 +192,6 @@ ul.tabs li a:hover, ul.tabs li.active a {
#js-rightcol .jsmodule { #js-rightcol .jsmodule {
margin-bottom: 10px; margin-bottom: 10px;
} }
#js-rightcol .jsmod-content {
padding-left: 10px;
}
.js-rightcol-pad { .js-rightcol-pad {
border: 1px solid #d6dde0; border: 1px solid #d6dde0;
-moz-border-radius: 10px 10px 10px 10px; -moz-border-radius: 10px 10px 10px 10px;
@ -228,14 +225,56 @@ ul.social li {
height: 28px; height: 28px;
line-height: 28px; line-height: 28px;
} }
ul.social li a {
padding-left: 10px;
}
ul.social li.facebook { ul.social li.facebook {
background: url("/static/images/icons/facebook.png") left center no-repeat; background: url("/static/images/icons/facebook.png") 10px center no-repeat;
}
ul.social li.facebook span {
padding-left: 10px;
}
ul.social li.facebook:hover {
background: #8dc63f url("/static/images/icons/facebook-hover.png") 10px center no-repeat;
}
ul.social li.facebook:hover span {
color: #fff;
} }
ul.social li.twitter { ul.social li.twitter {
background: url("/static/images/icons/twitter.png") left center no-repeat; background: url("/static/images/icons/twitter.png") 10px center no-repeat;
}
ul.social li.twitter span {
padding-left: 10px;
}
ul.social li.twitter:hover {
background: #8dc63f url("/static/images/icons/twitter-hover.png") 10px center no-repeat;
}
ul.social li.twitter:hover span {
color: #fff;
} }
ul.social li.email { ul.social li.email {
background: url("/static/images/icons/email.png") left center no-repeat; background: url("/static/images/icons/email.png") 10px center no-repeat;
}
ul.social li.email span {
padding-left: 10px;
}
ul.social li.email:hover {
background: #8dc63f url("/static/images/icons/email-hover.png") 10px center no-repeat;
}
ul.social li.email:hover span {
color: #fff;
}
ul.social li.embed {
background: url("/static/images/icons/embed.png") 10px center no-repeat;
}
ul.social li.embed span {
padding-left: 10px;
}
ul.social li.embed:hover {
background: #8dc63f url("/static/images/icons/embed-hover.png") 10px center no-repeat;
}
ul.social li.embed:hover span {
color: #fff;
} }
#widgetcode { #widgetcode {
display: none; display: none;

View File

@ -175,16 +175,28 @@ a.my-setting.active {
width: 100%; width: 100%;
} }
#tabs.wantto { #tabs.wantto {
border-bottom: 4px solid #bacfd6; border-bottom: 4px solid #d6dde0;
}
#tabs.wantto ul.tabs li.tabs3.active a {
background: #d6dde0;
color: #3d4e53;
} }
#tabs.ungluing { #tabs.ungluing {
border-bottom: 4px solid #eabc7c; border-bottom: 4px solid #eabc7c;
} }
#tabs.ungluing ul.tabs li.tabs2.active a {
background: #eabc7c;
color: #fff;
}
#tabs.unglued { #tabs.unglued {
border-bottom: 4px solid #a7d26a; border-bottom: 4px solid #8dc63f;
}
#tabs.unglued ul.tabs li.tabs1.active a {
background: #8dc63f;
color: #fff;
} }
#tabs ul.book-list-view { #tabs ul.book-list-view {
margin-bottom: 4px !important; margin-bottom: 0 !important;
} }
#tabs-1, #tabs-2, #tabs-3 { #tabs-1, #tabs-2, #tabs-3 {
margin-left: 10px; margin-left: 10px;
@ -214,13 +226,21 @@ ul.tabs li a {
-moz-border-radius: 7px 7px 0 0; -moz-border-radius: 7px 7px 0 0;
-webkit-border-radius: 7px 7px 0 0; -webkit-border-radius: 7px 7px 0 0;
border-radius: 7px 7px 0 0; border-radius: 7px 7px 0 0;
background: #d6dde0;
color: #3d4e53;
}
ul.tabs li a:hover, ul.tabs li.active a {
background: #6994a3; background: #6994a3;
color: #fff; color: #fff;
} }
ul.tabs li.tabs1 a:hover, ul.tabs li.active a {
background: #8dc63f;
color: #ffffff;
}
ul.tabs li.tabs2 a:hover, ul.tabs li.active a {
background: #eabc7c;
color: #fff;
}
ul.tabs li.tabs3 a:hover, ul.tabs li.active a {
background: #d6dde0;
color: #3d4e53;
}
.book-list span.rounded > span { .book-list span.rounded > span {
line-height: normal; line-height: normal;
width: 75px; width: 75px;

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

View File

@ -5,6 +5,22 @@
border: solid 5px #EDF3F4; border: solid 5px #EDF3F4;
} }
.shareclass(@sharewhere) {
background:url("@{image-base}icons/@{sharewhere}.png") 10px center no-repeat;
span {
padding-left:10px;
}
&:hover {
background:@green url("@{image-base}icons/@{sharewhere}-hover.png") 10px center no-repeat;
span {
color: #fff;
}
}
}
#js-page-wrap { #js-page-wrap {
overflow:hidden; overflow:hidden;
} }
@ -206,10 +222,6 @@ ul.tabs {
.jsmodule { .jsmodule {
margin-bottom:10px; margin-bottom:10px;
} }
.jsmod-content {
padding-left:10px;
}
} }
.js-rightcol-pad { .js-rightcol-pad {
@ -246,17 +258,26 @@ ul.social li {
padding:5px 0 5px 30px; padding:5px 0 5px 30px;
.height(28px); .height(28px);
a {
padding-left: 10px;
}
&.facebook { &.facebook {
background:url("@{image-base}icons/facebook.png") left center no-repeat; .shareclass("facebook");
} }
&.twitter { &.twitter {
background:url("@{image-base}icons/twitter.png") left center no-repeat; .shareclass("twitter");
} }
&.email { &.email {
background:url("@{image-base}icons/email.png") left center no-repeat; .shareclass("email");
} }
&.embed {
.shareclass("embed");
}
} }
#widgetcode { #widgetcode {

View File

@ -200,20 +200,35 @@ a.my-setting.active {
width: 100%; width: 100%;
&.wantto { &.wantto {
border-bottom: 4px solid #bacfd6; border-bottom: 4px solid @blue-grey;
ul.tabs li.tabs3.active a {
background: @blue-grey;
color: @text-blue;
}
} }
&.ungluing { &.ungluing {
border-bottom: 4px solid #eabc7c; border-bottom: 4px solid #eabc7c;
ul.tabs li.tabs2.active a {
background: #eabc7c;
color: #fff;
}
} }
&.unglued { &.unglued {
border-bottom: 4px solid #a7d26a; border-bottom: 4px solid @green;
ul.tabs li.tabs1.active a {
background: @green;
color: #fff;
}
} }
} }
#tabs ul.book-list-view { #tabs ul.book-list-view {
margin-bottom:4px !important; margin-bottom:0 !important;
} }
#tabs-1, #tabs-1,
@ -244,14 +259,24 @@ ul.tabs {
padding:0 10px; padding:0 10px;
min-width:80px; min-width:80px;
.border-radius(7px, 7px, 0, 0); .border-radius(7px, 7px, 0, 0);
background:@blue-grey;
color:@text-blue;
}
a:hover, &.active a {
background:@medium-blue; background:@medium-blue;
color:#fff; color:#fff;
} }
&.tabs1 a:hover, &.active a {
background:@green;
color:#fff
}
&.tabs2 a:hover, &.active a {
background:#eabc7c;
color:#fff;
}
&.tabs3 a:hover, &.active a {
background:@blue-grey;
color:@text-blue;
}
} }
} }