Cybook: Fixed reference to IDs on Windows

This commit is contained in:
John Schember 2009-01-06 19:12:17 -05:00
commit 1d451f4ee2
18 changed files with 268 additions and 118 deletions

View File

@ -16,6 +16,7 @@ def freeze():
from calibre.linux import entry_points
from calibre import walk
from calibre.web.feeds.recipes import recipe_modules
from calibre.ebooks.lrf.fonts import FONT_MAP
import calibre
@ -37,6 +38,7 @@ def freeze():
'/usr/lib/libxml2.so.2',
'/usr/lib/libxslt.so.1',
'/usr/lib/libxslt.so.1',
'/usr/lib/libexslt.so.0',
'/usr/lib/libMagickWand.so',
'/usr/lib/libMagickCore.so',
]
@ -72,6 +74,7 @@ def freeze():
os.makedirs(DIST_DIR)
includes = [x[0] for x in executables.values()]
includes += ['calibre.ebooks.lrf.fonts.prs500.'+x for x in FONT_MAP.values()]
excludes = ['matplotlib', "Tkconstants", "Tkinter", "tcl", "_imagingtk",
"ImageTk", "FixTk", 'wx', 'PyQt4.QtAssistant', 'PyQt4.QtOpenGL.so',

View File

@ -326,7 +326,7 @@ def main():
'genshi', 'calibre.web.feeds.recipes.*',
'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*',
'keyword', 'codeop', 'pydoc', 'readline',
'BeautifulSoup'
'BeautifulSoup', 'calibre.ebooks.lrf.fonts.prs500.*',
],
'packages' : ['PIL', 'Authorization', 'lxml'],
'excludes' : ['IPython'],

View File

@ -176,6 +176,7 @@ def main(args=sys.argv):
'BeautifulSoup', 'pyreadline',
'pydoc', 'IPython.Extensions.*',
'calibre.web.feeds.recipes.*',
'calibre.ebooks.lrf.fonts.prs500.*',
'PyQt4.QtWebKit', 'PyQt4.QtNetwork',
],
'packages' : ['PIL', 'lxml', 'cherrypy'],

View File

