diff --git a/src/calibre/devices/bebook/driver.py b/src/calibre/devices/bebook/driver.py index d3e887eb74..b6655d37ec 100644 --- a/src/calibre/devices/bebook/driver.py +++ b/src/calibre/devices/bebook/driver.py @@ -14,7 +14,7 @@ class BEBOOK(USBMS): # Ordered list of supported formats - FORMATS = ['mobi', 'epub', 'pdf', 'mobi', 'txt'] + FORMATS = ['mobi', 'epub', 'pdf', 'txt'] VENDOR_ID = [0x0525] PRODUCT_ID = [0x8803, 0x6803] diff --git a/src/calibre/devices/usbobserver/usbobserver.c b/src/calibre/devices/usbobserver/usbobserver.c index 20b4944d41..051901f849 100644 --- a/src/calibre/devices/usbobserver/usbobserver.c +++ b/src/calibre/devices/usbobserver/usbobserver.c @@ -71,12 +71,16 @@ usbobserver_get_usb_devices(PyObject *self, PyObject *args) { plugInInterface = NULL; dev = NULL; //Create an intermediate plugin kr = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); - if ((kIOReturnSuccess != kr) || !plugInInterface) - printf("Unable to create a plug-in (%08x)\n", kr); + if ((kIOReturnSuccess != kr) || !plugInInterface) { + printf("Unable to create a plug-in (%08x)\n", kr); continue; + } //Now create the device interface HRESULT result = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID)&dev); - if (result || !dev) printf("Couldn't create a device interface (%08x)\n", (int) result); + if (result || !dev) { + printf("Couldn't create a device interface (%08x)\n", (int) result); + continue; + } kr = (*dev)->GetDeviceVendor(dev, &vendor); kr = (*dev)->GetDeviceProduct(dev, &product); diff --git a/src/calibre/ebooks/mobi/reader.py b/src/calibre/ebooks/mobi/reader.py index b787ce7e7c..d6390f2643 100644 --- a/src/calibre/ebooks/mobi/reader.py +++ b/src/calibre/ebooks/mobi/reader.py @@ -683,12 +683,13 @@ class MobiReader(object): image_index += 1 try: im = PILImage.open(buf) + im = im.convert('RGB') except IOError: continue path = os.path.join(output_dir, '%05d.jpg'%image_index) self.image_names.append(os.path.basename(path)) - im.convert('RGB').save(open(path, 'wb'), format='JPEG') + im.save(open(path, 'wb'), format='JPEG') def get_metadata(stream): from calibre.utils.logging import Log diff --git a/src/calibre/gui2/dialogs/fetch_metadata.py b/src/calibre/gui2/dialogs/fetch_metadata.py index 805cc1c3bf..62f26c757f 100644 --- a/src/calibre/gui2/dialogs/fetch_metadata.py +++ b/src/calibre/gui2/dialogs/fetch_metadata.py @@ -187,6 +187,8 @@ class FetchMetadata(QDialog, Ui_FetchMetadata): def terminate(self): if hasattr(self, 'fetcher') and self.fetcher.isRunning(): self.fetcher.terminate() + if hasattr(self, '_hangcheck') and self._hangcheck.isActive(): + self._hangcheck.stop() def __enter__(self, *args): diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index e3f3ddd37c..0c84f52f20 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -422,22 +422,22 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): publisher = qstring_to_unicode(self.publisher.currentText()) if isbn or title or author or publisher: d = FetchMetadata(self, isbn, title, author, publisher, self.timeout) + self._fetch_metadata_scope = d with d: - d.exec_() - if d.result() == QDialog.Accepted: - book = d.selected_book() - if book: - self.title.setText(book.title) - self.authors.setText(authors_to_string(book.authors)) - if book.author_sort: self.author_sort.setText(book.author_sort) - if book.publisher: self.publisher.setEditText(book.publisher) - if book.isbn: self.isbn.setText(book.isbn) - summ = book.comments - if summ: - prefix = qstring_to_unicode(self.comments.toPlainText()) - if prefix: - prefix += '\n' - self.comments.setText(prefix + summ) + if d.exec_() == QDialog.Accepted: + book = d.selected_book() + if book: + self.title.setText(book.title) + self.authors.setText(authors_to_string(book.authors)) + if book.author_sort: self.author_sort.setText(book.author_sort) + if book.publisher: self.publisher.setEditText(book.publisher) + if book.isbn: self.isbn.setText(book.isbn) + summ = book.comments + if summ: + prefix = qstring_to_unicode(self.comments.toPlainText()) + if prefix: + prefix += '\n' + self.comments.setText(prefix + summ) else: error_dialog(self, _('Cannot fetch metadata'), _('You must specify at least one of ISBN, Title, ' diff --git a/src/calibre/gui2/images/news/times_online.png b/src/calibre/gui2/images/news/times_online.png new file mode 100644 index 0000000000..c9cd67d546 Binary files /dev/null and b/src/calibre/gui2/images/news/times_online.png differ diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 413d171960..9135182258 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -193,6 +193,8 @@ class ResultCache(SearchQueryParser): if query and query.strip(): location = location.lower().strip() query = query.lower() + if not isinstance(query, unicode): + query = query.decode('utf-8') if location in ('tag', 'author', 'format'): location += 's' all = ('title', 'authors', 'publisher', 'tags', 'comments', 'series', 'formats') diff --git a/src/calibre/utils/genshi/LICENSE b/src/calibre/utils/genshi/LICENSE new file mode 100644 index 0000000000..28b70b6fe2 --- /dev/null +++ b/src/calibre/utils/genshi/LICENSE @@ -0,0 +1,28 @@ +Copyright © 2006-2007 Edgewall Software[[BR]] +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + 3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR “AS IS” AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/src/calibre/web/feeds/recipes/__init__.py b/src/calibre/web/feeds/recipes/__init__.py index bda81ddc89..c036b45966 100644 --- a/src/calibre/web/feeds/recipes/__init__.py +++ b/src/calibre/web/feeds/recipes/__init__.py @@ -43,6 +43,7 @@ recipe_modules = ['recipe_' + r for r in ( 'seattle_times', 'scott_hanselman', 'coding_horror', 'twitchfilms', 'stackoverflow', 'telepolis_artikel', 'zaobao', 'usnews', 'straitstimes', 'index_hu', 'pcworld_hu', 'hrt', 'rts', + 'h1', 'h2', 'h3', )] import re, imp, inspect, time, os diff --git a/src/calibre/web/feeds/recipes/recipe_h1.py b/src/calibre/web/feeds/recipes/recipe_h1.py new file mode 100644 index 0000000000..2678e5b2eb --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_h1.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import with_statement + +__license__ = 'GPL v3' +__copyright__ = '2009, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from calibre.web.feeds.news import BasicNewsRecipe + +class H168(BasicNewsRecipe): + title = u'168\xf3ra' + oldest_article = 4 + max_articles_per_feed = 50 + language = _('Hungarian') + __author__ = 'Ezmegaz' + + feeds = [(u'Itthon', + u'http://www.168ora.hu/static/rss/cikkek_itthon.xml'), (u'Gl\xf3busz', + u'http://www.168ora.hu/static/rss/cikkek_globusz.xml'), (u'Punch', + u'http://www.168ora.hu/static/rss/cikkek_punch.xml'), (u'Arte', + u'http://www.168ora.hu/static/rss/cikkek_arte.xml'), (u'Buxa', + u'http://www.168ora.hu/static/rss/cikkek_buxa.xml'), (u'Sebess\xe9g', + u'http://www.168ora.hu/static/rss/cikkek_sebesseg.xml'), (u'Tud\xe1s', + u'http://www.168ora.hu/static/rss/cikkek_tudas.xml'), (u'Sport', + u'http://www.168ora.hu/static/rss/cikkek_sport.xml'), (u'V\xe9lem\xe9ny', + u'http://www.168ora.hu/static/rss/cikkek_velemeny.xml'), (u'Dolce Vita', + u'http://www.168ora.hu/static/rss/cikkek_dolcevita.xml'), (u'R\xe1di\xf3', + u'http://www.168ora.hu/static/rss/radio.xml')] + + + diff --git a/src/calibre/web/feeds/recipes/recipe_h2.py b/src/calibre/web/feeds/recipes/recipe_h2.py new file mode 100644 index 0000000000..20c251ded9 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_h2.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import with_statement + +__license__ = 'GPL v3' +__copyright__ = '2009, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from calibre.web.feeds.news import BasicNewsRecipe + +class ATV(BasicNewsRecipe): + title = u'ATV' + oldest_article = 5 + max_articles_per_feed = 50 + language = _('Hungarian') + __author__ = 'Ezmegaz' + + + feeds = [(u'H\xedrek', u'http://atv.hu/rss/1'), (u'Cikkek', + u'http://atv.hu/rss/2')] + diff --git a/src/calibre/web/feeds/recipes/recipe_h3.py b/src/calibre/web/feeds/recipes/recipe_h3.py new file mode 100644 index 0000000000..a4da0c71cd --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_h3.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import with_statement + +__license__ = 'GPL v3' +__copyright__ = '2009, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +from calibre.web.feeds.news import BasicNewsRecipe + +class H3(BasicNewsRecipe): + title = u'H\xedrszerz\u0151' + oldest_article = 5 + max_articles_per_feed = 50 + language = _('Hungarian') + __author__ = 'Ezmegaz' + + + feeds = [(u'Belf\xf6ld', + u'http://www.hirszerzo.hu/rss.belfold.xml'), (u'K\xfclf\xf6ld', + u'http://www.hirszerzo.hu/rss.kulfold.xml'), (u'Profit', + u'http://www.hirszerzo.hu/rss.profit.xml'), (u'Shake', + u'http://www.hirszerzo.hu/rss.shake.xml'), (u'Publicisztika', + u'http://www.hirszerzo.hu/rss.publicisztika.xml'), (u'Elemz\xe9s', + u'http://www.hirszerzo.hu/rss.elemzes.xml'), (u'Sorok k\xf6z\xf6tt', + u'http://www.hirszerzo.hu/rss.sorok_kozott.xml'), (u'Gal\xe9ria', + u'http://www.hirszerzo.hu/rss.galeria.xml'), (u'Patro', + u'http://www.hirszerzo.hu/rss.patro.xml')] + diff --git a/src/calibre/web/feeds/recipes/recipe_newsweek.py b/src/calibre/web/feeds/recipes/recipe_newsweek.py index 7d1fc403d4..54e54a9a83 100644 --- a/src/calibre/web/feeds/recipes/recipe_newsweek.py +++ b/src/calibre/web/feeds/recipes/recipe_newsweek.py @@ -12,6 +12,7 @@ class Newsweek(BasicNewsRecipe): __author__ = 'Kovid Goyal' description = 'Weekly news and current affairs in the US' no_stylesheets = True + encoding = 'utf-8' language = _('English') remove_tags = [ {'class':['navbar', 'ad', 'sponsorLinksArticle', 'mm-content', @@ -106,3 +107,12 @@ class Newsweek(BasicNewsRecipe): href = a['href'].split('#')[0] return self.index_to_soup(href) + def get_cover_url(self): + cover_url = None + soup = self.index_to_soup(self.INDEX) + link_item = soup.find('div',attrs={'class':'cover-image'}) + if link_item and link_item.a and link_item.a.img: + cover_url = link_item.a.img['src'] + return cover_url + + diff --git a/src/calibre/web/feeds/recipes/recipe_times_online.py b/src/calibre/web/feeds/recipes/recipe_times_online.py index 45e9a1e10e..f652ddc62c 100644 --- a/src/calibre/web/feeds/recipes/recipe_times_online.py +++ b/src/calibre/web/feeds/recipes/recipe_times_online.py @@ -1,42 +1,65 @@ -#!/usr/bin/env python - -__license__ = 'GPL v3' -__copyright__ = '2008, Darko Miletic ' -''' -timesonline.co.uk -''' - -from calibre.web.feeds.news import BasicNewsRecipe - -class TimesOnline(BasicNewsRecipe): - title = u'The Times Online' - __author__ = 'Darko Miletic' - description = 'UK news' - oldest_article = 7 - max_articles_per_feed = 100 - no_stylesheets = True - use_embedded_content = False - language = _('English') - simultaneous_downloads = 1 - - remove_tags_after = dict(name='div', attrs={'class':'bg-666'}) - remove_tags = [ - dict(name='div' , attrs={'class':'hide-from-print padding-bottom-7' }) - ] - - feeds = [ - (u'Top stories from Times Online', u'http://www.timesonline.co.uk/tol/feeds/rss/topstories.xml' ), - ('Latest Business News', 'http://www.timesonline.co.uk/tol/feeds/rss/business.xml'), - ('Economics', 'http://www.timesonline.co.uk/tol/feeds/rss/economics.xml'), - ('World News', 'http://www.timesonline.co.uk/tol/feeds/rss/worldnews.xml'), - ('UK News', 'http://www.timesonline.co.uk/tol/feeds/rss/uknews.xml'), - ('Travel News', 'http://www.timesonline.co.uk/tol/feeds/rss/travel.xml'), - ('Sports News', 'http://www.timesonline.co.uk/tol/feeds/rss/sport.xml'), - ('Film News', 'http://www.timesonline.co.uk/tol/feeds/rss/film.xml'), - ('Tech news', 'http://www.timesonline.co.uk/tol/feeds/rss/tech.xml'), - ('Literary Supplement', 'http://www.timesonline.co.uk/tol/feeds/rss/thetls.xml'), - ] - - def print_version(self, url): - main = url.partition('#')[0] - return main + '?print=yes' \ No newline at end of file +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2008-2009, Darko Miletic ' +''' +timesonline.co.uk +''' + +from calibre.web.feeds.news import BasicNewsRecipe +from calibre.ebooks.BeautifulSoup import BeautifulSoup, Tag + +class Timesonline(BasicNewsRecipe): + title = 'The Times Online' + __author__ = 'Darko Miletic' + description = 'UK news' + publisher = 'timesonline.co.uk' + category = 'news, politics, UK' + oldest_article = 2 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + simultaneous_downloads = 1 + encoding = 'cp1252' + lang = 'en-UK' + language = _('English') + + html2lrf_options = [ + '--comment', description + , '--category', category + , '--publisher', publisher + ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + + remove_tags = [dict(name=['embed','object'])] + remove_tags_after = dict(name='div', attrs={'class':'bg-666'}) + + feeds = [ + (u'Top stories from Times Online', u'http://www.timesonline.co.uk/tol/feeds/rss/topstories.xml' ), + ('Latest Business News', 'http://www.timesonline.co.uk/tol/feeds/rss/business.xml'), + ('Economics', 'http://www.timesonline.co.uk/tol/feeds/rss/economics.xml'), + ('World News', 'http://www.timesonline.co.uk/tol/feeds/rss/worldnews.xml'), + ('UK News', 'http://www.timesonline.co.uk/tol/feeds/rss/uknews.xml'), + ('Travel News', 'http://www.timesonline.co.uk/tol/feeds/rss/travel.xml'), + ('Sports News', 'http://www.timesonline.co.uk/tol/feeds/rss/sport.xml'), + ('Film News', 'http://www.timesonline.co.uk/tol/feeds/rss/film.xml'), + ('Tech news', 'http://www.timesonline.co.uk/tol/feeds/rss/tech.xml'), + ('Literary Supplement', 'http://www.timesonline.co.uk/tol/feeds/rss/thetls.xml'), + ] + + def print_version(self, url): + return url + '?print=yes' + + def get_article_url(self, article): + return article.get('guid', None) + + def preprocess_html(self, soup): + soup.html['xml:lang'] = self.lang + soup.html['lang'] = self.lang + mlang = Tag(soup,'meta',[("http-equiv","Content-Language"),("content",self.lang)]) + mcharset = Tag(soup,'meta',[("http-equiv","Content-Type"),("content","text/html; charset=UTF-8")]) + soup.head.insert(0,mlang) + soup.head.insert(1,mcharset) + return self.adeify_images(soup) + \ No newline at end of file