Pull from trunk

This commit is contained in:
Kovid Goyal 2009-04-19 15:49:37 -07:00
commit 6411a81fef
5 changed files with 31 additions and 42 deletions

View File

@ -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 <kovid@kovidgoyal.net>"
'''
Various run time constants.

View File

@ -4,13 +4,15 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
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())
sys.exit(main())

View File

@ -20,12 +20,11 @@ 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
from calibre.customize.ui import run_plugins_on_import
from calibre.gui2 import config as gui_conf
class CoverFetcher(QThread):
@ -60,9 +59,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()
@ -290,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()
@ -378,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)

View File

@ -589,17 +589,7 @@
<item>
<widget class="QPushButton" name="fetch_cover_button">
<property name="text">
<string>Fetch &amp;cover image from server</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="password_button">
<property name="toolTip">
<string>Change the username and/or password for your account at LibraryThing.com</string>
</property>
<property name="text">
<string>Change &amp;password</string>
<string>Download &amp;cover</string>
</property>
</widget>
</item>
@ -655,7 +645,6 @@
<tabstop>comments</tabstop>
<tabstop>fetch_metadata_button</tabstop>
<tabstop>fetch_cover_button</tabstop>
<tabstop>password_button</tabstop>
<tabstop>formats</tabstop>
<tabstop>add_format_button</tabstop>
<tabstop>remove_format_button</tabstop>

View File

@ -266,7 +266,7 @@ class BasicNewsRecipe(object):
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