@ -2,7 +2,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
__appname__ = 'calibre'
__version__ = '0.4.125'
__version__ = '0.4.126'
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
'''
Various run time constants.

View File

@ -105,30 +105,43 @@ def reread_metadata_plugins():
for plugin in _initialized_plugins:
if isinstance(plugin, MetadataReaderPlugin):
for ft in plugin.file_types:
_metadata_readers[ft] = plugin
if not _metadata_readers.has_key(ft):
_metadata_readers[ft] = []
_metadata_readers[ft].append(plugin)
elif isinstance(plugin, MetadataWriterPlugin):
for ft in plugin.file_types:
_metadata_writers[ft] = plugin
if not _metadata_writers.has_key(ft):
_metadata_writers[ft] = []
_metadata_writers[ft].append(plugin)
def get_file_type_metadata(stream, ftype):
mi = MetaInformation(None, None)
try:
plugin = _metadata_readers[ftype.lower().strip()]
if not is_disabled(plugin):
with plugin:
mi = plugin.get_metadata(stream, ftype.lower().strip())
except:
pass
ftype = ftype.lower().strip()
if _metadata_readers.has_key(ftype):
for plugin in _metadata_readers[ftype]:
if not is_disabled(plugin):
with plugin:
try:
mi = plugin.get_metadata(stream, ftype.lower().strip())
break
except:
continue
return mi
def set_file_type_metadata(stream, mi, ftype):
try:
plugin = _metadata_writers[ftype.lower().strip()]
if not is_disabled(plugin):
with plugin:
plugin.set_metadata(stream, mi, ftype.lower().strip())
except:
traceback.print_exc()
ftype = ftype.lower().strip()
if _metadata_writers.has_key(ftype):
for plugin in _metadata_writers[ftype]:
if not is_disabled(plugin):
with plugin:
try:
plugin.set_metadata(stream, mi, ftype.lower().strip())
break
except:
traceback.print_exc()
def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'):
occasion = {'import':_on_import, 'preprocess':_on_preprocess,

View File

@ -222,11 +222,11 @@ class CYBOOKG3(Device):
path = path.replace('card:', self._card_prefix[:-1])
return path
def _windows_match_device(self, device_id):
@classmethod
def windows_match_device(cls, device_id):
device_id = device_id.upper()
if 'VEN_'+self.VENDOR_NAME in device_id and \
'PROD_'+self.PRODUCT_NAME in device_id:
if 'VEN_'+cls.VENDOR_NAME in device_id and \
'PROD_'+cls.PRODUCT_NAME in device_id:
return True
vid, pid = hex(cls.VENDOR_ID)[2:], hex(cls.PRODUCT_ID)[2:]
@ -243,7 +243,7 @@ class CYBOOKG3(Device):
wmi = __import__('wmi', globals(), locals(), [], -1)
c = wmi.WMI()
for drive in c.Win32_DiskDrive():
if self._windows_match_device(str(drive.PNPDeviceID)):
if self.__class__.windows_match_device(str(drive.PNPDeviceID)):
if drive.Partitions == 0:
continue
try:

View File

@ -50,7 +50,8 @@ def get_font_path(name):
try:
font_mod = __import__('calibre.ebooks.lrf.fonts.prs500', {}, {},
[fname], -1)
except ImportError:
getattr(font_mod, fname)
except (ImportError, AttributeError):
font_mod = __import__('calibre.ebooks.lrf.fonts.liberation', {}, {},
[LIBERATION_FONT_MAP[name]], -1)
p = PersistentTemporaryFile('.ttf', 'font_')
@ -80,4 +81,4 @@ def get_font(name, size, encoding='unic'):
path = get_font_path(name)
return ImageFont.truetype(path, size, encoding=encoding)
elif name in FONT_FILE_MAP.keys():
return ImageFont.truetype(FONT_FILE_MAP[name], size, encoding=encoding)
return ImageFont.truetype(FONT_FILE_MAP[name], size, encoding=encoding)

View File

@ -245,7 +245,6 @@ class HTMLConverter(object, LoggingInterface):
self.override_css = {}
self.override_pcss = {}
self.table_render_job_server = None
if self._override_css is not None:
if os.access(self._override_css, os.R_OK):
@ -266,41 +265,37 @@ class HTMLConverter(object, LoggingInterface):
paths = [os.path.abspath(path) for path in paths]
paths = [path.decode(sys.getfilesystemencoding()) if not isinstance(path, unicode) else path for path in paths]
try:
while len(paths) > 0 and self.link_level <= self.link_levels:
for path in paths:
if path in self.processed_files:
continue
try:
self.add_file(path)
except KeyboardInterrupt:
while len(paths) > 0 and self.link_level <= self.link_levels:
for path in paths:
if path in self.processed_files:
continue
try:
self.add_file(path)
except KeyboardInterrupt:
raise
except:
if self.link_level == 0: # Die on errors in the first level
raise
except:
if self.link_level == 0: # Die on errors in the first level
raise
for link in self.links:
if link['path'] == path:
self.links.remove(link)
break
self.log_warn('Could not process '+path)
if self.verbose:
self.log_exception(' ')
self.links = self.process_links()
self.link_level += 1
paths = [link['path'] for link in self.links]
if self.current_page is not None and self.current_page.has_text():
self.book.append(self.current_page)
for text, tb in self.extra_toc_entries:
self.book.addTocEntry(text, tb)
if self.base_font_size > 0:
self.log_info('\tRationalizing font sizes...')
self.book.rationalize_font_sizes(self.base_font_size)
finally:
if self.table_render_job_server is not None:
self.table_render_job_server.killall()
for link in self.links:
if link['path'] == path:
self.links.remove(link)
break
self.log_warn('Could not process '+path)
if self.verbose:
self.log_exception(' ')
self.links = self.process_links()
self.link_level += 1
paths = [link['path'] for link in self.links]
if self.current_page is not None and self.current_page.has_text():
self.book.append(self.current_page)
for text, tb in self.extra_toc_entries:
self.book.addTocEntry(text, tb)
if self.base_font_size > 0:
self.log_info('\tRationalizing font sizes...')
self.book.rationalize_font_sizes(self.base_font_size)
def is_baen(self, soup):
return bool(soup.find('meta', attrs={'name':'Publisher',
@ -1732,15 +1727,11 @@ class HTMLConverter(object, LoggingInterface):
self.process_children(tag, tag_css, tag_pseudo_css)
elif tagname == 'table' and not self.ignore_tables and not self.in_table:
if self.render_tables_as_images:
if self.table_render_job_server is None:
from calibre.parallel import Server
self.table_render_job_server = Server(number_of_workers=1)
print 'Rendering table...'
from calibre.ebooks.lrf.html.table_as_image import render_table
pheight = int(self.current_page.pageStyle.attrs['textheight'])
pwidth = int(self.current_page.pageStyle.attrs['textwidth'])
images = render_table(self.table_render_job_server,
self.soup, tag, tag_css,
images = render_table(self.soup, tag, tag_css,
os.path.dirname(self.target_prefix),
pwidth, pheight, self.profile.dpi,
self.text_size_multiplier_for_rendered_tables)

View File

@ -6,14 +6,11 @@ __docformat__ = 'restructuredtext en'
'''
Render HTML tables as images.
'''
import os, tempfile, atexit, shutil, time
from PyQt4.Qt import QUrl, QApplication, QSize, \
import os, tempfile, atexit, shutil
from PyQt4.Qt import QUrl, QApplication, QSize, QEventLoop, \
SIGNAL, QPainter, QImage, QObject, Qt
from PyQt4.QtWebKit import QWebPage
from calibre.parallel import ParallelJob
__app = None
class HTMLTableRenderer(QObject):
@ -27,13 +24,15 @@ class HTMLTableRenderer(QObject):
self.app = None
self.width, self.height, self.dpi = width, height, dpi
self.base_dir = base_dir
self.images = []
self.tdir = tempfile.mkdtemp(prefix='calibre_render_table')
self.loop = QEventLoop()
self.page = QWebPage()
self.connect(self.page, SIGNAL('loadFinished(bool)'), self.render_html)
self.page.mainFrame().setTextSizeMultiplier(factor)
self.page.mainFrame().setHtml(html,
QUrl('file:'+os.path.abspath(self.base_dir)))
self.images = []
self.tdir = tempfile.mkdtemp(prefix='calibre_render_table')
def render_html(self, ok):
try:
@ -63,7 +62,7 @@ class HTMLTableRenderer(QObject):
finally:
QApplication.quit()
def render_table(server, soup, table, css, base_dir, width, height, dpi, factor=1.0):
def render_table(soup, table, css, base_dir, width, height, dpi, factor=1.0):
head = ''
for e in soup.findAll(['link', 'style']):
head += unicode(e)+'\n\n'
@ -83,24 +82,13 @@ def render_table(server, soup, table, css, base_dir, width, height, dpi, factor=
</body>
</html>
'''%(head, width-10, style, unicode(table))
job = ParallelJob('render_table', lambda j : j, None,
args=[html, base_dir, width, height, dpi, factor])
server.add_job(job)
while not job.has_run:
time.sleep(2)
if job.exception is not None:
print 'Failed to render table'
print job.exception
print job.traceback
images, tdir = job.result
images, tdir = do_render(html, base_dir, width, height, dpi, factor)
atexit.register(shutil.rmtree, tdir)
return images
def do_render(html, base_dir, width, height, dpi, factor):
app = QApplication.instance()
if app is None:
app = QApplication([])
if QApplication.instance() is None:
QApplication([])
tr = HTMLTableRenderer(html, base_dir, width, height, dpi, factor)
app.exec_()
tr.loop.exec_()
return tr.images, tr.tdir

