mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
When bulk deleting formats use a single temp dir
When bulk deleting formats, use a single temporary directory for the deleted files. This makes restoring them from the recycle bin a little cleaner. Also might fix the reported issue with windows choking on creating a large number of folders.
This commit is contained in:
parent
e260906211
commit
c9a88a1a80
@ -1199,14 +1199,18 @@ class DB(object):
|
|||||||
def has_format(self, book_id, fmt, fname, path):
|
def has_format(self, book_id, fmt, fname, path):
|
||||||
return self.format_abspath(book_id, fmt, fname, path) is not None
|
return self.format_abspath(book_id, fmt, fname, path) is not None
|
||||||
|
|
||||||
def remove_format(self, book_id, fmt, fname, path):
|
def remove_formats(self, remove_map):
|
||||||
path = self.format_abspath(book_id, fmt, fname, path)
|
paths = []
|
||||||
if path is not None:
|
for book_id, removals in remove_map.iteritems():
|
||||||
try:
|
for fmt, fname, path in removals:
|
||||||
delete_service().delete_files((path,), self.library_path)
|
path = self.format_abspath(book_id, fmt, fname, path)
|
||||||
except:
|
if path is not None:
|
||||||
import traceback
|
paths.append(path)
|
||||||
traceback.print_exc()
|
try:
|
||||||
|
delete_service().delete_files(paths, self.library_path)
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
def cover_last_modified(self, path):
|
def cover_last_modified(self, path):
|
||||||
path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg'))
|
path = os.path.abspath(os.path.join(self.library_path, path, 'cover.jpg'))
|
||||||
|
@ -1280,6 +1280,7 @@ class Cache(object):
|
|||||||
self.format_metadata_cache[book_id].pop(fmt, None)
|
self.format_metadata_cache[book_id].pop(fmt, None)
|
||||||
|
|
||||||
if not db_only:
|
if not db_only:
|
||||||
|
removes = defaultdict(set)
|
||||||
for book_id, fmts in formats_map.iteritems():
|
for book_id, fmts in formats_map.iteritems():
|
||||||
try:
|
try:
|
||||||
path = self._field_for('path', book_id).replace('/', os.sep)
|
path = self._field_for('path', book_id).replace('/', os.sep)
|
||||||
@ -1291,7 +1292,9 @@ class Cache(object):
|
|||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
if name and path:
|
if name and path:
|
||||||
self.backend.remove_format(book_id, fmt, name, path)
|
removes[book_id].add((fmt, name, path))
|
||||||
|
if removes:
|
||||||
|
self.backend.remove_formats(removes)
|
||||||
|
|
||||||
size_map = table.remove_formats(formats_map, self.backend)
|
size_map = table.remove_formats(formats_map, self.backend)
|
||||||
self.fields['size'].table.update_sizes(size_map)
|
self.fields['size'].table.update_sizes(size_map)
|
||||||
|
@ -196,12 +196,10 @@ class DeleteAction(InterfaceAction):
|
|||||||
_('Choose formats to be deleted'), ids)
|
_('Choose formats to be deleted'), ids)
|
||||||
if not fmts:
|
if not fmts:
|
||||||
return
|
return
|
||||||
for id in ids:
|
m = self.gui.library_view.model()
|
||||||
for fmt in fmts:
|
m.db.new_api.remove_formats({book_id:fmts for book_id in ids})
|
||||||
self.gui.library_view.model().db.remove_format(id, fmt,
|
m.refresh_ids(ids)
|
||||||
index_is_id=True, notify=False)
|
m.current_changed(self.gui.library_view.currentIndex(),
|
||||||
self.gui.library_view.model().refresh_ids(ids)
|
|
||||||
self.gui.library_view.model().current_changed(self.gui.library_view.currentIndex(),
|
|
||||||
self.gui.library_view.currentIndex())
|
self.gui.library_view.currentIndex())
|
||||||
if ids:
|
if ids:
|
||||||
self.gui.tags_view.recount()
|
self.gui.tags_view.recount()
|
||||||
@ -216,8 +214,10 @@ class DeleteAction(InterfaceAction):
|
|||||||
exclude=True)
|
exclude=True)
|
||||||
if fmts is None:
|
if fmts is None:
|
||||||
return
|
return
|
||||||
|
m = self.gui.library_view.model()
|
||||||
|
removals = {}
|
||||||
for id in ids:
|
for id in ids:
|
||||||
bfmts = self.gui.library_view.model().db.formats(id, index_is_id=True)
|
bfmts = m.db.formats(id, index_is_id=True)
|
||||||
if bfmts is None:
|
if bfmts is None:
|
||||||
continue
|
continue
|
||||||
bfmts = set([x.lower() for x in bfmts.split(',')])
|
bfmts = set([x.lower() for x in bfmts.split(',')])
|
||||||
@ -225,14 +225,14 @@ class DeleteAction(InterfaceAction):
|
|||||||
if bfmts - rfmts:
|
if bfmts - rfmts:
|
||||||
# Do not delete if it will leave the book with no
|
# Do not delete if it will leave the book with no
|
||||||
# formats
|
# formats
|
||||||
for fmt in rfmts:
|
removals[id] = rfmts
|
||||||
self.gui.library_view.model().db.remove_format(id, fmt,
|
if removals:
|
||||||
index_is_id=True, notify=False)
|
m.db.new_api.remove_formats(removals)
|
||||||
self.gui.library_view.model().refresh_ids(ids)
|
m.refresh_ids(ids)
|
||||||
self.gui.library_view.model().current_changed(self.gui.library_view.currentIndex(),
|
m.current_changed(self.gui.library_view.currentIndex(),
|
||||||
self.gui.library_view.currentIndex())
|
self.gui.library_view.currentIndex())
|
||||||
if ids:
|
if ids:
|
||||||
self.gui.tags_view.recount()
|
self.gui.tags_view.recount()
|
||||||
|
|
||||||
def delete_all_formats(self, *args):
|
def delete_all_formats(self, *args):
|
||||||
ids = self._get_selected_ids()
|
ids = self._get_selected_ids()
|
||||||
@ -244,17 +244,18 @@ class DeleteAction(InterfaceAction):
|
|||||||
+'</p>', 'delete_all_formats', self.gui):
|
+'</p>', 'delete_all_formats', self.gui):
|
||||||
return
|
return
|
||||||
db = self.gui.library_view.model().db
|
db = self.gui.library_view.model().db
|
||||||
|
removals = {}
|
||||||
for id in ids:
|
for id in ids:
|
||||||
fmts = db.formats(id, index_is_id=True, verify_formats=False)
|
fmts = db.formats(id, index_is_id=True, verify_formats=False)
|
||||||
if fmts:
|
if fmts:
|
||||||
for fmt in fmts.split(','):
|
removals[id] = fmts.split(',')
|
||||||
self.gui.library_view.model().db.remove_format(id, fmt,
|
if removals:
|
||||||
index_is_id=True, notify=False)
|
db.new_api.remove_formats(removals)
|
||||||
self.gui.library_view.model().refresh_ids(ids)
|
self.gui.library_view.model().refresh_ids(ids)
|
||||||
self.gui.library_view.model().current_changed(self.gui.library_view.currentIndex(),
|
self.gui.library_view.model().current_changed(self.gui.library_view.currentIndex(),
|
||||||
self.gui.library_view.currentIndex())
|
self.gui.library_view.currentIndex())
|
||||||
if ids:
|
if ids:
|
||||||
self.gui.tags_view.recount()
|
self.gui.tags_view.recount()
|
||||||
|
|
||||||
def remove_matching_books_from_device(self, *args):
|
def remove_matching_books_from_device(self, *args):
|
||||||
if not self.gui.device_manager.is_device_present:
|
if not self.gui.device_manager.is_device_present:
|
||||||
|
@ -398,13 +398,14 @@ def command_add(args, dbpath):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
def do_remove(db, ids):
|
def do_remove(db, ids):
|
||||||
|
book_ids = set()
|
||||||
for x in ids:
|
for x in ids:
|
||||||
if isinstance(x, int):
|
if isinstance(x, int):
|
||||||
db.delete_book(x)
|
book_ids.add(x)
|
||||||
else:
|
else:
|
||||||
for y in x:
|
book_ids |= set(x)
|
||||||
db.delete_book(y)
|
|
||||||
|
|
||||||
|
db.new_api.remove_books(book_ids)
|
||||||
db.clean()
|
db.clean()
|
||||||
send_message()
|
send_message()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user