regluit/api/resources.py

178 lines
6.5 KiB
Python
Raw Normal View History

import logging
from tastypie import fields
from tastypie.constants import ALL, ALL_WITH_RELATIONS
from tastypie.resources import ModelResource, Resource, Bundle
from tastypie.utils import trailing_slash
from tastypie.authentication import ApiKeyAuthentication, Authentication
2016-04-09 17:22:31 +00:00
from tastypie.exceptions import BadRequest
2016-04-08 00:38:53 +00:00
from django.conf.urls import url
2013-06-03 16:31:39 +00:00
from django.contrib import auth
2015-12-19 01:01:22 +00:00
from django.contrib.auth.models import User
2018-07-24 15:33:39 +00:00
from django.urls import reverse
2013-06-03 16:31:39 +00:00
from regluit.core import models
2015-12-19 01:21:28 +00:00
import regluit.core.isbn
logger = logging.getLogger(__name__)
class EditionResource(ModelResource):
work = fields.ForeignKey('regluit.api.resources.WorkResource', 'work')
identifiers = fields.ToManyField('regluit.api.resources.IdentifierResource', 'identifiers')
2017-06-29 17:22:58 +00:00
ebooks = fields.ToManyField('regluit.api.resources.EbookResource', 'ebooks')
class Meta:
authentication = ApiKeyAuthentication()
queryset = models.Edition.objects.all()
resource_name = 'edition'
filtering = {
"isbn_13": ALL, "identifiers": ALL_WITH_RELATIONS,
}
2017-02-14 18:59:19 +00:00
def build_filters(self, filters = None, **kwargs):
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, 'identifiers': ALL_WITH_RELATIONS}
2013-02-18 20:15:53 +00:00
ordering = ['num_wishes']
class CampaignResource(ModelResource):
work = fields.ToOneField(WorkResource, 'work')
def alter_list_data_to_serialize(self, request, data):
"""
annotate the list of campaigns with information from the logged in
user. note: this isn't the user identified by the api username/api_key
it's the the user that client might be logged into unglue.it as.
"""
u = auth.get_user(request)
if isinstance(u, User):
data['meta']['logged_in_username'] = u.username
wishlist_work_ids = [w.id for w in u.wishlist.works.all()]
else:
data['meta']['logged_in_username'] = None
wishlist_work_ids = []
for o in data['objects']:
o.data['in_wishlist'] = o.obj.work_id in wishlist_work_ids
# there's probably a better place up the chain (where the Campaign objects are directly available) to grab the status
c = models.Campaign.objects.get(id=o.data["id"])
o.data['status'] = c.status
o.data['current_total'] = c.current_total
# TODO: add pledging information
return data
def alter_detail_data_to_serialize(self, request, obj):
c = models.Campaign.objects.get(id=obj.data["id"])
obj.data['status'] = c.status
obj.data['current_total'] = c.current_total
return obj
class Meta:
authentication = ApiKeyAuthentication()
queryset = models.Campaign.objects.all()
resource_name = 'campaign'
excludes = ['amazon_receiver', 'paypal_receiver']
filtering = {
"work": ALL_WITH_RELATIONS,
}
class AuthorResource(ModelResource):
works = fields.ToManyField(WorkResource, 'works')
class Meta:
authentication = ApiKeyAuthentication()
queryset = models.Author.objects.all()
resource_name = 'author'
class SubjectResource(ModelResource):
works = fields.ToManyField(WorkResource, 'works')
class Meta:
authentication = ApiKeyAuthentication()
queryset = models.Subject.objects.all()
resource_name = 'subject'
2017-06-29 17:22:58 +00:00
class EbookResource(ModelResource):
edition = fields.ToOneField(EditionResource, 'edition')
class Meta:
authentication = ApiKeyAuthentication()
queryset = models.Ebook.objects.all()
resource_name = 'ebook'
excludes = ['url']
class PublisherResource(ModelResource):
ebooks = fields.ToManyField(EbookResource, attribute=lambda bundle: models.Ebook.objects.filter(edition__publisher_name=bundle.obj.name))
class Meta:
authentication = ApiKeyAuthentication()
queryset = models.Publisher.objects.all()
resource_name = 'publisher'
2015-12-19 01:21:28 +00:00
class FreeResource(ModelResource):
def alter_list_data_to_serialize(self, request, data):
del data["meta"]["limit"]
del data["meta"]["offset"]
return data
def dehydrate(self, bundle):
bundle.data["filetype"]=bundle.obj.format
bundle.data["rights"]=bundle.obj.rights
bundle.data["provider"]=bundle.obj.provider
bundle.data["href"]=reverse('download_ebook',kwargs={'ebook_id':bundle.obj.id})
return bundle
2016-04-09 17:22:31 +00:00
def obj_get_list(self, bundle, **kwargs):
request = bundle.request
2015-12-19 01:21:28 +00:00
isbn =""
if hasattr(request, 'GET'):
isbn = request.GET.get("isbn","")
isbn = isbn.replace('-','')
if len(isbn)==10:
isbn=regluit.core.isbn.convert_10_to_13(isbn)
try:
work=models.Identifier.objects.get(type='isbn',value=isbn,).work
base_object_list = models.Ebook.objects.filter(edition__work=work)
2016-04-08 22:12:10 +00:00
return base_object_list
2015-12-19 01:21:28 +00:00
except ValueError:
raise BadRequest("Invalid resource lookup data provided (mismatched type).")
except models.Identifier.DoesNotExist:
2016-04-08 22:12:10 +00:00
return models.Ebook.objects.none()
class Meta:
2018-07-24 02:51:01 +00:00
queryset = models.Ebook.objects.all()
authentication = ApiKeyAuthentication()
2015-12-19 01:21:28 +00:00
fields = [ 'provider', 'rights' ]
limit = 0
include_resource_uri = False