X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/67df302167539474edd02b57c2e8bd30349d7625..fa5a185ce54eb7bacaadc34f05abb63e701d39d8:/apps/api/handlers.py diff --git a/apps/api/handlers.py b/apps/api/handlers.py index 40121d6af..cca504f8f 100644 --- a/apps/api/handlers.py +++ b/apps/api/handlers.py @@ -1,17 +1,190 @@ # -*- coding: utf-8 -*- # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# + +from datetime import datetime from django.shortcuts import get_object_or_404 from django.contrib.auth.decorators import login_required, user_passes_test +from django.utils import simplejson as json from piston.handler import BaseHandler from piston.utils import rc, validate -from catalogue.models import Book + +from api.models import Deleted +from api.helpers import timestamp +from catalogue.models import Book, Tag from catalogue.forms import BookImportForm +from catalogue.views import tagged_object_list +""" +class TagHandler(BaseHandler): + allowed_methods = ('GET',) + model = Tag + def read(self, request, tags=''): + if tags == '': + return Tag.objects.all() + else: + return tagged_object_list(request, tags, api=True) -staff_required = user_passes_test(lambda user: user.is_staff) +class BookHandler(BaseHandler): + model = Book + #fields = ('slug', 'title') + + def read(self, request, slug=None): + if slug: + return get_object_or_404(Book, slug=slug) + else: + return Book.objects.all() +""" + + +class WLHandler(BaseHandler): + + @staticmethod + def fields(request, name): + fields_str = request.GET.get(name) if request is not None else None + return fields_str.split(',') if fields_str is not None else None + + @staticmethod + def book_dict(book, fields=None, extra_fields=None): + obj = {} + for field in ('slug', 'title', 'description', + 'extra_info', 'gazeta_link', 'wiki_link'): + if getattr(book, field): + obj[field] = getattr(book, field) + for field in ('created_at', 'changed_at'): + obj[field] = timestamp(getattr(book, field)) + for field in ('xml', 'epub', 'txt', 'pdf', 'html'): + f = getattr(book, field+'_file') + if f: + obj[field] = f.url + for media in book.medias.all(): + obj.setdefault(media.type, []).append(media.file.url) + if book.parent: + obj['parent'] = book.parent.id + obj['parent_number'] = book.parent_number + if fields is not None: + for key in obj.keys(): + if key not in fields: + del obj[key] + + # if there's still extra_info, we can parse it + if 'extra_info' in obj: + extra = json.loads(obj['extra_info']) + if extra_fields is not None: + for key in extra.keys(): + if key not in extra_fields: + del extra[key] + obj['extra_info'] = extra + + obj['id'] = book.id + return obj + + @classmethod + def book_changes(cls, since=0, request=None): + since = datetime.fromtimestamp(float(since)) + book_fields = cls.fields(request, 'book_fields') + extra_fields = cls.fields(request, 'extra_fields') + + added = [] + changed = [] + deleted = [] + + last_change = since + for book in Book.objects.filter(changed_at__gt=since): + if book.changed_at > last_change: + last_change = book.changed_at + book_d = cls.book_dict(book, book_fields, extra_fields) + if book.created_at > since: + added.append(book_d) + else: + changed.append(book_d) + for book in Deleted.objects.filter(type='Book', deleted_at__gt=since, created_at__lte=since): + if book.deleted_at > last_change: + last_change = book.deleted_at + deleted.append(book.id) + return {'added': added, 'changed': changed, 'deleted': deleted, 'last_change': timestamp(last_change)} + + @staticmethod + def tag_dict(tag, fields=None): + obj = {} + for field in ('name', 'slug', 'sort_key', 'category', 'description', 'main_page', #'created_at', 'changed_at', + 'gazeta_link', 'wiki_link'): + if getattr(tag, field): + obj[field] = getattr(tag, field) + if fields is not None: + for key in obj.keys(): + if key not in fields: + del obj[key] + obj['id'] = tag.id + return obj + + @classmethod + def tag_changes(cls, since=0, request=None): + since = datetime.fromtimestamp(float(since)) + tag_fields = cls.fields(request, 'tag_fields') + + added = [] + changed = [] + deleted = [] + + last_change = since + for tag in Tag.objects.filter(changed_at__gt=since): + if tag.changed_at > last_change: + last_change = tag.changed_at + tag_d = cls.tag_dict(tag, tag_fields) + if tag.created_at > since: + added.append(tag_d) + else: + changed.append(tag_d) + + for tag in Deleted.objects.filter(type='Tag', deleted_at__gt=since, created_at__lte=since): + if tag.deleted_at > last_change: + last_change = tag.deleted_at + deleted.append(tag.id) + return {'added': added, 'changed': changed, 'deleted': deleted, 'last_change': timestamp(last_change)} + + +class BookChangesHandler(WLHandler): + allowed_methods = ('GET',) + + def read(self, request, since): + return self.book_changes(since, request) + + +class TagChangesHandler(WLHandler): + allowed_methods = ('GET',) + + def read(self, request, since): + return self.tag_changes(since, request) + + +class ChangesHandler(WLHandler): + allowed_methods = ('GET',) + + def read(self, request, since): + changes = { + 'books': self.book_changes(since, request), + 'tags': self.tag_changes(since, request), + } + + last_change = 0 + changes_rev = {} + for model in changes: + for field in changes[model]: + if field == 'last_change': + if changes[model][field] > last_change: + last_change = changes[model][field] + else: + changes_rev.setdefault(field, {})[model] = changes[model][field] + changes_rev['last_change'] = last_change + return changes_rev + + + +# old +""" +staff_required = user_passes_test(lambda user: user.is_staff) class BookHandler(BaseHandler): model = Book @@ -32,4 +205,4 @@ class BookHandler(BaseHandler): return rc.CREATED else: return rc.BAD_REQUEST - +"""