View File

@ -600,6 +600,33 @@
<header>widgets.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>title</tabstop>
<tabstop>swap_button</tabstop>
<tabstop>authors</tabstop>
<tabstop>author_sort</tabstop>
<tabstop>auto_author_sort</tabstop>
<tabstop>rating</tabstop>
<tabstop>publisher</tabstop>
<tabstop>tags</tabstop>
<tabstop>tag_editor_button</tabstop>
<tabstop>series</tabstop>
<tabstop>remove_series_button</tabstop>
<tabstop>series_index</tabstop>
<tabstop>isbn</tabstop>
<tabstop>comments</tabstop>
<tabstop>fetch_metadata_button</tabstop>
<tabstop>fetch_cover_button</tabstop>
<tabstop>password_button</tabstop>
<tabstop>cover_button</tabstop>
<tabstop>reset_cover</tabstop>
<tabstop>cover_path</tabstop>
<tabstop>add_format_button</tabstop>
<tabstop>button_set_cover</tabstop>
<tabstop>remove_format_button</tabstop>
<tabstop>formats</tabstop>
<tabstop>button_box</tabstop>
</tabstops>
<resources>
<include location="../images.qrc" />
</resources>

View File

@ -1424,9 +1424,14 @@ in which you want to store your books files. Any existing books will be automati
self.memory_view.write_settings()
def quit(self, checked, restart=False):
if self.shutdown():
self.restart_after_quit = restart
QApplication.instance().quit()
if not self.confirm_quit():
return
try:
self.shutdown()
except:
pass
self.restart_after_quit = restart
QApplication.instance().quit()
def donate(self):
BUTTON = '''
@ -1457,22 +1462,26 @@ in which you want to store your books files. Any existing books will be automati
QDesktopServices.openUrl(QUrl.fromLocalFile(pt.name))
def shutdown(self):
msg = _('There are active jobs. Are you sure you want to quit?')
if self.job_manager.has_device_jobs():
msg = '<p>'+__appname__ + _(''' is communicating with the device!<br>
'Quitting may cause corruption on the device.<br>
'Are you sure you want to quit?''')+'</p>'
def confirm_quit(self):
if self.job_manager.has_jobs():
msg = _('There are active jobs. Are you sure you want to quit?')
if self.job_manager.has_device_jobs():
msg = '<p>'+__appname__ + _(''' is communicating with the device!<br>
'Quitting may cause corruption on the device.<br>
'Are you sure you want to quit?''')+'</p>'
d = QMessageBox(QMessageBox.Warning, _('WARNING: Active jobs'), msg,
QMessageBox.Yes|QMessageBox.No, self)
d.setIconPixmap(QPixmap(':/images/dialog_warning.svg'))
d.setDefaultButton(QMessageBox.No)
if d.exec_() != QMessageBox.Yes:
return False
return True
self.job_manager.terminate_all_jobs()
def shutdown(self):
self.write_settings()
self.job_manager.terminate_all_jobs()
self.device_manager.keep_going = False
self.cover_cache.stop()
self.hide()
@ -1498,7 +1507,11 @@ in which you want to store your books files. Any existing books will be automati
self.hide()
e.ignore()
else:
if self.shutdown():
if self.confirm_quit():
try:
self.shutdown()
except:
pass
e.accept()
else:
e.ignore()

