mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Handle case change for tags and authors.
This commit is contained in:
parent
e1c90d5be0
commit
e8fd598c48
@ -160,6 +160,7 @@ class EditMetadataAction(InterfaceAction):
|
|||||||
break
|
break
|
||||||
|
|
||||||
changed.add(d.id)
|
changed.add(d.id)
|
||||||
|
changed |= 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()
|
||||||
|
|
||||||
@ -775,7 +776,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)
|
||||||
@ -882,9 +884,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
|
||||||
@ -903,7 +905,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)
|
||||||
@ -913,7 +918,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
|
||||||
|
|
||||||
|
@ -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,38 @@ 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)
|
author_id, name = \
|
||||||
if author:
|
self.conn.get('SELECT id, name from authors WHERE name=?', (a,))[0]
|
||||||
aid = author
|
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 +1674,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 +2137,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,6 +2148,7 @@ 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):
|
||||||
tag = tag.strip()
|
tag = tag.strip()
|
||||||
if not tag:
|
if not tag:
|
||||||
@ -2144,8 +2164,11 @@ 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:
|
||||||
|
case_changed = False
|
||||||
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 +2176,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 +2187,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