diff --git a/setup/installer/windows/main.c b/setup/installer/windows/main.c index d76850504e..780be94330 100644 --- a/setup/installer/windows/main.c +++ b/setup/installer/windows/main.c @@ -23,6 +23,9 @@ wWinMain(HINSTANCE Inst, HINSTANCE PrevInst, ret = execute_python_entrypoint(BASENAME, MODULE, FUNCTION, stdout_redirect, stderr_redirect); + if (stdout != NULL) fclose(stdout); + if (stderr != NULL) fclose(stderr); + DeleteFile(stdout_redirect); DeleteFile(stderr_redirect); diff --git a/src/calibre/devices/kindle/apnx.py b/src/calibre/devices/kindle/apnx.py index ee519750e0..178c1091f3 100644 --- a/src/calibre/devices/kindle/apnx.py +++ b/src/calibre/devices/kindle/apnx.py @@ -164,7 +164,7 @@ class APNXBuilder(object): if c == '/': closing = True continue - elif c in ('d', 'p'): + elif c == 'p': if closing: in_p = False else: diff --git a/src/calibre/ebooks/metadata/extz.py b/src/calibre/ebooks/metadata/extz.py index 1bda263015..021450fca5 100644 --- a/src/calibre/ebooks/metadata/extz.py +++ b/src/calibre/ebooks/metadata/extz.py @@ -70,7 +70,7 @@ def set_metadata(stream, mi): # Update the metadata. old_mi = opf.to_book_metadata() old_mi.smart_update(mi) - opf.smart_update(metadata_to_opf(old_mi)) + opf.smart_update(metadata_to_opf(old_mi), replace_metadata=True) newopf = StringIO(opf.render()) safe_replace(stream, opf_path, newopf, extra_replacements=replacements, add_missing=True) diff --git a/src/calibre/ebooks/metadata/sources/identify.py b/src/calibre/ebooks/metadata/sources/identify.py index 3d4807ac02..1bd071d6f9 100644 --- a/src/calibre/ebooks/metadata/sources/identify.py +++ b/src/calibre/ebooks/metadata/sources/identify.py @@ -13,6 +13,7 @@ from Queue import Queue, Empty from threading import Thread from io import BytesIO from operator import attrgetter +from urlparse import urlparse from calibre.customize.ui import metadata_plugins, all_metadata_plugins from calibre.ebooks.metadata.sources.base import create_log, msprefs @@ -458,6 +459,14 @@ def urls_from_identifiers(identifiers): # {{{ if oclc: ans.append(('OCLC', 'oclc', oclc, 'http://www.worldcat.org/oclc/'+oclc)) + url = identifiers.get('uri', None) + if url is None: + url = identifiers.get('url', None) + if url and url.startswith('http'): + url = url[:8].replace('|', ':') + url[8:].replace('|', ',') + parts = urlparse(url) + name = parts.netloc + ans.append((name, 'url', url, url)) return ans # }}} diff --git a/src/calibre/gui2/actions/choose_library.py b/src/calibre/gui2/actions/choose_library.py index f6b19fc4aa..9fd156b802 100644 --- a/src/calibre/gui2/actions/choose_library.py +++ b/src/calibre/gui2/actions/choose_library.py @@ -246,7 +246,8 @@ class ChooseLibraryAction(InterfaceAction): def delete_requested(self, name, location): loc = location.replace('/', os.sep) if not question_dialog(self.gui, _('Are you sure?'), '
'+
- _('All files from
%s
will be '
+ _('All files (not just ebooks) '
+ 'from
%s
will be '
'permanently deleted. Are you sure?') % loc,
show_copy_button=False):
return
diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py
index 26f6788a75..1cfb04921d 100644
--- a/src/calibre/gui2/library/views.py
+++ b/src/calibre/gui2/library/views.py
@@ -439,10 +439,16 @@ class BooksView(QTableView): # {{{
if tweaks['sort_columns_at_startup'] is not None:
sh = []
- for c,d in tweaks['sort_columns_at_startup']:
- if not isinstance(d, bool):
- d = True if d == 0 else False
- sh.append((c, d))
+ try:
+ for c,d in tweaks['sort_columns_at_startup']:
+ if not isinstance(d, bool):
+ d = True if d == 0 else False
+ sh.append((c, d))
+ except:
+ # Ignore invalid tweak values as users seem to often get them
+ # wrong
+ import traceback
+ traceback.print_exc()
old_state['sort_history'] = sh
self.apply_state(old_state)
diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py
index eadfa55549..645ce3b228 100644
--- a/src/calibre/gui2/main.py
+++ b/src/calibre/gui2/main.py
@@ -299,13 +299,13 @@ def run_gui(opts, args, actions, listener, app, gui_debug=None):
if getattr(runner.main, 'debug_on_restart', False):
run_in_debug_mode()
else:
+ import subprocess
print 'Restarting with:', e, sys.argv
if hasattr(sys, 'frameworks_dir'):
app = os.path.dirname(os.path.dirname(sys.frameworks_dir))
- import subprocess
subprocess.Popen('sleep 3s; open '+app, shell=True)
else:
- os.execvp(e, sys.argv)
+ subprocess.Popen([e] + sys.argv[1:])
else:
if iswindows:
try:
diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py
index 1620734209..59c6512c53 100644
--- a/src/calibre/gui2/metadata/basic_widgets.py
+++ b/src/calibre/gui2/metadata/basic_widgets.py
@@ -298,11 +298,12 @@ class AuthorSortEdit(EnLineEdit):
self.current_val = self.db.author_sort_from_authors(authors)
def initialize(self, db, id_):
- self.current_val = db.author_sort(id_, index_is_id=True)
+ self.current_val = self.original_val = db.author_sort(id_, index_is_id=True)
def commit(self, db, id_):
aus = self.current_val
- db.set_author_sort(id_, aus, notify=False, commit=False)
+ if aus != self.original_val:
+ db.set_author_sort(id_, aus, notify=False, commit=False)
return True
# }}}
diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py
index 89184bedf9..065f0e8446 100644
--- a/src/calibre/library/database2.py
+++ b/src/calibre/library/database2.py
@@ -33,7 +33,7 @@ from calibre import isbytestring
from calibre.utils.filenames import ascii_filename
from calibre.utils.date import utcnow, now as nowf, utcfromtimestamp
from calibre.utils.config import prefs, tweaks, from_json, to_json
-from calibre.utils.icu import sort_key
+from calibre.utils.icu import sort_key, strcmp
from calibre.utils.search_query_parser import saved_searches, set_saved_searches
from calibre.ebooks import BOOK_EXTENSIONS, check_ebook_format
from calibre.utils.magick.draw import save_cover_data_to
@@ -1920,6 +1920,18 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
result.append(r)
return ' & '.join(result).replace('|', ',')
+ def _update_author_in_cache(self, id_, ss, final_authors):
+ self.conn.execute('UPDATE books SET author_sort=? WHERE id=?', (ss, id_))
+ self.data.set(id_, self.FIELD_MAP['authors'],
+ ','.join([a.replace(',', '|') for a in final_authors]),
+ row_is_id=True)
+ self.data.set(id_, self.FIELD_MAP['author_sort'], ss, row_is_id=True)
+
+ aum = self.authors_with_sort_strings(id_, index_is_id=True)
+ self.data.set(id_, self.FIELD_MAP['au_map'],
+ ':#:'.join([':::'.join((au.replace(',', '|'), aus)) for (au, aus) in aum]),
+ row_is_id=True)
+
def _set_authors(self, id, authors, allow_case_change=False):
if not authors:
authors = [_('Unknown')]
@@ -1933,14 +1945,17 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
a = a.strip().replace(',', '|')
if not isinstance(a, unicode):
a = a.decode(preferred_encoding, 'replace')
- aus = self.conn.get('SELECT id, name FROM authors WHERE name=?', (a,))
+ aus = self.conn.get('SELECT id, name, sort FROM authors WHERE name=?', (a,))
if aus:
- aid, name = aus[0]
+ aid, name, sort = aus[0]
# Handle change of case
if name != a:
if allow_case_change:
- self.conn.execute('''UPDATE authors
- SET name=? WHERE id=?''', (a, aid))
+ ns = author_to_author_sort(a.replace('|', ','))
+ if strcmp(sort, ns) == 0:
+ sort = ns
+ self.conn.execute('''UPDATE authors SET name=?, sort=?
+ WHERE id=?''', (a, sort, aid))
case_change = True
else:
a = name
@@ -1957,17 +1972,14 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
bks = self.conn.get('''SELECT book FROM books_authors_link
WHERE author=?''', (aid,))
books_to_refresh |= set([bk[0] for bk in bks])
+ for bk in books_to_refresh:
+ ss = self.author_sort_from_book(id, index_is_id=True)
+ aus = self.author_sort(bk, index_is_id=True)
+ if strcmp(aus, ss) == 0:
+ self._update_author_in_cache(bk, ss, final_authors)
+ # This can repeat what was done above in rare cases. Let it.
ss = self.author_sort_from_book(id, index_is_id=True)
- self.conn.execute('UPDATE books SET author_sort=? WHERE id=?',
- (ss, id))
- self.data.set(id, self.FIELD_MAP['authors'],
- ','.join([a.replace(',', '|') for a in final_authors]),
- row_is_id=True)
- self.data.set(id, self.FIELD_MAP['author_sort'], ss, row_is_id=True)
- aum = self.authors_with_sort_strings(id, index_is_id=True)
- self.data.set(id, self.FIELD_MAP['au_map'],
- ':#:'.join([':::'.join((au.replace(',', '|'), aus)) for (au, aus) in aum]),
- row_is_id=True)
+ self._update_author_in_cache(id, ss, final_authors)
return books_to_refresh
def set_authors(self, id, authors, notify=True, commit=True,