From 064275ef26e3e57ed27ae90d258b9172838b462f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2009 09:10:44 -0800 Subject: [PATCH 01/14] IGN:Add the Times Literary Supplement to the Times Online recipe --- src/calibre/trac/donations/server.py | 3 +-- src/calibre/web/feeds/recipes/recipe_times_online.py | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/calibre/trac/donations/server.py b/src/calibre/trac/donations/server.py index cbb68d972e..c3e0337290 100644 --- a/src/calibre/trac/donations/server.py +++ b/src/calibre/trac/donations/server.py @@ -217,8 +217,7 @@ class Server(object): pos = pos.replace(month = 1) else: pos = pos.replace(month = pos.month + 1) - - _months = list(months(self.earliest, self.latest))[:-1][:12] + _months = list(months(self.earliest, self.latest))[:-1][-12:] _months = [range_for_month(*m) for m in _months] _months = [self.get_slice(*m) for m in _months] x = [m.min for m in _months] diff --git a/src/calibre/web/feeds/recipes/recipe_times_online.py b/src/calibre/web/feeds/recipes/recipe_times_online.py index e52df9201a..e57b331820 100644 --- a/src/calibre/web/feeds/recipes/recipe_times_online.py +++ b/src/calibre/web/feeds/recipes/recipe_times_online.py @@ -33,6 +33,7 @@ class TimesOnline(BasicNewsRecipe): ('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): From 5e057aa907dbea92d51c2789562a5b9b49645c4e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2009 09:50:32 -0800 Subject: [PATCH 02/14] Added recipe for Heise Telepolis (thanks to Darko Miletic) --- src/calibre/gui2/images/news/telepolis.png | Bin 0 -> 586 bytes src/calibre/web/feeds/recipes/__init__.py | 2 +- .../web/feeds/recipes/recipe_telepolis.py | 34 ++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/calibre/gui2/images/news/telepolis.png create mode 100644 src/calibre/web/feeds/recipes/recipe_telepolis.py diff --git a/src/calibre/gui2/images/news/telepolis.png b/src/calibre/gui2/images/news/telepolis.png new file mode 100644 index 0000000000000000000000000000000000000000..7b1c14b96cb21701f5e1eff679404ab85edc0cc5 GIT binary patch literal 586 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%b@U_I1CZGssfk$L9 zkoEv$x0Bg+Ai=T%$8;bK*3S@gZ0%tN2F7Af7sn8b)4h`ymfdy`aLq4by0;;AT5DSq z@8*PrL>}JIv{~m166=;5%oo@!;pKBWErMHR_1TU6ciXo_y|vw3?pFR@e*S*O35A9a zpI1LT{rK<~r3VEJ2UK;K*w=`7aN5^6u&6m|PWZ%B>Ch(M&$GKP#m&v);DzrQ+m&nY z3*6;TG1#>@=)qUf==F*Z<}pNzUb-#)@lzAWtIx*!?hEH~m#RFzU~=WH*lN*l)io;^ z?ld>MUI0mjhfl(SXmaFomRNFZJ+wDe=IY~WmRU^FgT@1dUP9ju2|E- zk@WA~Jnc^X)siJPegT{vuN#8T^vH;Qv)}kVe)8-ojAwKAh;p9&ZnsT0$IK?}uQ9v% zqsJ$Hd~qqUo?>L=Yy5G4LvYZkCzJmD+M)U}rfmYt4bg^mf=TZ-&1X(&DtHwzUCuwf zNrEj&Mqf#s{UPJot`}AjrgN5^_F7nGt+cfJ=w03YpF@tN?ENP3c>~9R4_4=-_9gve zFkU{DdF{=O*}%9^Epd$~NiIrFEJ@W(0TK*G1_qY828Ox@mLUd~Rwl+)Ag+a#fkDk# gy$di6x%nxXX_W*tDAz Date: Fri, 9 Jan 2009 10:37:41 -0800 Subject: [PATCH 03/14] Fix EPUB version of Christian Science Monitor. Fixes #1578 (News - dl News not saving .epub properly) --- src/calibre/web/feeds/recipes/recipe_chr_mon.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/calibre/web/feeds/recipes/recipe_chr_mon.py b/src/calibre/web/feeds/recipes/recipe_chr_mon.py index dceeb5aab8..b9f94fcd1c 100644 --- a/src/calibre/web/feeds/recipes/recipe_chr_mon.py +++ b/src/calibre/web/feeds/recipes/recipe_chr_mon.py @@ -42,3 +42,9 @@ class ChristianScienceMonitor(BasicNewsRecipe): feeds[-1][1].append(art) return feeds + def postprocess_html(self, soup, first_fetch): + html = soup.find('html') + if html is None: + return soup + html.extract() + return html From 4ee280755189b1ab024deafd54ee94a74ab96633 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2009 11:51:40 -0800 Subject: [PATCH 04/14] Fix #1579 (Problem retrieveing image file as cover) --- src/calibre/web/feeds/news.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 15b42d442d..85ed39a16d 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -765,6 +765,8 @@ class BasicNewsRecipe(object, LoggingInterface): self.log_debug(traceback.format_exc()) if cu is not None: ext = cu.rpartition('.')[-1] + if '?' in ext: + ext = '' ext = ext.lower() if ext else 'jpg' self.report_progress(1, _('Downloading cover from %s')%cu) cpath = os.path.join(self.output_dir, 'cover.'+ext) From db322903261e0e3d28a8a30d48d7e125c92a65a7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2009 12:36:03 -0800 Subject: [PATCH 05/14] Error checking and getting meta-data right --- src/calibre/ebooks/pdf/pdftrim.py | 20 +++++++++++++++----- src/pyPdf/pdf.py | 6 ++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/calibre/ebooks/pdf/pdftrim.py b/src/calibre/ebooks/pdf/pdftrim.py index b194d93b9d..2054f22558 100644 --- a/src/calibre/ebooks/pdf/pdftrim.py +++ b/src/calibre/ebooks/pdf/pdftrim.py @@ -29,7 +29,7 @@ def config(defaults=None): c.add_opt('top_right_y', [ '-w', '--righty'], default=default_crop, help=_('Number of pixels to crop from the right most y (default is %d)')%default_crop ) c.add_opt('bounding', ['-b', '--bounding'], - help=_('A file generated by ghostscript which allows each page to be individually cropped')) + help=_('A file generated by ghostscript which allows each page to be individually cropped [gs -dSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox > bounding] ')) return c @@ -38,14 +38,24 @@ def option_parser(): return c.option_parser(usage=_('''\ %prog [options] file.pdf - Crop a pdf. + Crops a pdf. ''')) def main(args=sys.argv): parser = option_parser() opts, args = parser.parse_args(args) - source = os.path.abspath(args[1]) - input_pdf = PdfFileReader(file(source, "rb")) + try: + source = os.path.abspath(args[1]) + input_pdf = PdfFileReader(file(source, "rb")) + except: + print "Unable to read input" + return 2 + info = input_pdf.getDocumentInfo() + title = 'Unknown' + author = 'Unknown' + if info.title: + title = info.title + author = info.author if opts.bounding != None: try: bounding = open( opts.bounding , 'r' ) @@ -53,7 +63,7 @@ def main(args=sys.argv): except: print 'Error opening %s' % opts.bounding return 1 - output_pdf = PdfFileWriter() + output_pdf = PdfFileWriter(title=title,author=author) for page_number in range (0, input_pdf.getNumPages() ): page = input_pdf.getPage(page_number) if opts.bounding != None: diff --git a/src/pyPdf/pdf.py b/src/pyPdf/pdf.py index 3cf7a60f0e..362879a39a 100644 --- a/src/pyPdf/pdf.py +++ b/src/pyPdf/pdf.py @@ -55,7 +55,7 @@ from utils import readNonWhitespace, readUntilWhitespace, ConvertFunctionsToVirt # This class supports writing PDF files out, given pages produced by another # class (typically {@link #PdfFileReader PdfFileReader}). class PdfFileWriter(object): - def __init__(self): + def __init__(self,title=u"Unknown",author=u"Unknown"): self._header = "%PDF-1.3" self._objects = [] # array of indirect objects @@ -71,7 +71,9 @@ class PdfFileWriter(object): # info object info = DictionaryObject() info.update({ - NameObject("/Producer"): createStringObject(u"Python PDF Library - http://pybrary.net/pyPdf/") + NameObject("/Producer"): createStringObject(u"Python PDF Library - http://pybrary.net/pyPdf/"), + NameObject("/Author"): createStringObject(author), + NameObject("/Title"): createStringObject(title), }) self._info = self._addObject(info) From f02c3619185f1b38e215c4f49dfa188eace05a5a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2009 17:13:09 -0800 Subject: [PATCH 06/14] Fix regression in news download scheduling system. If you set news to be downloaded using calibre versions before 0.4.125, all the scheduling/account information for the downloads may be lost. You have to reset the recipes for download. Sorry for the inconvenience. Fixes #1580 (News Download Duplicates & Unscheduled downloads) --- src/calibre/gui2/dialogs/scheduler.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/dialogs/scheduler.py b/src/calibre/gui2/dialogs/scheduler.py index f61c220bb9..a4bfe9f665 100644 --- a/src/calibre/gui2/dialogs/scheduler.py +++ b/src/calibre/gui2/dialogs/scheduler.py @@ -75,7 +75,13 @@ def save_recipes(recipes): def load_recipes(): config.refresh() - return [Recipe().unpickle(r) for r in config.get('scheduled_recipes', [])] + recipes = [] + for r in config.get('scheduled_recipes', []): + r = Recipe().unpickle(r) + if r.builtin and not str(r.id).startswith('recipe_'): + continue + recipes.append(r) + return recipes class RecipeModel(QAbstractListModel, SearchQueryParser): @@ -438,7 +444,7 @@ class Scheduler(QObject): self.lock.unlock() def main(args=sys.argv): - app = QApplication([]) + QApplication([]) from calibre.library.database2 import LibraryDatabase2 d = SchedulerDialog(LibraryDatabase2('/home/kovid/documents/library')) d.exec_() From d269e83191eaddc27a4970d9718ace9e93f8ff79 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2009 17:14:13 -0800 Subject: [PATCH 07/14] Fix #1585 (Fedora Download page has wrong package name) --- src/calibre/trac/plugins/download.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/trac/plugins/download.py b/src/calibre/trac/plugins/download.py index 3b0965eefc..0fee4fdb0d 100644 --- a/src/calibre/trac/plugins/download.py +++ b/src/calibre/trac/plugins/download.py @@ -35,7 +35,7 @@ class Distribution(object): ('xdg-utils', '1.0.2', 'xdg-utils', 'xdg-utils', 'xdg-utils'), ('dbus-python', '0.82.2', 'dbus-python', 'python-dbus', 'dbus-python'), ('lxml', '2.0.5', 'lxml', 'python-lxml', 'python-lxml'), - ('BeautifulSoup', '3.0.5', 'beautifulsoup', 'python-beautifulsoup', 'python-beautifulsoup'), + ('BeautifulSoup', '3.0.5', 'beautifulsoup', 'python-beautifulsoup', 'python-BeautifulSoup'), ('help2man', '1.36.4', 'help2man', 'help2man', 'help2man'), ] From f46fedab9b2aba0920e43aebc304bebf61d7cd4f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2009 17:25:55 -0800 Subject: [PATCH 08/14] EPUB output: Don't split on page breaks when converting from PDF files, since PDF files have page breaks after every page. This makes reading EPUBs generated from PDFs more pleasant. --- src/calibre/ebooks/epub/from_any.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/calibre/ebooks/epub/from_any.py b/src/calibre/ebooks/epub/from_any.py index e204b38b03..51fdcc4e6a 100644 --- a/src/calibre/ebooks/epub/from_any.py +++ b/src/calibre/ebooks/epub/from_any.py @@ -67,6 +67,7 @@ def txt2opf(path, tdir, opts): def pdf2opf(path, tdir, opts): from calibre.ebooks.lrf.pdf.convert_from import generate_html generate_html(path, tdir) + opts.dont_split_on_page_breaks = True return os.path.join(tdir, 'metadata.opf') def epub2opf(path, tdir, opts): From e26b23255f849ea650129b8bca01266e8a52de4d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2009 18:19:04 -0800 Subject: [PATCH 09/14] version 0.4.127 --- 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 2209f482f5..12b17b7f0a 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.4.126' +__version__ = '0.4.127' __author__ = "Kovid Goyal " ''' Various run time constants. From 7a5306e24378ef89bc5dfd1883d9069f0353ed36 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 9 Jan 2009 18:27:39 -0800 Subject: [PATCH 10/14] IGN:Tag release From fb2832c3edb7727a8f6e52f5918a5297d801a0bb Mon Sep 17 00:00:00 2001 From: "Marshall T. Vandegrift" Date: Sat, 10 Jan 2009 00:34:02 -0500 Subject: [PATCH 11/14] Fix glitch in HTML 3.2 font/@face -> CSS font-family conversion. --- src/calibre/ebooks/html.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/calibre/ebooks/html.py b/src/calibre/ebooks/html.py index 84af7527bd..c938847051 100644 --- a/src/calibre/ebooks/html.py +++ b/src/calibre/ebooks/html.py @@ -796,7 +796,18 @@ class Processor(Parser): setting = '' face = font.attrib.pop('face', None) if face is not None: - setting += 'font-face:%s;'%face + faces = [] + for face in face.split(','): + if ' ' in face: + face = "%s" % face + faces.append(face) + for generic in ('serif', 'sans-serif', 'monospace'): + if generic in faces: + break + else: + faces.append('serif') + family = ', '.join(faces) + setting += 'font-family: %s;' % family color = font.attrib.pop('color', None) if color is not None: setting += 'color:%s'%color From 0fc8aa3f4a7e57a3697b7262d47e547c7eae1071 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 10 Jan 2009 09:34:08 -0800 Subject: [PATCH 12/14] Recipe for Common Dreams by XanthanGum --- src/calibre/web/feeds/recipes/__init__.py | 2 +- .../web/feeds/recipes/recipe_common_dreams.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/calibre/web/feeds/recipes/recipe_common_dreams.py diff --git a/src/calibre/web/feeds/recipes/__init__.py b/src/calibre/web/feeds/recipes/__init__.py index d9ecce0e72..362bfeeafc 100644 --- a/src/calibre/web/feeds/recipes/__init__.py +++ b/src/calibre/web/feeds/recipes/__init__.py @@ -21,7 +21,7 @@ recipe_modules = ['recipe_' + r for r in ( 'linux_magazine', 'telegraph_uk', 'utne', 'sciencedaily', 'forbes', 'time_magazine', 'endgadget', 'fudzilla', 'nspm_int', 'nspm', 'pescanik', 'spiegel_int', 'themarketticker', 'tomshardware', 'xkcd', 'ftd', 'zdnet', - 'joelonsoftware', 'telepolis', + 'joelonsoftware', 'telepolis', 'common_dreams', )] import re, imp, inspect, time, os diff --git a/src/calibre/web/feeds/recipes/recipe_common_dreams.py b/src/calibre/web/feeds/recipes/recipe_common_dreams.py new file mode 100644 index 0000000000..18a4233d69 --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_common_dreams.py @@ -0,0 +1,16 @@ + +from calibre.web.feeds.news import BasicNewsRecipe + +class CommonDreams(BasicNewsRecipe): + title = u'Common Dreams' + description = u'Progressive news and views' + __author__ = u'XanthanGum' + oldest_article = 7 + max_articles_per_feed = 100 + + feeds = [ + (u'Common Dreams Headlines', + u'http://www.commondreams.org/feed/headlines_rss'), + (u'Common Dreams Views', u'http://www.commondreams.org/feed/views_rss'), + (u'Common Dreams Newswire', u'http://www.commondreams.org/feed/newswire_rss') + ] From 399b6bbcb0c2ff341e3706f8c0f5b48a602516ad Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 10 Jan 2009 16:28:09 -0800 Subject: [PATCH 13/14] Fix #1588 (Recipe for "The Economist") --- src/calibre/web/feeds/recipes/recipe_economist.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/calibre/web/feeds/recipes/recipe_economist.py b/src/calibre/web/feeds/recipes/recipe_economist.py index 3c75bd4237..9ed19802b4 100644 --- a/src/calibre/web/feeds/recipes/recipe_economist.py +++ b/src/calibre/web/feeds/recipes/recipe_economist.py @@ -49,8 +49,10 @@ class Economist(BasicNewsRecipe): if not index_started: continue text = string.capwords(text) - feeds[text] = [] - ans.append(text) + if text not in feeds.keys(): + feeds[text] = [] + if text not in ans: + ans.append(text) key = text continue if key is None: From 719926222ec9cbd8b03da5872dc4ffb26636e749 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 10 Jan 2009 17:01:11 -0800 Subject: [PATCH 14/14] IGN:Allow drivers to perform arbitrary post id match checks to detect devices --- src/calibre/devices/interface.py | 14 ++++++++++++++ src/calibre/devices/scanner.py | 6 ++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/calibre/devices/interface.py b/src/calibre/devices/interface.py index 85d25d82a4..04d61a25dc 100644 --- a/src/calibre/devices/interface.py +++ b/src/calibre/devices/interface.py @@ -41,6 +41,20 @@ class Device(object): '''Return the FDI description of this device for HAL on linux.''' return '' + @classmethod + def can_handle(cls, device_info): + ''' + Optional method to perform further checks on a device to see if this driver + is capable of handling it. If it is not it should return False. This method + is only called after the vendor, product ids and the bcd have matched, so + it can do some relatively time intensive checks. The default implementation + returns True. + + :param device_info: On windows a device ID string. On Unix a tuple of + ``(vendor_id, product_id, bcd)``. + ''' + return True + def open(self): ''' Perform any device specific initialization. Called after the device is diff --git a/src/calibre/devices/scanner.py b/src/calibre/devices/scanner.py index ec937fc84d..26ea67ea44 100644 --- a/src/calibre/devices/scanner.py +++ b/src/calibre/devices/scanner.py @@ -63,12 +63,14 @@ class DeviceScanner(object): for device_id in self.devices: if vid in device_id and pid in device_id: if self.test_bcd_windows(device_id, getattr(device, 'BCD', None)): - return True + if device.can_handle(device_id): + return True else: for vendor, product, bcdDevice in self.devices: if device.VENDOR_ID == vendor and device.PRODUCT_ID == product: if self.test_bcd(bcdDevice, getattr(device, 'BCD', None)): - return True + if device.can_handle((vendor, product, bcdDevice)): + return True return False