From 39b99a8a8920dca527eb823b860303103389fd91 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Thu, 17 Jan 2019 00:42:29 +0100 Subject: [PATCH] More API testing. --- src/api/tests/res/responses/audiobooks.json | 1 - src/api/tests/res/responses/blog.json | 1 - src/api/tests/res/responses/books-child.json | 70 +++++++++++++++ .../tests/res/responses/books-grandchild.json | 52 +++++++++++ src/api/tests/res/responses/books-parent.json | 87 ++++++++++++++++++ src/api/tests/res/responses/books.json | 50 +++++++++++ src/api/tests/res/responses/collection.json | 24 +++++ src/api/tests/res/responses/collections.json | 8 +- src/api/tests/res/responses/daisy.json | 1 - src/api/tests/res/responses/ebooks.json | 3 + src/api/tests/res/responses/filter-books.json | 11 ++- src/api/tests/res/responses/fragment.json | 30 +++++++ src/api/tests/res/responses/fragments.json | 24 +++++ src/api/tests/res/responses/newest.json | 17 ---- src/api/tests/res/responses/preview.json | 1 - src/api/tests/res/responses/recommended.json | 1 - src/api/tests/res/responses/tags.json | 14 +++ src/api/tests/tests.py | 90 +++++++++++++++++-- src/catalogue/__init__.py | 5 ++ src/catalogue/fixtures/test-books.yaml | 84 +++++++++++++++-- src/catalogue/models/book.py | 4 +- src/catalogue/models/collection.py | 3 - src/catalogue/test_utils.py | 4 + src/catalogue/utils.py | 4 + src/wolnelektury/settings/test.py | 1 + 25 files changed, 542 insertions(+), 48 deletions(-) delete mode 100644 src/api/tests/res/responses/audiobooks.json delete mode 100644 src/api/tests/res/responses/blog.json create mode 100644 src/api/tests/res/responses/books-child.json create mode 100644 src/api/tests/res/responses/books-grandchild.json create mode 100644 src/api/tests/res/responses/books-parent.json create mode 100644 src/api/tests/res/responses/books.json create mode 100644 src/api/tests/res/responses/collection.json delete mode 100644 src/api/tests/res/responses/daisy.json create mode 100644 src/api/tests/res/responses/fragment.json create mode 100644 src/api/tests/res/responses/fragments.json delete mode 100644 src/api/tests/res/responses/newest.json delete mode 100644 src/api/tests/res/responses/preview.json delete mode 100644 src/api/tests/res/responses/recommended.json create mode 100644 src/api/tests/res/responses/tags.json diff --git a/src/api/tests/res/responses/audiobooks.json b/src/api/tests/res/responses/audiobooks.json deleted file mode 100644 index fe51488c7..000000000 --- a/src/api/tests/res/responses/audiobooks.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/src/api/tests/res/responses/blog.json b/src/api/tests/res/responses/blog.json deleted file mode 100644 index fe51488c7..000000000 --- a/src/api/tests/res/responses/blog.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/src/api/tests/res/responses/books-child.json b/src/api/tests/res/responses/books-child.json new file mode 100644 index 000000000..4c5c13450 --- /dev/null +++ b/src/api/tests/res/responses/books-child.json @@ -0,0 +1,70 @@ +{ + "epochs": [], + "fragment_data": { + "html": "Fragment", + "title": "Parent, Child" + }, + "txt": "", + "children": [ + { + "kind": "", + "full_sort_key": "$grandchild$3", + "author": "", + "url": "https://example.com/katalog/lektura/grandchild/", + "cover_color": "#000000", + "title": "Grandchild", + "cover": "", + "liked": null, + "slug": "grandchild", + "epoch": "", + "href": "https://example.com/api/books/grandchild/", + "genre": "Sonet", + "simple_thumb": "", + "has_audio": false, + "cover_thumb": "" + } + ], + "xml": "", + "genres": [ + { + "url": "https://example.com/katalog/gatunek/wiersz/", + "href": "https://example.com/api/genres/wiersz/", + "name": "Wiersz", + "slug": "wiersz" + } + ], + "title": "Child", + "media": [], + "html": "", + "preview": false, + "fb2": "", + "kinds": [], + "parent": { + "kind": "Liryka", + "full_sort_key": "john doe$parent$1", + "author": "John Doe", + "url": "https://example.com/katalog/lektura/parent/", + "cover_color": "#a6820a", + "title": "Parent", + "cover": "https://example.com/media/cover/parent.jpg", + "liked": null, + "slug": "parent", + "epoch": "Barok", + "href": "https://example.com/api/books/parent/", + "genre": "Sonet", + "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg", + "has_audio": true, + "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193" + }, + "cover_color": "#000000", + "simple_cover": "", + "authors": [], + "audio_length": "", + "epub": "", + "cover_thumb": "", + "mobi": "", + "url": "https://example.com/katalog/lektura/child/", + "cover": "", + "pdf": "", + "simple_thumb": "" +} diff --git a/src/api/tests/res/responses/books-grandchild.json b/src/api/tests/res/responses/books-grandchild.json new file mode 100644 index 000000000..faf8c783e --- /dev/null +++ b/src/api/tests/res/responses/books-grandchild.json @@ -0,0 +1,52 @@ +{ + "epochs": [], + "fragment_data": { + "html": "Fragment", + "title": "Parent, Child" + }, + "txt": "https://example.com/media/txt/grandchild.txt", + "children": [], + "xml": "", + "genres": [ + { + "url": "https://example.com/katalog/gatunek/sonet/", + "href": "https://example.com/api/genres/sonet/", + "name": "Sonet", + "slug": "sonet" + } + ], + "title": "Grandchild", + "media": [], + "html": "https://example.com/media/html/grandchild.html", + "preview": false, + "fb2": "https://example.com/media/fb2/grandchild.fb2", + "kinds": [], + "parent": { + "kind": "", + "full_sort_key": "$child$2", + "author": "", + "url": "https://example.com/katalog/lektura/child/", + "cover_color": "#000000", + "title": "Child", + "cover": "", + "liked": null, + "slug": "child", + "epoch": "", + "href": "https://example.com/api/books/child/", + "genre": "Wiersz", + "simple_thumb": "", + "has_audio": false, + "cover_thumb": "" + }, + "cover_color": "#000000", + "simple_cover": "", + "authors": [], + "audio_length": "", + "epub": "", + "cover_thumb": "", + "mobi": "", + "url": "https://example.com/katalog/lektura/grandchild/", + "cover": "", + "pdf": "", + "simple_thumb": "" +} diff --git a/src/api/tests/res/responses/books-parent.json b/src/api/tests/res/responses/books-parent.json new file mode 100644 index 000000000..ade38cc8f --- /dev/null +++ b/src/api/tests/res/responses/books-parent.json @@ -0,0 +1,87 @@ +{ + "epochs": [ + { + "url": "https://example.com/katalog/epoka/barok/", + "href": "https://example.com/api/epochs/barok/", + "name": "Barok", + "slug": "barok" + } + ], + "fragment_data": null, + "txt": "", + "children": [ + { + "kind": "", + "full_sort_key": "$child$2", + "author": "", + "url": "https://example.com/katalog/lektura/child/", + "cover_color": "#000000", + "title": "Child", + "cover": "", + "liked": null, + "slug": "child", + "epoch": "", + "href": "https://example.com/api/books/child/", + "genre": "Wiersz", + "simple_thumb": "", + "has_audio": false, + "cover_thumb": "" + } + ], + "xml": "https://example.com/media/xml/parent.xml", + "genres": [ + { + "url": "https://example.com/katalog/gatunek/sonet/", + "href": "https://example.com/api/genres/sonet/", + "name": "Sonet", + "slug": "sonet" + } + ], + "title": "Parent", + "media": [ + { + "url": "https://example.com/media/daisy/parent.daisy", + "director": "", + "type": "daisy", + "name": "Parent DAISY", + "artist": "" + }, + { + "url": "https://example.com/media/mp3/parent.mp3", + "director": "Director", + "type": "mp3", + "name": "Parent Audiobook", + "artist": "Artist" + } + ], + "html": "", + "preview": false, + "fb2": "", + "kinds": [ + { + "url": "https://example.com/katalog/rodzaj/liryka/", + "href": "https://example.com/api/kinds/liryka/", + "name": "Liryka", + "slug": "liryka" + } + ], + "parent": null, + "cover_color": "#a6820a", + "simple_cover": "https://example.com/media/simple_cover/parent.jpg", + "authors": [ + { + "url": "https://example.com/katalog/autor/john-doe/", + "href": "https://example.com/api/authors/john-doe/", + "name": "John Doe", + "slug": "john-doe" + } + ], + "audio_length": "1:00", + "epub": "https://example.com/media/epub/parent.epub", + "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193", + "mobi": "https://example.com/media/mobi/parent.mobi", + "url": "https://example.com/katalog/lektura/parent/", + "cover": "https://example.com/media/cover/parent.jpg", + "pdf": "https://example.com/media/pdf/parent.pdf", + "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg" +} diff --git a/src/api/tests/res/responses/books.json b/src/api/tests/res/responses/books.json new file mode 100644 index 000000000..f83e74e42 --- /dev/null +++ b/src/api/tests/res/responses/books.json @@ -0,0 +1,50 @@ +[ + { + "kind": "", + "full_sort_key": "$child$2", + "cover_color": "#000000", + "author": "", + "url": "https://example.com/katalog/lektura/child/", + "has_audio": false, + "title": "Child", + "cover": "", + "epoch": "", + "href": "https://example.com/api/books/child/", + "genre": "Wiersz", + "simple_thumb": "", + "slug": "child", + "cover_thumb": "" + }, + { + "kind": "", + "full_sort_key": "$grandchild$3", + "cover_color": "#000000", + "author": "", + "url": "https://example.com/katalog/lektura/grandchild/", + "has_audio": false, + "title": "Grandchild", + "cover": "", + "epoch": "", + "href": "https://example.com/api/books/grandchild/", + "genre": "Sonet", + "simple_thumb": "", + "slug": "grandchild", + "cover_thumb": "" + }, + { + "kind": "Liryka", + "full_sort_key": "john doe$parent$1", + "cover_color": "#a6820a", + "author": "John Doe", + "url": "https://example.com/katalog/lektura/parent/", + "has_audio": true, + "title": "Parent", + "cover": "cover/parent.jpg", + "epoch": "Barok", + "href": "https://example.com/api/books/parent/", + "genre": "Sonet", + "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg", + "slug": "parent", + "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193" + } +] diff --git a/src/api/tests/res/responses/collection.json b/src/api/tests/res/responses/collection.json new file mode 100644 index 000000000..866abedbd --- /dev/null +++ b/src/api/tests/res/responses/collection.json @@ -0,0 +1,24 @@ +{ + "url": "https://example.com/katalog/lektury/a-collection/", + "books": [ + { + "kind": "Liryka", + "full_sort_key": "john doe$parent$1", + "author": "John Doe", + "url": "https://example.com/katalog/lektura/parent/", + "cover_color": "#a6820a", + "title": "Parent", + "cover": "https://example.com/media/cover/parent.jpg", + "liked": null, + "slug": "parent", + "epoch": "Barok", + "href": "https://example.com/api/books/parent/", + "genre": "Sonet", + "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg", + "has_audio": true, + "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193" + } + ], + "description": "Description", + "title": "A Collection" +} diff --git a/src/api/tests/res/responses/collections.json b/src/api/tests/res/responses/collections.json index fe51488c7..a0852cdb0 100644 --- a/src/api/tests/res/responses/collections.json +++ b/src/api/tests/res/responses/collections.json @@ -1 +1,7 @@ -[] +[ + { + "url": "https://example.com/katalog/lektury/a-collection/", + "href": "https://example.com/dapi/collections/a-collection/", + "title": "A Collection" + } +] diff --git a/src/api/tests/res/responses/daisy.json b/src/api/tests/res/responses/daisy.json deleted file mode 100644 index fe51488c7..000000000 --- a/src/api/tests/res/responses/daisy.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/src/api/tests/res/responses/ebooks.json b/src/api/tests/res/responses/ebooks.json index 70084ef6c..171c153a9 100644 --- a/src/api/tests/res/responses/ebooks.json +++ b/src/api/tests/res/responses/ebooks.json @@ -2,6 +2,7 @@ { "fb2": "", "mobi": "", + "title": "Child", "author": "", "cover": "", "href": "https://example.com/api/books/child/", @@ -13,6 +14,7 @@ { "fb2": "https://example.com/media/fb2/grandchild.fb2", "mobi": "", + "title": "Grandchild", "author": "", "cover": "", "href": "https://example.com/api/books/grandchild/", @@ -24,6 +26,7 @@ { "fb2": "", "mobi": "https://example.com/media/mobi/parent.mobi", + "title": "Parent", "author": "John Doe", "cover": "cover/parent.jpg", "href": "https://example.com/api/books/parent/", diff --git a/src/api/tests/res/responses/filter-books.json b/src/api/tests/res/responses/filter-books.json index db41287ea..b56ffb148 100644 --- a/src/api/tests/res/responses/filter-books.json +++ b/src/api/tests/res/responses/filter-books.json @@ -6,11 +6,12 @@ "author": "", "url": "https://example.com/katalog/lektura/child/", "has_audio": false, + "title": "Child", "cover": "", "epoch": "", "href": "https://example.com/api/books/child/", "key": "book$child", - "genre": "", + "genre": "Wiersz", "simple_thumb": "", "slug": "child", "cover_thumb": "" @@ -22,11 +23,12 @@ "author": "", "url": "https://example.com/katalog/lektura/grandchild/", "has_audio": false, + "title": "Grandchild", "cover": "", "epoch": "", "href": "https://example.com/api/books/grandchild/", "key": "book$grandchild", - "genre": "", + "genre": "Sonet", "simple_thumb": "", "slug": "grandchild", "cover_thumb": "" @@ -37,13 +39,14 @@ "cover_color": "#a6820a", "author": "John Doe", "url": "https://example.com/katalog/lektura/parent/", - "has_audio": false, + "has_audio": true, + "title": "Parent", "cover": "cover/parent.jpg", "epoch": "Barok", "href": "https://example.com/api/books/parent/", "key": "book$parent", "genre": "Sonet", - "simple_thumb": "https://example.com/media/cover/parent_cover_api_thumb.jpg", + "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg", "slug": "parent", "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193" } diff --git a/src/api/tests/res/responses/fragment.json b/src/api/tests/res/responses/fragment.json new file mode 100644 index 000000000..40db3f4f3 --- /dev/null +++ b/src/api/tests/res/responses/fragment.json @@ -0,0 +1,30 @@ +{ + "url": "https://example.com/katalog/lektura/child.html#man-anchor", + "text": "A fragment", + "book": { + "kind": "", + "full_sort_key": "$child$2", + "author": "", + "url": "https://example.com/katalog/lektura/child/", + "cover_color": "#000000", + "title": "Child", + "cover": "", + "liked": null, + "slug": "child", + "epoch": "", + "href": "https://example.com/api/books/child/", + "genre": "Wiersz", + "simple_thumb": "", + "has_audio": false, + "cover_thumb": "" + }, + "anchor": "an-anchor", + "themes": [ + { + "url": "https://example.com/katalog/motyw/koniec/", + "href": "https://example.com/api/themes/koniec/", + "name": "Koniec", + "slug": "koniec" + } + ] +} diff --git a/src/api/tests/res/responses/fragments.json b/src/api/tests/res/responses/fragments.json new file mode 100644 index 000000000..1733ba171 --- /dev/null +++ b/src/api/tests/res/responses/fragments.json @@ -0,0 +1,24 @@ +[ + { + "url": "https://example.com/katalog/lektura/child.html#man-anchor", + "book": { + "kind": "", + "full_sort_key": "$child$2", + "author": "", + "url": "https://example.com/katalog/lektura/child/", + "cover_color": "#000000", + "title": "Child", + "cover": "", + "liked": null, + "slug": "child", + "epoch": "", + "href": "https://example.com/api/books/child/", + "genre": "Wiersz", + "simple_thumb": "", + "has_audio": false, + "cover_thumb": "" + }, + "anchor": "an-anchor", + "href": "https://example.com/api/books/child/fragments/an-anchor/" + } +] diff --git a/src/api/tests/res/responses/newest.json b/src/api/tests/res/responses/newest.json deleted file mode 100644 index 8abde743f..000000000 --- a/src/api/tests/res/responses/newest.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "kind": "Liryka", - "full_sort_key": "john doe$parent$1", - "cover_color": "#a6820a", - "author": "John Doe", - "url": "https://example.com/katalog/lektura/parent/", - "has_audio": false, - "cover": "cover/parent.jpg", - "epoch": "Barok", - "href": "https://example.com/api/books/parent/", - "genre": "Sonet", - "simple_thumb": "https://example.com/media/cover/parent_cover_api_thumb.jpg", - "slug": "parent", - "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193" - } -] diff --git a/src/api/tests/res/responses/preview.json b/src/api/tests/res/responses/preview.json deleted file mode 100644 index fe51488c7..000000000 --- a/src/api/tests/res/responses/preview.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/src/api/tests/res/responses/recommended.json b/src/api/tests/res/responses/recommended.json deleted file mode 100644 index fe51488c7..000000000 --- a/src/api/tests/res/responses/recommended.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/src/api/tests/res/responses/tags.json b/src/api/tests/res/responses/tags.json new file mode 100644 index 000000000..4729bebab --- /dev/null +++ b/src/api/tests/res/responses/tags.json @@ -0,0 +1,14 @@ +[ + { + "url": "https://example.com/katalog/gatunek/sonet/", + "href": "https://example.com/api/genres/sonet/", + "name": "Sonet", + "slug": "sonet" + }, + { + "url": "https://example.com/katalog/gatunek/wiersz/", + "href": "https://example.com/api/genres/wiersz/", + "name": "Wiersz", + "slug": "wiersz" + } +] diff --git a/src/api/tests/tests.py b/src/api/tests/tests.py index 32d394e70..5486b5f53 100644 --- a/src/api/tests/tests.py +++ b/src/api/tests/tests.py @@ -35,6 +35,10 @@ class ApiTest(TestCase): good_data = json.load(f) self.assertEqual(data, good_data, json.dumps(data, indent=4)) + def assert_slugs(self, url, slugs): + have_slugs = [x['slug'] for x in self.load_json(url)] + self.assertEqual(have_slugs, slugs, have_slugs) + class BookTests(ApiTest): @@ -101,19 +105,87 @@ class PictureTests(ApiTest): Picture.objects.get(slug=slug) -class URLTests(ApiTest): +class BooksTests(ApiTest): fixtures = ['test-books.yaml'] - def test_get(self): - # book lists - self.assert_json_response('/api/audiobooks/', 'audiobooks.json') - self.assert_json_response('/api/daisy/', 'daisy.json') + def test_books(self): + self.assert_json_response('/api/books/', 'books.json') + self.assert_json_response('/api/books/?new_api=true', 'books.json') + + self.assert_slugs('/api/audiobooks/', ['parent']) + self.assert_slugs('/api/daisy/', ['parent']) + self.assert_slugs('/api/newest/', ['parent']) + self.assert_slugs('/api/parent_books/', ['parent']) + self.assert_slugs('/api/recommended/', ['parent']) + + # Book paging. + self.assert_slugs('/api/books/after/grandchild/count/1/', ['parent']) + self.assert_slugs('/api/books/?new_api=true&after=$grandchild$3&count=1', ['parent']) + + # By tag. + self.assert_slugs('/api/authors/john-doe/books/', ['parent']) + self.assert_slugs('/api/genres/sonet/books/?authors=john-doe', ['parent']) + # It is probably a mistake that this doesn't filter: + self.assert_slugs('/api/books/?authors=john-doe', ['child', 'grandchild', 'parent']) + + # Parent books by tag. + # Notice this contains a grandchild, if a child doesn't have the tag. + # This probably isn't really intended behavior and should be redefined. + self.assert_slugs('/api/genres/sonet/parent_books/', ['grandchild', 'parent']) + + def test_ebooks(self): self.assert_json_response('/api/ebooks/', 'ebooks.json') + + def test_filter_books(self): self.assert_json_response('/api/filter-books/', 'filter-books.json') - self.assert_json_response('/api/newest/', 'newest.json') + self.assert_slugs( + '/api/filter-books/?lektura=false&preview=false', + ['child', 'grandchild', 'parent']) + self.assert_slugs( + '/api/filter-books/?lektura=true', + []) - self.assert_json_response('/api/blog/', 'blog.json') - self.assert_json_response('/api/preview/', 'preview.json') - self.assert_json_response('/api/recommended/', 'recommended.json') + Book.objects.filter(slug='child').update(preview=True) + self.assert_slugs('/api/filter-books/?preview=true', ['child']) + self.assert_slugs('/api/filter-books/?preview=false', ['grandchild', 'parent']) + + self.assert_slugs('/api/filter-books/?audiobook=true', ['parent']) + self.assert_slugs('/api/filter-books/?audiobook=false', ['child', 'grandchild']) + self.assert_slugs('/api/filter-books/?genres=wiersz', ['child']) + + self.assert_slugs('/api/filter-books/?search=parent', ['parent']) + + def test_collections(self): self.assert_json_response('/api/collections/', 'collections.json') + self.assert_json_response('/api/collections/a-collection/', 'collection.json') + + def test_book(self): + self.assert_json_response('/api/books/parent/', 'books-parent.json') + self.assert_json_response('/api/books/child/', 'books-child.json') + self.assert_json_response('/api/books/grandchild/', 'books-grandchild.json') + + def test_tags(self): + # List of tags by category. + self.assert_json_response('/api/genres/', 'tags.json') + + def test_fragments(self): + # This is not supported, though it probably should be. + #self.assert_json_response('/api/books/child/fragments/', 'fragments.json') + + self.assert_json_response('/api/genres/wiersz/fragments/', 'fragments.json') + self.assert_json_response('/api/genres/wiersz/fragments/', 'fragments.json') + + self.assert_json_response('/api/books/child/fragments/an-anchor/', 'fragment.json') + + +class BlogTests(ApiTest): + def test_get(self): + self.assertEqual(self.load_json('/api/blog/'), []) + + +class PreviewTests(ApiTest): + def unauth(self): + self.assert_json_response('/api/preview/', 'preview.json') + + diff --git a/src/catalogue/__init__.py b/src/catalogue/__init__.py index 16c132645..612517b92 100644 --- a/src/catalogue/__init__.py +++ b/src/catalogue/__init__.py @@ -4,6 +4,7 @@ # import logging from django.conf import settings as settings +from django.utils.module_loading import import_string from catalogue.utils import AppSettings @@ -25,6 +26,7 @@ class Settings(AppSettings): REDAKCJA_URL = "http://redakcja.wolnelektury.pl" GOOD_LICENSES = {r'CC BY \d\.\d', r'CC BY-SA \d\.\d'} RELATED_RANDOM_PICTURE_CHANCE = .5 + GET_MP3_LENGTH = 'catalogue.utils.get_mp3_length' def _more_DONT_BUILD(self, value): for format_ in ['cover', 'pdf', 'epub', 'mobi', 'fb2', 'txt']: @@ -45,5 +47,8 @@ class Settings(AppSettings): value[format_] = getattr(settings, attname) return value + def _more_GET_MP3_LENGTH(self, value): + return import_string(value) + app_settings = Settings('CATALOGUE') diff --git a/src/catalogue/fixtures/test-books.yaml b/src/catalogue/fixtures/test-books.yaml index 43ca447e9..ad7636863 100644 --- a/src/catalogue/fixtures/test-books.yaml +++ b/src/catalogue/fixtures/test-books.yaml @@ -2,20 +2,25 @@ pk: 1 fields: slug: parent + title: Parent sort_key: parent sort_key_author: john doe + xml_file: xml/parent.xml epub_file: epub/parent.epub mobi_file: mobi/parent.mobi pdf_file: pdf/parent.pdf cover: cover/parent.jpg - cover_api_thumb: cover/parent_cover_api_thumb.jpg + cover_api_thumb: cover_api_thumb/parent.jpg + simple_cover: simple_cover/parent.jpg + recommended: true created_at: "1970-01-03 0:0Z" changed_at: "1970-01-03 0:0Z" - extra_info: "{\"epoch\": \"Barok\"}" + extra_info: '{"epoch": "Barok"}' - model: catalogue.book pk: 2 fields: slug: child + title: Child sort_key: child parent: 1 created_at: "1970-01-02 0:0Z" @@ -24,6 +29,7 @@ pk: 3 fields: slug: grandchild + title: Grandchild sort_key: grandchild parent: 2 txt_file: txt/grandchild.txt @@ -68,29 +74,95 @@ name: Sonet created_at: "1970-01-03 0:0Z" changed_at: "1970-01-03 0:0Z" +- model: catalogue.tag + pk: 5 + fields: + slug: wiersz + sort_key: wiersz + category: genre + name: Wiersz + created_at: "1970-01-03 0:0Z" + changed_at: "1970-01-03 0:0Z" + - model: catalogue.tagrelation - pk: 1 fields: tag: 1 content_type: ['catalogue', 'book'] object_id: 1 - model: catalogue.tagrelation - pk: 2 fields: tag: 2 content_type: ['catalogue', 'book'] object_id: 1 - model: catalogue.tagrelation - pk: 3 fields: tag: 3 content_type: ['catalogue', 'book'] object_id: 1 - model: catalogue.tagrelation - pk: 4 fields: tag: 4 content_type: ['catalogue', 'book'] object_id: 1 +- model: catalogue.tagrelation + fields: + tag: 4 + content_type: ['catalogue', 'book'] + object_id: 3 +- model: catalogue.tagrelation + fields: + tag: 5 + content_type: ['catalogue', 'book'] + object_id: 2 + +- model: catalogue.bookmedia + fields: + book: 1 + type: mp3 + name: Parent Audiobook + file: mp3/parent.mp3 + uploaded_at: "1970-01-03 0:0Z" + extra_info: {"director_name": "Director", "artist_name": "Artist"} +- model: catalogue.bookmedia + fields: + book: 1 + type: daisy + name: Parent DAISY + file: daisy/parent.daisy + uploaded_at: "1970-01-03 0:0Z" + +- model: catalogue.fragment + id: 1 + fields: + short_text: "Fragment" + text: "A fragment" + anchor: "an-anchor" + book: 2 +- model: catalogue.tagrelation + fields: + tag: 5 + content_type: ['catalogue', 'fragment'] + object_id: 1 +- model: catalogue.tag + pk: 101 + fields: + slug: koniec + sort_key: koniec + category: theme + name: Koniec + created_at: "1970-01-03 0:0Z" + changed_at: "1970-01-03 0:0Z" +- model: catalogue.tagrelation + fields: + tag: 101 + content_type: ['catalogue', 'fragment'] + object_id: 1 + +- model: catalogue.collection + fields: + title: A Collection + slug: a-collection + description: Description + book_slugs: parent diff --git a/src/catalogue/models/book.py b/src/catalogue/models/book.py index 8c53d9c1a..6e6c50f8f 100644 --- a/src/catalogue/models/book.py +++ b/src/catalogue/models/book.py @@ -229,11 +229,9 @@ class Book(models.Model): return '%d:%02d:%02d' % (hours, minutes, seconds) def get_audio_length(self): - from mutagen.mp3 import MP3 total = 0 for media in self.get_mp3() or (): - audio = MP3(media.file.path) - total += audio.info.length + total += app_settings.GET_MP3_LENGTH(media.file.path) return int(total) def has_media(self, type_): diff --git a/src/catalogue/models/collection.py b/src/catalogue/models/collection.py index 15a4e2adc..e95204341 100644 --- a/src/catalogue/models/collection.py +++ b/src/catalogue/models/collection.py @@ -14,10 +14,7 @@ class Collection(models.Model): title = models.CharField(_('title'), max_length=120, db_index=True) slug = models.SlugField(_('slug'), max_length=120, primary_key=True) description = models.TextField(_('description'), null=True, blank=True) - - models.SlugField(_('slug'), max_length=120, unique=True, db_index=True) book_slugs = models.TextField(_('book slugs')) - kind = models.CharField(_('kind'), max_length=10, blank=False, default='book', db_index=True, choices=(('book', _('book')), ('picture', _('picture')))) diff --git a/src/catalogue/test_utils.py b/src/catalogue/test_utils.py index 18c567406..8c76b899d 100644 --- a/src/catalogue/test_utils.py +++ b/src/catalogue/test_utils.py @@ -91,3 +91,7 @@ def get_fixture(path, app=None): mod_path = extract_stack(limit=2)[0][0] f_path = join(dirname(abspath(mod_path)), 'files', path) return f_path + + +def get_mp3_length(path): + return 60 diff --git a/src/catalogue/utils.py b/src/catalogue/utils.py index 1c188418e..380ec8ecd 100644 --- a/src/catalogue/utils.py +++ b/src/catalogue/utils.py @@ -355,3 +355,7 @@ def gallery_path(slug): def gallery_url(slug): return '%s%s%s/' % (settings.MEDIA_URL, settings.IMAGE_DIR, slug) + +def get_mp3_length(path): + from mutagen.mp3 import MP3 + return int(MP3(path).info.length) diff --git a/src/wolnelektury/settings/test.py b/src/wolnelektury/settings/test.py index 0de27c7a7..0ad0e6988 100644 --- a/src/wolnelektury/settings/test.py +++ b/src/wolnelektury/settings/test.py @@ -1,3 +1,4 @@ from wolnelektury.settings import * THUMBNAIL_BACKEND = 'wolnelektury.test_utils.DummyThumbnailBackend' +CATALOGUE_GET_MP3_LENGTH = 'catalogue.test_utils.get_mp3_length' -- 2.20.1