From a5c5880cb9c4b3d23c8095ca73ac16980f862d29 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 Jul 2009 10:52:05 -0600 Subject: [PATCH 1/7] Fix detection of UK firmware 505s on OS X and update USA Today recipe --- src/calibre/devices/prs505/driver.py | 8 ++-- src/calibre/devices/usbms/device.py | 18 +++++++-- .../web/feeds/recipes/recipe_usatoday.py | 37 +++++++++++++------ 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 6c7049d8e8..9a9ce9c5ed 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -33,9 +33,9 @@ class PRS505(CLI, Device): WINDOWS_CARD_A_MEM = ['PRS-505/UC:MS', 'PRS-505/CE:MS'] WINDOWS_CARD_B_MEM = ['PRS-505/UC:SD', 'PRS-505/CE:SD'] - OSX_MAIN_MEM = 'Sony PRS-505/UC Media' - OSX_CARD_A_MEM = 'Sony PRS-505/UC:MS Media' - OSX_CARD_B_MEM = 'Sony PRS-505/UC:SD' + OSX_MAIN_MEM = ['Sony PRS-505/UC Media', 'Sony PRS-505/CE Media'] + OSX_CARD_A_MEM = ['Sony PRS-505/UC:MS Media', 'Sony PRS-505/CE:MS Media'] + OSX_CARD_B_MEM = ['Sony PRS-505/UC:SD', 'Sony PRS-505/CE:SD'] MAIN_MEMORY_VOLUME_LABEL = 'Sony Reader Main Memory' STORAGE_CARD_VOLUME_LABEL = 'Sony Reader Storage Card' @@ -185,7 +185,7 @@ class PRS505(CLI, Device): def add_books_to_metadata(self, locations, metadata, booklists): if not locations or not metadata: return - + metadata = iter(metadata) for location in locations: info = metadata.next() diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index c4819307a4..abc6445c86 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -284,12 +284,24 @@ class Device(DeviceConfig, DevicePlugin): names[loc] = match.group(1) break + def check_line(line, pat): + if pat is None: + return False + if not line.strip().endswith(''): + return False + if isinstance(pat, basestring): + pat = [pat] + for x in pat: + if x in line: + return True + return False + for i, line in enumerate(lines): - if self.OSX_MAIN_MEM is not None and line.strip().endswith('') and self.OSX_MAIN_MEM in line: + if check_line(line, self.OSX_MAIN_MEM): get_dev_node(lines[i+1:], 'main') - if self.OSX_CARD_A_MEM is not None and line.strip().endswith('') and self.OSX_CARD_A_MEM in line: + if check_line(line, self.OSX_CARD_A_MEM): get_dev_node(lines[i+1:], 'carda') - if self.OSX_CARD_B_MEM is not None and line.strip().endswith('') and self.OSX_CARD_B_MEM in line: + if check_line(line, self.OSX_CARD_B_MEM): get_dev_node(lines[i+1:], 'cardb') if len(names.keys()) == 3: break diff --git a/src/calibre/web/feeds/recipes/recipe_usatoday.py b/src/calibre/web/feeds/recipes/recipe_usatoday.py index b69fce42f3..792f37244f 100644 --- a/src/calibre/web/feeds/recipes/recipe_usatoday.py +++ b/src/calibre/web/feeds/recipes/recipe_usatoday.py @@ -14,21 +14,34 @@ class USAToday(BasicNewsRecipe): title = 'USA Today' timefmt = ' [%d %b %Y]' max_articles_per_feed = 20 - no_stylesheets = True language = _('English') + __author__ = _('Kovid Goyal and Sujata Raman') + + no_stylesheets = True extra_css = ''' - .inside-head { font: x-large bold } - .inside-head2 { font: x-large bold } - .inside-head3 { font: x-large bold } - .byLine { font: large } - ''' + .inside-head{font-family:Arial,Helvetica,sans-serif; font-size:large; font-weight:bold } + .inside-head2{font-family:Arial,Helvetica,sans-serif; font-size:large; font-weight:bold } + .inside-head3{font-family:Arial,Helvetica,sans-serif; font-size:large; font-weight:bold } + h3{font-family:Arial,Helvetica,sans-serif; font-size:large; font-weight:bold } + h4{font-family:Arial,Helvetica,sans-serif; font-size:x-small; font-weight:bold } + .side-by-side{font-family:Arial,Helvetica,sans-serif; font-size:x-small;} + #byLineTag{font-family:Arial,Helvetica,sans-serif; font-size:xx-small;} + .inside-copy{font-family:Arial,Helvetica,sans-serif; font-size:x-small;text-align:left} + .caption{font-family:Arial,Helvetica,sans-serif; font-size:x-small;} + ''' + remove_tags = [ + dict(name='div', attrs={'class':'inside-copy'}), + {'class':['tagListLabel','piped-taglist-string',]} + ] + html2lrf_options = ['--ignore-tables'] preprocess_regexps = [ (re.compile(r'', re.IGNORECASE | re.DOTALL), lambda match : ''), (re.compile(r'.*?', re.IGNORECASE | re.DOTALL), lambda match : ''), ] - + + feeds = [ ('Top Headlines', 'http://rssfeeds.usatoday.com/usatoday-NewsTopStories'), ('Sport Headlines', 'http://rssfeeds.usatoday.com/UsatodaycomSports-TopStories'), @@ -39,13 +52,13 @@ class USAToday(BasicNewsRecipe): ('Weather Headlines', 'http://rssfeeds.usatoday.com/usatoday-WeatherTopStories'), ('Most Popular', 'http://rssfeeds.usatoday.com/Usatoday-MostViewedArticles'), ] - - ## Getting the print version - + + ## Getting the print version + def print_version(self, url): return 'http://www.printthis.clickability.com/pt/printThis?clickMap=printThis&fb=Y&url=' + url - + def postprocess_html(self, soup, first_fetch): for t in soup.findAll(['table', 'tr', 'td']): t.name = 'div' - return soup \ No newline at end of file + return soup From bbc08cc15f3195470e07ec1ed9676ba9e8af65b3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 Jul 2009 12:03:46 -0600 Subject: [PATCH 2/7] Show multiple authors correctly in metadata dialogs --- src/calibre/gui2/convert/metadata.py | 9 ++++++--- src/calibre/gui2/dialogs/metadata_single.py | 13 +++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/calibre/gui2/convert/metadata.py b/src/calibre/gui2/convert/metadata.py index 82e7b21148..cfb248da74 100644 --- a/src/calibre/gui2/convert/metadata.py +++ b/src/calibre/gui2/convert/metadata.py @@ -39,8 +39,6 @@ class MetadataWidget(Widget, Ui_Form): mi = self.db.get_metadata(self.book_id, index_is_id=True) self.title.setText(mi.title) - if mi.authors: - self.author.setCurrentIndex(self.author.findText(authors_to_string(mi.authors))) if mi.publisher: self.publisher.setCurrentIndex(self.publisher.findText(mi.publisher)) self.author_sort.setText(mi.author_sort if mi.author_sort else '') @@ -75,7 +73,12 @@ class MetadataWidget(Widget, Ui_Form): id, name = i name = authors_to_string([name.strip().replace('|', ',') for n in name.split(',')]) self.author.addItem(name) - self.author.setCurrentIndex(-1) + + au = self.db.authors(self.book_id, True) + if not au: + au = _('Unknown') + au = ' & '.join([a.strip().replace('|', ',') for a in au.split(',')]) + self.author.setEditText(au) def initialize_series(self): all_series = self.db.all_series() diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 0c2211e5c7..13acd161ae 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -330,19 +330,16 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): def initalize_authors(self): all_authors = self.db.all_authors() all_authors.sort(cmp=lambda x, y : cmp(x[1], y[1])) - author_id = self.db.author_id(self.row) - idx, c = None, 0 for i in all_authors: id, name = i - if id == author_id: - idx = c name = [name.strip().replace('|', ',') for n in name.split(',')] self.authors.addItem(authors_to_string(name)) - c += 1 - self.authors.setEditText('') - if idx is not None: - self.authors.setCurrentIndex(idx) + au = self.db.authors(self.row) + if not au: + au = _('Unknown') + au = ' & '.join([a.strip().replace('|', ',') for a in au.split(',')]) + self.authors.setEditText(au) def initialize_series(self): self.series.setSizeAdjustPolicy(self.series.AdjustToContentsOnFirstShow) From 55a4f4a208c735556c22372ee1db48733171b248 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 Jul 2009 12:25:04 -0600 Subject: [PATCH 3/7] Fix #2813 (PRS-505 not recognized) --- src/calibre/devices/prs505/driver.py | 14 +++++----- src/calibre/devices/usbms/device.py | 39 +++++++++++++++++----------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index 9a9ce9c5ed..f73bdbc44e 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -4,8 +4,7 @@ __copyright__ = '2008, Kovid Goyal ' \ ''' Device driver for the SONY PRS-505 ''' -import os -import time +import os, re, time from itertools import cycle from calibre import sanitize_file_name as sanitize @@ -30,12 +29,12 @@ class PRS505(CLI, Device): VENDOR_NAME = 'SONY' WINDOWS_MAIN_MEM = 'PRS-505' - WINDOWS_CARD_A_MEM = ['PRS-505/UC:MS', 'PRS-505/CE:MS'] - WINDOWS_CARD_B_MEM = ['PRS-505/UC:SD', 'PRS-505/CE:SD'] + WINDOWS_CARD_A_MEM = re.compile(r'PRS-505/\S+:MS') + WINDOWS_CARD_B_MEM = re.compile(r'PRS-505/\S+:SD') - OSX_MAIN_MEM = ['Sony PRS-505/UC Media', 'Sony PRS-505/CE Media'] - OSX_CARD_A_MEM = ['Sony PRS-505/UC:MS Media', 'Sony PRS-505/CE:MS Media'] - OSX_CARD_B_MEM = ['Sony PRS-505/UC:SD', 'Sony PRS-505/CE:SD'] + OSX_MAIN_MEM = re.compile(r'Sony PRS-505/\S+ Media') + OSX_CARD_A_MEM = re.compile(r'Sony PRS-505/\S+:MS Media') + OSX_CARD_B_MEM = re.compile(r'Sony PRS-505/\S+:SD') MAIN_MEMORY_VOLUME_LABEL = 'Sony Reader Main Memory' STORAGE_CARD_VOLUME_LABEL = 'Sony Reader Storage Card' @@ -79,6 +78,7 @@ class PRS505(CLI, Device): self.report_progress(1.0, _('Get device information...')) return (self.__class__.__name__, '', '', '') + def books(self, oncard=None, end_session=True): if oncard == 'carda' and not self._card_a_prefix: self.report_progress(1.0, _('Getting list of books on device...')) diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index abc6445c86..619753d685 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -31,6 +31,8 @@ class Device(DeviceConfig, DevicePlugin): WINDOWS_CARD_A_MEM = None WINDOWS_CARD_B_MEM = None + # The following are used by the check_ioreg_line method and can be either: + # None, a string, a list of strings or a compiled regular expression OSX_MAIN_MEM = None OSX_CARD_A_MEM = None OSX_CARD_B_MEM = None @@ -185,6 +187,10 @@ class Device(DeviceConfig, DevicePlugin): if device_id is None or \ 'VEN_' + str(self.VENDOR_NAME).upper() not in pnp_id: return False + + if hasattr(device_id, 'search'): + return device_id.search(pnp_id) is not None + if isinstance(device_id, basestring): device_id = [device_id] @@ -269,6 +275,21 @@ class Device(DeviceConfig, DevicePlugin): def osx_sort_names(self, names): return names + def check_ioreg_line(self, line, pat): + if pat is None: + return False + if not line.strip().endswith(''): + return False + if hasattr(pat, 'search'): + return pat.search(line) is not None + if isinstance(pat, basestring): + pat = [pat] + for x in pat: + if x in line: + return True + return False + + def get_osx_mountpoints(self, raw=None): raw = self.run_ioreg(raw) lines = raw.splitlines() @@ -284,24 +305,12 @@ class Device(DeviceConfig, DevicePlugin): names[loc] = match.group(1) break - def check_line(line, pat): - if pat is None: - return False - if not line.strip().endswith(''): - return False - if isinstance(pat, basestring): - pat = [pat] - for x in pat: - if x in line: - return True - return False - for i, line in enumerate(lines): - if check_line(line, self.OSX_MAIN_MEM): + if self.check_ioreg_line(line, self.OSX_MAIN_MEM): get_dev_node(lines[i+1:], 'main') - if check_line(line, self.OSX_CARD_A_MEM): + if self.check_ioreg_line(line, self.OSX_CARD_A_MEM): get_dev_node(lines[i+1:], 'carda') - if check_line(line, self.OSX_CARD_B_MEM): + if self.check_ioreg_line(line, self.OSX_CARD_B_MEM): get_dev_node(lines[i+1:], 'cardb') if len(names.keys()) == 3: break From 2ca1777869b399d07b7314db28a67748ee379d3d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 Jul 2009 12:34:55 -0600 Subject: [PATCH 4/7] Don't send a copy to the recycle bin when changing metadata on windows --- src/calibre/library/database2.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 41e4387e1e..334cb78992 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -40,11 +40,15 @@ def delete_file(path): except: os.remove(path) -def delete_tree(path): - try: - winshell.delete_file(path, silent=True, no_confirm=True) - except: +def delete_tree(path, permanent=False): + if permanent: shutil.rmtree(path) + else: + try: + if not permanent: + winshell.delete_file(path, silent=True, no_confirm=True) + except: + shutil.rmtree(path) copyfile = os.link if hasattr(os, 'link') else shutil.copyfile @@ -661,9 +665,9 @@ class LibraryDatabase2(LibraryDatabase): name = name[:-1] return name - def rmtree(self, path): + def rmtree(self, path, permanent=False): if not self.normpath(self.library_path).startswith(self.normpath(path)): - delete_tree(path) + delete_tree(path, permanent=permanent) def normpath(self, path): path = os.path.abspath(os.path.realpath(path)) @@ -715,10 +719,10 @@ class LibraryDatabase2(LibraryDatabase): # Delete not needed directories if current_path and os.path.exists(spath): if self.normpath(spath) != self.normpath(tpath): - self.rmtree(spath) + self.rmtree(spath, permanent=True) parent = os.path.dirname(spath) if len(os.listdir(parent)) == 0: - self.rmtree(parent) + self.rmtree(parent, permanent=True) def add_listener(self, listener): ''' From 8e754b32454cb468f2963559ca2327de12457099 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 Jul 2009 16:39:25 -0600 Subject: [PATCH 5/7] Oops --- src/calibre/devices/prs505/driver.py | 6 +++--- src/calibre/devices/usbms/device.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/calibre/devices/prs505/driver.py b/src/calibre/devices/prs505/driver.py index f73bdbc44e..3e46e46cde 100644 --- a/src/calibre/devices/prs505/driver.py +++ b/src/calibre/devices/prs505/driver.py @@ -32,9 +32,9 @@ class PRS505(CLI, Device): WINDOWS_CARD_A_MEM = re.compile(r'PRS-505/\S+:MS') WINDOWS_CARD_B_MEM = re.compile(r'PRS-505/\S+:SD') - OSX_MAIN_MEM = re.compile(r'Sony PRS-505/\S+ Media') - OSX_CARD_A_MEM = re.compile(r'Sony PRS-505/\S+:MS Media') - OSX_CARD_B_MEM = re.compile(r'Sony PRS-505/\S+:SD') + OSX_MAIN_MEM = re.compile(r'Sony PRS-505/[^:]+ Media') + OSX_CARD_A_MEM = re.compile(r'Sony PRS-505/[^:]+:MS Media') + OSX_CARD_B_MEM = re.compile(r'Sony PRS-505/[^:]+:SD Media') MAIN_MEMORY_VOLUME_LABEL = 'Sony Reader Main Memory' STORAGE_CARD_VOLUME_LABEL = 'Sony Reader Storage Card' diff --git a/src/calibre/devices/usbms/device.py b/src/calibre/devices/usbms/device.py index 619753d685..d34e8aa676 100644 --- a/src/calibre/devices/usbms/device.py +++ b/src/calibre/devices/usbms/device.py @@ -306,11 +306,11 @@ class Device(DeviceConfig, DevicePlugin): break for i, line in enumerate(lines): - if self.check_ioreg_line(line, self.OSX_MAIN_MEM): + if 'main' not in names and self.check_ioreg_line(line, self.OSX_MAIN_MEM): get_dev_node(lines[i+1:], 'main') - if self.check_ioreg_line(line, self.OSX_CARD_A_MEM): + if 'carda' not in names and self.check_ioreg_line(line, self.OSX_CARD_A_MEM): get_dev_node(lines[i+1:], 'carda') - if self.check_ioreg_line(line, self.OSX_CARD_B_MEM): + if 'cardb' not in names and self.check_ioreg_line(line, self.OSX_CARD_B_MEM): get_dev_node(lines[i+1:], 'cardb') if len(names.keys()) == 3: break From 272437e901b0840f94f90699244a4d3e067448f4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 Jul 2009 17:11:21 -0600 Subject: [PATCH 6/7] EPUB Input:Fix handling of user specified cover. Also set --page-breaks-before to / by default for EPUB input, since EPUB files typically already have the needed page breaks --- src/calibre/ebooks/epub/input.py | 4 +++- src/calibre/ebooks/oeb/transforms/metadata.py | 14 ++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/calibre/ebooks/epub/input.py b/src/calibre/ebooks/epub/input.py index 3405e1ef4e..dc2aa230d5 100644 --- a/src/calibre/ebooks/epub/input.py +++ b/src/calibre/ebooks/epub/input.py @@ -8,7 +8,7 @@ from itertools import cycle from lxml import etree -from calibre.customize.conversion import InputFormatPlugin +from calibre.customize.conversion import InputFormatPlugin, OptionRecommendation class EPUBInput(InputFormatPlugin): @@ -17,6 +17,8 @@ class EPUBInput(InputFormatPlugin): description = 'Convert EPUB files (.epub) to HTML' file_types = set(['epub']) + recommendations = set([('page_breaks_before', '/', OptionRecommendation.MED)]) + @classmethod def decrypt_font(cls, key, path): raw = open(path, 'rb').read() diff --git a/src/calibre/ebooks/oeb/transforms/metadata.py b/src/calibre/ebooks/oeb/transforms/metadata.py index e91c4c3140..0969509626 100644 --- a/src/calibre/ebooks/oeb/transforms/metadata.py +++ b/src/calibre/ebooks/oeb/transforms/metadata.py @@ -87,6 +87,7 @@ class MergeMetadata(object): if cover_id is not None: m.add('cover', cover_id) + def set_cover(self, mi, prefer_metadata_cover): cdata = '' if mi.cover and os.access(mi.cover, os.R_OK): @@ -94,12 +95,13 @@ class MergeMetadata(object): elif mi.cover_data and mi.cover_data[-1]: cdata = mi.cover_data[1] id = None - if 'cover' in self.oeb.guide: - href = self.oeb.guide['cover'].href - id = self.oeb.manifest.hrefs[href].id - if not prefer_metadata_cover and cdata: - self.oeb.manifest.hrefs[href]._data = cdata - elif cdata: + old_cover = self.oeb.guide.remove('cover') + self.oeb.guide.remove('titlepage') + if old_cover is not None: + if old_cover.href in self.oeb.manifest.hrefs: + item = self.oeb.manifest.hrefs[old_cover.href] + self.oeb.manifest.remove(item) + if cdata: id, href = self.oeb.manifest.generate('cover', 'cover.jpg') self.oeb.manifest.add(id, href, 'image/jpeg', data=cdata) self.oeb.guide.add('cover', 'Cover', href) From 7afc38ba2cde8c7e8026c637a6c64b6df0d5fb39 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 13 Jul 2009 17:37:03 -0600 Subject: [PATCH 7/7] Simplify setting of covers in database and remove unneccessary Qt dependancy --- src/calibre/gui2/convert/metadata.py | 4 ++-- src/calibre/gui2/dialogs/metadata_single.py | 4 ++-- src/calibre/library/database2.py | 26 ++++++++++++--------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/calibre/gui2/convert/metadata.py b/src/calibre/gui2/convert/metadata.py index cfb248da74..5e633ba82d 100644 --- a/src/calibre/gui2/convert/metadata.py +++ b/src/calibre/gui2/convert/metadata.py @@ -10,7 +10,7 @@ import os, uuid from PyQt4.Qt import QPixmap, SIGNAL -from calibre.gui2 import choose_images, error_dialog, pixmap_to_data +from calibre.gui2 import choose_images, error_dialog from calibre.gui2.convert.metadata_ui import Ui_Form from calibre.ebooks.metadata import authors_to_string, string_to_authors, \ MetaInformation @@ -185,7 +185,7 @@ class MetadataWidget(Widget, Ui_Form): opf.render(self.opf_file) self.opf_file.close() if self.cover_changed: - self.db.set_cover(self.book_id, pixmap_to_data(self.cover.pixmap())) + self.db.set_cover(self.book_id, self.cover.pixmap()) cover = self.db.cover(self.book_id, index_is_id=True) if cover: cf = PersistentTemporaryFile('.jpeg') diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 13acd161ae..723e1d01b9 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -16,7 +16,7 @@ from PyQt4.QtCore import SIGNAL, QObject, QCoreApplication, Qt, QTimer, QThread, from PyQt4.QtGui import QPixmap, QListWidgetItem, QErrorMessage, QDialog from calibre.gui2 import qstring_to_unicode, error_dialog, file_icon_provider, \ - choose_files, pixmap_to_data, choose_images, ResizableDialog + choose_files, choose_images, ResizableDialog from calibre.gui2.dialogs.metadata_single_ui import Ui_MetadataSingleDialog from calibre.gui2.dialogs.fetch_metadata import FetchMetadata from calibre.gui2.dialogs.tag_editor import TagEditor @@ -512,7 +512,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.db.set_pubdate(self.id, datetime(d.year(), d.month(), d.day())) if self.cover_changed: - self.db.set_cover(self.id, pixmap_to_data(self.cover.pixmap())) + self.db.set_cover(self.id, self.cover.pixmap()) QDialog.accept(self) if callable(self.accepted_callback): self.accepted_callback(self.id) diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 334cb78992..3af4002eae 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -11,9 +11,15 @@ import os, re, sys, shutil, cStringIO, glob, collections, textwrap, \ from itertools import repeat from datetime import datetime -from PyQt4.QtCore import QCoreApplication, QThread, QReadWriteLock -from PyQt4.QtGui import QApplication, QImage -__app = None +from PyQt4.QtCore import QThread, QReadWriteLock +try: + from PIL import Image as PILImage + PILImage +except ImportError: + import Image as PILImage + + +from PyQt4.QtGui import QImage from calibre.ebooks.metadata import title_sort from calibre.library.database import LibraryDatabase @@ -819,14 +825,11 @@ class LibraryDatabase2(LibraryDatabase): if callable(getattr(data, 'save', None)): data.save(path) else: - if not QCoreApplication.instance(): - global __app - __app = QApplication([]) - p = QImage() - if callable(getattr(data, 'read', None)): - data = data.read() - p.loadFromData(data) - p.save(path) + f = data + if not callable(getattr(data, 'read', None)): + f = cStringIO.StringIO(data) + im = PILImage.open(f) + im.convert('RGB').save(path, 'JPEG') def all_formats(self): formats = self.conn.get('SELECT format from data') @@ -1528,6 +1531,7 @@ class LibraryDatabase2(LibraryDatabase): return data def migrate_old(self, db, progress): + from PyQt4.QtCore import QCoreApplication header = _(u'

Migrating old database to ebook library in %s

')%self.library_path progress.setValue(0) progress.setLabelText(header)