From 2e4e4c4a3b149116d81698b6666ce8b7ae22857c Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 19 Dec 2018 21:34:40 +0100 Subject: [PATCH] Remove unused code. --- src/api/emitters.py | 65 +-------- src/api/helpers.py | 6 - src/api/management/__init__.py | 0 src/api/management/commands/__init__.py | 0 src/api/management/commands/mobileinit.py | 162 ---------------------- src/api/urls.py | 18 --- src/catalogue/models/book.py | 2 - 7 files changed, 1 insertion(+), 252 deletions(-) delete mode 100755 src/api/management/__init__.py delete mode 100755 src/api/management/commands/__init__.py delete mode 100755 src/api/management/commands/mobileinit.py diff --git a/src/api/emitters.py b/src/api/emitters.py index 531ae19bb..50a2d4101 100644 --- a/src/api/emitters.py +++ b/src/api/emitters.py @@ -4,71 +4,8 @@ # """ Wrappers for piston Emitter classes. - -When outputting a queryset of selected models, instead of returning -XML or JSON stanzas, SSI include statements are returned. - """ -from django.conf import settings -from django.core.urlresolvers import reverse -from django.db.models.query import QuerySet -from piston.emitters import Emitter, XMLEmitter, JSONEmitter -from catalogue.models import Book, Fragment, Tag -from django.utils.translation import get_language - - -class SsiQS(object): - """A wrapper for QuerySet that won't serialize.""" - - def __init__(self, queryset): - self.queryset = queryset - - def __unicode__(self): - raise TypeError("This is not serializable.") - - def get_ssis(self, emitter_format): - """Yields SSI include statements for the queryset.""" - url_pattern = reverse( - 'api_include', - kwargs={ - 'model': self.queryset.model.__name__.lower(), - 'pk': '0000', - 'emitter_format': emitter_format, - 'lang': get_language(), - }) - for instance in self.queryset: - yield "" % url_pattern.replace('0000', str(instance.pk)) - - -class SsiEmitterMixin(object): - def construct(self): - ssify_api = getattr(settings, 'SSIFY_API', True) - if ssify_api and isinstance(self.data, QuerySet) and self.data.model in (Book, Fragment, Tag): - return SsiQS(self.data) - else: - return super(SsiEmitterMixin, self).construct() - - -class SsiJsonEmitter(SsiEmitterMixin, JSONEmitter): - def render(self, request): - try: - return super(SsiJsonEmitter, self).render(request) - except TypeError: - return '[%s]' % ",".join(self.construct().get_ssis('json')) - -Emitter.register('json', SsiJsonEmitter, 'application/json; charset=utf-8') - - -class SsiXmlEmitter(SsiEmitterMixin, XMLEmitter): - def render(self, request): - try: - return super(SsiXmlEmitter, self).render(request) - except TypeError: - return '\n' \ - '%s' % \ - ''.join(self.construct().get_ssis('xml')) - -Emitter.register('xml', SsiXmlEmitter, 'text/xml; charset=utf-8') +from piston.emitters import Emitter # hack diff --git a/src/api/helpers.py b/src/api/helpers.py index 03fc18ce6..ffe92846f 100644 --- a/src/api/helpers.py +++ b/src/api/helpers.py @@ -2,15 +2,9 @@ # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from time import mktime from piston.resource import Resource -def timestamp(dtime): - """converts a datetime.datetime object to a timestamp int""" - return int(mktime(dtime.timetuple())) - - class CsrfExemptResource(Resource): """A Custom Resource that is csrf exempt""" def __init__(self, handler, authentication=None): diff --git a/src/api/management/__init__.py b/src/api/management/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/src/api/management/commands/__init__.py b/src/api/management/commands/__init__.py deleted file mode 100755 index e69de29bb..000000000 diff --git a/src/api/management/commands/mobileinit.py b/src/api/management/commands/mobileinit.py deleted file mode 100755 index ccf27bc76..000000000 --- a/src/api/management/commands/mobileinit.py +++ /dev/null @@ -1,162 +0,0 @@ -# -*- 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 -import os.path -import sqlite3 -from django.core.management.base import BaseCommand - -from api.helpers import timestamp -from api.settings import MOBILE_INIT_DB -from catalogue.models import Book, Tag -from wolnelektury.utils import makedirs - - -class Command(BaseCommand): - help = 'Creates an initial SQLite file for the mobile app.' - - def handle(self, **options): - # those should be versioned - last_checked = timestamp(datetime.now()) - db = init_db(last_checked) - for b in Book.objects.all(): - add_book(db, b) - for t in Tag.objects.exclude( - category__in=('book', 'set', 'theme')).exclude(items=None): - # only add non-empty tags - add_tag(db, t) - db.commit() - db.close() - current(last_checked) - - -def pretty_size(size): - """ Turns size in bytes into a prettier string. - - >>> pretty_size(100000) - '97 KiB' - """ - if not size: - return None - units = ['B', 'KiB', 'MiB', 'GiB'] - size = float(size) - unit = units.pop(0) - while size > 1000 and units: - size /= 1024 - unit = units.pop(0) - if size < 10: - return "%.1f %s" % (size, unit) - return "%d %s" % (size, unit) - # - # if not isinstance(value, unicode): - # value = unicode(value, 'utf-8') - # - # # try to replace chars - # value = re.sub('[^a-zA-Z0-9\\s\\-]{1}', replace_char, value) - # value = value.lower() - # value = re.sub(r'[^a-z0-9{|}]+', '~', value) - # - # return value.encode('ascii', 'ignore') - - -def init_db(last_checked): - makedirs(MOBILE_INIT_DB) - db = sqlite3.connect(os.path.join(MOBILE_INIT_DB, 'initial.db-%d' % last_checked)) - - schema = """ -CREATE TABLE book ( - id INTEGER PRIMARY KEY, - title VARCHAR, - cover VARCHAR, - html_file VARCHAR, - html_file_size INTEGER, - parent INTEGER, - parent_number INTEGER, - - sort_key VARCHAR, - pretty_size VARCHAR, - authors VARCHAR, - _local BOOLEAN -); -CREATE INDEX IF NOT EXISTS book_title_index ON book (sort_key); -CREATE INDEX IF NOT EXISTS book_title_index ON book (title); -CREATE INDEX IF NOT EXISTS book_parent_index ON book (parent); - -CREATE TABLE tag ( - id INTEGER PRIMARY KEY, - name VARCHAR, - category VARCHAR, - sort_key VARCHAR, - books VARCHAR); -CREATE INDEX IF NOT EXISTS tag_name_index ON tag (name); -CREATE INDEX IF NOT EXISTS tag_category_index ON tag (category); -CREATE INDEX IF NOT EXISTS tag_sort_key_index ON tag (sort_key); - -CREATE TABLE state (last_checked INTEGER); -""" - - db.executescript(schema) - db.execute("INSERT INTO state VALUES (:last_checked)", {'last_checked': last_checked}) - return db - - -def current(last_checked): - target = os.path.join(MOBILE_INIT_DB, 'initial.db') - if os.path.lexists(target): - os.unlink(target) - os.symlink( - 'initial.db-%d' % last_checked, - target, - ) - - -book_sql = """ - INSERT INTO book - (id, title, cover, html_file, html_file_size, parent, parent_number, sort_key, pretty_size, authors) - VALUES - (:id, :title, :cover, :html_file, :html_file_size, :parent, :parent_number, :sort_key, :size_str, :authors); -""" -book_tag_sql = "INSERT INTO book_tag (book, tag) VALUES (:book, :tag);" -tag_sql = """ - INSERT INTO tag - (id, category, name, sort_key, books) - VALUES - (:id, :category, :name, :sort_key, :book_ids); -""" -categories = {'author': 'autor', - 'epoch': 'epoka', - 'genre': 'gatunek', - 'kind': 'rodzaj', - 'theme': 'motyw' - } - - -def add_book(db, book): - if book.html_file: - html_file = book.html_file.url - html_file_size = book.html_file.size - else: - html_file = html_file_size = None - db.execute(book_sql, { - 'title': book.title, - 'cover': book.cover.url if book.cover else None, - 'html_file': html_file, - 'html_file_size': html_file_size, - 'parent': book.parent_id, - 'parent_number': book.parent_number, - 'sort_key': book.sort_key, - 'size_str': pretty_size(html_file_size), - 'authors': book.author_unicode(), - }) - - -def add_tag(db, tag): - books = Book.tagged_top_level([tag]) - book_ids = ','.join(str(book_id) for book_id in books.values_list('id', flat=True)) - db.execute(tag_sql, { - 'category': categories[tag.category], - 'name': tag.name, - 'sort_key': tag.sort_key, - 'book_ids': book_ids, - }) diff --git a/src/api/urls.py b/src/api/urls.py index bb0c1f474..bd832fe25 100644 --- a/src/api/urls.py +++ b/src/api/urls.py @@ -7,7 +7,6 @@ from django.views.decorators.csrf import csrf_exempt from django.views.generic import TemplateView from piston.authentication import OAuthAuthentication, oauth_access_token, oauth_request_token from piston.resource import Resource -from ssify import ssi_included import catalogue.views from api import handlers from api.helpers import CsrfExemptResource @@ -72,29 +71,12 @@ tags_re = r'^(?P(?:(?:[a-z0-9-]+/){2}){0,6})' paginate_re = r'(?:after/(?P[a-z0-9-]+)/)?(?:count/(?P[0-9]+)/)?$' -@ssi_included -def incl(request, model, pk, emitter_format): - resource = { - 'book': book_list_resource, - 'fragment': fragment_list_resource, - 'tag': tag_list_resource, - }[model] - request.piwik_track = False - resp = resource(request, pk=pk, emitter_format=emitter_format) - if emitter_format == 'xml': - # Ugly, but quick way of stripping header and tags. - resp.content = resp.content[49:-11] - return resp - - urlpatterns = [ url(r'^oauth/request_token/$', oauth_request_token), url(r'^oauth/authorize/$', oauth_user_auth, name='oauth_user_auth'), url(r'^oauth/access_token/$', csrf_exempt(oauth_access_token)), url(r'^$', TemplateView.as_view(template_name='api/main.html'), name='api'), - url(r'^include/(?Pbook|fragment|tag)/(?P\d+)\.(?P.+)\.(?Pxml|json)$', - incl, name='api_include'), # info boxes (used by mobile app) url(r'book/(?P\d*?)/info\.html$', catalogue.views.book_info), diff --git a/src/catalogue/models/book.py b/src/catalogue/models/book.py index dbbee782b..8c53d9c1a 100644 --- a/src/catalogue/models/book.py +++ b/src/catalogue/models/book.py @@ -115,8 +115,6 @@ class Book(models.Model): html_built = django.dispatch.Signal() published = django.dispatch.Signal() - short_html_url_name = 'catalogue_book_short' - class AlreadyExists(Exception): pass -- 2.20.1