View File

@ -13,7 +13,7 @@ from calibre.utils.config import prefs
from calibre.gui2.dialogs.lrf_single import LRFSingleDialog, LRFBulkDialog
from calibre.gui2.dialogs.epub import Config as EPUBConvert
import calibre.gui2.dialogs.comicconf as ComicConf
from calibre.gui2 import warning_dialog, dynamic
from calibre.gui2 import warning_dialog
from calibre.ptempfile import PersistentTemporaryFile
from calibre.ebooks.lrf import preferred_source_formats as LRF_PREFERRED_SOURCE_FORMATS
from calibre.ebooks.metadata.opf import OPFCreator
@ -22,7 +22,9 @@ from calibre.ebooks.epub.from_any import SOURCE_FORMATS as EPUB_PREFERRED_SOURCE
def convert_single_epub(parent, db, comics, others):
changed = False
jobs = []
for row in others:
others_ids = [db.id(row) for row in others]
comics_ids = [db.id(row) for row in comics]
for row, row_id in zip(others, others_ids):
temp_files = []
d = EPUBConvert(parent, db, row)
if d.source_format is not None:
@ -44,10 +46,10 @@ def convert_single_epub(parent, db, comics, others):
opts.cover = d.cover_file.name
temp_files.extend([d.opf_file, pt, of])
jobs.append(('any2epub', args, _('Convert book: ')+d.mi.title,
'EPUB', db.id(row), temp_files))
'EPUB', row_id, temp_files))
changed = True
for row in comics:
for row, row_id in zip(comics, comics_ids):
mi = db.get_metadata(row)
title = author = _('Unknown')
if mi.title:
@ -76,7 +78,7 @@ def convert_single_epub(parent, db, comics, others):
args = [pt.name, opts]
changed = True
jobs.append(('comic2epub', args, _('Convert comic: ')+opts.title,
'EPUB', db.id(row), [pt, of]))
'EPUB', row_id, [pt, of]))
return jobs, changed
@ -85,7 +87,9 @@ def convert_single_epub(parent, db, comics, others):
def convert_single_lrf(parent, db, comics, others):
changed = False
jobs = []
for row in others:
others_ids = [db.id(row) for row in others]
comics_ids = [db.id(row) for row in comics]
for row, row_id in zip(others, others_ids):
temp_files = []
d = LRFSingleDialog(parent, db, row)
if d.selected_format:
@ -104,10 +108,10 @@ def convert_single_lrf(parent, db, comics, others):
temp_files.append(d.cover_file)
temp_files.extend([pt, of])
jobs.append(('any2lrf', [cmdline], _('Convert book: ')+d.title(),
'LRF', db.id(row), temp_files))
'LRF', row_id, temp_files))
changed = True
for row in comics:
for row, row_id in zip(comics, comics_ids):
mi = db.get_metadata(row)
title = author = _('Unknown')
if mi.title:
@ -138,7 +142,7 @@ def convert_single_lrf(parent, db, comics, others):
args = [pt.name, opts]
changed = True
jobs.append(('comic2lrf', args, _('Convert comic: ')+opts.title,
'LRF', db.id(row), [pt, of]))
'LRF', row_id, [pt, of]))
return jobs, changed
@ -162,6 +166,7 @@ def convert_bulk_epub(parent, db, comics, others):
parent.status_bar.showMessage(_('Starting Bulk conversion of %d books')%total, 2000)
for i, row in enumerate(others+comics):
row_id = db.id(row)
if row in others:
data = None
for fmt in EPUB_PREFERRED_SOURCE_FORMATS:
@ -198,7 +203,7 @@ def convert_bulk_epub(parent, db, comics, others):
desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title))
temp_files = [cf] if cf is not None else []
temp_files.extend([opf_file, pt, of])
jobs.append(('any2epub', args, desc, 'EPUB', db.id(row), temp_files))
jobs.append(('any2epub', args, desc, 'EPUB', row_id, temp_files))
else:
options = comic_opts.copy()
mi = db.get_metadata(row)
@ -224,7 +229,7 @@ def convert_bulk_epub(parent, db, comics, others):
options.verbose = 1
args = [pt.name, options]
desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title))
jobs.append(('comic2epub', args, desc, 'EPUB', db.id(row), [pt, of]))
jobs.append(('comic2epub', args, desc, 'EPUB', row_id, [pt, of]))
if bad_rows:
res = []
@ -255,6 +260,7 @@ def convert_bulk_lrf(parent, db, comics, others):
parent.status_bar.showMessage(_('Starting Bulk conversion of %d books')%total, 2000)
for i, row in enumerate(others+comics):
row_id = db.id(row)
if row in others:
cmdline = list(d.cmdline)
mi = db.get_metadata(row)
@ -294,7 +300,7 @@ def convert_bulk_lrf(parent, db, comics, others):
desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title))
temp_files = [cf] if cf is not None else []
temp_files.extend([pt, of])
jobs.append(('any2lrf', [cmdline], desc, 'LRF', db.id(row), temp_files))
jobs.append(('any2lrf', [cmdline], desc, 'LRF', row_id, temp_files))
else:
options = comic_opts.copy()
mi = db.get_metadata(row)
@ -320,7 +326,7 @@ def convert_bulk_lrf(parent, db, comics, others):
options.verbose = 1
args = [pt.name, options]
desc = _('Convert book %d of %d (%s)')%(i+1, total, repr(mi.title))
jobs.append(('comic2lrf', args, desc, 'LRF', db.id(row), [pt, of]))
jobs.append(('comic2lrf', args, desc, 'LRF', row_id, [pt, of]))
if bad_rows:
res = []

