mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Legacy rename API
This commit is contained in:
parent
064294fa32
commit
17c520d1d9
@ -30,7 +30,7 @@ from calibre.ebooks.metadata.book.base import Metadata
|
|||||||
from calibre.ebooks.metadata.opf2 import metadata_to_opf
|
from calibre.ebooks.metadata.opf2 import metadata_to_opf
|
||||||
from calibre.ptempfile import (base_dir, PersistentTemporaryFile,
|
from calibre.ptempfile import (base_dir, PersistentTemporaryFile,
|
||||||
SpooledTemporaryFile)
|
SpooledTemporaryFile)
|
||||||
from calibre.utils.config import prefs
|
from calibre.utils.config import prefs, tweaks
|
||||||
from calibre.utils.date import now as nowf, utcnow, UNDEFINED_DATE
|
from calibre.utils.date import now as nowf, utcnow, UNDEFINED_DATE
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
|
|
||||||
@ -1100,16 +1100,16 @@ class Cache(object):
|
|||||||
self._update_last_modified(tuple(formats_map.iterkeys()))
|
self._update_last_modified(tuple(formats_map.iterkeys()))
|
||||||
|
|
||||||
@read_api
|
@read_api
|
||||||
def get_next_series_num_for(self, series):
|
def get_next_series_num_for(self, series, field='series'):
|
||||||
books = ()
|
books = ()
|
||||||
sf = self.fields['series']
|
sf = self.fields[field]
|
||||||
if series:
|
if series:
|
||||||
q = icu_lower(series)
|
q = icu_lower(series)
|
||||||
for val, book_ids in sf.iter_searchable_values(self._get_metadata, frozenset(self.all_book_ids())):
|
for val, book_ids in sf.iter_searchable_values(self._get_metadata, frozenset(self._all_book_ids())):
|
||||||
if q == icu_lower(val):
|
if q == icu_lower(val):
|
||||||
books = book_ids
|
books = book_ids
|
||||||
break
|
break
|
||||||
series_indices = sorted(self._field_for('series_index', book_id) for book_id in books)
|
series_indices = sorted(self._field_for(sf.index_field.name, book_id) for book_id in books)
|
||||||
return _get_next_series_num_for_list(tuple(series_indices), unwrap=False)
|
return _get_next_series_num_for_list(tuple(series_indices), unwrap=False)
|
||||||
|
|
||||||
@read_api
|
@read_api
|
||||||
@ -1223,24 +1223,30 @@ class Cache(object):
|
|||||||
return val_map
|
return val_map
|
||||||
|
|
||||||
@write_api
|
@write_api
|
||||||
def rename_items(self, field, item_id_to_new_name_map):
|
def rename_items(self, field, item_id_to_new_name_map, change_index=True):
|
||||||
|
f = self.fields[field]
|
||||||
try:
|
try:
|
||||||
func = self.fields[field].table.rename_item
|
func = f.table.rename_item
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
raise ValueError('Cannot rename items for one-one fields: %s' % field)
|
raise ValueError('Cannot rename items for one-one fields: %s' % field)
|
||||||
affected_books = set()
|
affected_books = set()
|
||||||
|
moved_books = set()
|
||||||
id_map = {}
|
id_map = {}
|
||||||
for item_id, new_name in item_id_to_new_name_map.iteritems():
|
for item_id, new_name in item_id_to_new_name_map.iteritems():
|
||||||
books, new_id = func(item_id, new_name, self.backend)
|
books, new_id = func(item_id, new_name, self.backend)
|
||||||
affected_books.update(books)
|
affected_books.update(books)
|
||||||
id_map[item_id] = new_id
|
id_map[item_id] = new_id
|
||||||
|
if new_id != item_id:
|
||||||
|
moved_books.update(books)
|
||||||
if affected_books:
|
if affected_books:
|
||||||
if field == 'authors':
|
if field == 'authors':
|
||||||
self._set_field('author_sort', # also marks as dirty
|
self._set_field('author_sort',
|
||||||
{k:' & '.join(v) for k, v in self._author_sort_strings_for_books(affected_books).iteritems()})
|
{k:' & '.join(v) for k, v in self._author_sort_strings_for_books(affected_books).iteritems()})
|
||||||
self._update_path(affected_books, mark_as_dirtied=False)
|
self._update_path(affected_books, mark_as_dirtied=False)
|
||||||
else:
|
elif change_index and hasattr(f, 'index_field') and tweaks['series_index_auto_increment'] != 'no_change':
|
||||||
self._mark_as_dirty(affected_books)
|
for book_id in moved_books:
|
||||||
|
self._set_field(f.index_field.name, {book_id:self._get_next_series_num_for(self._field_for(field, book_id), field=field)})
|
||||||
|
self._mark_as_dirty(affected_books)
|
||||||
return affected_books, id_map
|
return affected_books, id_map
|
||||||
|
|
||||||
@write_api
|
@write_api
|
||||||
|
@ -290,7 +290,7 @@ class LibraryDatabase(object):
|
|||||||
|
|
||||||
def authors_sort_strings(self, index, index_is_id=False):
|
def authors_sort_strings(self, index, index_is_id=False):
|
||||||
book_id = index if index_is_id else self.id(index)
|
book_id = index if index_is_id else self.id(index)
|
||||||
return list(self.author_sort_strings_for_books.canonical_author_sort_for_books((book_id,))[book_id])
|
return list(self.new_api.author_sort_strings_for_books((book_id,))[book_id])
|
||||||
|
|
||||||
def author_sort_from_book(self, index, index_is_id=False):
|
def author_sort_from_book(self, index, index_is_id=False):
|
||||||
return ' & '.join(self.authors_sort_strings(index, index_is_id=index_is_id))
|
return ' & '.join(self.authors_sort_strings(index, index_is_id=index_is_id))
|
||||||
@ -500,6 +500,9 @@ class LibraryDatabase(object):
|
|||||||
book_id = index if index_is_id else self.id(index)
|
book_id = index if index_is_id else self.id(index)
|
||||||
return self.new_api.get_metadata(book_id, get_cover=get_cover, get_user_categories=get_user_categories, cover_as_data=cover_as_data)
|
return self.new_api.get_metadata(book_id, get_cover=get_cover, get_user_categories=get_user_categories, cover_as_data=cover_as_data)
|
||||||
|
|
||||||
|
def rename_series(self, old_id, new_name, change_index=True):
|
||||||
|
self.new_api.rename_items('series', {old_id:new_name}, change_index=change_index)
|
||||||
|
|
||||||
# Private interface {{{
|
# Private interface {{{
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for row in self.data.iterall():
|
for row in self.data.iterall():
|
||||||
@ -582,6 +585,16 @@ for field in (
|
|||||||
return func
|
return func
|
||||||
setattr(LibraryDatabase, 'set_%s' % field.replace('!', ''), MT(setter(field)))
|
setattr(LibraryDatabase, 'set_%s' % field.replace('!', ''), MT(setter(field)))
|
||||||
|
|
||||||
|
for field in ('authors', 'tags', 'publisher'):
|
||||||
|
def renamer(field):
|
||||||
|
def func(self, old_id, new_name):
|
||||||
|
id_map = self.new_api.rename_items(field, {old_id:new_name})[1]
|
||||||
|
if field == 'authors':
|
||||||
|
return id_map[old_id]
|
||||||
|
return func
|
||||||
|
fname = field[:-1] if field in {'tags', 'authors'} else field
|
||||||
|
setattr(LibraryDatabase, 'rename_%s' % fname, MT(renamer(field)))
|
||||||
|
|
||||||
LibraryDatabase.update_last_modified = MT(
|
LibraryDatabase.update_last_modified = MT(
|
||||||
lambda self, book_ids, commit=False, now=None: self.new_api.update_last_modified(book_ids, now=now))
|
lambda self, book_ids, commit=False, now=None: self.new_api.update_last_modified(book_ids, now=now))
|
||||||
|
|
||||||
|
@ -472,6 +472,7 @@ class LegacyTest(BaseTest):
|
|||||||
nmi = [ndb.get_metadata(x) for x in (0, 1, 2)]
|
nmi = [ndb.get_metadata(x) for x in (0, 1, 2)]
|
||||||
self.assertEqual([x.author_sort_map for x in omi], [x.author_sort_map for x in nmi])
|
self.assertEqual([x.author_sort_map for x in omi], [x.author_sort_map for x in nmi])
|
||||||
self.assertEqual([x.author_link_map for x in omi], [x.author_link_map for x in nmi])
|
self.assertEqual([x.author_link_map for x in omi], [x.author_link_map for x in nmi])
|
||||||
|
db.close()
|
||||||
|
|
||||||
ndb = self.init_legacy(self.cloned_library)
|
ndb = self.init_legacy(self.cloned_library)
|
||||||
db = self.init_old(self.cloned_library)
|
db = self.init_old(self.cloned_library)
|
||||||
@ -554,6 +555,7 @@ class LegacyTest(BaseTest):
|
|||||||
('@all_tags',),
|
('@all_tags',),
|
||||||
('#tags', 0), ('#tags', 1), ('#tags', 2),
|
('#tags', 0), ('#tags', 1), ('#tags', 2),
|
||||||
))
|
))
|
||||||
|
db.close()
|
||||||
|
|
||||||
ndb = self.init_legacy(self.cloned_library)
|
ndb = self.init_legacy(self.cloned_library)
|
||||||
db = self.init_old(self.cloned_library)
|
db = self.init_old(self.cloned_library)
|
||||||
@ -563,6 +565,31 @@ class LegacyTest(BaseTest):
|
|||||||
('@all_tags',),
|
('@all_tags',),
|
||||||
('@tags', 0), ('@tags', 1), ('@tags', 2),
|
('@tags', 0), ('@tags', 1), ('@tags', 2),
|
||||||
))
|
))
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
ndb = self.init_legacy(self.cloned_library)
|
||||||
|
db = self.init_old(self.cloned_library)
|
||||||
|
a = {v:k for k, v in ndb.new_api.get_id_map('authors').iteritems()}['Author One']
|
||||||
|
t = {v:k for k, v in ndb.new_api.get_id_map('tags').iteritems()}['Tag One']
|
||||||
|
s = {v:k for k, v in ndb.new_api.get_id_map('series').iteritems()}['A Series One']
|
||||||
|
p = {v:k for k, v in ndb.new_api.get_id_map('publisher').iteritems()}['Publisher One']
|
||||||
|
run_funcs(self, db, ndb, (
|
||||||
|
('rename_author', a, 'Author Two'),
|
||||||
|
('rename_tag', t, 'News'),
|
||||||
|
('rename_series', s, 'ss'),
|
||||||
|
('rename_publisher', p, 'publisher one'),
|
||||||
|
(db.clean,),
|
||||||
|
(db.refresh,),
|
||||||
|
('@all_tags',),
|
||||||
|
('tags', 0), ('tags', 1), ('tags', 2),
|
||||||
|
('series', 0), ('series', 1), ('series', 2),
|
||||||
|
('publisher', 0), ('publisher', 1), ('publisher', 2),
|
||||||
|
('series_index', 0), ('series_index', 1), ('series_index', 2),
|
||||||
|
('authors', 0), ('authors', 1), ('authors', 2),
|
||||||
|
('author_sort', 0), ('author_sort', 1), ('author_sort', 2),
|
||||||
|
))
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -541,5 +541,5 @@ class WritingTest(BaseTest):
|
|||||||
self.assertEqual(c.all_field_names('#series'), {'My Series Two'})
|
self.assertEqual(c.all_field_names('#series'), {'My Series Two'})
|
||||||
self.assertEqual(c.field_for('#series', 2), 'My Series Two')
|
self.assertEqual(c.field_for('#series', 2), 'My Series Two')
|
||||||
self.assertEqual(c.field_for('#series_index', 1), 3.0)
|
self.assertEqual(c.field_for('#series_index', 1), 3.0)
|
||||||
self.assertEqual(c.field_for('#series_index', 2), 1.0)
|
self.assertEqual(c.field_for('#series_index', 2), 4.0)
|
||||||
# }}}
|
# }}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user