From 40dd093352d63eac2be7a205f4ca80492f010d52 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 19 Apr 2009 15:35:13 -0700 Subject: [PATCH 1/4] Switch to using OpenLibrary as the primary source of book covers. Should speed up cover fetching. Also Fix #2316 (Calibre now fetches smaller images as covers) --- src/calibre/ebooks/metadata/library_thing.py | 35 +++++++++++--------- src/calibre/gui2/dialogs/metadata_single.py | 7 ++-- src/calibre/gui2/dialogs/metadata_single.ui | 2 +- src/calibre/web/feeds/news.py | 2 +- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/calibre/ebooks/metadata/library_thing.py b/src/calibre/ebooks/metadata/library_thing.py index ef41d5e937..0f46c72c75 100644 --- a/src/calibre/ebooks/metadata/library_thing.py +++ b/src/calibre/ebooks/metadata/library_thing.py @@ -4,13 +4,15 @@ __copyright__ = '2008, Kovid Goyal ' Fetch cover from LibraryThing.com based on ISBN number. ''' -import sys, socket, os, re, mechanize +import sys, socket, os, re from calibre import browser as _browser from calibre.utils.config import OptionParser -from calibre.ebooks.BeautifulSoup import BeautifulSoup +from calibre.ebooks.BeautifulSoup import BeautifulSoup browser = None +OPENLIBRARY = 'http://covers.openlibrary.org/b/isbn/%s-L.jpg?default=false' + class LibraryThingError(Exception): pass @@ -30,15 +32,21 @@ def login(username, password, force=True): browser['formusername'] = username browser['formpassword'] = password browser.submit() - -def cover_from_isbn(isbn, timeout=5.): + +def cover_from_isbn(isbn, timeout=5., username=None, password=None): global browser if browser is None: browser = _browser() _timeout = socket.getdefaulttimeout() socket.setdefaulttimeout(timeout) - src = None + src = None + try: + return browser.open(OPENLIBRARY%isbn).read(), 'jpg' + except: + pass # Cover not found + if username and password: + login(username, password, force=False) try: src = browser.open('http://www.librarything.com/isbn/'+isbn).read().decode('utf-8', 'replace') except Exception, err: @@ -55,7 +63,7 @@ def cover_from_isbn(isbn, timeout=5.): url = url.find('img') if url is None: raise LibraryThingError(_('LibraryThing.com server error. Try again later.')) - url = re.sub(r'_SX\d+', '', url['src']) + url = re.sub(r'_S[XY]\d+', '', url['src']) cover_data = browser.open(url).read() return cover_data, url.rpartition('.')[-1] finally: @@ -68,9 +76,9 @@ _(''' Fetch a cover image for the book identified by ISBN from LibraryThing.com ''')) - parser.add_option('-u', '--username', default=None, + parser.add_option('-u', '--username', default=None, help='Username for LibraryThing.com') - parser.add_option('-p', '--password', default=None, + parser.add_option('-p', '--password', default=None, help='Password for LibraryThing.com') return parser @@ -81,13 +89,8 @@ def main(args=sys.argv): parser.print_help() return 1 isbn = args[1] - if opts.username and opts.password: - try: - login(opts.username, opts.password) - except mechanize.FormNotFoundError: - raise LibraryThingError(_('LibraryThing.com server error. Try again later.')) - - cover_data, ext = cover_from_isbn(isbn) + cover_data, ext = cover_from_isbn(isbn, username=opts.username, + password=opts.password) if not ext: ext = 'jpg' oname = os.path.abspath(isbn+'.'+ext) @@ -96,4 +99,4 @@ def main(args=sys.argv): return 0 if __name__ == '__main__': - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 4a74c87097..1a2f2d3129 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -20,7 +20,7 @@ from calibre.gui2.dialogs.password import PasswordDialog from calibre.gui2.widgets import ProgressIndicator from calibre.ebooks import BOOK_EXTENSIONS from calibre.ebooks.metadata import authors_to_sort_string, string_to_authors, authors_to_string -from calibre.ebooks.metadata.library_thing import login, cover_from_isbn +from calibre.ebooks.metadata.library_thing import cover_from_isbn from calibre import islinux from calibre.ebooks.metadata.meta import get_metadata from calibre.utils.config import prefs @@ -60,9 +60,8 @@ class CoverFetcher(QThread): return self.isbn = results[0] - if self.username and self.password: - login(self.username, self.password, force=False) - self.cover_data = cover_from_isbn(self.isbn, timeout=self.timeout)[0] + self.cover_data = cover_from_isbn(self.isbn, timeout=self.timeout, + username=self.username, password=self.password)[0] except Exception, e: self.exception = e self.traceback = traceback.format_exc() diff --git a/src/calibre/gui2/dialogs/metadata_single.ui b/src/calibre/gui2/dialogs/metadata_single.ui index 6e96c8d741..5772609de6 100644 --- a/src/calibre/gui2/dialogs/metadata_single.ui +++ b/src/calibre/gui2/dialogs/metadata_single.ui @@ -589,7 +589,7 @@ - Fetch &cover image from server + Download &cover image diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 2494951ccd..bb3610343e 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -265,7 +265,7 @@ class BasicNewsRecipe(object, LoggingInterface): def get_feeds(self): ''' - Return a list of :term:RSS feeds to fetch for this profile. Each element of the list + Return a list of :term:`RSS` feeds to fetch for this profile. Each element of the list must be a 2-element tuple of the form (title, url). If title is None or an empty string, the title from the feed is used. This method is useful if your recipe needs to do some processing to figure out the list of feeds to download. If From fc599043699940c4e2549654f54785f0d3ed6a90 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 19 Apr 2009 15:46:25 -0700 Subject: [PATCH 2/4] IGN:Now that we use OpenLibrary for covers. Remove password dialog for LibraryThing --- src/calibre/gui2/dialogs/metadata_single.py | 14 ++++++-------- src/calibre/gui2/dialogs/metadata_single.ui | 13 +------------ 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 1a2f2d3129..05756407b3 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -25,7 +25,6 @@ from calibre import islinux from calibre.ebooks.metadata.meta import get_metadata from calibre.utils.config import prefs from calibre.customize.ui import run_plugins_on_import -from calibre.gui2 import config as gui_conf class CoverFetcher(QThread): @@ -289,7 +288,6 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.series_index.setValue(self.db.series_index(row)) QObject.connect(self.series, SIGNAL('currentIndexChanged(int)'), self.enable_series_index) QObject.connect(self.series, SIGNAL('editTextChanged(QString)'), self.enable_series_index) - QObject.connect(self.password_button, SIGNAL('clicked()'), self.change_password) self.show() height_of_rest = self.frameGeometry().height() - self.cover.height() @@ -377,15 +375,15 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): def fetch_cover(self): isbn = unicode(self.isbn.text()).strip() - d = self.lt_password_dialog() - if not gui_conf['asked_library_thing_password'] and \ - (not d.username() or not d.password()): - d.exec_() - gui_conf['asked_library_thing_password'] = True + #d = self.lt_password_dialog() + #if not gui_conf['asked_library_thing_password'] and \ + # (not d.username() or not d.password()): + # d.exec_() + # gui_conf['asked_library_thing_password'] = True self.fetch_cover_button.setEnabled(False) self.setCursor(Qt.WaitCursor) title, author = map(unicode, (self.title.text(), self.authors.text())) - self.cover_fetcher = CoverFetcher(d.username(), d.password(), isbn, + self.cover_fetcher = CoverFetcher(None, None, isbn, self.timeout, title, author) self.cover_fetcher.start() self._hangcheck = QTimer(self) diff --git a/src/calibre/gui2/dialogs/metadata_single.ui b/src/calibre/gui2/dialogs/metadata_single.ui index 5772609de6..2c4ab859a3 100644 --- a/src/calibre/gui2/dialogs/metadata_single.ui +++ b/src/calibre/gui2/dialogs/metadata_single.ui @@ -589,17 +589,7 @@ - Download &cover image - - - - - - - Change the username and/or password for your account at LibraryThing.com - - - Change &password + Download &cover @@ -655,7 +645,6 @@ comments fetch_metadata_button fetch_cover_button - password_button formats add_format_button remove_format_button From db67fe6cd582f67b80ea93ebefb97f580eaa668c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 19 Apr 2009 15:47:02 -0700 Subject: [PATCH 3/4] version 0.5.8 --- src/calibre/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/constants.py b/src/calibre/constants.py index 138a631b7c..186eb37e34 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -2,7 +2,7 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __appname__ = 'calibre' -__version__ = '0.5.7' +__version__ = '0.5.8' __author__ = "Kovid Goyal " ''' Various run time constants. From cb7d91de134e48a05d9e2756895a99242bd50685 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 19 Apr 2009 15:48:56 -0700 Subject: [PATCH 4/4] IGN:Tag release