View File

@ -83,9 +83,11 @@ STANZA_TEMPLATE='''\
<link py:if="record['cover']" rel="x-stanza-cover-image-thumbnail" type="image/png" href="${quote(record['cover'].replace(sep, '/')).replace('http%3A', 'http:')}" />
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<py:for each="f in ('authors','publisher','rating','tags','series', 'isbn')">
<py:for each="f in ('authors', 'publisher', 'rating', 'tags', 'series', 'isbn')">
<py:if test="record[f]">
${f.capitalize()}:${unicode(', '.join(record[f]) if f=='tags' else record[f])}<br/>
${f.capitalize()}:${unicode(', '.join(record[f]) if f=='tags' else record[f])}
<py:if test="f =='series'"># ${str(record['series_index'])}</py:if>
<br/>
</py:if>
</py:for>
<py:if test="record['comments']">
@ -231,7 +233,7 @@ NULL = DevNull()
def do_add(db, paths, one_book_per_directory, recurse, add_duplicates):
orig = sys.stdout
sys.stdout = NULL
#sys.stdout = NULL
try:
files, dirs = [], []
for path in paths:

View File

@ -17,7 +17,9 @@ from calibre.constants import terminal_controller, iswindows, isosx, \
from calibre.utils.lock import LockError, ExclusiveFile
from collections import defaultdict
if iswindows:
if os.environ.has_key('CALIBRE_CONFIG_DIRECTORY'):
config_dir = os.path.abspath(os.environ['CALIBRE_CONFIG_DIRECTORY'])
elif iswindows:
config_dir = plugins['winutil'][0].special_folder_path(plugins['winutil'][0].CSIDL_APPDATA)
if not os.access(config_dir, os.W_OK|os.X_OK):
config_dir = os.path.expanduser('~')

View File

@ -22,7 +22,7 @@ match to a given font specification. The main functions in this module are:
.. autofunction:: match
'''
import sys, os, locale, codecs
import sys, os, locale, codecs, subprocess, re
from ctypes import cdll, c_void_p, Structure, c_int, POINTER, c_ubyte, c_char, util, \
pointer, byref, create_string_buffer, Union, c_char_p, c_double
@ -34,6 +34,7 @@ except:
iswindows = 'win32' in sys.platform or 'win64' in sys.platform
isosx = 'darwin' in sys.platform
isbsd = 'bsd' in sys.platform
DISABLED = False
#if isosx:
# libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c'))
@ -57,6 +58,13 @@ def load_library():
return cdll.LoadLibrary(lib)
elif iswindows:
return cdll.LoadLibrary('libfontconfig-1')
elif isbsd:
raw = subprocess.Popen('pkg-config --libs-only-L fontconfig'.split(),
stdout=subprocess.PIPE).stdout.read().strip()
match = re.search(r'-L([^\s,]+)', raw)
if not match:
return cdll.LoadLibrary('libfontconfig.so')
return cdll.LoadLibrary(match.group(1)+'/libfontconfig.so')
else:
try:
return cdll.LoadLibrary(util.find_library('fontconfig'))

