Handle case change for tags and authors.

This commit is contained in:
Charles Haley 2011-02-02 18:42:03 +00:00
parent e1c90d5be0
commit e8fd598c48
4 changed files with 57 additions and 21 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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: