regluit/api/views.py

240 lines
8.5 KiB
Python
Raw Normal View History

2013-06-03 16:31:39 +00:00
from tastypie.models import ApiKey
2016-02-22 23:03:07 +00:00
import json
2016-02-22 15:24:59 +00:00
import logging
2011-09-21 05:22:48 +00:00
from django.contrib import auth
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
2018-07-24 15:33:39 +00:00
from django.urls import reverse
from django.shortcuts import render, render_to_response
2013-06-03 16:31:39 +00:00
from django.template import RequestContext
2016-02-18 19:37:35 +00:00
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.base import View, TemplateView
from django.http import (
HttpResponse,
HttpResponseNotFound,
HttpResponseBadRequest,
HttpResponseRedirect,
2015-08-27 19:23:25 +00:00
Http404,
)
2016-02-18 19:37:35 +00:00
import regluit.core.isbn
2015-07-30 04:34:05 +00:00
from regluit.core.bookloader import load_from_yaml
from regluit.api import opds, onix, opds_json
2015-08-04 16:02:06 +00:00
from regluit.api.models import repo_allowed
2013-06-03 16:31:39 +00:00
from regluit.core import models
2016-02-22 15:24:59 +00:00
logger = logging.getLogger(__name__)
def editions(request):
editions = models.Edition.objects.all()
return render(request, 'editions.html',
{'editions':editions},
)
2011-09-21 05:22:48 +00:00
def negotiate_content(request,work_id):
if request.META.get('HTTP_ACCEPT', None):
if "opds-catalog" in request.META['HTTP_ACCEPT']:
return HttpResponseRedirect(reverse('opds_acqusition',args=['all'])+'?work='+work_id)
2015-08-28 20:20:46 +00:00
elif "text/xml" in request.META['HTTP_ACCEPT']:
return HttpResponseRedirect(reverse('onix',args=['all'])+'?work='+work_id)
return HttpResponseRedirect(reverse('work', kwargs={'work_id': work_id}))
2016-11-21 19:14:30 +00:00
def featured_work():
try:
work = models.Work.objects.filter(featured__isnull=False).distinct().order_by('-featured')[0]
except:
#shouldn't occur except in tests
work = models.Work.objects.all()[0]
return work
def widget(request, isbn):
2011-09-21 05:22:48 +00:00
"""
2015-02-18 18:09:43 +00:00
supply info for book panel. parameter is named isbn for historical reasons. can be isbn or work_id
2011-09-21 05:22:48 +00:00
"""
if isbn == 'featured':
2016-11-21 19:14:30 +00:00
work = featured_work()
else :
if len(isbn)==10:
isbn = regluit.core.isbn.convert_10_to_13(isbn)
if len(isbn)==13:
try:
identifier = models.Identifier.objects.get(type = 'isbn', value = isbn )
work = identifier.work
except models.Identifier.DoesNotExist:
return render(request, 'widget.html',
{ 'work':None,},
)
else:
work= models.safe_get_work(isbn)
return render(request, 'widget.html',
2015-02-18 18:09:43 +00:00
{'work':work, },
2011-09-21 05:22:48 +00:00
)
2016-11-21 19:14:30 +00:00
def featured_cover(request):
work = featured_work()
2017-02-14 19:37:36 +00:00
tn = work.cover_image_thumbnail()
return HttpResponseRedirect(tn if tn else "/static/images/generic_cover_larger.png")
2016-11-21 19:14:30 +00:00
def featured_url(request):
work = featured_work()
return HttpResponseRedirect(reverse('work', kwargs={'work_id': work.id}))
2015-07-30 04:34:05 +00:00
def load_yaml(request):
if request.method == "GET":
return render(request, 'load_yaml.html', { })
2015-07-30 04:34:05 +00:00
repo_url = request.POST.get('repo_url', None)
if not repo_url:
return HttpResponse('needs repo_url')
2015-08-04 16:02:06 +00:00
(allowed,reason) =repo_allowed(repo_url)
if not allowed:
return HttpResponse('repo_url not allowed: '+reason)
2015-07-30 04:34:05 +00:00
try:
work_id = load_from_yaml(repo_url)
return HttpResponseRedirect(reverse('work', args=[work_id]))
except:
return HttpResponse('unsuccessful')
2016-02-18 19:37:35 +00:00
@csrf_exempt
def travisci_webhook(request):
2016-02-22 23:03:07 +00:00
"""
Respond to travis-ci webhooks from Project GITenberg repositories. If the webhook is successfully parsed,
the metdata.yaml for the repository is loaded using load_from_yaml.
https://docs.travis-ci.com/user/notifications/#Webhook-notification
2016-02-22 23:03:07 +00:00
"""
if request.method == "POST":
2016-02-22 15:24:59 +00:00
try:
data = json.loads(request.POST.get('payload'))
2016-02-22 15:24:59 +00:00
# example of URL to feed to yaml loader:
# https://github.com/GITenberg/Adventures-of-Huckleberry-Finn_76/raw/master/metadata.yaml
if data['status_message'] == 'Passed' and data['type'] == 'push':
# another way to get owner_name / name would be request.META.get('HTTP_TRAVIS_REPO_SLUG', '')
repo_url = "https://github.com/{}/{}/raw/master/metadata.yaml".format(data['repository']['owner_name'],
data['repository']['name'])
2016-02-22 15:24:59 +00:00
work_id = load_from_yaml(repo_url)
return HttpResponse('Successful. work_id: {}'.format(work_id))
except Exception as e:
return HttpResponseBadRequest('Unsuccessful. Exception: {}'.format(unicode(e)))
2016-02-22 15:24:59 +00:00
else:
return HttpResponse('No action')
else:
return HttpResponse('No action')
2016-02-22 15:24:59 +00:00
2015-07-30 04:34:05 +00:00
class ApiHelpView(TemplateView):
template_name = "api_help.html"
def get_context_data(self, **kwargs):
context = super(ApiHelpView, self).get_context_data(**kwargs)
# base_url passed in to allow us to write absolute URLs for this site
base_url = self.request.build_absolute_uri("/")[:-1]
context["base_url"] = base_url
# if user is logged in, pass in the user's API key
u = auth.get_user(self.request)
if u.is_authenticated:
api_key = ApiKey.objects.filter(user=u)[0].key
context['api_key'] = api_key
# pass in a sample Campaign whose widget can be displayed
campaigns = models.Campaign.objects.all()
if len(campaigns):
c = campaigns[0]
isbn = c.work.first_isbn_13
context["campaign"] = campaigns[0]
context["campaign_isbn"] = isbn
return context
class OPDSNavigationView(TemplateView):
json=False
2017-07-27 14:33:13 +00:00
# https://stackoverflow.com/a/6867976: secret to how to change content-type
def render_to_response(self, context, **response_kwargs):
if json:
response_kwargs['content_type'] = "application/vnd.opds.navigation+json"
else:
response_kwargs['content_type'] = "application/atom+xml;profile=opds-catalog;kind=navigation"
return super(TemplateView, self).render_to_response(context, **response_kwargs)
def get_context_data(self, **kwargs):
context = super(OPDSNavigationView, self).get_context_data(**kwargs)
if json:
context["feeds"] = opds_json.feeds()
context["feed"] = opds_json.get_facet_facet('all')
else:
context["feeds"] = opds.feeds()
context["feed"] = opds.get_facet_facet('all')
return context
class OPDSAcquisitionView(View):
json = False
def get(self, request, *args, **kwargs):
work = request.GET.get('work', None)
if work:
if self.json:
return HttpResponse(opds_json.opds_feed_for_work(work),
2017-03-17 21:19:26 +00:00
content_type="application/opds-publication+json")
else:
return HttpResponse(opds.opds_feed_for_work(work),
content_type="application/atom+xml;profile=opds-catalog;kind=acquisition")
facet = kwargs.get('facet')
2014-11-04 00:36:26 +00:00
page = request.GET.get('page', None)
2014-12-06 20:00:23 +00:00
order_by = request.GET.get('order_by', 'newest')
2014-11-04 00:36:26 +00:00
try:
page = int(page)
except:
page = None
if self.json:
facet_class = opds_json.get_facet_class(facet)()
return HttpResponse(facet_class.feed(page,order_by),
2017-03-17 21:19:26 +00:00
content_type="application/opds+json")
else:
facet_class = opds.get_facet_class(facet)()
return HttpResponse(facet_class.feed(page,order_by),
content_type="application/atom+xml;profile=opds-catalog;kind=acquisition")
class OnixView(View):
def get(self, request, *args, **kwargs):
2015-08-28 20:20:46 +00:00
work = request.GET.get('work', None)
if work:
try:
work=models.safe_get_work(work)
except models.Work.DoesNotExist:
raise Http404
return HttpResponse(onix.onix_feed_for_work(work),
content_type="text/xml")
facet = kwargs.get('facet', 'all')
2015-08-27 19:23:25 +00:00
if facet:
max = request.GET.get('max', 100)
try:
max = int(max)
except:
max = None
facet_class = opds.get_facet_class(facet)()
return HttpResponse(onix.onix_feed(facet_class, max),
content_type="text/xml")
2015-12-19 01:21:28 +00:00