1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 from datetime import datetime
6 from piston.handler import BaseHandler
8 from api.helpers import timestamp
9 from api.models import Deleted
10 from catalogue.models import Book, Tag
12 class CatalogueHandler(BaseHandler):
15 def fields(request, name):
16 fields_str = request.GET.get(name) if request is not None else None
17 return fields_str.split(',') if fields_str is not None else None
20 def book_dict(book, fields=None):
21 all_fields = ('url', 'title', 'description',
22 'gazeta_link', 'wiki_link',
23 'xml', 'epub', 'txt', 'pdf', 'html',
24 'mp3', 'ogg', 'daisy',
25 'parent', 'parent_number',
27 'license', 'license_description', 'source_name',
28 'technical_editors', 'editors',
31 fields = (f for f in fields if f in all_fields)
35 extra_info = book.get_extra_info_value()
40 if field in ('xml', 'epub', 'txt', 'pdf', 'html'):
41 f = getattr(book, field+'_file')
48 elif field in ('mp3', 'ogg', 'daisy'):
50 for m in book.medias.filter(type=''):
52 'url': m.file.get_absolute_url(),
59 obj[field] = book.get_absolute_url()
62 obj[field] = [t.id for t in book.tags.exclude(category__in=('book', 'set'))]
64 elif field in ('license', 'license_description', 'source_name',
65 'technical_editors', 'editors'):
66 f = extra_info.get(field)
71 f = getattr(book, field)
79 def book_changes(cls, since=0, request=None, fields=None):
80 since = datetime.fromtimestamp(int(since))
82 fields = cls.fields(request, 'book_fields')
89 for book in Book.objects.filter(changed_at__gte=since):
90 book_d = cls.book_dict(book, fields)
91 updated.append(book_d)
93 for book in Deleted.objects.filter(content_type=Book, deleted_at__gte=since, created_at__lt=since):
94 deleted.append(book.id)
95 return {'updated': updated, 'deleted': deleted}
98 def tag_dict(tag, fields=None):
99 all_fields = ('name', 'category', 'sort_key', 'description',
100 'gazeta_link', 'wiki_link',
105 fields = (f for f in fields if f in all_fields)
113 obj[field] = tag.get_absolute_url()
116 f = getattr(tag, field)
124 def tag_changes(cls, since=0, request=None, fields=None, categories=None):
125 since = datetime.fromtimestamp(int(since))
127 fields = cls.fields(request, 'tag_fields')
129 categories = cls.fields(request, 'tag_categories')
131 all_categories = ('author', 'theme', 'epoch', 'kind', 'genre')
133 categories = (c for c in categories if c in all_categories)
135 categories = all_categories
140 for tag in Tag.objects.filter(category__in=categories, changed_at__gte=since):
141 tag_d = cls.tag_dict(tag, fields)
142 updated.append(tag_d)
144 for tag in Deleted.objects.filter(category__in=categories,
145 content_type=Tag, deleted_at__gte=since, created_at__lt=since):
146 deleted.append(tag.id)
147 return {'updated': updated, 'deleted': deleted}
150 def changes(cls, since=0, request=None, book_fields=None,
151 tag_fields=None, tag_categories=None):
153 'time_checked': timestamp(datetime.now())
157 'books': cls.book_changes(since, request, book_fields),
158 'tags': cls.tag_changes(since, request, tag_fields, tag_categories),
161 for model in changes_by_type:
162 for field in changes_by_type[model]:
163 changes.setdefault(field, {})[model] = changes_by_type[model][field]
167 class BookChangesHandler(CatalogueHandler):
168 allowed_methods = ('GET',)
170 def read(self, request, since):
171 return self.book_changes(since, request)
174 class TagChangesHandler(CatalogueHandler):
175 allowed_methods = ('GET',)
177 def read(self, request, since):
178 return self.tag_changes(since, request)
181 class ChangesHandler(CatalogueHandler):
182 allowed_methods = ('GET',)
184 def read(self, request, since):
185 return self.changes(since, request)