mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Allow changing the case of authors and tags via the edit metadata dialog and the book list
This commit is contained in:
commit
f62451d918
@ -160,6 +160,7 @@ class EditMetadataAction(InterfaceAction):
|
|||||||
break
|
break
|
||||||
|
|
||||||
changed.add(d.id)
|
changed.add(d.id)
|
||||||
|
self.gui.library_view.model().refresh_ids(list(d.books_to_refresh))
|
||||||
if d.row_delta == 0:
|
if d.row_delta == 0:
|
||||||
break
|
break
|
||||||
current_row += d.row_delta
|
current_row += d.row_delta
|
||||||
|
@ -622,6 +622,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
|||||||
|
|
||||||
self.original_author = unicode(self.authors.text()).strip()
|
self.original_author = unicode(self.authors.text()).strip()
|
||||||
self.original_title = unicode(self.title.text()).strip()
|
self.original_title = unicode(self.title.text()).strip()
|
||||||
|
self.books_to_refresh = set()
|
||||||
|
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
@ -779,7 +780,8 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
|||||||
_('You have changed the tags. In order to use the tags'
|
_('You have changed the tags. In order to use the tags'
|
||||||
' editor, you must either discard or apply these '
|
' editor, you must either discard or apply these '
|
||||||
'changes. Apply changes?'), show_copy_button=False):
|
'changes. Apply changes?'), show_copy_button=False):
|
||||||
self.apply_tags(commit=True, notify=True)
|
self.books_to_refresh |= self.apply_tags(commit=True, notify=True,
|
||||||
|
allow_case_change=True)
|
||||||
self.original_tags = unicode(self.tags.text())
|
self.original_tags = unicode(self.tags.text())
|
||||||
else:
|
else:
|
||||||
self.tags.setText(self.original_tags)
|
self.tags.setText(self.original_tags)
|
||||||
@ -886,9 +888,9 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
|||||||
break
|
break
|
||||||
|
|
||||||
def apply_tags(self, commit=False, notify=False):
|
def apply_tags(self, commit=False, notify=False):
|
||||||
self.db.set_tags(self.id, [x.strip() for x in
|
return self.db.set_tags(self.id, [x.strip() for x in
|
||||||
unicode(self.tags.text()).split(',')],
|
unicode(self.tags.text()).split(',')],
|
||||||
notify=notify, commit=commit)
|
notify=notify, commit=commit, allow_case_change=True)
|
||||||
|
|
||||||
def next_triggered(self, row_delta, *args):
|
def next_triggered(self, row_delta, *args):
|
||||||
self.row_delta = row_delta
|
self.row_delta = row_delta
|
||||||
@ -907,7 +909,10 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
|||||||
self.db.set_title_sort(self.id, ts, notify=False, commit=False)
|
self.db.set_title_sort(self.id, ts, notify=False, commit=False)
|
||||||
au = unicode(self.authors.text()).strip()
|
au = unicode(self.authors.text()).strip()
|
||||||
if au and au != self.original_author:
|
if au and au != self.original_author:
|
||||||
self.db.set_authors(self.id, string_to_authors(au), notify=False)
|
self.books_to_refresh |= self.db.set_authors(self.id,
|
||||||
|
string_to_authors(au),
|
||||||
|
notify=False,
|
||||||
|
allow_case_change=True)
|
||||||
aus = unicode(self.author_sort.text()).strip()
|
aus = unicode(self.author_sort.text()).strip()
|
||||||
if aus:
|
if aus:
|
||||||
self.db.set_author_sort(self.id, aus, notify=False, commit=False)
|
self.db.set_author_sort(self.id, aus, notify=False, commit=False)
|
||||||
@ -917,7 +922,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
|
|||||||
notify=False, commit=False)
|
notify=False, commit=False)
|
||||||
self.db.set_rating(self.id, 2*self.rating.value(), notify=False,
|
self.db.set_rating(self.id, 2*self.rating.value(), notify=False,
|
||||||
commit=False)
|
commit=False)
|
||||||
self.apply_tags()
|
self.books_to_refresh |= self.apply_tags()
|
||||||
self.db.set_publisher(self.id,
|
self.db.set_publisher(self.id,
|
||||||
unicode(self.publisher.currentText()).strip(),
|
unicode(self.publisher.currentText()).strip(),
|
||||||
notify=False, commit=False)
|
notify=False, commit=False)
|
||||||
|
@ -819,6 +819,7 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
value.toDate() if column in ('timestamp', 'pubdate') else \
|
value.toDate() if column in ('timestamp', 'pubdate') else \
|
||||||
unicode(value.toString())
|
unicode(value.toString())
|
||||||
id = self.db.id(row)
|
id = self.db.id(row)
|
||||||
|
books_to_refresh = set([id])
|
||||||
if column == 'rating':
|
if column == 'rating':
|
||||||
val = 0 if val < 0 else 5 if val > 5 else val
|
val = 0 if val < 0 else 5 if val > 5 else val
|
||||||
val *= 2
|
val *= 2
|
||||||
@ -850,8 +851,9 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
return False
|
return False
|
||||||
self.db.set_pubdate(id, qt_to_dt(val, as_utc=False))
|
self.db.set_pubdate(id, qt_to_dt(val, as_utc=False))
|
||||||
else:
|
else:
|
||||||
self.db.set(row, column, val)
|
books_to_refresh |= self.db.set(row, column, val,
|
||||||
self.refresh_ids([id], row)
|
allow_case_change=True)
|
||||||
|
self.refresh_ids(list(books_to_refresh), row)
|
||||||
self.dataChanged.emit(index, index)
|
self.dataChanged.emit(index, index)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -156,6 +156,7 @@ class AuthorsEdit(MultiCompleteComboBox):
|
|||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
self.dialog = parent
|
self.dialog = parent
|
||||||
|
self.books_to_refresh = set([])
|
||||||
MultiCompleteComboBox.__init__(self, parent)
|
MultiCompleteComboBox.__init__(self, parent)
|
||||||
self.setToolTip(self.TOOLTIP)
|
self.setToolTip(self.TOOLTIP)
|
||||||
self.setWhatsThis(self.TOOLTIP)
|
self.setWhatsThis(self.TOOLTIP)
|
||||||
@ -166,6 +167,7 @@ class AuthorsEdit(MultiCompleteComboBox):
|
|||||||
return _('Unknown')
|
return _('Unknown')
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
|
self.books_to_refresh = set([])
|
||||||
all_authors = db.all_authors()
|
all_authors = db.all_authors()
|
||||||
all_authors.sort(key=lambda x : sort_key(x[1]))
|
all_authors.sort(key=lambda x : sort_key(x[1]))
|
||||||
for i in all_authors:
|
for i in all_authors:
|
||||||
@ -185,7 +187,8 @@ class AuthorsEdit(MultiCompleteComboBox):
|
|||||||
|
|
||||||
def commit(self, db, id_):
|
def commit(self, db, id_):
|
||||||
authors = self.current_val
|
authors = self.current_val
|
||||||
db.set_authors(id_, authors, notify=False)
|
self.books_to_refresh |= db.set_authors(id_, authors, notify=False,
|
||||||
|
allow_case_change=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@dynamic_property
|
@dynamic_property
|
||||||
@ -824,6 +827,7 @@ class TagsEdit(MultiCompleteLineEdit): # {{{
|
|||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
MultiCompleteLineEdit.__init__(self, parent)
|
MultiCompleteLineEdit.__init__(self, parent)
|
||||||
|
self.books_to_refresh = set([])
|
||||||
self.setToolTip(self.TOOLTIP)
|
self.setToolTip(self.TOOLTIP)
|
||||||
self.setWhatsThis(self.TOOLTIP)
|
self.setWhatsThis(self.TOOLTIP)
|
||||||
|
|
||||||
@ -838,6 +842,7 @@ class TagsEdit(MultiCompleteLineEdit): # {{{
|
|||||||
return property(fget=fget, fset=fset)
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
|
self.books_to_refresh = set([])
|
||||||
tags = db.tags(id_, index_is_id=True)
|
tags = db.tags(id_, index_is_id=True)
|
||||||
tags = tags.split(',') if tags else []
|
tags = tags.split(',') if tags else []
|
||||||
self.current_val = tags
|
self.current_val = tags
|
||||||
@ -866,7 +871,9 @@ class TagsEdit(MultiCompleteLineEdit): # {{{
|
|||||||
|
|
||||||
|
|
||||||
def commit(self, db, id_):
|
def commit(self, db, id_):
|
||||||
db.set_tags(id_, self.current_val, notify=False, commit=False)
|
self.books_to_refresh |= db.set_tags(
|
||||||
|
id_, self.current_val, notify=False, commit=False,
|
||||||
|
allow_case_change=True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -31,6 +31,8 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
def __init__(self, db, parent=None):
|
def __init__(self, db, parent=None):
|
||||||
self.db = db
|
self.db = db
|
||||||
self.changed = set([])
|
self.changed = set([])
|
||||||
|
self.books_to_refresh = set([])
|
||||||
|
self.rows_to_refresh = set([])
|
||||||
ResizableDialog.__init__(self, parent)
|
ResizableDialog.__init__(self, parent)
|
||||||
|
|
||||||
def setupUi(self, *args): # {{{
|
def setupUi(self, *args): # {{{
|
||||||
@ -192,6 +194,7 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
|
|
||||||
def __call__(self, id_):
|
def __call__(self, id_):
|
||||||
self.book_id = id_
|
self.book_id = id_
|
||||||
|
self.books_to_refresh = set([])
|
||||||
for widget in self.basic_metadata_widgets:
|
for widget in self.basic_metadata_widgets:
|
||||||
widget.initialize(self.db, id_)
|
widget.initialize(self.db, id_)
|
||||||
for widget in self.custom_metadata_widgets:
|
for widget in self.custom_metadata_widgets:
|
||||||
@ -295,6 +298,8 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
try:
|
try:
|
||||||
if not widget.commit(self.db, self.book_id):
|
if not widget.commit(self.db, self.book_id):
|
||||||
return False
|
return False
|
||||||
|
self.books_to_refresh |= getattr(widget, 'books_to_refresh',
|
||||||
|
set([]))
|
||||||
except IOError, err:
|
except IOError, err:
|
||||||
if err.errno == 13: # Permission denied
|
if err.errno == 13: # Permission denied
|
||||||
import traceback
|
import traceback
|
||||||
@ -352,6 +357,9 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
self.prev_button.setToolTip(tip)
|
self.prev_button.setToolTip(tip)
|
||||||
self.prev_button.setVisible(prev is not None)
|
self.prev_button.setVisible(prev is not None)
|
||||||
self(self.db.id(self.row_list[self.current_row]))
|
self(self.db.id(self.row_list[self.current_row]))
|
||||||
|
rows = self.db.refresh_ids(list(self.books_to_refresh))
|
||||||
|
if rows:
|
||||||
|
self.rows_to_refresh |= set(rows)
|
||||||
|
|
||||||
def break_cycles(self):
|
def break_cycles(self):
|
||||||
# Break any reference cycles that could prevent python
|
# Break any reference cycles that could prevent python
|
||||||
@ -618,7 +626,7 @@ class MetadataSingleDialogAlt(MetadataSingleDialogBase): # {{{
|
|||||||
def edit_metadata(db, row_list, current_row, parent=None, view_slot=None):
|
def edit_metadata(db, row_list, current_row, parent=None, view_slot=None):
|
||||||
d = MetadataSingleDialog(db, parent)
|
d = MetadataSingleDialog(db, parent)
|
||||||
d.start(row_list, current_row, view_slot=view_slot)
|
d.start(row_list, current_row, view_slot=view_slot)
|
||||||
return d.changed
|
return d.changed, d.rows_to_refresh
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from PyQt4.Qt import QApplication
|
from PyQt4.Qt import QApplication
|
||||||
|
@ -1479,17 +1479,19 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
return float(tweaks['series_index_auto_increment'])
|
return float(tweaks['series_index_auto_increment'])
|
||||||
return 1.0
|
return 1.0
|
||||||
|
|
||||||
def set(self, row, column, val):
|
def set(self, row, column, val, allow_case_change=False):
|
||||||
'''
|
'''
|
||||||
Convenience method for setting the title, authors, publisher or rating
|
Convenience method for setting the title, authors, publisher or rating
|
||||||
'''
|
'''
|
||||||
id = self.data[row][0]
|
id = self.data[row][0]
|
||||||
col = {'title':1, 'authors':2, 'publisher':3, 'rating':4, 'tags':7}[column]
|
col = {'title':1, 'authors':2, 'publisher':3, 'rating':4, 'tags':7}[column]
|
||||||
|
|
||||||
|
books_to_refresh = set()
|
||||||
self.data.set(row, col, val)
|
self.data.set(row, col, val)
|
||||||
if column == 'authors':
|
if column == 'authors':
|
||||||
val = string_to_authors(val)
|
val = string_to_authors(val)
|
||||||
self.set_authors(id, val, notify=False)
|
books_to_refresh |= self.set_authors(id, val, notify=False,
|
||||||
|
allow_case_change=allow_case_change)
|
||||||
elif column == 'title':
|
elif column == 'title':
|
||||||
self.set_title(id, val, notify=False)
|
self.set_title(id, val, notify=False)
|
||||||
elif column == 'publisher':
|
elif column == 'publisher':
|
||||||
@ -1497,11 +1499,13 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
elif column == 'rating':
|
elif column == 'rating':
|
||||||
self.set_rating(id, val, notify=False)
|
self.set_rating(id, val, notify=False)
|
||||||
elif column == 'tags':
|
elif column == 'tags':
|
||||||
self.set_tags(id, [x.strip() for x in val.split(',') if x.strip()],
|
books_to_refresh |= \
|
||||||
append=False, notify=False)
|
self.set_tags(id, [x.strip() for x in val.split(',') if x.strip()],
|
||||||
|
append=False, notify=False, allow_case_change=allow_case_change)
|
||||||
self.data.refresh_ids(self, [id])
|
self.data.refresh_ids(self, [id])
|
||||||
self.set_path(id, True)
|
self.set_path(id, True)
|
||||||
self.notify('metadata', [id])
|
self.notify('metadata', [id])
|
||||||
|
return books_to_refresh
|
||||||
|
|
||||||
def set_metadata(self, id, mi, ignore_errors=False,
|
def set_metadata(self, id, mi, ignore_errors=False,
|
||||||
set_title=True, set_authors=True, commit=True):
|
set_title=True, set_authors=True, commit=True):
|
||||||
@ -1627,28 +1631,41 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
result.append(r)
|
result.append(r)
|
||||||
return ' & '.join(result).replace('|', ',')
|
return ' & '.join(result).replace('|', ',')
|
||||||
|
|
||||||
def _set_authors(self, id, authors):
|
def _set_authors(self, id, authors, allow_case_change=False):
|
||||||
if not authors:
|
if not authors:
|
||||||
authors = [_('Unknown')]
|
authors = [_('Unknown')]
|
||||||
self.conn.execute('DELETE FROM books_authors_link WHERE book=?',(id,))
|
self.conn.execute('DELETE FROM books_authors_link WHERE book=?',(id,))
|
||||||
|
books_to_refresh = set()
|
||||||
for a in authors:
|
for a in authors:
|
||||||
if not a:
|
if not a:
|
||||||
continue
|
continue
|
||||||
a = a.strip().replace(',', '|')
|
a = a.strip().replace(',', '|')
|
||||||
if not isinstance(a, unicode):
|
if not isinstance(a, unicode):
|
||||||
a = a.decode(preferred_encoding, 'replace')
|
a = a.decode(preferred_encoding, 'replace')
|
||||||
author = self.conn.get('SELECT id from authors WHERE name=?', (a,), all=False)
|
aus = self.conn.get('SELECT id, name from authors WHERE name=?', (a,))
|
||||||
if author:
|
if aus:
|
||||||
aid = author
|
author_id, name = aus[0]
|
||||||
|
else:
|
||||||
|
author_id, name = (None, None)
|
||||||
|
if author_id:
|
||||||
|
aid = author_id
|
||||||
# Handle change of case
|
# Handle change of case
|
||||||
self.conn.execute('UPDATE authors SET name=? WHERE id=?', (a, aid))
|
if allow_case_change and name != a:
|
||||||
|
self.conn.execute('UPDATE authors SET name=? WHERE id=?', (a, aid))
|
||||||
|
case_change = True
|
||||||
else:
|
else:
|
||||||
aid = self.conn.execute('INSERT INTO authors(name) VALUES (?)', (a,)).lastrowid
|
aid = self.conn.execute('INSERT INTO authors(name) VALUES (?)', (a,)).lastrowid
|
||||||
|
case_change = False
|
||||||
try:
|
try:
|
||||||
self.conn.execute('INSERT INTO books_authors_link(book, author) VALUES (?,?)',
|
self.conn.execute('INSERT INTO books_authors_link(book, author) VALUES (?,?)',
|
||||||
(id, aid))
|
(id, aid))
|
||||||
except IntegrityError: # Sometimes books specify the same author twice in their metadata
|
except IntegrityError: # Sometimes books specify the same author twice in their metadata
|
||||||
pass
|
pass
|
||||||
|
if case_change:
|
||||||
|
bks = self.conn.get('SELECT book FROM books_authors_link WHERE author=?',
|
||||||
|
(aid,))
|
||||||
|
books_to_refresh |= set([bk[0] for bk in bks])
|
||||||
|
|
||||||
ss = self.author_sort_from_book(id, index_is_id=True)
|
ss = self.author_sort_from_book(id, index_is_id=True)
|
||||||
self.conn.execute('UPDATE books SET author_sort=? WHERE id=?',
|
self.conn.execute('UPDATE books SET author_sort=? WHERE id=?',
|
||||||
(ss, id))
|
(ss, id))
|
||||||
@ -1660,21 +1677,25 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.data.set(id, self.FIELD_MAP['au_map'],
|
self.data.set(id, self.FIELD_MAP['au_map'],
|
||||||
':#:'.join([':::'.join((au.replace(',', '|'), aus)) for (au, aus) in aum]),
|
':#:'.join([':::'.join((au.replace(',', '|'), aus)) for (au, aus) in aum]),
|
||||||
row_is_id=True)
|
row_is_id=True)
|
||||||
|
return books_to_refresh
|
||||||
|
|
||||||
def set_authors(self, id, authors, notify=True, commit=True):
|
def set_authors(self, id, authors, notify=True, commit=True,
|
||||||
|
allow_case_change=False):
|
||||||
'''
|
'''
|
||||||
Note that even if commit is False, the db will still be committed to
|
Note that even if commit is False, the db will still be committed to
|
||||||
because this causes the location of files to change
|
because this causes the location of files to change
|
||||||
|
|
||||||
:param authors: A list of authors.
|
:param authors: A list of authors.
|
||||||
'''
|
'''
|
||||||
self._set_authors(id, authors)
|
books_to_refresh = self._set_authors(id, authors,
|
||||||
|
allow_case_change=allow_case_change)
|
||||||
self.dirtied([id], commit=False)
|
self.dirtied([id], commit=False)
|
||||||
if commit:
|
if commit:
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
self.set_path(id, index_is_id=True)
|
self.set_path(id, index_is_id=True)
|
||||||
if notify:
|
if notify:
|
||||||
self.notify('metadata', [id])
|
self.notify('metadata', [id])
|
||||||
|
return books_to_refresh
|
||||||
|
|
||||||
def set_title_sort(self, id, title_sort_, notify=True, commit=True):
|
def set_title_sort(self, id, title_sort_, notify=True, commit=True):
|
||||||
if not title_sort_:
|
if not title_sort_:
|
||||||
@ -2119,7 +2140,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
def commit(self):
|
def commit(self):
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
|
||||||
def set_tags(self, id, tags, append=False, notify=True, commit=True):
|
def set_tags(self, id, tags, append=False, notify=True, commit=True,
|
||||||
|
allow_case_change=False):
|
||||||
'''
|
'''
|
||||||
@param tags: list of strings
|
@param tags: list of strings
|
||||||
@param append: If True existing tags are not removed
|
@param append: If True existing tags are not removed
|
||||||
@ -2129,7 +2151,9 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.conn.execute('DELETE FROM tags WHERE (SELECT COUNT(id) FROM books_tags_link WHERE tag=tags.id) < 1')
|
self.conn.execute('DELETE FROM tags WHERE (SELECT COUNT(id) FROM books_tags_link WHERE tag=tags.id) < 1')
|
||||||
otags = self.get_tags(id)
|
otags = self.get_tags(id)
|
||||||
tags = self.cleanup_tags(tags)
|
tags = self.cleanup_tags(tags)
|
||||||
|
books_to_refresh = set()
|
||||||
for tag in (set(tags)-otags):
|
for tag in (set(tags)-otags):
|
||||||
|
case_changed = False
|
||||||
tag = tag.strip()
|
tag = tag.strip()
|
||||||
if not tag:
|
if not tag:
|
||||||
continue
|
continue
|
||||||
@ -2144,8 +2168,9 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if idx > -1:
|
if idx > -1:
|
||||||
etag = existing_tags[idx]
|
etag = existing_tags[idx]
|
||||||
tid = self.conn.get('SELECT id FROM tags WHERE name=?', (etag,), all=False)
|
tid = self.conn.get('SELECT id FROM tags WHERE name=?', (etag,), all=False)
|
||||||
if etag != tag:
|
if allow_case_change and etag != tag:
|
||||||
self.conn.execute('UPDATE tags SET name=? WHERE id=?', (tag, tid))
|
self.conn.execute('UPDATE tags SET name=? WHERE id=?', (tag, tid))
|
||||||
|
case_changed = True
|
||||||
else:
|
else:
|
||||||
tid = self.conn.execute('INSERT INTO tags(name) VALUES(?)', (tag,)).lastrowid
|
tid = self.conn.execute('INSERT INTO tags(name) VALUES(?)', (tag,)).lastrowid
|
||||||
|
|
||||||
@ -2153,6 +2178,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
(id, tid), all=False):
|
(id, tid), all=False):
|
||||||
self.conn.execute('INSERT INTO books_tags_link(book, tag) VALUES (?,?)',
|
self.conn.execute('INSERT INTO books_tags_link(book, tag) VALUES (?,?)',
|
||||||
(id, tid))
|
(id, tid))
|
||||||
|
if case_changed:
|
||||||
|
bks = self.conn.get('SELECT book FROM books_tags_link WHERE tag=?',
|
||||||
|
(tid,))
|
||||||
|
books_to_refresh |= set([bk[0] for bk in bks])
|
||||||
self.dirtied([id], commit=False)
|
self.dirtied([id], commit=False)
|
||||||
if commit:
|
if commit:
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
@ -2160,6 +2189,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.data.set(id, self.FIELD_MAP['tags'], tags, row_is_id=True)
|
self.data.set(id, self.FIELD_MAP['tags'], tags, row_is_id=True)
|
||||||
if notify:
|
if notify:
|
||||||
self.notify('metadata', [id])
|
self.notify('metadata', [id])
|
||||||
|
return books_to_refresh
|
||||||
|
|
||||||
def unapply_tags(self, book_id, tags, notify=True):
|
def unapply_tags(self, book_id, tags, notify=True):
|
||||||
for tag in tags:
|
for tag in tags:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user