Merge branch 'master' of github.com:Gluejar/regluit
commit
a1561d7f8d
|
@ -74,11 +74,8 @@ Below are the steps for getting regluit running on EC2 with Apache and mod_wsgi,
|
|||
1. `sudo cp deploy/celeryd.conf /etc/default/celeryd`
|
||||
1. `sudo mkdir /var/log/celery`
|
||||
1. `sudo chown celery:celery /var/log/celery`
|
||||
1. `sudo mkdir /var/run/celery`
|
||||
1. `sudo chown celery:celery /var/run/celery`
|
||||
1. `sudo /etc/init.d/celeryd start`
|
||||
|
||||
|
||||
OS X Develper Notes
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -23,21 +23,52 @@ class UserResource(ModelResource):
|
|||
fields = ['username', 'first_name', 'last_name']
|
||||
|
||||
class EditionResource(ModelResource):
|
||||
work = fields.ForeignKey('regluit.api.resources.WorkResource', 'work')
|
||||
identifiers = fields.ToManyField('regluit.api.resources.IdentifierResource', 'identifiers')
|
||||
class Meta:
|
||||
authentication = ApiKeyAuthentication()
|
||||
queryset = models.Edition.objects.all()
|
||||
resource_name = 'edition'
|
||||
filtering = {
|
||||
"isbn_13": ALL,
|
||||
"isbn_13": ALL, "identifiers": ALL_WITH_RELATIONS,
|
||||
}
|
||||
|
||||
def build_filters(self, filters = None):
|
||||
if filters is None:
|
||||
filters = {}
|
||||
for filter_expr, value in filters.items():
|
||||
if filter_expr.startswith('isbn_13'):
|
||||
filters['identifiers__type'] = 'isbn'
|
||||
if len(filter_expr)>7:
|
||||
filters['identifiers__value'+filter_expr[7:]] = value
|
||||
else:
|
||||
filters['identifiers__value'] = value
|
||||
del filters[ filter_expr ]
|
||||
return super(EditionResource, self).build_filters(filters)
|
||||
|
||||
class IdentifierResource(ModelResource):
|
||||
work = fields.ForeignKey('regluit.api.resources.WorkResource', 'work')
|
||||
edition = fields.ForeignKey('regluit.api.resources.EditionResource', 'edition')
|
||||
|
||||
class Meta:
|
||||
authentication = ApiKeyAuthentication()
|
||||
queryset = models.Identifier.objects.all()
|
||||
resource_name = 'identifier'
|
||||
filtering = {
|
||||
"value": ALL, "type" : ALL,
|
||||
}
|
||||
|
||||
|
||||
|
||||
class WorkResource(ModelResource):
|
||||
editions = fields.ToManyField(EditionResource, 'editions')
|
||||
identifiers = fields.ToManyField(IdentifierResource, 'identifiers')
|
||||
|
||||
class Meta:
|
||||
authentication = ApiKeyAuthentication()
|
||||
queryset = models.Work.objects.all()
|
||||
resource_name = 'work'
|
||||
filtering = {'editions': ALL_WITH_RELATIONS, 'id': ALL}
|
||||
filtering = {'editions': ALL_WITH_RELATIONS, 'id': ALL, 'identifiers': ALL_WITH_RELATIONS}
|
||||
|
||||
class CampaignResource(ModelResource):
|
||||
work = fields.ToOneField(WorkResource, 'work')
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
{% if user.is_authenticated %}
|
||||
<h3>Campaign info</h3>
|
||||
<p>JSON to get data on all campaigns</p>
|
||||
<a href="/api/v1/campaign/?format=json&api_key={{api_key}}&username={{user.username}}">{{base_url}}/api/v1/campaign/?format=json&api_key={api_key}&username={username}</a>
|
||||
<a href="/api/v1/campaign/?format=json&api_key={{api_key}}&username={{user.username}}">{{base_url}}/api/v1/campaign/?format=json&api_key={api_key}&username={username}</a>
|
||||
<h3>Identifier Resolution</h3>
|
||||
<p>JSON to get work/edition data for an isbn</p>
|
||||
<a href="/api/v1/identifier/?format=json&api_key={{api_key}}&type=isbn&value=9780441012039">{{base_url}}/api/v1/identifier/?format=json&api_key={api_key}&ype=isbn&value=9780441012039</a>
|
||||
<p> In addition to isbn, you can use 'goog' if you have a google books id, and 'oclc' for oclc numbers.</p>
|
||||
{% endif %}
|
||||
|
||||
<h3>Campaign Widgets</h3>
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<!--- editions --->
|
||||
|
||||
{% if work %}
|
||||
{% with work.editions.all.0.googlebooks_id as googlebooks_id %}
|
||||
{% with work.googlebooks_id as googlebooks_id %}
|
||||
{% include "book_panel.html" %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
|
|
13
api/tests.py
13
api/tests.py
|
@ -12,7 +12,7 @@ import regluit.core.isbn
|
|||
class ApiTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
edition = bookloader.add_by_isbn(isbn='0441012035')
|
||||
edition = bookloader.add_by_isbn_from_google(isbn='0441012035')
|
||||
campaign = models.Campaign.objects.create(
|
||||
name=edition.work.title,
|
||||
work=edition.work,
|
||||
|
@ -57,7 +57,8 @@ class ApiTests(TestCase):
|
|||
def test_campaign_lookup_by_isbn(self):
|
||||
r = self.client.get('/api/v1/campaign/', data={
|
||||
'format': 'json',
|
||||
'work__editions__isbn_13': regluit.core.isbn.convert_10_to_13('0441012035'),
|
||||
'work__identifiers__value': regluit.core.isbn.convert_10_to_13('0441012035'),
|
||||
'work__identifiers__type': 'isbn',
|
||||
'username': self.user.username,
|
||||
'api_key': self.user.api_key.key
|
||||
})
|
||||
|
@ -75,7 +76,8 @@ class ApiTests(TestCase):
|
|||
|
||||
r = self.client.get('/api/v1/campaign/', data={
|
||||
'format': 'json',
|
||||
'work__editions__isbn_13': regluit.core.isbn.convert_10_to_13('0441012035'),
|
||||
'work__identifiers__value': regluit.core.isbn.convert_10_to_13('0441012035'),
|
||||
'work__identifiers__type': 'isbn',
|
||||
'username': self.user.username,
|
||||
'api_key': self.user.api_key.key
|
||||
})
|
||||
|
@ -83,11 +85,12 @@ class ApiTests(TestCase):
|
|||
self.assertEqual(j['meta']['logged_in_username'], 'test')
|
||||
self.assertEqual(j['objects'][0]['in_wishlist'], False)
|
||||
|
||||
w = models.Work.objects.get(editions__isbn_13=regluit.core.isbn.convert_10_to_13('0441012035'))
|
||||
w = models.Work.objects.get(identifiers__value=regluit.core.isbn.convert_10_to_13('0441012035'), identifiers__type='isbn')
|
||||
self.user.wishlist.add_work(w,'test')
|
||||
r = self.client.get('/api/v1/campaign/', data={
|
||||
'format': 'json',
|
||||
'work__editions__isbn_13': regluit.core.isbn.convert_10_to_13('0441012035'),
|
||||
'work__identifiers__value': regluit.core.isbn.convert_10_to_13('0441012035'),
|
||||
'work__identifiers__type': 'isbn',
|
||||
'username': self.user.username,
|
||||
'api_key': self.user.api_key.key
|
||||
})
|
||||
|
|
|
@ -8,6 +8,7 @@ from regluit.api import resources
|
|||
v1_api = Api(api_name='v1')
|
||||
v1_api.register(resources.UserResource())
|
||||
v1_api.register(resources.WorkResource())
|
||||
v1_api.register(resources.IdentifierResource())
|
||||
v1_api.register(resources.EditionResource())
|
||||
v1_api.register(resources.CampaignResource())
|
||||
v1_api.register(resources.AuthorResource())
|
||||
|
|
36
api/views.py
36
api/views.py
|
@ -13,9 +13,11 @@ from tastypie.models import ApiKey
|
|||
def isbn(request,isbn):
|
||||
if len(isbn)==10:
|
||||
isbn=regluit.core.isbn.convert_10_to_13(isbn)
|
||||
editions = models.Edition.objects.filter( Q(isbn_13 = isbn))
|
||||
# models.Campaign.objects.filter(work__editions__isbn_13='9780811216999')
|
||||
|
||||
try:
|
||||
edition = models.Identifier.objects.get( Q(type = 'isbn', value = isbn)).edition
|
||||
editions = [edition]
|
||||
except models.Identifier.DoesNotExist:
|
||||
editions = []
|
||||
return render_to_response('isbn.html',
|
||||
{'isbn':isbn, 'editions':editions},
|
||||
context_instance=RequestContext(request)
|
||||
|
@ -44,23 +46,14 @@ def widget(request,isbn):
|
|||
Current implementation is to supply info for current book panel design
|
||||
"""
|
||||
|
||||
# presumably 0 or 1 Edition will match
|
||||
if len(isbn)==10:
|
||||
isbn=regluit.core.isbn.convert_10_to_13(isbn)
|
||||
editions = models.Edition.objects.filter( Q(isbn_13 = isbn))
|
||||
# if 1 edition: should be 0 or 1 corresponding Work
|
||||
# for 1 Work, there will be a Campaign or not
|
||||
assert len(editions) < 2
|
||||
|
||||
if len(editions):
|
||||
edition = editions[0]
|
||||
try:
|
||||
work = edition.work
|
||||
campaigns = work.campaigns.all()
|
||||
except Exception, e:
|
||||
work = None
|
||||
campaigns = []
|
||||
else:
|
||||
isbn = regluit.core.isbn.convert_10_to_13(isbn)
|
||||
try:
|
||||
identifier = models.Identifier.objects.get( Q( type = 'isbn', value = isbn ))
|
||||
work = identifier.work
|
||||
edition = identifier.edition
|
||||
campaigns = work.campaigns.all()
|
||||
except models.Identifer.DoesNotExist:
|
||||
edition = None
|
||||
work = None
|
||||
campaigns = []
|
||||
|
@ -104,10 +97,7 @@ class ApiHelpView(TemplateView):
|
|||
campaigns = models.Campaign.objects.all()
|
||||
if len(campaigns):
|
||||
c = campaigns[0]
|
||||
try:
|
||||
isbn = c.work.editions.all()[0].isbn_13
|
||||
except IndexError:
|
||||
isbn = ''
|
||||
isbn = c.work.first_isbn_13
|
||||
context["campaign"] = campaigns[0]
|
||||
context["campaign_isbn"] = isbn
|
||||
|
||||
|
|
|
@ -15,44 +15,85 @@ import regluit.core.isbn
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def add_by_oclc(oclc):
|
||||
logger.info("adding book by oclc %s", oclc)
|
||||
for edition in models.Edition.objects.filter(oclc=oclc):
|
||||
return edition
|
||||
def add_by_oclc(isbn, work=None):
|
||||
# this is indirection in case we have a data source other than google
|
||||
return add_by_oclc_from_google(isbn)
|
||||
|
||||
url = "https://www.googleapis.com/books/v1/volumes"
|
||||
results = _get_json(url, {"q": '"OCLC%s"' % oclc})
|
||||
|
||||
if not results.has_key('items') or len(results['items']) == 0:
|
||||
logger.warn("no google hits for %s" % oclc)
|
||||
def add_by_oclc_from_google(oclc):
|
||||
if oclc:
|
||||
logger.info("adding book by oclc %s" , oclc)
|
||||
else:
|
||||
return None
|
||||
try:
|
||||
return models.Identifier.objects.get(type='oclc', value=oclc).edition
|
||||
except:
|
||||
url = "https://www.googleapis.com/books/v1/volumes"
|
||||
results = _get_json(url, {"q": '"OCLC%s"' % oclc})
|
||||
|
||||
if not results.has_key('items') or len(results['items']) == 0:
|
||||
logger.warn("no google hits for %s" , oclc)
|
||||
return None
|
||||
|
||||
try:
|
||||
e = add_by_googlebooks_id(results['items'][0]['id'], results=results['items'][0])
|
||||
models.Identifier(type='oclc', value=oclc, edition=e, work=e.work).save()
|
||||
return e
|
||||
except LookupFailure, e:
|
||||
logger.exception("failed to add edition for %s", oclc)
|
||||
except IntegrityError, e:
|
||||
logger.exception("google books data for %s didn't fit our db", oclc)
|
||||
return None
|
||||
|
||||
try:
|
||||
e = add_by_googlebooks_id(results['items'][0]['id'])
|
||||
e.oclc = oclc
|
||||
e.save()
|
||||
return e
|
||||
except LookupFailure, e:
|
||||
logger.exception("failed to add edition for %s", oclc)
|
||||
except IntegrityError, e:
|
||||
logger.exception("google books data for %s didn't fit our db", oclc)
|
||||
return None
|
||||
|
||||
|
||||
def add_by_isbn(isbn, work=None):
|
||||
"""add a book to the UnglueIt database based on ISBN. The work parameter
|
||||
if not isbn:
|
||||
return None
|
||||
e = add_by_isbn_from_google(isbn, work=work)
|
||||
if e:
|
||||
return e
|
||||
|
||||
logger.info("null came back from add_by_isbn_from_google: %s", isbn)
|
||||
|
||||
if not work or not work.title:
|
||||
return None
|
||||
|
||||
# if there's a work with a title, we want to create stub editions and
|
||||
# works, even if google doesn't know about it # but if it's not valid,
|
||||
# forget it!
|
||||
|
||||
try:
|
||||
isbn = regluit.core.isbn.ISBN(isbn)
|
||||
except:
|
||||
logger.exception("invalid isbn: %s", isbn)
|
||||
return None
|
||||
if not isbn.valid:
|
||||
return None
|
||||
isbn = isbn.to_string()
|
||||
|
||||
# we don't know the language ->'xx'
|
||||
w = models.Work(title=work.title, language='xx')
|
||||
w.save()
|
||||
e = models.Edition(title=work.title,work=w)
|
||||
e.save()
|
||||
e.new = True
|
||||
models.Identifier(type='isbn', value=isbn, work=w, edition=e).save()
|
||||
return e
|
||||
|
||||
|
||||
def add_by_isbn_from_google(isbn, work=None):
|
||||
"""add a book to the UnglueIt database from google based on ISBN. The work parameter
|
||||
is optional, and if not supplied the edition will be associated with
|
||||
a stub work.
|
||||
"""
|
||||
if not isbn:
|
||||
return None
|
||||
if len(isbn)==10:
|
||||
isbn=regluit.core.isbn.convert_10_to_13(isbn)
|
||||
isbn = regluit.core.isbn.convert_10_to_13(isbn)
|
||||
|
||||
logger.info("adding book by isbn %s", isbn)
|
||||
# save a lookup to google if we already have this isbn
|
||||
has_isbn = Q(isbn_13=isbn)
|
||||
for edition in models.Edition.objects.filter(has_isbn):
|
||||
# check if we already have this isbn
|
||||
edition = get_edition_by_id(type='isbn',value=isbn)
|
||||
if edition:
|
||||
edition.new = False
|
||||
return edition
|
||||
|
||||
|
@ -60,58 +101,89 @@ def add_by_isbn(isbn, work=None):
|
|||
results = _get_json(url, {"q": "isbn:%s" % isbn})
|
||||
|
||||
if not results.has_key('items') or len(results['items']) == 0:
|
||||
logger.warn("no google hits for %s" % isbn)
|
||||
logger.warn("no google hits for %s" , isbn)
|
||||
return None
|
||||
|
||||
try:
|
||||
return add_by_googlebooks_id(results['items'][0]['id'], work)
|
||||
return add_by_googlebooks_id(results['items'][0]['id'], work=work, results=results['items'][0])
|
||||
except LookupFailure, e:
|
||||
logger.exception("failed to add edition for %s", isbn)
|
||||
except IntegrityError, e:
|
||||
logger.exception("google books data for %s didn't fit our db", isbn)
|
||||
return None
|
||||
|
||||
def get_work_by_id(type,value):
|
||||
if value:
|
||||
try:
|
||||
return models.Identifier.objects.get(type=type,value=value).work
|
||||
except models.Identifier.DoesNotExist:
|
||||
return None
|
||||
|
||||
def add_by_googlebooks_id(googlebooks_id, work=None):
|
||||
def get_edition_by_id(type,value):
|
||||
if value:
|
||||
try:
|
||||
return models.Identifier.objects.get(type=type,value=value).edition
|
||||
except models.Identifier.DoesNotExist:
|
||||
return None
|
||||
|
||||
|
||||
def add_by_googlebooks_id(googlebooks_id, work=None, results=None):
|
||||
"""add a book to the UnglueIt database based on the GoogleBooks ID. The
|
||||
work parameter is optional, and if not supplied the edition will be
|
||||
associated with a stub work.
|
||||
associated with a stub work.
|
||||
|
||||
"""
|
||||
|
||||
# don't ping google again if we already know about the edition
|
||||
try:
|
||||
e = models.Edition.objects.get(googlebooks_id=googlebooks_id)
|
||||
return e
|
||||
except models.Edition.DoesNotExist:
|
||||
return models.Identifier.objects.get(type='goog', value=googlebooks_id).edition
|
||||
except models.Identifier.DoesNotExist:
|
||||
pass
|
||||
|
||||
logger.info("loading metadata from google for %s", googlebooks_id)
|
||||
url = "https://www.googleapis.com/books/v1/volumes/%s" % googlebooks_id
|
||||
item = _get_json(url)
|
||||
|
||||
# if google has been queried by caller, don't call again
|
||||
if results:
|
||||
item =results
|
||||
else:
|
||||
logger.info("loading metadata from google for %s", googlebooks_id)
|
||||
url = "https://www.googleapis.com/books/v1/volumes/%s" % googlebooks_id
|
||||
item = _get_json(url)
|
||||
d = item['volumeInfo']
|
||||
|
||||
# don't add the edition to a work with a different language
|
||||
# https://www.pivotaltracker.com/story/show/17234433
|
||||
language = d.get('language')
|
||||
language = d['language']
|
||||
if work and work.language != language:
|
||||
logger.warn("ignoring %s since it is %s instead of %s" %
|
||||
logger.info("not connecting %s since it is %s instead of %s" %
|
||||
(googlebooks_id, language, work.language))
|
||||
return
|
||||
|
||||
e = models.Edition(googlebooks_id=googlebooks_id)
|
||||
work = None
|
||||
isbn = None
|
||||
for i in d.get('industryIdentifiers', []):
|
||||
if i['type'] == 'ISBN_10' and not isbn:
|
||||
isbn = regluit.core.isbn.convert_10_to_13(i['identifier'])
|
||||
elif i['type'] == 'ISBN_13':
|
||||
isbn = i['identifier']
|
||||
|
||||
# now check to see if there's an existing Work
|
||||
if not work:
|
||||
work = get_work_by_id(type='isbn',value=isbn)
|
||||
if not work:
|
||||
work = models.Work.objects.create(title=d['title'], language=language)
|
||||
work.new = True
|
||||
work.save()
|
||||
|
||||
|
||||
# because this is a new google id, we have to create a new edition
|
||||
e = models.Edition(work=work)
|
||||
e.title = d.get('title')
|
||||
e.description = d.get('description')
|
||||
e.publisher = d.get('publisher')
|
||||
e.publication_date = d.get('publishedDate', '')
|
||||
|
||||
for i in d.get('industryIdentifiers', []):
|
||||
if i['type'] == 'ISBN_13':
|
||||
e.isbn_13 = i['identifier']
|
||||
elif i['type'] == 'ISBN_13':
|
||||
e.isbn_13 = i['identifier']
|
||||
|
||||
e.save()
|
||||
e.new=True
|
||||
e.new = True
|
||||
|
||||
# create identifier where needed
|
||||
models.Identifier(type='goog',value=googlebooks_id,edition=e,work=work).save()
|
||||
if isbn:
|
||||
models.Identifier.get_or_add(type='isbn',value=isbn,edition=e,work=work)
|
||||
|
||||
for a in d.get('authors', []):
|
||||
a, created = models.Author.objects.get_or_create(name=a)
|
||||
|
@ -133,16 +205,7 @@ def add_by_googlebooks_id(googlebooks_id, work=None):
|
|||
url=pdf.get('downloadLink', None),
|
||||
provider='google')
|
||||
ebook.save()
|
||||
|
||||
# if we know what work the edition should be attached to, attach it
|
||||
if work:
|
||||
work.editions.add(e)
|
||||
|
||||
# otherwise we need to create a stub work
|
||||
else:
|
||||
w = models.Work.objects.create(title=e.title, language=language)
|
||||
w.editions.add(e)
|
||||
|
||||
|
||||
return e
|
||||
|
||||
|
||||
|
@ -156,26 +219,42 @@ def add_related(isbn):
|
|||
|
||||
# this is the work everything will hang off
|
||||
work = edition.work
|
||||
|
||||
new_editions = []
|
||||
other_editions = {}
|
||||
for other_isbn in thingisbn(isbn):
|
||||
# 979's come back as 13
|
||||
if len(other_isbn)==10:
|
||||
other_isbn=regluit.core.isbn.convert_10_to_13(other_isbn)
|
||||
related_edition = add_by_isbn(other_isbn, work)
|
||||
if related_edition and related_edition.work != edition.work:
|
||||
merge_works(edition.work, related_edition.work)
|
||||
other_isbn = regluit.core.isbn.convert_10_to_13(other_isbn)
|
||||
related_edition = add_by_isbn(other_isbn, work=work)
|
||||
|
||||
if related_edition:
|
||||
new_editions.append(related_edition)
|
||||
related_language = related_edition.work.language
|
||||
if edition.work.language == related_language:
|
||||
new_editions.append(related_edition)
|
||||
if related_edition.work != edition.work:
|
||||
merge_works(edition.work, related_edition.work)
|
||||
else:
|
||||
if other_editions.has_key(related_language):
|
||||
other_editions[related_language].append(related_edition)
|
||||
else:
|
||||
other_editions[related_language]=[related_edition]
|
||||
|
||||
# group the other language editions together
|
||||
for lang_group in other_editions.itervalues():
|
||||
if len(lang_group)>1:
|
||||
lang_edition = lang_group[0]
|
||||
for related_edition in lang_group[1:]:
|
||||
if lang_edition.work != related_edition.work:
|
||||
merge_works(lang_edition.work, related_edition.work)
|
||||
|
||||
return new_editions
|
||||
|
||||
|
||||
|
||||
def thingisbn(isbn):
|
||||
"""given an ISBN return a list of related edition ISBNs, according to
|
||||
Library Thing. (takes isbn_10 or isbn_13, returns isbn_10, except for 979 isbns, which come back as isbn_13')
|
||||
"""
|
||||
logger.info("looking up %s at ThingISBN" % isbn)
|
||||
logger.info("looking up %s at ThingISBN" , isbn)
|
||||
url = "http://www.librarything.com/api/thingISBN/%s" % isbn
|
||||
xml = requests.get(url, headers={"User-Agent": settings.USER_AGENT}).content
|
||||
doc = ElementTree.fromstring(xml)
|
||||
|
@ -185,7 +264,10 @@ def thingisbn(isbn):
|
|||
def merge_works(w1, w2):
|
||||
"""will merge the second work (w2) into the first (w1)
|
||||
"""
|
||||
logger.info("merging work %s into %s", w1, w2)
|
||||
logger.info("merging work %s into %s", w2, w1)
|
||||
for identifier in w2.identifiers.all():
|
||||
identifier.work = w1
|
||||
identifier.save()
|
||||
for edition in w2.editions.all():
|
||||
edition.work = w1
|
||||
edition.save()
|
||||
|
@ -193,7 +275,7 @@ def merge_works(w1, w2):
|
|||
campaign.work = w1
|
||||
campaign.save()
|
||||
for wishlist in models.Wishlist.objects.filter(works__in=[w2]):
|
||||
w2source=wishlist.work_source(w2)
|
||||
w2source = wishlist.work_source(w2)
|
||||
wishlist.remove_work(w2)
|
||||
wishlist.add_work(w1, w2source)
|
||||
# TODO: should we decommission w2 instead of deleting it, so that we can
|
||||
|
@ -202,6 +284,10 @@ def merge_works(w1, w2):
|
|||
|
||||
|
||||
def add_openlibrary(work):
|
||||
if work.openlibrary_lookup is not None:
|
||||
# don't hit OL if we've visited in the past month or so
|
||||
if datetime.datetime.now()- work.openlibrary_lookup < datetime.timedelta(days=30):
|
||||
return
|
||||
work.openlibrary_lookup = datetime.datetime.now()
|
||||
work.save()
|
||||
|
||||
|
@ -217,11 +303,11 @@ def add_openlibrary(work):
|
|||
for edition in work.editions.all():
|
||||
isbn_key = "ISBN:%s" % edition.isbn_13
|
||||
params['bibkeys'] = isbn_key
|
||||
e = _get_json(url, params)
|
||||
e = _get_json(url, params, type='ol')
|
||||
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)
|
||||
w = _get_json("http://openlibrary.org" + work_key,type='ol')
|
||||
if w.has_key('subjects'):
|
||||
found = True
|
||||
break
|
||||
|
@ -235,24 +321,32 @@ def add_openlibrary(work):
|
|||
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()
|
||||
|
||||
models.Identifier.get_or_add(type='olwk',value=w['key'],work=work)
|
||||
if e[isbn_key]['details'].has_key('identifiers'):
|
||||
ids = e[isbn_key]['details']['identifiers']
|
||||
if ids.has_key('goodreads'):
|
||||
models.Identifier.get_or_add(type='gdrd',value=ids['goodreads'][0],work=work,edition=edition)
|
||||
if ids.has_key('librarything'):
|
||||
models.Identifier.get_or_add(type='ltwk',value=ids['librarything'][0],work=work)
|
||||
# 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={}, type='gb'):
|
||||
# TODO: should X-Forwarded-For change based on the request from client?
|
||||
headers = {'User-Agent': settings.USER_AGENT,
|
||||
'Accept': 'application/json',
|
||||
'X-Forwarded-For': '69.174.114.214'}
|
||||
params['key'] = settings.GOOGLE_BOOKS_API_KEY
|
||||
if type == 'gb':
|
||||
params['key'] = settings.GOOGLE_BOOKS_API_KEY
|
||||
response = requests.get(url, params=params, headers=headers)
|
||||
if response.status_code == 200:
|
||||
return json.loads(response.content)
|
||||
else:
|
||||
logger.error("unexpected HTTP response: %s" % response)
|
||||
if response.content:
|
||||
logger.error("response content: %s" % response.content)
|
||||
raise LookupFailure("GET failed: url=%s and params=%s" % (url, params))
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import django.utils.encoding
|
|||
|
||||
import regluit.core
|
||||
from regluit.core import bookloader
|
||||
from regluit.core import models
|
||||
|
||||
# import parse_qsl from cgi if it doesn't exist in urlparse
|
||||
try:
|
||||
|
@ -286,8 +287,7 @@ def load_goodreads_shelf_into_wishlist(user, shelf_name='all', goodreads_user_id
|
|||
link = review['book']['link']
|
||||
match = re.search('/show/(\d+)', link)
|
||||
if match:
|
||||
edition.goodreads_id = match.group(1)
|
||||
edition.save()
|
||||
identifier= models.Identifier.get_or_add(type = 'gdrd', value = match.group(1), edition = edition, work = edition.work)
|
||||
user.wishlist.add_work(edition.work, 'goodreads')
|
||||
logger.info("Work with isbn %s added to wishlist.", isbn)
|
||||
else:
|
||||
|
|
|
@ -6,6 +6,7 @@ import HTMLParser
|
|||
import logging
|
||||
import re
|
||||
from datetime import datetime
|
||||
from regluit.core import models
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -214,10 +215,9 @@ def load_librarything_into_wishlist(user, lt_username, max_books=None):
|
|||
if not edition:
|
||||
continue
|
||||
# add the librarything ids to the db since we know them now
|
||||
edition.librarything_id = book['book_id']
|
||||
edition.save()
|
||||
edition.work.librarything_id = book['work_id']
|
||||
edition.work.save()
|
||||
identifier= models.Identifier.get_or_add(type = 'thng', value = book['book_id'], edition = edition, work = edition.work)
|
||||
identifier= models.Identifier.get_or_add(type = 'ltwk', value = book['work_id'], work = edition.work)
|
||||
|
||||
user.wishlist.add_work(edition.work, 'librarything')
|
||||
if edition.new:
|
||||
regluit.core.tasks.populate_edition.delay(edition)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
from django.core.management.base import BaseCommand
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from regluit.core import bookloader
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "populate a user's wishlist with books from a file of isbns"
|
||||
args = "<filename> <username>"
|
||||
|
||||
def handle(self, filename, username, **options):
|
||||
user = User.objects.get(username=username)
|
||||
wishlist = user.wishlist
|
||||
for isbn in open(filename):
|
||||
isbn = isbn.strip()
|
||||
edition = bookloader.add_by_isbn(isbn)
|
||||
bookloader.add_related(isbn)
|
||||
if edition:
|
||||
user.wishlist.add_work(edition.work, source="user")
|
||||
print "loaded %s as %s for %s" % (isbn, edition, user)
|
||||
else:
|
||||
print "failed to load book for %s" % isbn
|
|
@ -1,19 +0,0 @@
|
|||
from django.db.models import Count
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from regluit.core import models
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "remove duplicates"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
q = models.Edition.objects.values("googlebooks_id")
|
||||
q = q.annotate(Count("googlebooks_id"))
|
||||
for r in q:
|
||||
if r['googlebooks_id__count'] == 1:
|
||||
continue
|
||||
gb = r['googlebooks_id']
|
||||
editions = models.Edition.objects.filter(googlebooks_id=gb)
|
||||
for e in editions[1:]:
|
||||
print "removing duplicate edition: %s" % e
|
||||
e.delete()
|
|
@ -0,0 +1,254 @@
|
|||
# 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 'Identifier'
|
||||
db.create_table('core_identifier', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('type', self.gf('django.db.models.fields.CharField')(max_length=4)),
|
||||
('value', self.gf('django.db.models.fields.CharField')(max_length=31)),
|
||||
('work', self.gf('django.db.models.fields.related.ForeignKey')(related_name='identifiers', to=orm['core.Work'])),
|
||||
('edition', self.gf('django.db.models.fields.related.ForeignKey')(related_name='identifiers', null=True, to=orm['core.Edition'])),
|
||||
))
|
||||
db.send_create_signal('core', ['Identifier'])
|
||||
|
||||
# Adding unique constraint on 'Identifier', fields ['type', 'value']
|
||||
db.create_unique('core_identifier', ['type', 'value'])
|
||||
|
||||
# migrating data
|
||||
if not db.dry_run:
|
||||
for work in orm.Work.objects.all():
|
||||
if work.librarything_id:
|
||||
identifier = orm.Identifier.objects.create(type='ltwk',value=work.librarything_id, work=work)
|
||||
identifier.save()
|
||||
if work.openlibrary_id:
|
||||
identifier = orm.Identifier.objects.create(type='olwk',value=work.openlibrary_id, work=work)
|
||||
identifier.save()
|
||||
for edition in work.editions.all():
|
||||
if edition.googlebooks_id:
|
||||
identifier = orm.Identifier.objects.create(type='goog',value=edition.googlebooks_id, work=work, edition=edition)
|
||||
identifier.save()
|
||||
if edition.goodreads_id:
|
||||
identifier = orm.Identifier.objects.create(type='gdrd',value=edition.goodreads_id, work=work, edition=edition)
|
||||
identifier.save()
|
||||
if edition.librarything_id:
|
||||
identifier = orm.Identifier.objects.create(type='thng',value=edition.librarything_id, work=work, edition=edition)
|
||||
identifier.save()
|
||||
if edition.isbn_13:
|
||||
identifier = orm.Identifier.objects.create(type='isbn',value=edition.isbn_13, work=work, edition=edition)
|
||||
identifier.save()
|
||||
if edition.oclc:
|
||||
identifier = orm.Identifier.objects.create(type='oclc',value=edition.oclc, work=work, edition=edition)
|
||||
identifier.save()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Removing unique constraint on 'Identifier', fields ['type', 'value']
|
||||
db.delete_unique('core_identifier', ['type', 'value'])
|
||||
|
||||
# Deleting model 'Identifier'
|
||||
db.delete_table('core_identifier')
|
||||
|
||||
|
||||
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(2012, 1, 7, 17, 53, 55, 504045)', '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', [], {'unique': 'True', 'max_length': '50'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': '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.identifier': {
|
||||
'Meta': {'unique_together': "(('type', 'value'),)", 'object_name': 'Identifier'},
|
||||
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'null': 'True', 'to': "orm['core.Edition']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '31'}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", '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': {'ordering': "['name']", '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']
|
|
@ -0,0 +1,267 @@
|
|||
# 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 'Work.librarything_id'
|
||||
db.delete_column('core_work', 'librarything_id')
|
||||
|
||||
# Deleting field 'Work.openlibrary_id'
|
||||
db.delete_column('core_work', 'openlibrary_id')
|
||||
|
||||
# Deleting field 'Edition.oclc'
|
||||
db.delete_column('core_edition', 'oclc')
|
||||
|
||||
# Deleting field 'Edition.isbn_13'
|
||||
db.delete_column('core_edition', 'isbn_13')
|
||||
|
||||
# Deleting field 'Edition.goodreads_id'
|
||||
db.delete_column('core_edition', 'goodreads_id')
|
||||
|
||||
# Deleting field 'Edition.googlebooks_id'
|
||||
db.delete_column('core_edition', 'googlebooks_id')
|
||||
|
||||
# Deleting field 'Edition.librarything_id'
|
||||
db.delete_column('core_edition', 'librarything_id')
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Adding field 'Work.librarything_id'
|
||||
db.add_column('core_work', 'librarything_id', self.gf('django.db.models.fields.CharField')(max_length=50, null=True), keep_default=False)
|
||||
|
||||
# Adding field 'Work.openlibrary_id'
|
||||
db.add_column('core_work', 'openlibrary_id', self.gf('django.db.models.fields.CharField')(max_length=50, null=True), keep_default=False)
|
||||
|
||||
# Adding field 'Edition.oclc'
|
||||
db.add_column('core_edition', 'oclc', self.gf('django.db.models.fields.CharField')(max_length=25, null=True), keep_default=False)
|
||||
|
||||
# Adding field 'Edition.isbn_13'
|
||||
db.add_column('core_edition', 'isbn_13', self.gf('django.db.models.fields.CharField')(max_length=13, null=True), keep_default=False)
|
||||
|
||||
# Adding field 'Edition.goodreads_id'
|
||||
db.add_column('core_edition', 'goodreads_id', self.gf('django.db.models.fields.CharField')(max_length=50, null=True), keep_default=False)
|
||||
|
||||
# Adding field 'Edition.googlebooks_id'
|
||||
db.add_column('core_edition', 'googlebooks_id', self.gf('django.db.models.fields.CharField')(default='0', max_length=50, unique=True), keep_default=False)
|
||||
|
||||
# Adding field 'Edition.librarything_id'
|
||||
db.add_column('core_edition', 'librarything_id', self.gf('django.db.models.fields.CharField')(max_length=50, null=True), keep_default=False)
|
||||
|
||||
# migrating data
|
||||
if not db.dry_run:
|
||||
|
||||
for identifier in orm.Identifier.objects.all():
|
||||
if identifier.type=='ltwk':
|
||||
identifier.work.librarything_id = identifier.value
|
||||
identifier.work.save()
|
||||
elif identifier.type=='olwk':
|
||||
identifier.work.openlibrary_id = identifier.value
|
||||
identifier.work.save()
|
||||
elif identifier.type=='goog':
|
||||
identifier.edition.googlebooks_id = identifier.value
|
||||
identifier.edition.save()
|
||||
elif identifier.type=='gdrd':
|
||||
identifier.edition.goodreads_id = identifier.value
|
||||
identifier.edition.save()
|
||||
elif identifier.type=='thng':
|
||||
identifier.edition.librarything_id = identifier.value
|
||||
identifier.edition.save()
|
||||
elif identifier.type=='isbn':
|
||||
identifier.edition.isbn_13 = identifier.value
|
||||
identifier.edition.save()
|
||||
elif identifier.type=='oclc':
|
||||
identifier.edition.oclc = identifier.value
|
||||
identifier.edition.save()
|
||||
|
||||
|
||||
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(2012, 1, 7, 21, 27, 56, 524980)', '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'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': '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.identifier': {
|
||||
'Meta': {'unique_together': "(('type', 'value'),)", 'object_name': 'Identifier'},
|
||||
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'null': 'True', 'to': "orm['core.Edition']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '31'}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", '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': {'ordering': "['name']", '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'}),
|
||||
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['core']
|
|
@ -0,0 +1,211 @@
|
|||
# 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 'Edition.publisher'
|
||||
db.alter_column('core_edition', 'publisher', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
|
||||
|
||||
# Changing field 'Edition.publication_date'
|
||||
db.alter_column('core_edition', 'publication_date', self.gf('django.db.models.fields.CharField')(max_length=50, null=True))
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Changing field 'Edition.publisher'
|
||||
db.alter_column('core_edition', 'publisher', self.gf('django.db.models.fields.CharField')(default='', max_length=255))
|
||||
|
||||
# Changing field 'Edition.publication_date'
|
||||
db.alter_column('core_edition', 'publication_date', self.gf('django.db.models.fields.CharField')(default=datetime.date(1901, 1, 1), max_length=50))
|
||||
|
||||
|
||||
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(2012, 1, 16, 14, 5, 44, 457292)', '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'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'public_domain': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'publication_date': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}),
|
||||
'publisher': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'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.identifier': {
|
||||
'Meta': {'unique_together': "(('type', 'value'),)", 'object_name': 'Identifier'},
|
||||
'edition': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", 'null': 'True', 'to': "orm['core.Edition']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'type': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
|
||||
'value': ('django.db.models.fields.CharField', [], {'max_length': '31'}),
|
||||
'work': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'identifiers'", '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': {'ordering': "['name']", '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', [], {'related_name': "'wishes'", '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'}),
|
||||
'openlibrary_lookup': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['core']
|
150
core/models.py
150
core/models.py
|
@ -198,7 +198,7 @@ class Campaign(models.Model):
|
|||
return self
|
||||
|
||||
def supporters(self):
|
||||
"""nb: returns (distinct) supporter IDs, not supporter objects"""
|
||||
"""nb: returns (distinct) supporter IDs, not supporter objects"""
|
||||
translist = self.transactions().values_list('user', flat=True).distinct()
|
||||
return translist
|
||||
|
||||
|
@ -208,12 +208,29 @@ class Campaign(models.Model):
|
|||
if premiums.count() == 0:
|
||||
premiums = Premium.objects.filter(campaign__isnull=True)
|
||||
return premiums
|
||||
|
||||
class Identifier(models.Model):
|
||||
# olib, ltwk, goog, gdrd, thng, isbn, oclc, olwk, olib
|
||||
type = models.CharField(max_length=4, null=False)
|
||||
value = models.CharField(max_length=31, null=False)
|
||||
work = models.ForeignKey("Work", related_name="identifiers", null=False)
|
||||
edition = models.ForeignKey("Edition", related_name="identifiers", null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = ("type", "value")
|
||||
|
||||
@classmethod
|
||||
def get_or_add(klass, type='goog', value=None, edition=None, work=None):
|
||||
try:
|
||||
return Identifier.objects.get(type=type, value=value)
|
||||
except Identifier.DoesNotExist:
|
||||
i=Identifier(type=type, value=value, edition=edition, work=work)
|
||||
i.save()
|
||||
return i
|
||||
|
||||
class Work(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
title = models.CharField(max_length=1000)
|
||||
openlibrary_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)
|
||||
openlibrary_lookup = models.DateTimeField(null=True)
|
||||
|
||||
|
@ -226,44 +243,62 @@ class Work(models.Model):
|
|||
|
||||
@property
|
||||
def googlebooks_id(self):
|
||||
# may want to denormalize this at some point to avoid an extra query
|
||||
try:
|
||||
return self.editions.all()[0].googlebooks_id
|
||||
return self.identifiers.filter(type='goog')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
return ''
|
||||
|
||||
@property
|
||||
def googlebooks_url(self):
|
||||
return "http://books.google.com/books?id=%s" % self.googlebooks_id
|
||||
if self.googlebooks_id:
|
||||
return "http://books.google.com/books?id=%s" % self.googlebooks_id
|
||||
else:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def goodreads_id(self):
|
||||
for e in self.editions.filter(goodreads_id__isnull=False):
|
||||
return e.goodreads_id
|
||||
try:
|
||||
return self.identifiers.filter(type='gdrd')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def goodreads_url(self):
|
||||
return "http://www.goodreads.com/book/show/%s" % self.goodreads_id
|
||||
|
||||
@property
|
||||
def librarything_id(self):
|
||||
try:
|
||||
return self.identifiers.filter(type='ltwk')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def librarything_url(self):
|
||||
return "http://www.librarything.com/work/%s" % self.librarything_id
|
||||
|
||||
@property
|
||||
def openlibrary_id(self):
|
||||
try:
|
||||
return self.identifiers.filter(type='olwk')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def openlibrary_url(self):
|
||||
return "http://openlibrary.org" + self.openlibrary_id
|
||||
|
||||
def cover_image_small(self):
|
||||
try:
|
||||
return self.editions.all()[0].cover_image_small()
|
||||
return self.editions.all()[0].cover_image_small()
|
||||
except IndexError:
|
||||
return "/static/images/generic_cover_larger.png"
|
||||
return "/static/images/generic_cover_larger.png"
|
||||
|
||||
def cover_image_thumbnail(self):
|
||||
try:
|
||||
return self.editions.all()[0].cover_image_thumbnail()
|
||||
return self.editions.all()[0].cover_image_thumbnail()
|
||||
except IndexError:
|
||||
return "/static/images/generic_cover_larger.png"
|
||||
return "/static/images/generic_cover_larger.png"
|
||||
|
||||
def author(self):
|
||||
authors = list(Author.objects.filter(editions__work=self).all())
|
||||
|
@ -291,7 +326,7 @@ class Work(models.Model):
|
|||
if self.first_ebook() or self.first_epub():
|
||||
status = "Available"
|
||||
else:
|
||||
status = "No campaign yet"
|
||||
status = "No campaign yet"
|
||||
return status
|
||||
|
||||
def percent_unglued(self):
|
||||
|
@ -369,8 +404,17 @@ class Work(models.Model):
|
|||
return description
|
||||
|
||||
def first_isbn_13(self):
|
||||
for e in self.editions.filter(isbn_13__isnull=False):
|
||||
return e.isbn_13
|
||||
try:
|
||||
return self.identifiers.filter(type='isbn')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def publication_date(self):
|
||||
for edition in Edition.objects.filter(work=self):
|
||||
if edition.publication_date:
|
||||
return edition.publication_date
|
||||
return ''
|
||||
|
||||
def __unicode__(self):
|
||||
return self.title
|
||||
|
@ -398,42 +442,78 @@ class Subject(models.Model):
|
|||
|
||||
|
||||
class Edition(models.Model):
|
||||
googlebooks_id = models.CharField(max_length=50, null=False, unique=True)
|
||||
goodreads_id = models.CharField(max_length=50, null=True)
|
||||
librarything_id = models.CharField(max_length=50, null=True)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
title = models.CharField(max_length=1000)
|
||||
description = models.TextField(default='', null=True)
|
||||
publisher = models.CharField(max_length=255)
|
||||
publication_date = models.CharField(max_length=50)
|
||||
publisher = models.CharField(max_length=255, null=True)
|
||||
publication_date = models.CharField(max_length=50, null=True)
|
||||
public_domain = models.NullBooleanField(null=True)
|
||||
isbn_13 = models.CharField(max_length=13, null=True)
|
||||
oclc = models.CharField(max_length=25, null=True)
|
||||
work = models.ForeignKey("Work", related_name="editions", null=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s (%s)" % (self.title, self.isbn_13)
|
||||
|
||||
def cover_image_small(self):
|
||||
server_id = random.randint(0, 9)
|
||||
return "http://bks%i.books.google.com/books?id=%s&printsec=frontcover&img=1&zoom=5" % (server_id, self.googlebooks_id)
|
||||
|
||||
if self.googlebooks_id:
|
||||
server_id = random.randint(0, 9)
|
||||
return "http://bks%i.books.google.com/books?id=%s&printsec=frontcover&img=1&zoom=5" % (server_id, self.googlebooks_id)
|
||||
else:
|
||||
return ''
|
||||
|
||||
def cover_image_thumbnail(self):
|
||||
server_id = random.randint(0, 9)
|
||||
return "http://bks%s.books.google.com/books?id=%s&printsec=frontcover&img=1&zoom=1" % (server_id, self.googlebooks_id)
|
||||
if self.googlebooks_id:
|
||||
server_id = random.randint(0, 9)
|
||||
return "http://bks%s.books.google.com/books?id=%s&printsec=frontcover&img=1&zoom=1" % (server_id, self.googlebooks_id)
|
||||
else:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def isbn_10(self):
|
||||
return regluit.core.isbn.convert_13_to_10(self.isbn_13)
|
||||
|
||||
@property
|
||||
def isbn_13(self):
|
||||
try:
|
||||
return self.identifiers.filter(type='isbn')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def googlebooks_id(self):
|
||||
try:
|
||||
return self.identifiers.filter(type='goog')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def librarything_id(self):
|
||||
try:
|
||||
return self.identifiers.filter(type='thng')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def oclc(self):
|
||||
try:
|
||||
return self.identifiers.filter(type='oclc')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
@property
|
||||
def goodreads_id(self):
|
||||
try:
|
||||
return self.identifiers.filter(type='gdrd')[0].value
|
||||
except IndexError:
|
||||
return ''
|
||||
|
||||
@classmethod
|
||||
def get_by_isbn(klass, isbn):
|
||||
if length(isbn)==10:
|
||||
isbn=regluit.core.isbn.convert_10_to_13(isbn)
|
||||
|
||||
for e in Edition.objects.filter( Q(isbn_13=isbn) ):
|
||||
return e
|
||||
return None
|
||||
try:
|
||||
return Identifier.objects.get( type='isbn', value=isbn ).edition
|
||||
except Identifier.DoesNotExist:
|
||||
return None
|
||||
|
||||
class Ebook(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
|
@ -456,9 +536,9 @@ class Wishlist(models.Model):
|
|||
|
||||
def add_work(self, work, source):
|
||||
try:
|
||||
w = Wishes.objects.get(wishlist=self,work=work)
|
||||
w.source=source
|
||||
except:
|
||||
w = Wishes.objects.get(wishlist=self,work=work)
|
||||
w.source=source
|
||||
except:
|
||||
Wishes.objects.create(source=source,wishlist=self,work=work)
|
||||
|
||||
def remove_work(self, work):
|
||||
|
|
|
@ -28,7 +28,7 @@ class BookLoaderTests(TestCase):
|
|||
edition = bookloader.add_by_isbn('0441012035')
|
||||
self.assertEqual(edition.title, 'Neuromancer')
|
||||
self.assertEqual(edition.publication_date, '2004')
|
||||
self.assertEqual(edition.publisher, 'Ace Books')
|
||||
self.assertEqual(edition.publisher, u'Ace Hardcover')
|
||||
self.assertEqual(edition.isbn_10, '0441012035')
|
||||
self.assertEqual(edition.isbn_13, '9780441012039')
|
||||
self.assertEqual(edition.googlebooks_id, "2NyiPwAACAAJ")
|
||||
|
@ -39,6 +39,7 @@ class BookLoaderTests(TestCase):
|
|||
|
||||
# work
|
||||
self.assertTrue(edition.work)
|
||||
|
||||
|
||||
def test_double_add(self):
|
||||
bookloader.add_by_isbn('0441012035')
|
||||
|
@ -48,7 +49,7 @@ class BookLoaderTests(TestCase):
|
|||
self.assertEqual(models.Work.objects.all().count(), 1)
|
||||
|
||||
def test_missing_isbn(self):
|
||||
e = bookloader.add_by_isbn('0139391401')
|
||||
e = bookloader.add_by_isbn_from_google('0139391401')
|
||||
self.assertEqual(e, None)
|
||||
|
||||
def test_thingisbn(self):
|
||||
|
@ -62,22 +63,22 @@ class BookLoaderTests(TestCase):
|
|||
edition = bookloader.add_by_isbn('0441012035')
|
||||
self.assertEqual(models.Edition.objects.count(), 1)
|
||||
self.assertEqual(models.Work.objects.count(), 1)
|
||||
|
||||
lang=edition.work.language
|
||||
# ask for related editions to be added using the work we just created
|
||||
bookloader.add_related('0441012035')
|
||||
self.assertTrue(models.Edition.objects.count() > 15)
|
||||
self.assertEqual(models.Work.objects.count(), 1)
|
||||
self.assertTrue(edition.work.editions.count() > 15)
|
||||
self.assertEqual(models.Work.objects.filter(language=lang).count(), 1)
|
||||
self.assertTrue(edition.work.editions.count() > 10)
|
||||
|
||||
# all the editions in the db should be tied to the work
|
||||
self.assertEqual(models.Edition.objects.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)
|
||||
self.assertTrue(edition.work.publication_date)
|
||||
edition.publication_date = None
|
||||
self.assertTrue(edition.work.publication_date)
|
||||
|
||||
def test_merge_works(self):
|
||||
# add two editions and see that there are two stub works
|
||||
|
@ -159,6 +160,8 @@ class BookLoaderTests(TestCase):
|
|||
self.assertTrue(len(subjects) > 10)
|
||||
self.assertTrue('Science fiction' in subjects)
|
||||
self.assertEqual(work.openlibrary_id, '/works/OL27258W')
|
||||
self.assertEqual(work.goodreads_id, '14770')
|
||||
self.assertEqual(work.librarything_id, '609')
|
||||
|
||||
|
||||
class SearchTests(TestCase):
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
CELERYD_NODES="w1"
|
||||
CELERYD_CHDIR="/opt/regluit/"
|
||||
CELERYD_LOG_FILE="/var/log/celery/%n.log"
|
||||
CELERYD_PID_FILE="/var/run/celery/%n.pid"
|
||||
CELERYD_PID_FILE="/var/log/celery/%n.pid"
|
||||
CELERYD_USER="celery"
|
||||
CELERYD_GROUP="celery"
|
||||
CELERYD="/opt/regluit/ENV/bin/django-admin.py celeryd"
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
WSGIPythonHome /opt/regluit/ENV
|
||||
WSGISocketPrefix /opt/regluit
|
||||
|
||||
<VirtualHost *:80>
|
||||
<VirtualHost _default_:80>
|
||||
|
||||
ServerName unglue.it
|
||||
ServerAdmin info@gluejar.com
|
||||
|
||||
RewriteEngine On
|
||||
|
||||
RewriteCond %{SERVER_NAME} !^unglue.it$ [NC]
|
||||
RewriteRule (.*) http://unglue.it$1 [R=301,L]
|
||||
|
||||
RewriteRule ^/$ https://unglue.it/ [R=301]
|
||||
RewriteRule /admin(.*) https://unglue.it/admin$1 [R=301]
|
||||
RewriteRule /accounts(.*) https://unglue.it/accounts$1 [R=301]
|
||||
|
@ -33,6 +36,11 @@ SSLCertificateFile /etc/ssl/certs/server.crt
|
|||
SSLCertificateKeyFile /etc/ssl/private/server.key
|
||||
SSLCertificateChainFile /etc/ssl/certs/gd_bundle.crt
|
||||
|
||||
RewriteEngine On
|
||||
|
||||
RewriteCond %{SERVER_NAME} !^unglue.it$ [NC]
|
||||
RewriteRule (.*) https://unglue.it$1 [R=301,L]
|
||||
|
||||
WSGIDaemonProcess regluit-ssl processes=4 threads=4 python-eggs=/tmp/regluit-python-eggs
|
||||
WSGIScriptAlias / /opt/regluit/deploy/regluit.wsgi
|
||||
|
||||
|
|
|
@ -123,9 +123,15 @@
|
|||
<div class="listview panelfront side1 icons">
|
||||
{% if status == 'No campaign yet' or status == 'INITIALIZED' %}
|
||||
<span class="rounded"><span class="grey"><span class="panelnope">Wished by </span>{{ work.wished_by.count }}</span></span>
|
||||
{% else %}
|
||||
{% if work.first_pdf_url or work.first_epub_url %}
|
||||
<span class="rounded"><span class="grey"><span class="panelnope">Loved by </span>{{ work.wished_by.count }}</span></span>
|
||||
{% else %}{% if work.first_pdf_url or work.first_epub_url %}
|
||||
<span class="listview boolist-ebook">
|
||||
{% if work.first_epub_url %}
|
||||
<a href="{{ work.first_epub_url }}">EPUB</a>
|
||||
{% endif %}
|
||||
{% if work.first_pdf_url %}
|
||||
<a href="{{ work.first_pdf_url }}">PDF</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% else %}
|
||||
|
||||
<div class="booklist-status-img">
|
||||
|
@ -135,16 +141,6 @@
|
|||
{% endif %}{% endif %}
|
||||
</div>
|
||||
<div class="listview panelfront side1 ebooks">
|
||||
{% if work.first_epub_url and work.first_pdf_url %}
|
||||
<span class="listview boolist-ebook">
|
||||
{% if work.first_epub_url %}
|
||||
<a href="{{ work.first_epub_url }}">epub</a>
|
||||
{% endif %}
|
||||
{% if work.first_pdf_url %}
|
||||
<a href="{{ work.first_pdf_url }}">pdf</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="unglue-this panelfront side1 none">
|
||||
<div class="unglue-this-inner1">
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
<p>Target: {{campaign.target}}</p>
|
||||
<p>Deadline: {{campaign.deadline}}</p>
|
||||
<p>Status: {{campaign.status}}</p>
|
||||
<p>ISBN: {{campaign.work.editions.all.0.isbn_10}} | {{campaign.work.editions.all.0.isbn_13}} </p>
|
||||
<p><a href="{% url widget isbn=campaign.work.editions.all.0.isbn_13 %}">Widget Link</a></p>
|
||||
<p>ISBN: {{campaign.work.editions.all.0.isbn_10}} | {{campaign.work.first_isbn_13}} </p>
|
||||
<p><a href="{% url widget isbn=campaign.work.first_isbn_13 %}">Widget Link</a></p>
|
||||
<p>Embed a widget:</p>
|
||||
<textarea rows="2" cols="80"><iframe src="{{base_url}}/api/widget/{{campaign.work.editions.all.0.isbn_13}}/" width="152" height="325" frameborder="0"></iframe></textarea>
|
||||
<textarea rows="2" cols="80"><iframe src="{{base_url}}/api/widget/{{campaign.work.first_isbn_13}}/" width="152" height="325" frameborder="0"></iframe></textarea>
|
||||
<p>PayPal receiver: {{campaign.paypal_receiver}}</p>
|
||||
<p>Current total (pledged/authorized): {{campaign.current_total}}</p>
|
||||
<form method="POST" action="{% url campaign_by_id pk=campaign.id %}" onsubmit="test()">
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
<div class="{% cycle 'row1' 'row2' %}">
|
||||
{% with campaign.status as status %}
|
||||
{% with campaign.deadline as deadline %}
|
||||
{% with campaign.work.editions.all.0.googlebooks_id as googlebooks_id %}
|
||||
{% with campaign.work.googlebooks_id as googlebooks_id %}
|
||||
{% with campaign.work as work %}
|
||||
{% include "book_panel.html" %}
|
||||
{% endwith %}{% endwith %}{% endwith %}{% endwith %}
|
||||
|
|
|
@ -23,7 +23,7 @@ Please fix the following before launching your campaign:
|
|||
<div class="book-detail-info">
|
||||
<h2 class="book-name">Title: <a href="{% url work campaign.work.id %}">{{ campaign.work.title }}</a></h2>
|
||||
<h3 class="book-author">Authors: {{ campaign.work.author }}</h3>
|
||||
<h3 class="book-year">Published: {{ campaign.work.editions.all.0.publication_date }}</h3>
|
||||
<h3 class="book-year">Published: {{ campaign.work.publication_date }}</h3>
|
||||
<h3 class="book-author">Language: {{ campaign.work.editions.all.0.language }}</h3>
|
||||
<p>Target Price: {{ campaign.pretarget }}</p>
|
||||
<p>End Date: {{ campaign.predeadline }}</p>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<div class="book-detail-info">
|
||||
<h2 class="book-name">{{ work.title }}</h2>
|
||||
<h3 class="book-author">{{ work.author }}</h3>
|
||||
<h3 class="book-year">{{ work.editions.all.0.publication_date }}</h3>
|
||||
<h3 class="book-year">{{ work.publication_date }}</h3>
|
||||
<div class="find-book">
|
||||
<label>Find it here</label>
|
||||
<!-- todo: these should be a real thing -->
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<div class="book-detail-info">
|
||||
<h2 class="book-name">Title: {{ work.title }}</h2>
|
||||
<h3 class="book-author">Authors: {{ work.author }}</h3>
|
||||
<h3 class="book-year">Published: {{ work.editions.all.0.publication_date }}</h3>
|
||||
<h3 class="book-year">Published: {{ work.publication_date }}</h3>
|
||||
<h3 class="book-author">Language: {{ work.editions.all.0.language }}</h3>
|
||||
</div>
|
||||
<form action="#">
|
||||
|
|
|
@ -253,7 +253,7 @@ how do I integrate the your wishlist thing with the tabs thing?
|
|||
<div class="{% cycle 'row1' 'row2' %}">
|
||||
{% with work.last_campaign_status as status %}
|
||||
{% with work.last_campaign.deadline as deadline %}
|
||||
{% with work.editions.all.0.googlebooks_id as googlebooks_id %}
|
||||
{% with work.googlebooks_id as googlebooks_id %}
|
||||
{% include "book_panel.html" %}
|
||||
{% endwith %}{% endwith %}{% endwith %}
|
||||
</div>
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
<div class="{% cycle 'row1' 'row2' %}">
|
||||
{% with work.last_campaign_status as status %}
|
||||
{% with work.last_campaign.deadline as deadline %}
|
||||
{% with work.editions.all.0.googlebooks_id as googlebooks_id %}
|
||||
{% with work.googlebooks_id as googlebooks_id %}
|
||||
{% include "book_panel.html" %}
|
||||
{% endwith %}{% endwith %}{% endwith %}
|
||||
</div>
|
||||
|
|
|
@ -28,38 +28,37 @@ jQuery(document).ready(function(){
|
|||
<div class="js-main">
|
||||
<div id="js-leftcol">
|
||||
<div class="jsmodule rounded">
|
||||
{% if work.last_campaign %}
|
||||
{% if status == 'ACTIVE' %}
|
||||
<div class="jsmod-content active{{ work.percent_unglued}}">
|
||||
<span>
|
||||
Campaign in Progress: <br />${{ work.last_campaign.current_total }}/${{ work.last_campaign.target }}
|
||||
<div class="jsmod-content{% if status == 'ACTIVE' %} active{{ work.percent_unglued}}{% endif %}">
|
||||
<span>
|
||||
{% if work.first_epub_url or work.first_pdf_url %}
|
||||
AVAILABLE!
|
||||
{% else %}{% if work.last_campaign %}
|
||||
{% if status == 'ACTIVE' %}
|
||||
Campaign in Progress: <br />${{ work.last_campaign.current_total }}/${{ work.last_campaign.target }}
|
||||
{% else %}
|
||||
{% if status == 'SUCCESSFUL' %}
|
||||
Unglued on {{ work.last_campaign.deadline|date:"M j, Y"}}! <br />${{ work.last_campaign.current_total }} raised of ${{ work.last_campaign.target }} goal
|
||||
{% else %}{% if status == 'INITIALIZED' %}
|
||||
Campaign starting soon
|
||||
{% else %}{% if status == 'SUSPENDED' %}
|
||||
Campaign suspended. <br />See <a href="/faq">FAQ</a>.
|
||||
{% else %}{% if status == 'WITHDRAWN' %}
|
||||
Campaign withdrawn. <br />See <a href="/faq">FAQ</a>.
|
||||
{% else %}{% if wishers == 1 %}
|
||||
{{ wishers }} Ungluer is WISHING
|
||||
{% else %}
|
||||
{{ wishers }} Ungluers are WISHING
|
||||
{% endif %}{% endif %}{% endif %}{% endif %}{% endif %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="jsmod-content">
|
||||
<span>
|
||||
{% if status == 'SUCCESSFUL' %}
|
||||
Unglued on {{ work.last_campaign.deadline|date:"M j, Y"}}! <br />${{ work.last_campaign.current_total }} raised of ${{ work.last_campaign.target }} goal
|
||||
{% else %}{% if status == 'INITIALIZED' %}
|
||||
Campaign starting soon
|
||||
{% else %}{% if status == 'SUSPENDED' %}
|
||||
Campaign suspended. <br />See <a href="/faq">FAQ</a>.
|
||||
{% else %}{% if status == 'WITHDRAWN' %}
|
||||
Campaign withdrawn. <br />See <a href="/faq">FAQ</a>.
|
||||
{% else %}{% if wishers == 1 %}
|
||||
{{ wishers }} Ungluer is WISHING
|
||||
{% else %}
|
||||
{{ wishers }} Ungluers are WISHING
|
||||
{% endif %}{% endif %}{% endif %}{% endif %}{% endif %}{% endif %}
|
||||
{% else %}
|
||||
<div class="jsmod-content">
|
||||
<span>
|
||||
{% if wishers == 1 %}
|
||||
{{ wishers }} Ungluer is WISHING
|
||||
{% else %}
|
||||
{{ wishers }} Ungluers are WISHING
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</span>
|
||||
<span class="spacer"> <br /> </span>
|
||||
{% if wishers == 1 %}
|
||||
{{ wishers }} Ungluer is WISHING
|
||||
{% else %}
|
||||
{{ wishers }} Ungluers are WISHING
|
||||
{% endif %}
|
||||
{% endif %}{% endif %}
|
||||
</span>
|
||||
<span class="spacer"> <br /> </span>
|
||||
</div>
|
||||
</div>
|
||||
{% include "explore.html" %}
|
||||
|
@ -103,17 +102,41 @@ jQuery(document).ready(function(){
|
|||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% if status == 'ACTIVE' %}
|
||||
<div class="pledged-info"><div class="pledged-group">{% if work.last_campaign.supporters.count == 1 %}One Ungluer has {% else %} {{ work.last_campaign.supporters.count }} Ungluers have {% endif %}pledged ${{ work.last_campaign.current_total }}<br />toward a ${{ work.last_campaign.target }} goal </div><div class="status"><img src="/static/images/images/icon-book-37by25-{{ work.percent_unglued }}.png" /></div></div>
|
||||
{% else %}
|
||||
<div class="pledged-info"><div class="pledged-group">
|
||||
{% if work.first_epub_url or work.first_pdf_url %}
|
||||
{% if wishers == 1 %}
|
||||
{{ wishers }} Ungluer has
|
||||
1 Ungluer is
|
||||
{% else %}
|
||||
{{ wishers }} Ungluers are
|
||||
{% endif %} enjoying this Work
|
||||
{% else %}{% if status == 'ACTIVE' %}
|
||||
{% if work.last_campaign.supporters.count == 1 %}
|
||||
One Ungluer has
|
||||
{% else %}
|
||||
{{ work.last_campaign.supporters.count }} Ungluers have
|
||||
{% endif %}
|
||||
pledged ${{ work.last_campaign.current_total }}<br />toward a ${{ work.last_campaign.target }} goal
|
||||
{% else %}
|
||||
{% if wishers == 1 %}
|
||||
1 Ungluer has
|
||||
{% else %}
|
||||
{{ wishers }} Ungluers have
|
||||
{% endif %}wished for this Work</div><div class="status"><img src="/static/images/images/icon-book-37by25-{{ work.percent_unglued }}.png" /></div></div>
|
||||
{% endif %}
|
||||
{% endif %} wished for this Work
|
||||
{% endif %}{% endif %}
|
||||
</div>
|
||||
<div class="status"><img src="/static/images/images/icon-book-37by25-{% if work.first_epub_url or work.first_pdf_url %}6{%else%}{{ work.percent_unglued }}{%endif%}.png" /></div>
|
||||
</div>
|
||||
<div class="btn_wishlist">
|
||||
{% if work.first_epub_url or work.first_pdf_url %}
|
||||
<span class="boolist-ebook">
|
||||
{% if work.first_epub_url %}
|
||||
<a href="{{ work.first_epub_url }}">EPUB</a>
|
||||
{% endif %}
|
||||
{% if work.first_pdf_url %}
|
||||
<a href="{{ work.first_pdf_url }}">PDF</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if request.user.is_anonymous %}
|
||||
<div class="create-account">
|
||||
<span title="{% url work work.id %}">Login to Add</span>
|
||||
|
@ -128,7 +151,7 @@ jQuery(document).ready(function(){
|
|||
</div>
|
||||
{% else %}
|
||||
<div class="add-wishlist">
|
||||
<span id="{{ work.googlebooks_id }}">Add to Wishlist</span>
|
||||
<span id="{{ work.googlebooks_id }}">Add to {% if work.first_epub_url or work.first_pdf_url %}Enjoying{% else %}Wishlist{% endif %}</span>
|
||||
</div>
|
||||
{% endif %}{% endif %}{% endif %}
|
||||
</div>
|
||||
|
@ -263,7 +286,7 @@ jQuery(document).ready(function(){
|
|||
<a href="https://twitter.com/intent/tweet?url={{request.build_absolute_uri|urlencode:"" }}&text=I'm%20ungluing%20{{ work.title|urlencode }}%20at%20%40unglueit"><li class="twitter"><span>Twitter</span></li></a>
|
||||
{% if request.user.is_authenticated %}<a href="{% url emailshare %}?next={{request.build_absolute_uri|urlencode:""}}"><li class="email"><span>Email</span></li></a>{% endif %}
|
||||
<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"><iframe src="https://{{request.META.HTTP_HOST}}/api/widget/{{work.editions.all.0.isbn_13}}/" width="152" height="325" frameborder="0"></iframe></textarea></div>
|
||||
<div id="widgetcode">Copy/paste this into your site:<br /><textarea rows="7" cols="22"><iframe src="https://{{request.META.HTTP_HOST}}/api/widget/{{work.first_isbn_13}}/" width="152" height="325" frameborder="0"></iframe></textarea></div>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
<div class="{% cycle 'row1' 'row2' %}">
|
||||
{% with work.last_campaign_status as status %}
|
||||
{% with work.last_campaign.deadline as deadline %}
|
||||
{% with work.editions.all.0.googlebooks_id as googlebooks_id %}
|
||||
{% with work.googlebooks_id as googlebooks_id %}
|
||||
{% include "book_panel.html" %}
|
||||
{% endwith %}{% endwith %}{% endwith %}
|
||||
</div>
|
||||
|
|
|
@ -47,6 +47,8 @@ class PageTests(TestCase):
|
|||
# logged in
|
||||
r = self.client.get("/supporter/test/")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
r = self.client.get("/search/?q=sverige")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
def test_view_by_other(self):
|
||||
# someone else's supporter page
|
||||
|
@ -60,6 +62,8 @@ class PageTests(TestCase):
|
|||
self.assertEqual(r.status_code, 200)
|
||||
r = anon_client.get("/")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
r = anon_client.get("/search/?q=sverige")
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
class GoogleBooksTest(TestCase):
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ urlpatterns = patterns(
|
|||
"regluit.frontend.views",
|
||||
url(r"^$", "home", name="home"),
|
||||
url(r"^supporter/(?P<supporter_username>.+)/$", "supporter", {'template_name': 'supporter.html'}, name="supporter"),
|
||||
url(r"^supporter2/(?P<supporter_username>.+)/$", "supporter", {'template_name': 'supporter_panel.html'}, name="supporter2"),
|
||||
url(r"^search/$", "search", name="search"),
|
||||
url(r"^privacy/$", TemplateView.as_view(template_name="privacy.html"),
|
||||
name="privacy"),
|
||||
|
|
|
@ -97,7 +97,7 @@ def work(request, work_id, action='display'):
|
|||
except:
|
||||
pledged = None
|
||||
try:
|
||||
pubdate = work.editions.all()[0].publication_date[:4]
|
||||
pubdate = work.publication_date[:4]
|
||||
except IndexError:
|
||||
pubdate = 'unknown'
|
||||
if not request.user.is_anonymous():
|
||||
|
@ -156,8 +156,8 @@ def manage_campaign(request, id):
|
|||
|
||||
def googlebooks(request, googlebooks_id):
|
||||
try:
|
||||
edition = models.Edition.objects.get(googlebooks_id=googlebooks_id)
|
||||
except models.Edition.DoesNotExist:
|
||||
edition = models.Identifier.objects.get(type='goog',value=googlebooks_id).edition
|
||||
except models.Identifier.DoesNotExist:
|
||||
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
|
||||
|
@ -817,9 +817,9 @@ def search(request):
|
|||
works=[]
|
||||
for result in results:
|
||||
try:
|
||||
edition = models.Edition.objects.get(googlebooks_id=result['googlebooks_id'])
|
||||
works.append(edition.work)
|
||||
except models.Edition.DoesNotExist:
|
||||
work = models.Identifier.objects.get(type='goog',value=result['googlebooks_id']).work
|
||||
works.append(work)
|
||||
except models.Identifier.DoesNotExist:
|
||||
works.append(result)
|
||||
context = {
|
||||
"q": q,
|
||||
|
@ -1161,7 +1161,7 @@ def work_librarything(request, work_id):
|
|||
|
||||
def work_openlibrary(request, work_id):
|
||||
work = get_object_or_404(models.Work, id=work_id)
|
||||
isbns = ["ISBN:" + e.isbn_13 for e in work.editions.filter(isbn_13__isnull=False)]
|
||||
isbns = ["ISBN:" + i.value for i in work.identifiers.filter(type='isbn')]
|
||||
url = None
|
||||
|
||||
if work.openlibrary_id:
|
||||
|
|
Loading…
Reference in New Issue