def opdsToMetadata(self, opdsBookStructure): authors = opdsBookStructure.author.replace(u'& ', u'&') metadata = Metadata(opdsBookStructure.title, authors.split(u'&')) metadata.uuid = opdsBookStructure.id.replace('urn:uuid:', '', 1) rawTimestamp = opdsBookStructure.updated parsableTimestamp = re.sub('((\.[0-9]+)?\+00:00|Z)$', '', rawTimestamp) metadata.timestamp = datetime.datetime.strptime(parsableTimestamp, '%Y-%m-%dT%H:%M:%S') tags = [] summary = opdsBookStructure.get(u'summary', u'') summarylines = summary.splitlines() for summaryline in summarylines: if summaryline.startswith(u'TAGS: '): tagsline = summaryline.replace(u'TAGS: ', u'') tagsline = tagsline.replace(u'<br />',u'') tagsline = tagsline.replace(u', ', u',') tags = tagsline.split(u',') metadata.tags = tags bookDownloadUrls = [] links = opdsBookStructure.get('links', []) for link in links: url = link.get('href', '') bookType = link.get('type', '') # Skip covers and thumbnails if not bookType.startswith('image/'): if bookType == 'application/epub+zip': # EPUB books are preferred and always put at the head of the list if found bookDownloadUrls.insert(0, url) else: # Formats other than EPUB (eg. AZW), are appended as they are found bookDownloadUrls.append(url) metadata.links = bookDownloadUrls return metadata
def opdsToMetadata(self, opdsBookStructure): authors = opdsBookStructure.author.replace(u"& ", u"&") metadata = Metadata(opdsBookStructure.title, authors.split(u"&")) metadata.uuid = opdsBookStructure.id.replace("urn:uuid:", "", 1) rawTimestamp = opdsBookStructure.updated parsableTimestamp = re.sub(r"((\.[0-9]+)?\+00:00|Z)$", "", rawTimestamp) metadata.timestamp = datetime.datetime.strptime( parsableTimestamp, "%Y-%m-%dT%H:%M:%S") tags = [] summary = opdsBookStructure.get(u"summary", u"") summarylines = summary.splitlines() for summaryline in summarylines: if summaryline.startswith(u"TAGS: "): tagsline = summaryline.replace(u"TAGS: ", u"") tagsline = tagsline.replace(u"<br />", u"") tagsline = tagsline.replace(u", ", u",") tags = tagsline.split(u",") metadata.tags = tags bookDownloadUrls = [] links = opdsBookStructure.get("links", []) for link in links: url = link.get("href", "") bookType = link.get("type", "") # Skip covers and thumbnails if not bookType.startswith("image/"): if bookType == "application/x-mobipocket-ebook": # azw3 books are preferred and always put at the head of the list if found bookDownloadUrls.insert(0, url) else: # Other formats are appended as they are found bookDownloadUrls.append(url) metadata.links = bookDownloadUrls return metadata
def test_legacy_adding_books(self): # {{{ 'Test various adding books methods' from calibre.ebooks.metadata.book.base import Metadata legacy, old = self.init_legacy(self.cloned_library), self.init_old(self.cloned_library) mi = Metadata('Added Book0', authors=('Added Author',)) with NamedTemporaryFile(suffix='.aff') as f: f.write(b'xxx') f.flush() T = partial(ET, 'add_books', ([f.name], ['AFF'], [mi]), old=old, legacy=legacy) T()(self) book_id = T(kwargs={'return_ids':True})(self)[1][0] self.assertEqual(legacy.new_api.formats(book_id), ('AFF',)) T(kwargs={'add_duplicates':False})(self) mi.title = 'Added Book1' mi.uuid = 'uuu' T = partial(ET, 'import_book', (mi,[f.name]), old=old, legacy=legacy) book_id = T()(self) self.assertNotEqual(legacy.uuid(book_id, index_is_id=True), old.uuid(book_id, index_is_id=True)) book_id = T(kwargs={'preserve_uuid':True})(self) self.assertEqual(legacy.uuid(book_id, index_is_id=True), old.uuid(book_id, index_is_id=True)) self.assertEqual(legacy.new_api.formats(book_id), ('AFF',)) with NamedTemporaryFile(suffix='.opf') as f: f.write(b'zzzz') f.flush() T = partial(ET, 'import_book', (mi,[f.name]), old=old, legacy=legacy) book_id = T()(self) self.assertFalse(legacy.new_api.formats(book_id)) mi.title = 'Added Book2' T = partial(ET, 'create_book_entry', (mi,), old=old, legacy=legacy) T() T({'add_duplicates':False}) T({'force_id':1000})
def test_legacy_adding_books(self): # {{{ 'Test various adding books methods' from calibre.ebooks.metadata.book.base import Metadata legacy, old = self.init_legacy(self.cloned_library), self.init_old(self.cloned_library) mi = Metadata('Added Book0', authors=('Added Author',)) with NamedTemporaryFile(suffix='.aff') as f: f.write(b'xxx') f.flush() T = partial(ET, 'add_books', ([f.name], ['AFF'], [mi]), old=old, legacy=legacy) T()(self) book_id = T(kwargs={'return_ids':True})(self)[1][0] self.assertEqual(legacy.new_api.formats(book_id), ('AFF',)) T(kwargs={'add_duplicates':False})(self) mi.title = 'Added Book1' mi.uuid = 'uuu' T = partial(ET, 'import_book', (mi,[f.name]), old=old, legacy=legacy) book_id = T()(self) self.assertNotEqual(legacy.uuid(book_id, index_is_id=True), old.uuid(book_id, index_is_id=True)) book_id = T(kwargs={'preserve_uuid':True})(self) self.assertEqual(legacy.uuid(book_id, index_is_id=True), old.uuid(book_id, index_is_id=True)) self.assertEqual(legacy.new_api.formats(book_id), ('AFF',)) T = partial(ET, 'add_format', old=old, legacy=legacy) T((0, 'AFF', BytesIO(b'fffff')))(self) T((0, 'AFF', BytesIO(b'fffff')))(self) T((0, 'AFF', BytesIO(b'fffff')), {'replace':True})(self) with NamedTemporaryFile(suffix='.opf') as f: f.write(b'zzzz') f.flush() T = partial(ET, 'import_book', (mi,[f.name]), old=old, legacy=legacy) book_id = T()(self) self.assertFalse(legacy.new_api.formats(book_id)) mi.title = 'Added Book2' T = partial(ET, 'create_book_entry', (mi,), old=old, legacy=legacy) T() T({'add_duplicates':False}) T({'force_id':1000}) with NamedTemporaryFile(suffix='.txt') as f: f.write(b'tttttt') f.seek(0) bid = legacy.add_catalog(f.name, 'My Catalog') self.assertEqual(old.add_catalog(f.name, 'My Catalog'), bid) cache = legacy.new_api self.assertEqual(cache.formats(bid), ('TXT',)) self.assertEqual(cache.field_for('title', bid), 'My Catalog') self.assertEqual(cache.field_for('authors', bid), ('calibre',)) self.assertEqual(cache.field_for('tags', bid), (_('Catalog'),)) self.assertTrue(bid < legacy.add_catalog(f.name, 'Something else')) self.assertEqual(legacy.add_catalog(f.name, 'My Catalog'), bid) self.assertEqual(old.add_catalog(f.name, 'My Catalog'), bid) bid = legacy.add_news(f.name, {'title':'Events', 'add_title_tag':True, 'custom_tags':('one', 'two')}) self.assertEqual(cache.formats(bid), ('TXT',)) self.assertEqual(cache.field_for('authors', bid), ('calibre',)) self.assertEqual(cache.field_for('tags', bid), (_('News'), 'Events', 'one', 'two')) old.close()
def test_create_book_entry(self): # {{{ 'Test the creation of new book entries' from calibre.ebooks.metadata.book.base import Metadata cache = self.init_cache() mi = Metadata('Created One', authors=('Creator One', 'Creator Two')) book_id = cache.create_book_entry(mi) self.assertIsNot(book_id, None) def do_test(cache, book_id): for field in ('path', 'uuid', 'author_sort', 'timestamp', 'pubdate', 'title', 'authors', 'series_index', 'sort'): self.assertTrue(cache.field_for(field, book_id)) for field in ('size', 'cover'): self.assertFalse(cache.field_for(field, book_id)) self.assertEqual( book_id, cache.fields['uuid'].table.uuid_to_id_map[cache.field_for( 'uuid', book_id)]) self.assertLess(now() - cache.field_for('timestamp', book_id), timedelta(seconds=30)) self.assertEqual(('Created One', ('Creator One', 'Creator Two')), (cache.field_for('title', book_id), cache.field_for('authors', book_id))) self.assertEqual(cache.field_for('series_index', book_id), 1.0) self.assertEqual(cache.field_for('pubdate', book_id), UNDEFINED_DATE) do_test(cache, book_id) # Test that the db contains correct data cache = self.init_cache() do_test(cache, book_id) self.assertIs(None, cache.create_book_entry(mi, add_duplicates=False), 'Duplicate added incorrectly') book_id = cache.create_book_entry(mi, cover=IMG) self.assertIsNot(book_id, None) self.assertEqual(IMG, cache.cover(book_id)) import calibre.db.cache as c orig = c.prefs c.prefs = {'new_book_tags': ('newbook', 'newbook2')} try: book_id = cache.create_book_entry(mi) self.assertEqual(('newbook', 'newbook2'), cache.field_for('tags', book_id)) mi.tags = ('one', 'two') book_id = cache.create_book_entry(mi) self.assertEqual(('one', 'two') + ('newbook', 'newbook2'), cache.field_for('tags', book_id)) mi.tags = () finally: c.prefs = orig mi.uuid = 'a preserved uuid' book_id = cache.create_book_entry(mi, preserve_uuid=True) self.assertEqual(mi.uuid, cache.field_for('uuid', book_id))
def read_metadata(root, ver=None, return_extra_data=False): ans = Metadata(_('Unknown'), [_('Unknown')]) prefixes, refines = read_prefixes(root), read_refines(root) identifiers = read_identifiers(root, prefixes, refines) ids = {} for key, vals in iteritems(identifiers): if key == 'calibre': ans.application_id = vals[0] elif key == 'uuid': ans.uuid = vals[0] else: ids[key] = vals[0] ans.set_identifiers(ids) ans.title = read_title(root, prefixes, refines) or ans.title ans.title_sort = read_title_sort(root, prefixes, refines) or ans.title_sort ans.languages = read_languages(root, prefixes, refines) or ans.languages auts, aus = [], [] for a in read_authors(root, prefixes, refines): auts.append(a.name), aus.append(a.sort) ans.authors = auts or ans.authors ans.author_sort = authors_to_string(aus) or ans.author_sort bkp = read_book_producers(root, prefixes, refines) if bkp: if bkp[0]: ans.book_producer = bkp[0] pd = read_pubdate(root, prefixes, refines) if not is_date_undefined(pd): ans.pubdate = pd ts = read_timestamp(root, prefixes, refines) if not is_date_undefined(ts): ans.timestamp = ts lm = read_last_modified(root, prefixes, refines) if not is_date_undefined(lm): ans.last_modified = lm ans.comments = read_comments(root, prefixes, refines) or ans.comments ans.publisher = read_publisher(root, prefixes, refines) or ans.publisher ans.tags = read_tags(root, prefixes, refines) or ans.tags ans.rating = read_rating(root, prefixes, refines) or ans.rating s, si = read_series(root, prefixes, refines) if s: ans.series, ans.series_index = s, si ans.author_link_map = read_author_link_map(root, prefixes, refines) or ans.author_link_map ans.user_categories = read_user_categories(root, prefixes, refines) or ans.user_categories for name, fm in iteritems((read_user_metadata(root, prefixes, refines) or {})): ans.set_user_metadata(name, fm) if return_extra_data: ans = ans, ver, read_raster_cover(root, prefixes, refines), first_spine_item( root, prefixes, refines) return ans
def read_metadata(root, ver=None, return_extra_data=False): ans = Metadata(_('Unknown'), [_('Unknown')]) prefixes, refines = read_prefixes(root), read_refines(root) identifiers = read_identifiers(root, prefixes, refines) ids = {} for key, vals in identifiers.iteritems(): if key == 'calibre': ans.application_id = vals[0] elif key == 'uuid': ans.uuid = vals[0] else: ids[key] = vals[0] ans.set_identifiers(ids) ans.title = read_title(root, prefixes, refines) or ans.title ans.title_sort = read_title_sort(root, prefixes, refines) or ans.title_sort ans.languages = read_languages(root, prefixes, refines) or ans.languages auts, aus = [], [] for a in read_authors(root, prefixes, refines): auts.append(a.name), aus.append(a.sort) ans.authors = auts or ans.authors ans.author_sort = authors_to_string(aus) or ans.author_sort bkp = read_book_producers(root, prefixes, refines) if bkp: if bkp[0]: ans.book_producer = bkp[0] pd = read_pubdate(root, prefixes, refines) if not is_date_undefined(pd): ans.pubdate = pd ts = read_timestamp(root, prefixes, refines) if not is_date_undefined(ts): ans.timestamp = ts lm = read_last_modified(root, prefixes, refines) if not is_date_undefined(lm): ans.last_modified = lm ans.comments = read_comments(root, prefixes, refines) or ans.comments ans.publisher = read_publisher(root, prefixes, refines) or ans.publisher ans.tags = read_tags(root, prefixes, refines) or ans.tags ans.rating = read_rating(root, prefixes, refines) or ans.rating s, si = read_series(root, prefixes, refines) if s: ans.series, ans.series_index = s, si ans.author_link_map = read_author_link_map(root, prefixes, refines) or ans.author_link_map ans.user_categories = read_user_categories(root, prefixes, refines) or ans.user_categories for name, fm in (read_user_metadata(root, prefixes, refines) or {}).iteritems(): ans.set_user_metadata(name, fm) if return_extra_data: ans = ans, ver, read_raster_cover(root, prefixes, refines), first_spine_item(root, prefixes, refines) return ans
def test_create_book_entry(self): # {{{ 'Test the creation of new book entries' from calibre.ebooks.metadata.book.base import Metadata cache = self.init_cache() mi = Metadata('Created One', authors=('Creator One', 'Creator Two')) book_id = cache.create_book_entry(mi) self.assertIsNot(book_id, None) def do_test(cache, book_id): for field in ('path', 'uuid', 'author_sort', 'timestamp', 'pubdate', 'title', 'authors', 'series_index', 'sort'): self.assertTrue(cache.field_for(field, book_id)) for field in ('size', 'cover'): self.assertFalse(cache.field_for(field, book_id)) self.assertEqual(book_id, cache.fields['uuid'].table.uuid_to_id_map[cache.field_for('uuid', book_id)]) self.assertLess(now() - cache.field_for('timestamp', book_id), timedelta(seconds=30)) self.assertEqual(('Created One', ('Creator One', 'Creator Two')), (cache.field_for('title', book_id), cache.field_for('authors', book_id))) self.assertEqual(cache.field_for('series_index', book_id), 1.0) self.assertEqual(cache.field_for('pubdate', book_id), UNDEFINED_DATE) do_test(cache, book_id) # Test that the db contains correct data cache = self.init_cache() do_test(cache, book_id) self.assertIs(None, cache.create_book_entry(mi, add_duplicates=False), 'Duplicate added incorrectly') book_id = cache.create_book_entry(mi, cover=IMG) self.assertIsNot(book_id, None) self.assertEqual(IMG, cache.cover(book_id)) import calibre.db.cache as c orig = c.prefs c.prefs = {'new_book_tags':('newbook', 'newbook2')} try: book_id = cache.create_book_entry(mi) self.assertEqual(('newbook', 'newbook2'), cache.field_for('tags', book_id)) mi.tags = ('one', 'two') book_id = cache.create_book_entry(mi) self.assertEqual(('one', 'two') + ('newbook', 'newbook2'), cache.field_for('tags', book_id)) mi.tags = () finally: c.prefs = orig mi.uuid = 'a preserved uuid' book_id = cache.create_book_entry(mi, preserve_uuid=True) self.assertEqual(mi.uuid, cache.field_for('uuid', book_id))
def test_legacy_adding_books(self): # {{{ 'Test various adding/deleting books methods' from calibre.ebooks.metadata.book.base import Metadata from calibre.ptempfile import TemporaryFile legacy, old = self.init_legacy(self.cloned_library), self.init_old( self.cloned_library) mi = Metadata('Added Book0', authors=('Added Author', )) with TemporaryFile(suffix='.aff') as name: with open(name, 'wb') as f: f.write(b'xxx') T = partial(ET, 'add_books', ([name], ['AFF'], [mi]), old=old, legacy=legacy) T()(self) book_id = T(kwargs={'return_ids': True})(self)[1][0] self.assertEqual(legacy.new_api.formats(book_id), ('AFF', )) T(kwargs={'add_duplicates': False})(self) mi.title = 'Added Book1' mi.uuid = 'uuu' T = partial(ET, 'import_book', (mi, [name]), old=old, legacy=legacy) book_id = T()(self) self.assertNotEqual(legacy.uuid(book_id, index_is_id=True), old.uuid(book_id, index_is_id=True)) book_id = T(kwargs={'preserve_uuid': True})(self) self.assertEqual(legacy.uuid(book_id, index_is_id=True), old.uuid(book_id, index_is_id=True)) self.assertEqual(legacy.new_api.formats(book_id), ('AFF', )) T = partial(ET, 'add_format', old=old, legacy=legacy) T((0, 'AFF', BytesIO(b'fffff')))(self) T((0, 'AFF', BytesIO(b'fffff')))(self) T((0, 'AFF', BytesIO(b'fffff')), {'replace': True})(self) with TemporaryFile(suffix='.opf') as name: with open(name, 'wb') as f: f.write(b'zzzz') T = partial(ET, 'import_book', (mi, [name]), old=old, legacy=legacy) book_id = T()(self) self.assertFalse(legacy.new_api.formats(book_id)) mi.title = 'Added Book2' T = partial(ET, 'create_book_entry', (mi, ), old=old, legacy=legacy) T() T({'add_duplicates': False}) T({'force_id': 1000}) with TemporaryFile(suffix='.txt') as name: with open(name, 'wb') as f: f.write(b'tttttt') bid = legacy.add_catalog(name, 'My Catalog') self.assertEqual(old.add_catalog(name, 'My Catalog'), bid) cache = legacy.new_api self.assertEqual(cache.formats(bid), ('TXT', )) self.assertEqual(cache.field_for('title', bid), 'My Catalog') self.assertEqual(cache.field_for('authors', bid), ('calibre', )) self.assertEqual(cache.field_for('tags', bid), (_('Catalog'), )) self.assertTrue(bid < legacy.add_catalog(name, 'Something else')) self.assertEqual(legacy.add_catalog(name, 'My Catalog'), bid) self.assertEqual(old.add_catalog(name, 'My Catalog'), bid) bid = legacy.add_news( name, { 'title': 'Events', 'add_title_tag': True, 'custom_tags': ('one', 'two') }) self.assertEqual(cache.formats(bid), ('TXT', )) self.assertEqual(cache.field_for('authors', bid), ('calibre', )) self.assertEqual(cache.field_for('tags', bid), (_('News'), 'Events', 'one', 'two')) self.assertTrue(legacy.cover(1, index_is_id=True)) origcov = legacy.cover(1, index_is_id=True) self.assertTrue(legacy.has_cover(1)) legacy.remove_cover(1) self.assertFalse(legacy.has_cover(1)) self.assertFalse(legacy.cover(1, index_is_id=True)) legacy.set_cover(3, origcov) self.assertEqual(legacy.cover(3, index_is_id=True), origcov) self.assertTrue(legacy.has_cover(3)) self.assertTrue(legacy.format(1, 'FMT1', index_is_id=True)) legacy.remove_format(1, 'FMT1', index_is_id=True) self.assertIsNone(legacy.format(1, 'FMT1', index_is_id=True)) legacy.delete_book(1) old.delete_book(1) self.assertNotIn(1, legacy.all_ids()) legacy.dump_metadata((2, 3)) old.close()
def _get_metadata(self, book_id, get_user_categories=True): # {{{ mi = Metadata(None, template_cache=self.formatter_template_cache) author_ids = self._field_ids_for('authors', book_id) aut_list = [self._author_data(i) for i in author_ids] aum = [] aus = {} aul = {} for rec in aut_list: aut = rec['name'] aum.append(aut) aus[aut] = rec['sort'] aul[aut] = rec['link'] mi.title = self._field_for('title', book_id, default_value=_('Unknown')) mi.authors = aum mi.author_sort = self._field_for('author_sort', book_id, default_value=_('Unknown')) mi.author_sort_map = aus mi.author_link_map = aul mi.comments = self._field_for('comments', book_id) mi.publisher = self._field_for('publisher', book_id) n = nowf() mi.timestamp = self._field_for('timestamp', book_id, default_value=n) mi.pubdate = self._field_for('pubdate', book_id, default_value=n) mi.uuid = self._field_for('uuid', book_id, default_value='dummy') mi.title_sort = self._field_for('sort', book_id, default_value=_('Unknown')) mi.book_size = self._field_for('size', book_id, default_value=0) mi.ondevice_col = self._field_for('ondevice', book_id, default_value='') mi.last_modified = self._field_for('last_modified', book_id, default_value=n) formats = self._field_for('formats', book_id) mi.format_metadata = {} mi.languages = list(self._field_for('languages', book_id)) if not formats: good_formats = None else: mi.format_metadata = FormatMetadata(self, book_id, formats) good_formats = FormatsList(formats, mi.format_metadata) mi.formats = good_formats mi.has_cover = _('Yes') if self._field_for( 'cover', book_id, default_value=False) else '' mi.tags = list(self._field_for('tags', book_id, default_value=())) mi.series = self._field_for('series', book_id) if mi.series: mi.series_index = self._field_for('series_index', book_id, default_value=1.0) mi.rating = self._field_for('rating', book_id) mi.set_identifiers( self._field_for('identifiers', book_id, default_value={})) mi.application_id = book_id mi.id = book_id composites = [] for key, meta in self.field_metadata.custom_iteritems(): mi.set_user_metadata(key, meta) if meta['datatype'] == 'composite': composites.append(key) else: val = self._field_for(key, book_id) if isinstance(val, tuple): val = list(val) extra = self._field_for(key + '_index', book_id) mi.set(key, val=val, extra=extra) for key in composites: mi.set(key, val=self._composite_for(key, book_id, mi)) user_cat_vals = {} if get_user_categories: user_cats = self.backend.prefs['user_categories'] for ucat in user_cats: res = [] for name, cat, ign in user_cats[ucat]: v = mi.get(cat, None) if isinstance(v, list): if name in v: res.append([name, cat]) elif name == v: res.append([name, cat]) user_cat_vals[ucat] = res mi.user_categories = user_cat_vals return mi
def test_create_book_entry(self): # {{{ "Test the creation of new book entries" from calibre.ebooks.metadata.book.base import Metadata cache = self.init_cache() mi = Metadata("Created One", authors=("Creator One", "Creator Two")) book_id = cache.create_book_entry(mi) self.assertIsNot(book_id, None) def do_test(cache, book_id): for field in ( "path", "uuid", "author_sort", "timestamp", "pubdate", "title", "authors", "series_index", "sort", ): self.assertTrue(cache.field_for(field, book_id)) for field in ("size", "cover"): self.assertFalse(cache.field_for(field, book_id)) self.assertEqual(book_id, cache.fields["uuid"].table.uuid_to_id_map[cache.field_for("uuid", book_id)]) self.assertLess(now() - cache.field_for("timestamp", book_id), timedelta(seconds=30)) self.assertEqual( ("Created One", ("Creator One", "Creator Two")), (cache.field_for("title", book_id), cache.field_for("authors", book_id)), ) self.assertEqual(cache.field_for("series_index", book_id), 1.0) self.assertEqual(cache.field_for("pubdate", book_id), UNDEFINED_DATE) do_test(cache, book_id) # Test that the db contains correct data cache = self.init_cache() do_test(cache, book_id) self.assertIs(None, cache.create_book_entry(mi, add_duplicates=False), "Duplicate added incorrectly") book_id = cache.create_book_entry(mi, cover=IMG) self.assertIsNot(book_id, None) self.assertEqual(IMG, cache.cover(book_id)) import calibre.db.cache as c orig = c.prefs c.prefs = {"new_book_tags": ("newbook", "newbook2")} try: book_id = cache.create_book_entry(mi) self.assertEqual(("newbook", "newbook2"), cache.field_for("tags", book_id)) mi.tags = ("one", "two") book_id = cache.create_book_entry(mi) self.assertEqual(("one", "two") + ("newbook", "newbook2"), cache.field_for("tags", book_id)) mi.tags = () finally: c.prefs = orig mi.uuid = "a preserved uuid" book_id = cache.create_book_entry(mi, preserve_uuid=True) self.assertEqual(mi.uuid, cache.field_for("uuid", book_id))
def _get_metadata(self, book_id, get_user_categories=True): # {{{ mi = Metadata(None, template_cache=self.formatter_template_cache) author_ids = self._field_ids_for('authors', book_id) aut_list = [self._author_data(i) for i in author_ids] aum = [] aus = {} aul = {} for rec in aut_list: aut = rec['name'] aum.append(aut) aus[aut] = rec['sort'] aul[aut] = rec['link'] mi.title = self._field_for('title', book_id, default_value=_('Unknown')) mi.authors = aum mi.author_sort = self._field_for('author_sort', book_id, default_value=_('Unknown')) mi.author_sort_map = aus mi.author_link_map = aul mi.comments = self._field_for('comments', book_id) mi.publisher = self._field_for('publisher', book_id) n = nowf() mi.timestamp = self._field_for('timestamp', book_id, default_value=n) mi.pubdate = self._field_for('pubdate', book_id, default_value=n) mi.uuid = self._field_for('uuid', book_id, default_value='dummy') mi.title_sort = self._field_for('sort', book_id, default_value=_('Unknown')) mi.book_size = self._field_for('size', book_id, default_value=0) mi.ondevice_col = self._field_for('ondevice', book_id, default_value='') mi.last_modified = self._field_for('last_modified', book_id, default_value=n) formats = self._field_for('formats', book_id) mi.format_metadata = {} mi.languages = list(self._field_for('languages', book_id)) if not formats: good_formats = None else: mi.format_metadata = FormatMetadata(self, book_id, formats) good_formats = FormatsList(formats, mi.format_metadata) mi.formats = good_formats mi.has_cover = _('Yes') if self._field_for('cover', book_id, default_value=False) else '' mi.tags = list(self._field_for('tags', book_id, default_value=())) mi.series = self._field_for('series', book_id) if mi.series: mi.series_index = self._field_for('series_index', book_id, default_value=1.0) mi.rating = self._field_for('rating', book_id) mi.set_identifiers(self._field_for('identifiers', book_id, default_value={})) mi.application_id = book_id mi.id = book_id composites = [] for key, meta in self.field_metadata.custom_iteritems(): mi.set_user_metadata(key, meta) if meta['datatype'] == 'composite': composites.append(key) else: val = self._field_for(key, book_id) if isinstance(val, tuple): val = list(val) extra = self._field_for(key+'_index', book_id) mi.set(key, val=val, extra=extra) for key in composites: mi.set(key, val=self._composite_for(key, book_id, mi)) user_cat_vals = {} if get_user_categories: user_cats = self.backend.prefs['user_categories'] for ucat in user_cats: res = [] for name,cat,ign in user_cats[ucat]: v = mi.get(cat, None) if isinstance(v, list): if name in v: res.append([name,cat]) elif name == v: res.append([name,cat]) user_cat_vals[ucat] = res mi.user_categories = user_cat_vals return mi
def test_legacy_adding_books(self): # {{{ "Test various adding/deleting books methods" from calibre.ebooks.metadata.book.base import Metadata legacy, old = self.init_legacy(self.cloned_library), self.init_old(self.cloned_library) mi = Metadata("Added Book0", authors=("Added Author",)) with NamedTemporaryFile(suffix=".aff") as f: f.write(b"xxx") f.flush() T = partial(ET, "add_books", ([f.name], ["AFF"], [mi]), old=old, legacy=legacy) T()(self) book_id = T(kwargs={"return_ids": True})(self)[1][0] self.assertEqual(legacy.new_api.formats(book_id), ("AFF",)) T(kwargs={"add_duplicates": False})(self) mi.title = "Added Book1" mi.uuid = "uuu" T = partial(ET, "import_book", (mi, [f.name]), old=old, legacy=legacy) book_id = T()(self) self.assertNotEqual(legacy.uuid(book_id, index_is_id=True), old.uuid(book_id, index_is_id=True)) book_id = T(kwargs={"preserve_uuid": True})(self) self.assertEqual(legacy.uuid(book_id, index_is_id=True), old.uuid(book_id, index_is_id=True)) self.assertEqual(legacy.new_api.formats(book_id), ("AFF",)) T = partial(ET, "add_format", old=old, legacy=legacy) T((0, "AFF", BytesIO(b"fffff")))(self) T((0, "AFF", BytesIO(b"fffff")))(self) T((0, "AFF", BytesIO(b"fffff")), {"replace": True})(self) with NamedTemporaryFile(suffix=".opf") as f: f.write(b"zzzz") f.flush() T = partial(ET, "import_book", (mi, [f.name]), old=old, legacy=legacy) book_id = T()(self) self.assertFalse(legacy.new_api.formats(book_id)) mi.title = "Added Book2" T = partial(ET, "create_book_entry", (mi,), old=old, legacy=legacy) T() T({"add_duplicates": False}) T({"force_id": 1000}) with NamedTemporaryFile(suffix=".txt") as f: f.write(b"tttttt") f.seek(0) bid = legacy.add_catalog(f.name, "My Catalog") self.assertEqual(old.add_catalog(f.name, "My Catalog"), bid) cache = legacy.new_api self.assertEqual(cache.formats(bid), ("TXT",)) self.assertEqual(cache.field_for("title", bid), "My Catalog") self.assertEqual(cache.field_for("authors", bid), ("calibre",)) self.assertEqual(cache.field_for("tags", bid), (_("Catalog"),)) self.assertTrue(bid < legacy.add_catalog(f.name, "Something else")) self.assertEqual(legacy.add_catalog(f.name, "My Catalog"), bid) self.assertEqual(old.add_catalog(f.name, "My Catalog"), bid) bid = legacy.add_news(f.name, {"title": "Events", "add_title_tag": True, "custom_tags": ("one", "two")}) self.assertEqual(cache.formats(bid), ("TXT",)) self.assertEqual(cache.field_for("authors", bid), ("calibre",)) self.assertEqual(cache.field_for("tags", bid), (_("News"), "Events", "one", "two")) self.assertTrue(legacy.cover(1, index_is_id=True)) origcov = legacy.cover(1, index_is_id=True) self.assertTrue(legacy.has_cover(1)) legacy.remove_cover(1) self.assertFalse(legacy.has_cover(1)) self.assertFalse(legacy.cover(1, index_is_id=True)) legacy.set_cover(3, origcov) self.assertEqual(legacy.cover(3, index_is_id=True), origcov) self.assertTrue(legacy.has_cover(3)) self.assertTrue(legacy.format(1, "FMT1", index_is_id=True)) legacy.remove_format(1, "FMT1", index_is_id=True) self.assertIsNone(legacy.format(1, "FMT1", index_is_id=True)) legacy.delete_book(1) old.delete_book(1) self.assertNotIn(1, legacy.all_ids()) legacy.dump_metadata((2, 3)) old.close()