mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix error message in OSX when dragging and dropping a cover onto the edit metadata dialog
This commit is contained in:
parent
ff57c45613
commit
7448079aa8
@ -57,7 +57,7 @@ r'''
|
|||||||
def _check_symlinks_prescript():
|
def _check_symlinks_prescript():
|
||||||
import os, tempfile, traceback, sys
|
import os, tempfile, traceback, sys
|
||||||
from Authorization import Authorization, kAuthorizationFlagDestroyRights
|
from Authorization import Authorization, kAuthorizationFlagDestroyRights
|
||||||
|
|
||||||
AUTHTOOL="""#!%(sp)s
|
AUTHTOOL="""#!%(sp)s
|
||||||
import os
|
import os
|
||||||
scripts = %(sp)s
|
scripts = %(sp)s
|
||||||
@ -71,13 +71,13 @@ for s, l in zip(scripts, links):
|
|||||||
os.symlink(s, l)
|
os.symlink(s, l)
|
||||||
os.umask(omask)
|
os.umask(omask)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dest_path = %(dest_path)s
|
dest_path = %(dest_path)s
|
||||||
resources_path = os.environ['RESOURCEPATH']
|
resources_path = os.environ['RESOURCEPATH']
|
||||||
scripts = %(scripts)s
|
scripts = %(scripts)s
|
||||||
links = [os.path.join(dest_path, i) for i in scripts]
|
links = [os.path.join(dest_path, i) for i in scripts]
|
||||||
scripts = [os.path.join(resources_path, 'loaders', i) for i in scripts]
|
scripts = [os.path.join(resources_path, 'loaders', i) for i in scripts]
|
||||||
|
|
||||||
bad = False
|
bad = False
|
||||||
for s, l in zip(scripts, links):
|
for s, l in zip(scripts, links):
|
||||||
if os.path.exists(l) and os.path.exists(os.path.realpath(l)):
|
if os.path.exists(l) and os.path.exists(os.path.realpath(l)):
|
||||||
@ -111,22 +111,22 @@ _check_symlinks_prescript()
|
|||||||
packages=self.packages,
|
packages=self.packages,
|
||||||
excludes=self.excludes,
|
excludes=self.excludes,
|
||||||
debug=debug)
|
debug=debug)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def makedmg(cls, d, volname,
|
def makedmg(cls, d, volname,
|
||||||
destdir='dist',
|
destdir='dist',
|
||||||
internet_enable=True,
|
internet_enable=True,
|
||||||
format='UDBZ'):
|
format='UDBZ'):
|
||||||
''' Copy a directory d into a dmg named volname '''
|
''' Copy a directory d into a dmg named volname '''
|
||||||
dmg = os.path.join(destdir, volname+'.dmg')
|
dmg = os.path.join(destdir, volname+'.dmg')
|
||||||
if os.path.exists(dmg):
|
if os.path.exists(dmg):
|
||||||
os.unlink(dmg)
|
os.unlink(dmg)
|
||||||
subprocess.check_call(['/usr/bin/hdiutil', 'create', '-srcfolder', os.path.abspath(d),
|
subprocess.check_call(['/usr/bin/hdiutil', 'create', '-srcfolder', os.path.abspath(d),
|
||||||
'-volname', volname, '-format', format, dmg])
|
'-volname', volname, '-format', format, dmg])
|
||||||
if internet_enable:
|
if internet_enable:
|
||||||
subprocess.check_call(['/usr/bin/hdiutil', 'internet-enable', '-yes', dmg])
|
subprocess.check_call(['/usr/bin/hdiutil', 'internet-enable', '-yes', dmg])
|
||||||
return dmg
|
return dmg
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def qt_dependencies(cls, path):
|
def qt_dependencies(cls, path):
|
||||||
pipe = subprocess.Popen('/usr/bin/otool -L '+path, shell=True, stdout=subprocess.PIPE).stdout
|
pipe = subprocess.Popen('/usr/bin/otool -L '+path, shell=True, stdout=subprocess.PIPE).stdout
|
||||||
@ -134,12 +134,12 @@ _check_symlinks_prescript()
|
|||||||
for l in pipe.readlines():
|
for l in pipe.readlines():
|
||||||
match = re.search(r'(.*)\(', l)
|
match = re.search(r'(.*)\(', l)
|
||||||
if not match:
|
if not match:
|
||||||
continue
|
continue
|
||||||
lib = match.group(1).strip()
|
lib = match.group(1).strip()
|
||||||
if lib.startswith(BuildAPP.QT_PREFIX):
|
if lib.startswith(BuildAPP.QT_PREFIX):
|
||||||
deps.append(lib)
|
deps.append(lib)
|
||||||
return deps
|
return deps
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fix_qt_dependencies(cls, path, deps):
|
def fix_qt_dependencies(cls, path, deps):
|
||||||
fp = '@executable_path/../Frameworks/'
|
fp = '@executable_path/../Frameworks/'
|
||||||
@ -155,8 +155,8 @@ _check_symlinks_prescript()
|
|||||||
newpath = fp + '%s.framework/Versions/Current/%s'%(module, module)
|
newpath = fp + '%s.framework/Versions/Current/%s'%(module, module)
|
||||||
cmd = ' '.join(['/usr/bin/install_name_tool', '-change', dep, newpath, path])
|
cmd = ' '.join(['/usr/bin/install_name_tool', '-change', dep, newpath, path])
|
||||||
subprocess.check_call(cmd, shell=True)
|
subprocess.check_call(cmd, shell=True)
|
||||||
|
|
||||||
|
|
||||||
def add_qt_plugins(self):
|
def add_qt_plugins(self):
|
||||||
macos_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'MacOS')
|
macos_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'MacOS')
|
||||||
for root, dirs, files in os.walk(BuildAPP.QT_PREFIX+'/plugins'):
|
for root, dirs, files in os.walk(BuildAPP.QT_PREFIX+'/plugins'):
|
||||||
@ -172,14 +172,14 @@ _check_symlinks_prescript()
|
|||||||
shutil.copymode(path, target)
|
shutil.copymode(path, target)
|
||||||
deps = BuildAPP.qt_dependencies(target)
|
deps = BuildAPP.qt_dependencies(target)
|
||||||
BuildAPP.fix_qt_dependencies(target, deps)
|
BuildAPP.fix_qt_dependencies(target, deps)
|
||||||
|
|
||||||
|
|
||||||
#deps = BuildAPP.qt_dependencies(path)
|
#deps = BuildAPP.qt_dependencies(path)
|
||||||
|
|
||||||
def fix_python_dependencies(self, files):
|
def fix_python_dependencies(self, files):
|
||||||
for f in files:
|
for f in files:
|
||||||
subprocess.check_call(['/usr/bin/install_name_tool', '-change', '/Library/Frameworks/Python.framework/Versions/2.6/Python', '@executable_path/../Frameworks/Python.framework/Versions/2.6/Python', f])
|
subprocess.check_call(['/usr/bin/install_name_tool', '-change', '/Library/Frameworks/Python.framework/Versions/2.6/Python', '@executable_path/../Frameworks/Python.framework/Versions/2.6/Python', f])
|
||||||
|
|
||||||
def fix_misc_dependencies(self, files):
|
def fix_misc_dependencies(self, files):
|
||||||
for path in files:
|
for path in files:
|
||||||
frameworks_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Frameworks')
|
frameworks_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Frameworks')
|
||||||
@ -195,15 +195,15 @@ _check_symlinks_prescript()
|
|||||||
if os.path.exists(bundle):
|
if os.path.exists(bundle):
|
||||||
subprocess.check_call(['/usr/bin/install_name_tool', '-change', dep,
|
subprocess.check_call(['/usr/bin/install_name_tool', '-change', dep,
|
||||||
'@executable_path/../Frameworks/'+name, path])
|
'@executable_path/../Frameworks/'+name, path])
|
||||||
|
|
||||||
|
|
||||||
def add_plugins(self):
|
def add_plugins(self):
|
||||||
self.add_qt_plugins()
|
self.add_qt_plugins()
|
||||||
frameworks_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Frameworks')
|
frameworks_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Frameworks')
|
||||||
plugins_dir = os.path.join(frameworks_dir, 'plugins')
|
plugins_dir = os.path.join(frameworks_dir, 'plugins')
|
||||||
if not os.path.exists(plugins_dir):
|
if not os.path.exists(plugins_dir):
|
||||||
os.mkdir(plugins_dir)
|
os.mkdir(plugins_dir)
|
||||||
|
|
||||||
maps = {}
|
maps = {}
|
||||||
for f in glob.glob('src/calibre/plugins/*'):
|
for f in glob.glob('src/calibre/plugins/*'):
|
||||||
tgt = plugins_dir
|
tgt = plugins_dir
|
||||||
@ -217,8 +217,8 @@ _check_symlinks_prescript()
|
|||||||
deps.append(dst)
|
deps.append(dst)
|
||||||
self.fix_python_dependencies(deps)
|
self.fix_python_dependencies(deps)
|
||||||
self.fix_misc_dependencies(deps)
|
self.fix_misc_dependencies(deps)
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
py2app.run(self)
|
py2app.run(self)
|
||||||
resource_dir = os.path.join(self.dist_dir,
|
resource_dir = os.path.join(self.dist_dir,
|
||||||
@ -242,8 +242,8 @@ _check_symlinks_prescript()
|
|||||||
os.chmod(path, stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH|stat.S_IREAD\
|
os.chmod(path, stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH|stat.S_IREAD\
|
||||||
|stat.S_IWUSR|stat.S_IROTH|stat.S_IRGRP)
|
|stat.S_IWUSR|stat.S_IROTH|stat.S_IRGRP)
|
||||||
self.add_plugins()
|
self.add_plugins()
|
||||||
|
|
||||||
|
|
||||||
print
|
print
|
||||||
print 'Adding pdftohtml'
|
print 'Adding pdftohtml'
|
||||||
os.link(os.path.expanduser('~/pdftohtml'), os.path.join(frameworks_dir, 'pdftohtml'))
|
os.link(os.path.expanduser('~/pdftohtml'), os.path.join(frameworks_dir, 'pdftohtml'))
|
||||||
@ -259,21 +259,21 @@ _check_symlinks_prescript()
|
|||||||
if os.path.exists(dst):
|
if os.path.exists(dst):
|
||||||
shutil.rmtree(dst)
|
shutil.rmtree(dst)
|
||||||
shutil.copytree('/usr/local/etc/fonts', dst, symlinks=False)
|
shutil.copytree('/usr/local/etc/fonts', dst, symlinks=False)
|
||||||
|
|
||||||
print
|
print
|
||||||
print 'Adding IPython'
|
print 'Adding IPython'
|
||||||
dst = os.path.join(resource_dir, 'lib', 'python2.6', 'IPython')
|
dst = os.path.join(resource_dir, 'lib', 'python2.6', 'IPython')
|
||||||
if os.path.exists(dst): shutil.rmtree(dst)
|
if os.path.exists(dst): shutil.rmtree(dst)
|
||||||
shutil.copytree(os.path.expanduser('~/build/ipython/IPython'), dst)
|
shutil.copytree(os.path.expanduser('~/build/ipython/IPython'), dst)
|
||||||
|
|
||||||
print
|
print
|
||||||
print 'Adding ImageMagick'
|
print 'Adding ImageMagick'
|
||||||
dest = os.path.join(frameworks_dir, 'ImageMagick')
|
dest = os.path.join(frameworks_dir, 'ImageMagick')
|
||||||
if os.path.exists(dest):
|
if os.path.exists(dest):
|
||||||
sutil.rmtree(dest)
|
shutil.rmtree(dest)
|
||||||
shutil.copytree(os.path.expanduser('~/ImageMagick'), dest, True)
|
shutil.copytree(os.path.expanduser('~/ImageMagick'), dest, True)
|
||||||
shutil.copyfile('/usr/local/lib/libpng12.0.dylib', os.path.join(dest, 'lib', 'libpng12.0.dylib'))
|
shutil.copyfile('/usr/local/lib/libpng12.0.dylib', os.path.join(dest, 'lib', 'libpng12.0.dylib'))
|
||||||
|
|
||||||
print
|
print
|
||||||
print 'Installing prescipt'
|
print 'Installing prescipt'
|
||||||
sf = [os.path.basename(s) for s in all_names]
|
sf = [os.path.basename(s) for s in all_names]
|
||||||
@ -293,13 +293,13 @@ sys.frameworks_dir = os.path.join(os.path.dirname(os.environ['RESOURCEPATH']), '
|
|||||||
print >>f, 'import sys, os'
|
print >>f, 'import sys, os'
|
||||||
f.write(src)
|
f.write(src)
|
||||||
f.close()
|
f.close()
|
||||||
print
|
print
|
||||||
print 'Adding main scripts to site-packages'
|
print 'Adding main scripts to site-packages'
|
||||||
f = zipfile.ZipFile(os.path.join(self.dist_dir, APPNAME+'.app', 'Contents', 'Resources', 'lib', 'python'+sys.version[:3], 'site-packages.zip'), 'a', zipfile.ZIP_DEFLATED)
|
f = zipfile.ZipFile(os.path.join(self.dist_dir, APPNAME+'.app', 'Contents', 'Resources', 'lib', 'python'+sys.version[:3], 'site-packages.zip'), 'a', zipfile.ZIP_DEFLATED)
|
||||||
for script in scripts['gui']+scripts['console']:
|
for script in scripts['gui']+scripts['console']:
|
||||||
f.write(script, script.partition('/')[-1])
|
f.write(script, script.partition('/')[-1])
|
||||||
f.close()
|
f.close()
|
||||||
print
|
print
|
||||||
print 'Creating console.app'
|
print 'Creating console.app'
|
||||||
contents_dir = os.path.dirname(resource_dir)
|
contents_dir = os.path.dirname(resource_dir)
|
||||||
cc_dir = os.path.join(contents_dir, 'console.app', 'Contents')
|
cc_dir = os.path.join(contents_dir, 'console.app', 'Contents')
|
||||||
@ -312,7 +312,7 @@ sys.frameworks_dir = os.path.join(os.path.dirname(os.environ['RESOURCEPATH']), '
|
|||||||
plist['LSUIElement'] = '1'
|
plist['LSUIElement'] = '1'
|
||||||
plistlib.writePlist(plist, os.path.join(cc_dir, x))
|
plistlib.writePlist(plist, os.path.join(cc_dir, x))
|
||||||
else:
|
else:
|
||||||
os.symlink(os.path.join('../..', x),
|
os.symlink(os.path.join('../..', x),
|
||||||
os.path.join(cc_dir, x))
|
os.path.join(cc_dir, x))
|
||||||
print
|
print
|
||||||
print 'Building disk image'
|
print 'Building disk image'
|
||||||
@ -343,9 +343,10 @@ def main():
|
|||||||
'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*',
|
'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*',
|
||||||
'keyword', 'codeop', 'pydoc', 'readline',
|
'keyword', 'codeop', 'pydoc', 'readline',
|
||||||
'BeautifulSoup', 'calibre.ebooks.lrf.fonts.prs500.*',
|
'BeautifulSoup', 'calibre.ebooks.lrf.fonts.prs500.*',
|
||||||
'dateutil',
|
'dateutil', 'email.iterators',
|
||||||
|
'email.generator',
|
||||||
],
|
],
|
||||||
'packages' : ['PIL', 'Authorization', 'lxml'],
|
'packages' : ['PIL', 'Authorization', 'lxml', 'dns'],
|
||||||
'excludes' : ['IPython'],
|
'excludes' : ['IPython'],
|
||||||
'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.'''
|
'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.'''
|
||||||
''' Visit http://calibre.kovidgoyal.net for details.''',
|
''' Visit http://calibre.kovidgoyal.net for details.''',
|
||||||
|
@ -11,7 +11,7 @@ from calibre.utils.config import OptionParser
|
|||||||
|
|
||||||
class FetchGoogle(Thread):
|
class FetchGoogle(Thread):
|
||||||
name = 'Google Books'
|
name = 'Google Books'
|
||||||
|
|
||||||
def __init__(self, title, author, publisher, isbn, verbose):
|
def __init__(self, title, author, publisher, isbn, verbose):
|
||||||
self.title = title
|
self.title = title
|
||||||
self.verbose = verbose
|
self.verbose = verbose
|
||||||
@ -21,17 +21,17 @@ class FetchGoogle(Thread):
|
|||||||
Thread.__init__(self, None)
|
Thread.__init__(self, None)
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
self.exception, self.tb = None, None
|
self.exception, self.tb = None, None
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
from calibre.ebooks.metadata.google_books import search
|
from calibre.ebooks.metadata.google_books import search
|
||||||
try:
|
try:
|
||||||
self.results = search(self.title, self.author, self.publisher,
|
self.results = search(self.title, self.author, self.publisher,
|
||||||
self.isbn, max_results=10,
|
self.isbn, max_results=10,
|
||||||
verbose=self.verbose)
|
verbose=self.verbose)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.results = []
|
self.results = []
|
||||||
self.exception = e
|
self.exception = e
|
||||||
self.tb = traceback.format_exc()
|
self.tb = traceback.format_exc()
|
||||||
|
|
||||||
|
|
||||||
class FetchISBNDB(Thread):
|
class FetchISBNDB(Thread):
|
||||||
@ -46,19 +46,21 @@ class FetchISBNDB(Thread):
|
|||||||
self.daemon = True
|
self.daemon = True
|
||||||
self.exception, self.tb = None, None
|
self.exception, self.tb = None, None
|
||||||
self.key = key
|
self.key = key
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
from calibre.ebooks.metadata.isbndb import option_parser, create_books
|
from calibre.ebooks.metadata.isbndb import option_parser, create_books
|
||||||
args = ['isbndb']
|
args = ['isbndb']
|
||||||
if self.isbn:
|
if self.isbn:
|
||||||
args.extend(['--isbn', self.isbn])
|
args.extend(['--isbn', self.isbn])
|
||||||
else:
|
else:
|
||||||
if self.title:
|
if self.title:
|
||||||
args.extend(['--title', self.title])
|
args.extend(['--title', self.title])
|
||||||
if self.author:
|
if self.author:
|
||||||
args.extend(['--author', self.author])
|
args.extend(['--author', self.author])
|
||||||
if self.publisher:
|
if self.publisher:
|
||||||
args.extend(['--publisher', self.publisher])
|
args.extend(['--publisher', self.publisher])
|
||||||
|
if self.verbose:
|
||||||
|
args.extend(['--verbose'])
|
||||||
args.append(self.key)
|
args.append(self.key)
|
||||||
try:
|
try:
|
||||||
opts, args = option_parser().parse_args(args)
|
opts, args = option_parser().parse_args(args)
|
||||||
@ -75,7 +77,7 @@ def result_index(source, result):
|
|||||||
if x.isbn == result.isbn:
|
if x.isbn == result.isbn:
|
||||||
return i
|
return i
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
def merge_results(one, two):
|
def merge_results(one, two):
|
||||||
for x in two:
|
for x in two:
|
||||||
idx = result_index(one, x)
|
idx = result_index(one, x)
|
||||||
@ -90,42 +92,42 @@ def search(title=None, author=None, publisher=None, isbn=None, isbndb_key=None,
|
|||||||
isbn is None)
|
isbn is None)
|
||||||
fetchers = [FetchGoogle(title, author, publisher, isbn, verbose)]
|
fetchers = [FetchGoogle(title, author, publisher, isbn, verbose)]
|
||||||
if isbndb_key:
|
if isbndb_key:
|
||||||
fetchers.append(FetchISBNDB(title, author, publisher, isbn, verbose,
|
fetchers.append(FetchISBNDB(title, author, publisher, isbn, verbose,
|
||||||
isbndb_key))
|
isbndb_key))
|
||||||
|
|
||||||
|
|
||||||
for fetcher in fetchers:
|
for fetcher in fetchers:
|
||||||
fetcher.start()
|
fetcher.start()
|
||||||
for fetcher in fetchers:
|
for fetcher in fetchers:
|
||||||
fetcher.join()
|
fetcher.join()
|
||||||
for fetcher in fetchers[1:]:
|
for fetcher in fetchers[1:]:
|
||||||
merge_results(fetchers[0].results, fetcher.results)
|
merge_results(fetchers[0].results, fetcher.results)
|
||||||
|
|
||||||
results = sorted(fetchers[0].results, cmp=lambda x, y : cmp(
|
results = sorted(fetchers[0].results, cmp=lambda x, y : cmp(
|
||||||
(x.comments.strip() if x.comments else ''),
|
(x.comments.strip() if x.comments else ''),
|
||||||
(y.comments.strip() if y.comments else '')
|
(y.comments.strip() if y.comments else '')
|
||||||
), reverse=True)
|
), reverse=True)
|
||||||
|
|
||||||
return results, [(x.name, x.exception, x.tb) for x in fetchers]
|
return results, [(x.name, x.exception, x.tb) for x in fetchers]
|
||||||
|
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
parser = OptionParser(textwrap.dedent(
|
parser = OptionParser(textwrap.dedent(
|
||||||
'''\
|
'''\
|
||||||
%prog [options]
|
%prog [options]
|
||||||
|
|
||||||
Fetch book metadata from online sources. You must specify at least one
|
Fetch book metadata from online sources. You must specify at least one
|
||||||
of title, author, publisher or ISBN. If you specify ISBN, the others
|
of title, author, publisher or ISBN. If you specify ISBN, the others
|
||||||
are ignored.
|
are ignored.
|
||||||
'''
|
'''
|
||||||
))
|
))
|
||||||
parser.add_option('-t', '--title', help='Book title')
|
parser.add_option('-t', '--title', help='Book title')
|
||||||
parser.add_option('-a', '--author', help='Book author(s)')
|
parser.add_option('-a', '--author', help='Book author(s)')
|
||||||
parser.add_option('-p', '--publisher', help='Book publisher')
|
parser.add_option('-p', '--publisher', help='Book publisher')
|
||||||
parser.add_option('-i', '--isbn', help='Book ISBN')
|
parser.add_option('-i', '--isbn', help='Book ISBN')
|
||||||
parser.add_option('-m', '--max-results', default=10,
|
parser.add_option('-m', '--max-results', default=10,
|
||||||
help='Maximum number of results to fetch')
|
help='Maximum number of results to fetch')
|
||||||
parser.add_option('-k', '--isbndb-key',
|
parser.add_option('-k', '--isbndb-key',
|
||||||
help=('The access key for your ISBNDB.com account. '
|
help=('The access key for your ISBNDB.com account. '
|
||||||
'Only needed if you want to search isbndb.com'))
|
'Only needed if you want to search isbndb.com'))
|
||||||
parser.add_option('-v', '--verbose', default=0, action='count',
|
parser.add_option('-v', '--verbose', default=0, action='count',
|
||||||
@ -135,19 +137,19 @@ def option_parser():
|
|||||||
def main(args=sys.argv):
|
def main(args=sys.argv):
|
||||||
parser = option_parser()
|
parser = option_parser()
|
||||||
opts, args = parser.parse_args(args)
|
opts, args = parser.parse_args(args)
|
||||||
results, exceptions = search(opts.title, opts.author, opts.publisher,
|
results, exceptions = search(opts.title, opts.author, opts.publisher,
|
||||||
opts.isbn, opts.isbndb_key, opts.verbose)
|
opts.isbn, opts.isbndb_key, opts.verbose)
|
||||||
for result in results:
|
for result in results:
|
||||||
print unicode(result).encode(preferred_encoding)
|
print unicode(result).encode(preferred_encoding)
|
||||||
print
|
print
|
||||||
|
|
||||||
for name, exception, tb in exceptions:
|
for name, exception, tb in exceptions:
|
||||||
if exception is not None:
|
if exception is not None:
|
||||||
print 'WARNING: Fetching from', name, 'failed with error:'
|
print 'WARNING: Fetching from', name, 'failed with error:'
|
||||||
print exception
|
print exception
|
||||||
print tb
|
print tb
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
@ -10,10 +10,10 @@ from calibre.gui2.dialogs.jobs_ui import Ui_JobsDialog
|
|||||||
from calibre import __appname__
|
from calibre import __appname__
|
||||||
|
|
||||||
class ProgressBarDelegate(QAbstractItemDelegate):
|
class ProgressBarDelegate(QAbstractItemDelegate):
|
||||||
|
|
||||||
def sizeHint(self, option, index):
|
def sizeHint(self, option, index):
|
||||||
return QSize(120, 30)
|
return QSize(120, 30)
|
||||||
|
|
||||||
def paint(self, painter, option, index):
|
def paint(self, painter, option, index):
|
||||||
opts = QStyleOptionProgressBarV2()
|
opts = QStyleOptionProgressBarV2()
|
||||||
opts.rect = option.rect
|
opts.rect = option.rect
|
||||||
@ -44,20 +44,23 @@ class JobsDialog(QDialog, Ui_JobsDialog):
|
|||||||
self.jobs_view.model().kill_job)
|
self.jobs_view.model().kill_job)
|
||||||
self.pb_delegate = ProgressBarDelegate(self)
|
self.pb_delegate = ProgressBarDelegate(self)
|
||||||
self.jobs_view.setItemDelegateForColumn(2, self.pb_delegate)
|
self.jobs_view.setItemDelegateForColumn(2, self.pb_delegate)
|
||||||
|
|
||||||
self.running_time_timer = QTimer(self)
|
self.running_time_timer = QTimer(self)
|
||||||
self.connect(self.running_time_timer, SIGNAL('timeout()'), self.update_running_time)
|
self.connect(self.running_time_timer, SIGNAL('timeout()'), self.update_running_time)
|
||||||
self.running_time_timer.start(1000)
|
self.running_time_timer.start(1000)
|
||||||
|
|
||||||
def update_running_time(self, *args):
|
def update_running_time(self, *args):
|
||||||
self.model.running_time_updated()
|
try:
|
||||||
|
self.model.running_time_updated()
|
||||||
|
except: # Raises random exceptions on OS X
|
||||||
|
pass
|
||||||
|
|
||||||
def kill_job(self):
|
def kill_job(self):
|
||||||
for index in self.jobs_view.selectedIndexes():
|
for index in self.jobs_view.selectedIndexes():
|
||||||
row = index.row()
|
row = index.row()
|
||||||
self.model.kill_job(row, self)
|
self.model.kill_job(row, self)
|
||||||
return
|
return
|
||||||
|
|
||||||
def closeEvent(self, e):
|
def closeEvent(self, e):
|
||||||
self.jobs_view.write_settings()
|
self.jobs_view.write_settings()
|
||||||
e.accept()
|
e.accept()
|
||||||
|
@ -18,27 +18,27 @@ from calibre.gui2.dialogs.job_view_ui import Ui_Dialog
|
|||||||
NONE = QVariant()
|
NONE = QVariant()
|
||||||
|
|
||||||
class JobManager(QAbstractTableModel):
|
class JobManager(QAbstractTableModel):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
QAbstractTableModel.__init__(self)
|
QAbstractTableModel.__init__(self)
|
||||||
self.wait_icon = QVariant(QIcon(':/images/jobs.svg'))
|
self.wait_icon = QVariant(QIcon(':/images/jobs.svg'))
|
||||||
self.running_icon = QVariant(QIcon(':/images/exec.svg'))
|
self.running_icon = QVariant(QIcon(':/images/exec.svg'))
|
||||||
self.error_icon = QVariant(QIcon(':/images/dialog_error.svg'))
|
self.error_icon = QVariant(QIcon(':/images/dialog_error.svg'))
|
||||||
self.done_icon = QVariant(QIcon(':/images/ok.svg'))
|
self.done_icon = QVariant(QIcon(':/images/ok.svg'))
|
||||||
|
|
||||||
self.jobs = []
|
self.jobs = []
|
||||||
self.server = Server()
|
self.server = Server()
|
||||||
self.add_job = Dispatcher(self._add_job)
|
self.add_job = Dispatcher(self._add_job)
|
||||||
self.status_update = Dispatcher(self._status_update)
|
self.status_update = Dispatcher(self._status_update)
|
||||||
self.start_work = Dispatcher(self._start_work)
|
self.start_work = Dispatcher(self._start_work)
|
||||||
self.job_done = Dispatcher(self._job_done)
|
self.job_done = Dispatcher(self._job_done)
|
||||||
|
|
||||||
def columnCount(self, parent=QModelIndex()):
|
def columnCount(self, parent=QModelIndex()):
|
||||||
return 4
|
return 4
|
||||||
|
|
||||||
def rowCount(self, parent=QModelIndex()):
|
def rowCount(self, parent=QModelIndex()):
|
||||||
return len(self.jobs)
|
return len(self.jobs)
|
||||||
|
|
||||||
def headerData(self, section, orientation, role):
|
def headerData(self, section, orientation, role):
|
||||||
if role != Qt.DisplayRole:
|
if role != Qt.DisplayRole:
|
||||||
return NONE
|
return NONE
|
||||||
@ -50,14 +50,14 @@ class JobManager(QAbstractTableModel):
|
|||||||
return QVariant(text)
|
return QVariant(text)
|
||||||
else:
|
else:
|
||||||
return QVariant(section+1)
|
return QVariant(section+1)
|
||||||
|
|
||||||
def data(self, index, role):
|
def data(self, index, role):
|
||||||
try:
|
try:
|
||||||
if role not in (Qt.DisplayRole, Qt.DecorationRole):
|
if role not in (Qt.DisplayRole, Qt.DecorationRole):
|
||||||
return NONE
|
return NONE
|
||||||
row, col = index.row(), index.column()
|
row, col = index.row(), index.column()
|
||||||
job = self.jobs[row]
|
job = self.jobs[row]
|
||||||
|
|
||||||
if role == Qt.DisplayRole:
|
if role == Qt.DisplayRole:
|
||||||
if col == 0:
|
if col == 0:
|
||||||
desc = job.description
|
desc = job.description
|
||||||
@ -102,31 +102,31 @@ class JobManager(QAbstractTableModel):
|
|||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return NONE
|
return NONE
|
||||||
|
|
||||||
def _add_job(self, job):
|
def _add_job(self, job):
|
||||||
self.emit(SIGNAL('layoutAboutToBeChanged()'))
|
self.emit(SIGNAL('layoutAboutToBeChanged()'))
|
||||||
self.jobs.append(job)
|
self.jobs.append(job)
|
||||||
self.jobs.sort()
|
self.jobs.sort()
|
||||||
self.emit(SIGNAL('job_added(int)'), self.rowCount())
|
self.emit(SIGNAL('job_added(int)'), self.rowCount())
|
||||||
self.emit(SIGNAL('layoutChanged()'))
|
self.emit(SIGNAL('layoutChanged()'))
|
||||||
|
|
||||||
def done_jobs(self):
|
def done_jobs(self):
|
||||||
return [j for j in self.jobs if j.status() in ['DONE', 'ERROR']]
|
return [j for j in self.jobs if j.status() in ['DONE', 'ERROR']]
|
||||||
|
|
||||||
def row_to_job(self, row):
|
def row_to_job(self, row):
|
||||||
return self.jobs[row]
|
return self.jobs[row]
|
||||||
|
|
||||||
def _start_work(self, job):
|
def _start_work(self, job):
|
||||||
self.emit(SIGNAL('layoutAboutToBeChanged()'))
|
self.emit(SIGNAL('layoutAboutToBeChanged()'))
|
||||||
self.jobs.sort()
|
self.jobs.sort()
|
||||||
self.emit(SIGNAL('layoutChanged()'))
|
self.emit(SIGNAL('layoutChanged()'))
|
||||||
|
|
||||||
def _job_done(self, job):
|
def _job_done(self, job):
|
||||||
self.emit(SIGNAL('layoutAboutToBeChanged()'))
|
self.emit(SIGNAL('layoutAboutToBeChanged()'))
|
||||||
self.jobs.sort()
|
self.jobs.sort()
|
||||||
self.emit(SIGNAL('job_done(int)'), len(self.jobs) - len(self.done_jobs()))
|
self.emit(SIGNAL('job_done(int)'), len(self.jobs) - len(self.done_jobs()))
|
||||||
self.emit(SIGNAL('layoutChanged()'))
|
self.emit(SIGNAL('layoutChanged()'))
|
||||||
|
|
||||||
def _status_update(self, job):
|
def _status_update(self, job):
|
||||||
try:
|
try:
|
||||||
row = self.jobs.index(job)
|
row = self.jobs.index(job)
|
||||||
@ -134,38 +134,38 @@ class JobManager(QAbstractTableModel):
|
|||||||
return
|
return
|
||||||
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'),
|
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'),
|
||||||
self.index(row, 0), self.index(row, 3))
|
self.index(row, 0), self.index(row, 3))
|
||||||
|
|
||||||
def running_time_updated(self):
|
def running_time_updated(self, *args):
|
||||||
for job in self.jobs:
|
for job in self.jobs:
|
||||||
if not job.is_running:
|
if not job.is_running:
|
||||||
continue
|
continue
|
||||||
row = self.jobs.index(job)
|
row = self.jobs.index(job)
|
||||||
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'),
|
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'),
|
||||||
self.index(row, 3), self.index(row, 3))
|
self.index(row, 3), self.index(row, 3))
|
||||||
|
|
||||||
def has_device_jobs(self):
|
def has_device_jobs(self):
|
||||||
for job in self.jobs:
|
for job in self.jobs:
|
||||||
if job.is_running and isinstance(job, DeviceJob):
|
if job.is_running and isinstance(job, DeviceJob):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def has_jobs(self):
|
def has_jobs(self):
|
||||||
for job in self.jobs:
|
for job in self.jobs:
|
||||||
if job.is_running:
|
if job.is_running:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def run_job(self, done, func, args=[], kwargs={},
|
def run_job(self, done, func, args=[], kwargs={},
|
||||||
description=None):
|
description=None):
|
||||||
job = ParallelJob(func, done, self, args=args, kwargs=kwargs,
|
job = ParallelJob(func, done, self, args=args, kwargs=kwargs,
|
||||||
description=description)
|
description=description)
|
||||||
self.server.add_job(job)
|
self.server.add_job(job)
|
||||||
return job
|
return job
|
||||||
|
|
||||||
|
|
||||||
def output(self, job):
|
def output(self, job):
|
||||||
self.emit(SIGNAL('output_received()'))
|
self.emit(SIGNAL('output_received()'))
|
||||||
|
|
||||||
def kill_job(self, row, view):
|
def kill_job(self, row, view):
|
||||||
job = self.jobs[row]
|
job = self.jobs[row]
|
||||||
if isinstance(job, DeviceJob):
|
if isinstance(job, DeviceJob):
|
||||||
@ -183,20 +183,20 @@ class JobManager(QAbstractTableModel):
|
|||||||
|
|
||||||
|
|
||||||
self.server.kill(job)
|
self.server.kill(job)
|
||||||
|
|
||||||
def terminate_all_jobs(self):
|
def terminate_all_jobs(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class DetailView(QDialog, Ui_Dialog):
|
class DetailView(QDialog, Ui_Dialog):
|
||||||
|
|
||||||
def __init__(self, parent, job):
|
def __init__(self, parent, job):
|
||||||
QDialog.__init__(self, parent)
|
QDialog.__init__(self, parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.setWindowTitle(job.description)
|
self.setWindowTitle(job.description)
|
||||||
self.job = job
|
self.job = job
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.log.setPlainText(self.job.console_text())
|
self.log.setPlainText(self.job.console_text())
|
||||||
vbar = self.log.verticalScrollBar()
|
vbar = self.log.verticalScrollBar()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user