View File

@ -20,7 +20,7 @@ recipe_modules = ['recipe_' + r for r in (
'science_news', 'the_nation', 'lrb', 'harpers_full', 'liberation',
'linux_magazine', 'telegraph_uk', 'utne', 'sciencedaily', 'forbes',
'time_magazine', 'endgadget', 'fudzilla', 'nspm_int', 'nspm', 'pescanik',
'spiegel_int', 'themarketticker', 'tomshardware', 'xkcd',
'spiegel_int', 'themarketticker', 'tomshardware', 'xkcd', 'ftd', 'zdnet',
)]
import re, imp, inspect, time, os

View File

@ -0,0 +1,49 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
'''
Fetch FTD.
'''
from calibre.web.feeds.news import BasicNewsRecipe
class FTheiseDe(BasicNewsRecipe):
title = 'FTD'
description = 'Financial Times Deutschland'
__author__ = 'Oliver Niesner'
use_embedded_content = False
timefmt = ' [%d %b %Y]'
max_articles_per_feed = 40
no_stylesheets = True
remove_tags = [dict(id='navi_top'),
dict(id='topbanner'),
dict(id='seitenkopf'),
dict(id='footer'),
dict(id='rating_open'),
dict(id='ADS_Top'),
dict(id='ADS_Middle1'),
#dict(id='IDMS_ajax_chart_price_information_table'),
dict(id='ivwimg'),
dict(name='span', attrs={'class':'rsaquo'}),
dict(name='p', attrs={'class':'zwischenhead'}),
dict(name='div', attrs={'class':'chartBox'}),
dict(name='span', attrs={'class':'vote_455857'}),
dict(name='div', attrs={'class':'relatedhalb'}),
dict(name='div', attrs={'class':'bpoll'}),
dict(name='div', attrs={'class':'pollokknopf'}),
dict(name='div', attrs={'class':'videohint'}),
dict(name='div', attrs={'class':'videoshadow'}),
dict(name='div', attrs={'class':'boxresp videorahmen'}),
dict(name='div', attrs={'class':'boxresp'}),
dict(name='div', attrs={'class':'abspielen'}),
dict(name='div', attrs={'class':'wertungoben'}),
dict(name='div', attrs={'class':'artikelfuss'}),
dict(name='div', attrs={'class':'artikelsplitfaq'})]
remove_tags_after = [dict(name='div', attrs={'class':'artikelfuss'})]
feeds = [ ('FTD', 'http://www.ftd.de/static/ticker/ftd-topnews.rdf') ]

View File

@ -0,0 +1,46 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
'''
Fetch zdnet.
'''
from calibre.web.feeds.news import BasicNewsRecipe
import re
class cdnet(BasicNewsRecipe):
title = 'zdnet'
description = 'zdnet security'
__author__ = 'Oliver Niesner'
use_embedded_content = False
timefmt = ' [%d %b %Y]'
max_articles_per_feed = 40
no_stylesheets = True
encoding = 'iso-8859-1'
#preprocess_regexps = \
# [(re.compile(i[0], re.IGNORECASE | re.DOTALL), i[1]) for i in
# [
# (r'<84>', lambda match: ''),
# (r'<93>', lambda match: ''),
# ]
# ]
remove_tags = [dict(id='eyebrows'),
dict(id='header'),
dict(id='search'),
dict(id='nav'),
dict(id=''),
dict(name='div', attrs={'class':'banner'}),
dict(name='p', attrs={'class':'tags'}),
dict(name='div', attrs={'class':'special1'})]
remove_tags_after = [dict(name='div', attrs={'class':'bloggerDesc clear'})]
feeds = [ ('zdnet', 'http://feeds.feedburner.com/zdnet/security') ]