From c2a80c1e7bc4409bc118c72e1146ec5c07481dd0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 13 Nov 2010 10:24:58 -0700 Subject: [PATCH 1/5] Improved sports feeds for the washington post recipe --- resources/recipes/wash_post.recipe | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/recipes/wash_post.recipe b/resources/recipes/wash_post.recipe index ae56172674..fb6d5bc598 100644 --- a/resources/recipes/wash_post.recipe +++ b/resources/recipes/wash_post.recipe @@ -31,8 +31,9 @@ class WashingtonPost(BasicNewsRecipe): ('Education', 'http://www.washingtonpost.com/wp-dyn/rss/education/index.xml'), ('Style', 'http://www.washingtonpost.com/wp-dyn/rss/print/style/index.xml'), - ('Sports', - 'http://feeds.washingtonpost.com/wp-dyn/rss/linkset/2010/08/19/LI2010081904067_xml'), + ('NFL Sports', + 'http://www.washingtonpost.com/wp-dyn/rss/sports/index/nfl/index.xml'), + ('Redskins', 'http://www.washingtonpost.com/wp-dyn/rss/sports/redskins/index.xml'), ('Editorials', 'http://www.washingtonpost.com/wp-dyn/rss/linkset/2005/05/30/LI2005053000331.xml'), ] From 85738074973cdab5588cd2596bddc1c4159b9b15 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 13 Nov 2010 10:50:21 -0700 Subject: [PATCH 2/5] SONY XML cache: Handle case where XML db contains reference to a file that does not exist gracefully --- src/calibre/devices/prs505/sony_cache.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/calibre/devices/prs505/sony_cache.py b/src/calibre/devices/prs505/sony_cache.py index c2899f54ee..f271329fc8 100644 --- a/src/calibre/devices/prs505/sony_cache.py +++ b/src/calibre/devices/prs505/sony_cache.py @@ -610,7 +610,11 @@ class XMLCache(object): # is not new, compare its Sony DB date against localtime and gmtime. # Count the matches. When we must set a date, use the one with the most # matches. Use localtime if the case of a tie, and hope it is right. - timestamp = os.path.getmtime(path) + try: + timestamp = os.path.getmtime(path) + except: + debug_print('Failed to get timestamp for:', path) + timestamp = time.time() rec_date = record.get('date', None) def clean(x): @@ -627,12 +631,12 @@ class XMLCache(object): pass if not getattr(book, '_new_book', False): # book is not new - if record.get('tz', None) is not None: - use_tz_var = True - if strftime(timestamp, zone=time.gmtime) == rec_date: - gtz_count += 1 - elif strftime(timestamp, zone=time.localtime) == rec_date: - ltz_count += 1 + if record.get('tz', None) is not None: + use_tz_var = True + if strftime(timestamp, zone=time.gmtime) == rec_date: + gtz_count += 1 + elif strftime(timestamp, zone=time.localtime) == rec_date: + ltz_count += 1 else: # book is new. Set the time using the current votes if use_tz_var: tz = time.localtime @@ -646,7 +650,10 @@ class XMLCache(object): debug_print("Use GMT TZ for new book", book.lpath) date = strftime(timestamp, zone=tz) record.set('date', clean(date)) - record.set('size', clean(str(os.stat(path).st_size))) + try: + record.set('size', clean(str(os.stat(path).st_size))) + except: + record.set('size', '0') title = book.title if book.title else _('Unknown') record_set('title', title) ts = book.title_sort From 1c8d3ea7523817a7c4ebc1e76370b52ddbed4842 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 13 Nov 2010 11:12:17 -0700 Subject: [PATCH 3/5] Fix #7443 (New Reader: Cybook Orizon) --- src/calibre/customize/builtins.py | 3 ++- src/calibre/devices/cybook/driver.py | 22 +++++++++++++++++++++- src/calibre/gui2/wizard/__init__.py | 5 +++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/calibre/customize/builtins.py b/src/calibre/customize/builtins.py index bd766827a5..681d953c9b 100644 --- a/src/calibre/customize/builtins.py +++ b/src/calibre/customize/builtins.py @@ -454,7 +454,7 @@ from calibre.customize.profiles import input_profiles, output_profiles from calibre.devices.apple.driver import ITUNES from calibre.devices.hanlin.driver import HANLINV3, HANLINV5, BOOX, SPECTRA from calibre.devices.blackberry.driver import BLACKBERRY -from calibre.devices.cybook.driver import CYBOOK +from calibre.devices.cybook.driver import CYBOOK, ORIZON from calibre.devices.eb600.driver import EB600, COOL_ER, SHINEBOOK, \ POCKETBOOK360, GER2, ITALICA, ECLICTO, DBOOK, INVESBOOK, \ BOOQ, ELONEX, POCKETBOOK301, MENTOR @@ -535,6 +535,7 @@ plugins += [ HANLINV5, BLACKBERRY, CYBOOK, + ORIZON, ILIAD, IREXDR1000, IREXDR800, diff --git a/src/calibre/devices/cybook/driver.py b/src/calibre/devices/cybook/driver.py index 7c436a7d0e..becb7912a9 100644 --- a/src/calibre/devices/cybook/driver.py +++ b/src/calibre/devices/cybook/driver.py @@ -5,7 +5,7 @@ __copyright__ = '2009, John Schember ' __docformat__ = 'restructuredtext en' ''' -Device driver for Bookeen's Cybook Gen 3 and Opus +Device driver for Bookeen's Cybook Gen 3 and Opus and Orizon ''' import os @@ -56,3 +56,23 @@ class CYBOOK(USBMS): if isunix: return device_info[3] == 'Bookeen' and (device_info[4] == 'Cybook Gen3' or device_info[4] == 'Cybook Opus') return True + +class ORIZON(CYBOOK): + + name = 'Orizon Device Interface' + gui_name = 'Orizon' + description = _('Communicate with the Cybook Orizon eBook reader.') + + BCD = [0x319] + + WINDOWS_MAIN_MEM = re.compile(r'CYBOOK_ORIZON__-FD') + WINDOWS_CARD_A_MEM = re.compile('CYBOOK_ORIZON__-SD') + + EBOOK_DIR_MAIN = EBOOK_DIR_CARD_A = 'Digital Editions' + + @classmethod + def can_handle(cls, device_info, debug=False): + if isunix: + return device_info[3] == 'Bookeen' and device_info[4] == 'Cybook Orizon' + return True + diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py index 54d034a705..2ac0908ea9 100644 --- a/src/calibre/gui2/wizard/__init__.py +++ b/src/calibre/gui2/wizard/__init__.py @@ -153,6 +153,11 @@ class CybookOpus(CybookG3): output_profile = 'cybook_opus' id = 'cybook_opus' +class CybookOrizon(CybookOpus): + + name = 'Cybook Orizon' + id = 'cybook_orizon' + class PocketBook360(CybookOpus): manufacturer = 'PocketBook' From 372c462ae73df22aba240c3b4ae684871e2fbe3e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 13 Nov 2010 12:00:41 -0700 Subject: [PATCH 4/5] Fix bug preventing customizing of builtin recipes if they are not ascii encoded --- src/calibre/library/database.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/calibre/library/database.py b/src/calibre/library/database.py index c4f6908002..6016dbd03e 100644 --- a/src/calibre/library/database.py +++ b/src/calibre/library/database.py @@ -9,6 +9,7 @@ from zlib import compress, decompress from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.metadata import string_to_authors +from calibre import isbytestring class Concatenate(object): '''String concatenation aggregator for sqlite''' @@ -1379,6 +1380,10 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE; self.conn.commit() def add_feed(self, title, script): + if isbytestring(title): + title = title.decode('utf-8') + if isbytestring(script): + script = script.decode('utf-8') self.conn.execute('INSERT INTO feeds(title, script) VALUES (?, ?)', (title, script)) self.conn.commit() From e8d4ec53ca0500b8f71e1f210fa43329a9423c22 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 13 Nov 2010 12:40:58 -0700 Subject: [PATCH 5/5] Press releases of the German government and EU COmmission by malfi --- resources/recipes/eu_commission.recipe | 58 ++++++++++++++++++++++++++ resources/recipes/german_gov.recipe | 28 +++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 resources/recipes/eu_commission.recipe create mode 100644 resources/recipes/german_gov.recipe diff --git a/resources/recipes/eu_commission.recipe b/resources/recipes/eu_commission.recipe new file mode 100644 index 0000000000..01d2a31a40 --- /dev/null +++ b/resources/recipes/eu_commission.recipe @@ -0,0 +1,58 @@ +from calibre.web.feeds.news import BasicNewsRecipe + +LANGUAGE = 'de' + +def feedlink(num): + return u'http://europa.eu/rapid/syndication/QuickRSSAction.do?id='+\ + str(num)+'&lang='+ LANGUAGE + +class EUCommissionPress(BasicNewsRecipe): + title = u'Pressemitteilungen der EU Kommission pro Politikbereich' + oldest_article = 7 + max_articles_per_feed = 100 + no_stylesheets = True + cover_url = 'http://ec.europa.eu/wel/template_2007/images/banners/banner-background.jpg' + __author__ = 'malfi' + language = LANGUAGE + keep_only_tags = [] + keep_only_tags.append(dict(name = 'div', attrs = {'class': 'pressReleaseContentMain'})) + remove_tags = [] + + + feeds = [ + (u'Pressemitteilung des Tages',feedlink(64)), + (u'Presidency',feedlink(137)), + (u'Foreign affairs and security policy',feedlink(138)), + (u'Agriculture and rural development',feedlink(139)), + (u'Budget and financial programming ',feedlink(140)), + (u'Climate action',feedlink(141)), + (u'Competition',feedlink(142)), + (u'Development',feedlink(143)), + (u'Digital agenda',feedlink(144)), + (u'Economic and monetary affairs',feedlink(145)), + (u'Education, culture, multilingualism and youth ',feedlink(146)), + (u'Employment, social Affairs and inclusion ',feedlink(147)), + (u'Energy',feedlink(148)), + (u'Enlargment and European neighbourhood policy ',feedlink(149)), + (u'Environment',feedlink(150)), + (u'Health and consumer policy',feedlink(151)), + (u'Home affairs',feedlink(152)), + (u'Industry and entrepreneurship',feedlink(153)), + (u'Inter-Institutional relations and administration',feedlink(154)), + (u'Internal market and services',feedlink(155)), + (u'International cooperation, humanitarian aid and crisis response',feedlink(156)), + (u'Justice, fundamental rights and citizenship',feedlink(157)), + (u'Maritime affairs and fisheries',feedlink(158)), + (u'Regional policy',feedlink(159)), + (u'Research and innovation',feedlink(160)), + (u'Taxation and customs union, audit and anti-fraud',feedlink(161)), + (u'Trade',feedlink(162)), + (u'Transport',feedlink(163)) + ] + extra_css = ''' + h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;} + h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;} + p{font-family:Arial,Helvetica,sans-serif;font-size:small;} + body{font-family:Helvetica,Arial,sans-serif;font-size:small;} + ''' + diff --git a/resources/recipes/german_gov.recipe b/resources/recipes/german_gov.recipe new file mode 100644 index 0000000000..afe55d89c9 --- /dev/null +++ b/resources/recipes/german_gov.recipe @@ -0,0 +1,28 @@ +import re + +from calibre.web.feeds.news import BasicNewsRecipe + +class GermanGovermentPress(BasicNewsRecipe): + title = u'Pressemitteilungen der Bundesregierung' + oldest_article = 14 + __author__ = 'malfi' + max_articles_per_feed = 100 + no_stylesheets = True + cover_url = 'http://www.bundesregierung.de/static/images/logoBR.gif' + language = 'de' + keep_only_tags = [] + keep_only_tags.append(dict(name = 'h2')) + keep_only_tags.append(dict(name = 'div', attrs = {'class': 'textblack'})) + keep_only_tags.append(dict(name = 'div', attrs = {'class': 'subtitle'})) + keep_only_tags.append(dict(name = 'div', attrs = {'class': 'text'})) + remove_tags = [] + feeds = [ (u'Pressemitteilungen',u'http://www.bundesregierung.de/Webs/Breg/DE/Service/RSS/Functions/bundesregierungPressemitteilungenRSS20,templateId=renderNewsfeed.rdf') ] + extra_css = ''' + h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;} + h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;} + p{font-family:Arial,Helvetica,sans-serif;font-size:small;} + body{font-family:Helvetica,Arial,sans-serif;font-size:small;} + ''' + def print_version(self, url): + m = re.search(r'^(.*).html$', url) + return str(m.group(1)) + ',layoutVariant=Druckansicht.html'