def setUp(self): WLTestCase.setUp(self) index = Index() index.index.delete_all() index.index.commit() self.do_doktora = Book.from_xml_file(get_fixture('do-doktora.xml')) self.do_anusie = Book.from_xml_file( get_fixture('fraszka-do-anusie.xml', catalogue))
def setUp(self): WLTestCase.setUp(self) index = Index() index.index.delete_all() index.index.commit() with self.settings(NO_SEARCH_INDEX=False): self.do_doktora = Book.from_xml_file(get_fixture('do-doktora.xml')) self.do_anusie = Book.from_xml_file( get_fixture('fraszka-do-anusie.xml', catalogue))
def setUp(self): WLTestCase.setUp(self) index = Index() index.index.delete_all() index.index.commit() self.do_doktora = Book.from_xml_file( get_fixture('do-doktora.xml')) self.do_anusie = Book.from_xml_file( get_fixture('fraszka-do-anusie.xml', catalogue))
def setUp(self): WLTestCase.setUp(self) index = Index() index.index.delete_all() index.index.commit() with self.settings(NO_SEARCH_INDEX=False): self.do_doktora = Book.from_xml_file( get_fixture('do-doktora.xml')) self.do_anusie = Book.from_xml_file( get_fixture('fraszka-do-anusie.xml', catalogue))
def setUp(self): WLTestCase.setUp(self) index = Index() self.search = Search() index.delete_query(self.search.index.query(uid="*")) index.index.commit() self.do_doktora = Book.from_xml_file( get_fixture('do-doktora.xml', opds)) self.do_anusie = Book.from_xml_file( get_fixture('fraszka-do-anusie.xml', catalogue))
def test_simple_import(self, parent_cover_changed): child = Book.from_text_and_meta(ContentFile(self.TEXT), self.child) parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent) parent_cover_changed.assert_called_with(child) # Now reimport parent. parent_cover_changed.reset_mock() parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, overwrite=True) self.assertEqual(parent_cover_changed.call_count, 0) # Now change cover in parent. parent_cover_changed.reset_mock() self.parent.cover_url = "http://example.com/other-cover.jpg" parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, overwrite=True) parent_cover_changed.assert_called_with(child)
def test_none_indexed(self): self.book2 = Book.create(self.user, 'book 2', slug='book2') self.make_gallery(self.book1, { '0001_1l' : 'aa', '0001_2r' : 'bb', '0002_1l' : 'cc', '0002_2r' : 'dd', }) self.make_gallery(self.book2, { '0001_1l' : 'ee', '0001_2r' : 'ff', '0002_1l' : 'gg', '0002_2r' : 'hh', }) self.book1.append(self.book2) files = listdir(join(self.scandir, self.book1.gallery)) files.sort() print files self.assertEqual(files, [ '0-0001_1l', '0-0001_2r', '0-0002_1l', '0-0002_2r', '1-0001_1l', '1-0001_2r', '1-0002_1l', '1-0002_2r', ])
def create_missing(request, slug=None): if slug is None: slug = '' slug = slug.replace(' ', '-') if request.method == "POST": form = forms.DocumentCreateForm(request.POST, request.FILES) if form.is_valid(): if request.user.is_authenticated(): creator = request.user else: creator = None book = Book.create( text=form.cleaned_data['text'], creator=creator, slug=form.cleaned_data['slug'], title=form.cleaned_data['title'], gallery=form.cleaned_data['gallery'], ) return http.HttpResponseRedirect(reverse("catalogue_book", args=[book.slug])) else: form = forms.DocumentCreateForm(initial={ "slug": slug, "title": slug.replace('-', ' ').title(), "gallery": slug, }) return render(request, "catalogue/document_create_missing.html", { "slug": slug, "form": form, "logout_to": '/', })
def test_new_child(self, parent_cover_changed): # Add parent without child first. parts, self.parent.parts = self.parent.parts, [] parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent) # Now import child and reimport parent. child = Book.from_text_and_meta(ContentFile(self.TEXT), self.child) self.parent.parts = parts parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, overwrite=True) parent_cover_changed.assert_called_with(child) # Now remove the child. parent_cover_changed.reset_mock() self.parent.parts = [] parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent, overwrite=True) parent_cover_changed.assert_called_with(child)
def tag_dict(tag, fields=None): all_fields = ("name", "category", "sort_key", "description", "gazeta_link", "wiki_link", "url", "books") if fields: fields = (f for f in fields if f in all_fields) else: fields = all_fields obj = {} for field in fields: if field == "url": obj[field] = tag.get_absolute_url() elif field == "books": obj[field] = [b.id for b in Book.tagged_top_level([tag]).iterator()] elif field == "sort_key": obj[field] = tag.sort_key else: f = getattr(tag, field) if f: obj[field] = f obj["id"] = tag.id return obj
def catalogue_csv(path): books_by_author, orphans, books_by_parent = Book.book_list() render_to_csv(path, 'reporting/catalogue.csv', { 'books_by_author': books_by_author, 'orphans': orphans, 'books_by_parent': books_by_parent, })
def test_book_with_footnote(self): book_text = """<utwor> <opowiadanie> <akap><pe><slowo_obce>rose</slowo_obce> --- kind of a flower.</pe></akap> <akap><pe><slowo_obce>rose</slowo_obce> --- kind of a flower.</pe></akap> <akap><pe><slowo_obce>rose</slowo_obce> (techn.) --- #FF007F.</pe></akap> </opowiadanie></utwor> """ book = Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.assertEqual( len(self.client.get('/przypisy/').context['object_list']), 2, 'There should be two notes on the note list.') self.assertEqual( len(self.client.get('/przypisy/?ltr=a').context['object_list']), 0, 'There should not be a note for the letter A.') self.assertEqual( len(self.client.get('/przypisy/?ltr=r').context['object_list']), 2, 'Both notes start with the letter R.') self.assertEqual( len(self.client.get('/przypisy/?qual=techn.').context['object_list']), 1, 'There should be a note qualified with \'techn.\' qualifier.')
def read(self, request, tags, top_level=False, audiobooks=False, daisy=False): """ Lists all books with given tags. :param tags: filtering tags; should be a path of categories and slugs, i.e.: authors/an-author/epoch/an-epoch/ :param top_level: if True and a book is included in the results, it's children are aren't. By default all books matching the tags are returned. """ try: tags = read_tags(tags, allowed=book_tag_categories) except ValueError: return rc.NOT_FOUND if tags: if top_level: books = Book.tagged_top_level(tags) return books if books else rc.NOT_FOUND else: books = Book.tagged.with_all(tags) else: books = Book.objects.all() if top_level: books = books.filter(parent=None) if audiobooks: books = books.filter(media__type="mp3").distinct() if daisy: books = books.filter(media__type="daisy").distinct() if books.exists(): return books else: return rc.NOT_FOUND
def save(self, **kwargs): return Book.from_xml_file( self.cleaned_data["book_xml_file"], overwrite=True, remote_gallery_url=self.cleaned_data["gallery_url"], **kwargs )
def tag_dict(tag, fields=None): all_fields = ('name', 'category', 'sort_key', 'description', 'gazeta_link', 'wiki_link', 'url', 'books', ) if fields: fields = (f for f in fields if f in all_fields) else: fields = all_fields obj = {} for field in fields: if field == 'url': obj[field] = tag.get_absolute_url() elif field == 'books': obj[field] = [b.id for b in Book.tagged_top_level([tag]).iterator()] elif field == 'sort_key': obj[field] = tag.sort_key else: f = getattr(tag, field) if f: obj[field] = f obj['id'] = tag.id return obj
def test_book_with_footnote(self): book_text = """<utwor> <opowiadanie> <akap><pe><slowo_obce>rose</slowo_obce> --- kind of a flower.</pe></akap> <akap><pe><slowo_obce>rose</slowo_obce> --- kind of a flower.</pe></akap> <akap><pe><slowo_obce>rose</slowo_obce> (techn.) --- #FF007F.</pe></akap> </opowiadanie></utwor> """ book = Book.from_text_and_meta(ContentFile(book_text), self.book_info) self.assertEqual( len(self.client.get('/przypisy/').context['object_list']), 2, 'There should be two notes on the note list.') self.assertEqual( len(self.client.get('/przypisy/?ltr=a').context['object_list']), 0, 'There should not be a note for the letter A.') self.assertEqual( len(self.client.get('/przypisy/?ltr=r').context['object_list']), 2, 'Both notes start with the letter R.') self.assertEqual( len( self.client.get( '/przypisy/?qual=techn.').context['object_list']), 1, 'There should be a note qualified with \'techn.\' qualifier.')
def catalogue_csv(path): books_by_author, orphans, books_by_parent = Book.book_list() render_to_csv( path, 'reporting/catalogue.csv', { 'books_by_author': books_by_author, 'orphans': orphans, 'books_by_parent': books_by_parent, })
def catalogue_pdf(path): books_by_author, orphans, books_by_parent = Book.book_list() render_to_pdf( path, "reporting/catalogue.texml", locals(), {"wl-logo.png": os.path.join(settings.STATIC_ROOT, "img/logo-big.png")}, )
def download_zip(request, format, slug=None): if format in Book.ebook_formats: url = Book.zip_format(format) elif format in ('mp3', 'ogg') and slug is not None: book = get_object_or_404(Book, slug=slug) url = book.zip_audiobooks(format) else: raise Http404('No format specified for zip package') return HttpResponseRedirect(urlquote_plus(settings.MEDIA_URL + url, safe='/?='))
def add_tag(db, tag): id = tag.id category = categories[tag.category] name = tag.name sort_key = tag.sort_key books = Book.tagged_top_level([tag]) book_ids = ','.join(str(b.id) for b in books) db.execute(tag_sql, locals())
def catalogue_pdf(path): books_by_author, orphans, books_by_parent = Book.book_list() render_to_pdf(path, 'reporting/catalogue.texml', { 'books_by_author': books_by_author, 'orphans': orphans, 'books_by_parent': books_by_parent, }, { "wl-logo.png": os.path.join(settings.STATIC_ROOT, "img/logo-big.png"), })
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, })
def add_tag(db, tag): id = tag.id # category = categories[tag.category] # localized names here? category = tag.category name = tag.name sort_key = tag.sort_key books = Book.tagged_top_level([tag]) book_ids = ','.join(str(b.id) for b in books) db.execute(tag_sql, locals())
def download_zip(request, format, slug=None): if format in Book.ebook_formats: url = Book.zip_format(format) elif format in ('mp3', 'ogg') and slug is not None: book = get_object_or_404(Book, slug=slug) url = book.zip_audiobooks(format) else: raise Http404('No format specified for zip package') return HttpResponseRedirect( urlquote_plus(settings.MEDIA_URL + url, safe='/?='))
def catalogue_pdf(path): books_by_author, orphans, books_by_parent = Book.book_list() render_to_pdf( path, 'reporting/catalogue.texml', { 'books_by_author': books_by_author, 'orphans': orphans, 'books_by_parent': books_by_parent, }, { "wl-logo.png": os.path.join(settings.STATIC_ROOT, "img/logo-big.png"), })
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, })
def setUp(self): self.user = User.objects.create(username='******') self.book1 = Book.create(self.user, 'book 1', slug='book1') self.book1.chunk_set.create(number=2, title='Second chunk', slug='book1-2') c=self.book1[1] c.gallery_start=3 self.scandir = join(settings.MEDIA_ROOT, settings.IMAGE_DIR) if not exists(self.scandir): makedirs(self.scandir)
def get_queryset(self): try: tags, ancestors = read_tags( self.kwargs.get('tags', ''), self.request, allowed=('author', 'epoch', 'kind', 'genre') ) except ValueError: raise Http404 new_api = self.request.query_params.get('new_api') after = self.request.query_params.get('after', self.kwargs.get('after')) count = self.request.query_params.get('count', self.kwargs.get('count')) if count: try: count = int(count) except TypeError: raise Http404 # Fixme if tags: if self.kwargs.get('top_level'): books = Book.tagged_top_level(tags) if not books: raise Http404 return books else: books = Book.tagged.with_all(tags) else: books = Book.objects.all() books = order_books(books, new_api) if self.kwargs.get('top_level'): books = books.filter(parent=None) if self.kwargs.get('audiobooks'): books = books.filter(media__type='mp3').distinct() if self.kwargs.get('daisy'): books = books.filter(media__type='daisy').distinct() if self.kwargs.get('recommended'): books = books.filter(recommended=True) if self.kwargs.get('newest'): books = books.order_by('-created_at') if after: books = books_after(books, after, new_api) prefetch_relations(books, 'author') prefetch_relations(books, 'genre') prefetch_relations(books, 'kind') prefetch_relations(books, 'epoch') if count: books = books[:count] return books
def read(self, request, tags=None, top_level=False, audiobooks=False, daisy=False, pk=None): """ Lists all books with given tags. :param tags: filtering tags; should be a path of categories and slugs, i.e.: authors/an-author/epoch/an-epoch/ :param top_level: if True and a book is included in the results, it's children are aren't. By default all books matching the tags are returned. """ if pk is not None: try: return Book.objects.get(pk=pk) except Book.DoesNotExist: return rc.NOT_FOUND try: tags, _ancestors = read_tags(tags, allowed=book_tag_categories) except ValueError: return rc.NOT_FOUND if tags: if top_level: books = Book.tagged_top_level(tags) return books if books else rc.NOT_FOUND else: books = Book.tagged.with_all(tags) else: books = Book.objects.all() if top_level: books = books.filter(parent=None) if audiobooks: books = books.filter(media__type='mp3').distinct() if daisy: books = books.filter(media__type='daisy').distinct() books = books.only('slug', 'title', 'cover', 'cover_thumb') for category in book_tag_categories: books = prefetch_relations(books, category) if books: return books else: return rc.NOT_FOUND
def book_list(request, filters=None, template_name='catalogue/book_list.html', nav_template_name='catalogue/snippets/book_list_nav.html', list_template_name='catalogue/snippets/book_list.html'): """ generates a listing of all books, optionally filtered """ books_by_author, orphans, books_by_parent = Book.book_list(filters) books_nav = OrderedDict() for tag in books_by_author: if books_by_author[tag]: books_nav.setdefault(tag.sort_key[0], []).append(tag) return render(request, template_name, { 'rendered_nav': render_to_string(nav_template_name, {'books_nav': books_nav}), 'rendered_book_list': render_to_string(list_template_name, { 'books_by_author': books_by_author, 'orphans': orphans, 'books_by_parent': books_by_parent, }) })
def import_book(self, file_path, options): verbose = options.get('verbose') file_base, ext = os.path.splitext(file_path) book = Book.from_xml_file(file_path, overwrite=options.get('force'), build_epub=options.get('build_epub'), build_txt=options.get('build_txt'), build_pdf=options.get('build_pdf'), build_mobi=options.get('build_mobi'), search_index=options.get('search_index'), search_index_reuse=True, search_index_tags=False) for ebook_format in Book.ebook_formats: if os.path.isfile(file_base + '.' + ebook_format): getattr(book, '%s_file' % ebook_format).save( '%s.%s' % (book.slug, ebook_format), File(file(file_base + '.' + ebook_format))) if verbose: print "Importing %s.%s" % (file_base, ebook_format) book.save()
def test_basic(self): book = Book(title='A Book') book.save() tag = Tag.objects.create(category='author', name='Author') book.tags = [tag] book.save() changes = json.loads(self.client.get('/api/changes/0.json?book_fields=title&tag_fields=name').content) self.assertEqual(changes['updated']['books'], [{'id': book.id, 'title': book.title}], 'Invalid book format in changes') self.assertEqual(changes['updated']['tags'], [{'id': tag.id, 'name': tag.name}], 'Invalid tag format in changes')
def test_both_indexed(self): self.book2 = Book.create(self.user, 'book 2', slug='book2') self.book2.chunk_set.create(number=2, title='Second chunk of second book', slug='book2-2') c = self.book2[1] c.gallery_start = 3 c.save() print "gallery starts:",self.book2[0].gallery_start, self.book2[1].gallery_start self.make_gallery(self.book1, { '1-0001_1l' : 'aa', '1-0001_2r' : 'bb', '1-0002_1l' : 'cc', '1-0002_2r' : 'dd', }) self.make_gallery(self.book2, { '1-0001_1l' : 'dd', # the same, should not be moved '1-0001_2r' : 'ff', '2-0002_1l' : 'gg', '2-0002_2r' : 'hh', }) self.book1.append(self.book2) files = listdir(join(self.scandir, self.book1.gallery)) files.sort() print files self.assertEqual(files, [ '1-0001_1l', '1-0001_2r', '1-0002_1l', '1-0002_2r', # '2-0001_1l', '2-0001_2r', '3-0002_1l', '3-0002_2r', ]) self.assertEqual((4, 6), (self.book1[2].gallery_start, self.book1[3].gallery_start))
def import_book(self, file_path, options): verbose = options.get('verbose') if options.get('dont_build'): dont_build = options.get('dont_build').lower().split(',') else: dont_build = None file_base, ext = os.path.splitext(file_path) book = Book.from_xml_file(file_path, overwrite=options.get('force'), dont_build=dont_build, search_index_tags=False) for ebook_format in Book.ebook_formats: if os.path.isfile(file_base + '.' + ebook_format): getattr(book, '%s_file' % ebook_format).save( '%s.%s' % (book.slug, ebook_format), File(file(file_base + '.' + ebook_format)), save=False ) if verbose: print "Importing %s.%s" % (file_base, ebook_format) book.save()
def test_book_with_footnote(self): BOOK_TEXT = """<utwor> <opowiadanie> <akap><pe><slowo_obce>rose</slowo_obce> --- kind of a flower.</pe></akap> </opowiadanie></utwor> """ book = Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info) self.assertEqual( len(self.client.get('/przypisy/').context['object_list']), 1, 'There should be a note on the note list.') self.assertEqual( len(self.client.get('/przypisy/a/').context['object_list']), 0, 'There should not be a note for the letter A.') self.assertEqual( len(self.client.get('/przypisy/r/').context['object_list']), 1, 'There should be a note for the letter R.')
def import_book(self, file_path, options): verbose = options.get('verbose') if options.get('dont_build'): dont_build = options.get('dont_build').lower().split(',') else: dont_build = None file_base, ext = os.path.splitext(file_path) book = Book.from_xml_file(file_path, overwrite=options.get('force'), dont_build=dont_build, search_index_tags=False) for ebook_format in Book.ebook_formats: if os.path.isfile(file_base + '.' + ebook_format): getattr(book, '%s_file' % ebook_format).save( '%s.%s' % (book.slug, ebook_format), File(file(file_base + '.' + ebook_format)), save=False) if verbose: print "Importing %s.%s" % (file_base, ebook_format) book.save()
def tagged_object_list(request, tags, list_type): try: tags = analyse_tags(request, tags) except ResponseInstead as e: return e.response if list_type == 'gallery' and any(tag.category == 'set' for tag in tags): raise Http404 if any(tag.category in ('theme', 'thing') for tag in tags): return theme_list(request, tags, list_type=list_type) if list_type == 'books': books = Book.tagged.with_all(tags) if any(tag.category == 'set' for tag in tags): params = {'objects': books} else: params = { 'objects': Book.tagged_top_level(tags), 'fragments': Fragment.objects.filter(book__in=books), 'related_tags': get_top_level_related_tags(tags), } elif list_type == 'gallery': params = {'objects': Picture.tagged.with_all(tags)} elif list_type == 'audiobooks': audiobooks = Book.objects.filter(media__type__in=('mp3', 'ogg')).distinct() params = { 'objects': Book.tagged.with_all(tags, audiobooks), 'extra': { 'daisy': Book.tagged.with_all( tags, audiobooks.filter(media__type='daisy').distinct()), } } else: raise Http404 return object_list(request, tags=tags, list_type=list_type, **params)
def test_basic(self): book = Book(title='A Book') book.save() tag = Tag.objects.create(category='author', name='Author') book.tags = [tag] book.save() changes = json.loads( self.client.get( '/api/changes/0.json?book_fields=title&tag_fields=name'). content) self.assertEqual(changes['updated']['books'], [{ 'id': book.id, 'title': book.title }], 'Invalid book format in changes') self.assertEqual(changes['updated']['tags'], [{ 'id': tag.id, 'name': tag.name }], 'Invalid tag format in changes')
def tagged_object_list(request, tags, list_type): try: tags = analyse_tags(request, tags) except ResponseInstead as e: return e.response if is_crawler(request) and len(tags) > 1: return HttpResponseForbidden('address removed from crawling. check robots.txt') if list_type == 'gallery' and any(tag.category == 'set' for tag in tags): raise Http404 if any(tag.category in ('theme', 'thing') for tag in tags): return theme_list(request, tags, list_type=list_type) if list_type == 'books': books = Book.tagged.with_all(tags) if any(tag.category == 'set' for tag in tags): params = {'objects': books} else: params = { 'objects': Book.tagged_top_level(tags), 'fragments': Fragment.objects.filter(book__in=books), 'related_tags': get_top_level_related_tags(tags), } elif list_type == 'gallery': params = {'objects': Picture.tagged.with_all(tags)} elif list_type == 'audiobooks': audiobooks = Book.objects.filter(media__type__in=('mp3', 'ogg')).distinct() params = { 'objects': Book.tagged.with_all(tags, audiobooks), 'extra': { 'daisy': Book.tagged.with_all(tags, audiobooks.filter(media__type='daisy').distinct()), } } else: raise Http404 return object_list(request, tags=tags, list_type=list_type, **params)
def read(self, request, tags, top_level=False, audiobooks=False, daisy=False): """ Lists all books with given tags. :param tags: filtering tags; should be a path of categories and slugs, i.e.: authors/an-author/epoch/an-epoch/ :param top_level: if True and a book is included in the results, it's children are aren't. By default all books matching the tags are returned. """ try: tags = read_tags(tags, allowed=book_tag_categories) except ValueError: return rc.NOT_FOUND if tags: if top_level: books = Book.tagged_top_level(tags) return books if books else rc.NOT_FOUND else: books = Book.tagged.with_all(tags) else: books = Book.objects.all() if top_level: books = books.filter(parent=None) if audiobooks: books = books.filter(media__type='mp3').distinct() if daisy: books = books.filter(media__type='daisy').distinct() if books.exists(): return books else: return rc.NOT_FOUND
def tag_dict(tag, fields=None): all_fields = ( 'name', 'category', 'sort_key', 'description', 'gazeta_link', 'wiki_link', 'url', 'books', ) if fields: fields = (f for f in fields if f in all_fields) else: fields = all_fields obj = {} for field in fields: if field == 'url': obj[field] = tag.get_absolute_url() elif field == 'books': obj[field] = [ b.id for b in Book.tagged_top_level([tag]).iterator() ] elif field == 'sort_key': obj[field] = tag.sort_key else: f = getattr(tag, field) if f: obj[field] = f obj['id'] = tag.id return obj
def book_list(request, filters=None, template_name='catalogue/book_list.html', nav_template_name='catalogue/snippets/book_list_nav.html', list_template_name='catalogue/snippets/book_list.html'): """ generates a listing of all books, optionally filtered """ books_by_author, orphans, books_by_parent = Book.book_list(filters) books_nav = OrderedDict() for tag in books_by_author: if books_by_author[tag]: books_nav.setdefault(tag.sort_key[0], []).append(tag) # WTF: dlaczego nie include? return render_to_response(template_name, { 'rendered_nav': render_to_string(nav_template_name, {'books_nav': books_nav}), 'rendered_book_list': render_to_string( list_template_name, { 'books_by_author': books_by_author, 'orphans': orphans, 'books_by_parent': books_by_parent, }) }, context_instance=RequestContext(request))
def catalogue_csv(path): books_by_author, orphans, books_by_parent = Book.book_list() render_to_csv(path, 'reporting/catalogue.csv', locals())
def save(self, commit=True, **kwargs): return Book.from_xml_file(self.cleaned_data['book_xml_file'], overwrite=True, **kwargs)
def for_set(cls, tag): books = Book.tagged_top_level([tag]) cont_tabs = (cls.get(b) for b in books.iterator()) return reduce(cls.join_conts, cont_tabs)
def save(self, **kwargs): return Book.from_xml_file(self.cleaned_data['book_xml_file'], overwrite=True, remote_gallery_url=self.cleaned_data['gallery_url'], **kwargs)
def setUp(self): self.user = User.objects.create(username='******') self.text1 = get_fixture('chunk1.xml') self.book = Book.create(self.user, self.text1, slug='test-book')
def items(self, tag): return Book.tagged_top_level([tag])
def test_change_cover(self, parent_cover_changed): child = Book.from_text_and_meta(ContentFile(self.TEXT), self.child) parent = Book.from_text_and_meta(ContentFile(self.TEXT), self.parent) parent_cover_changed.assert_called_with(child)