mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Cybook: Fixed reference to IDs on Windows
This commit is contained in:
commit
1d451f4ee2
@ -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',
|
||||
|
@ -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'],
|
||||
|
@ -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'],
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
@ -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>
|
||||
|
@ -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()
|
||||
|
@ -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 = []
|
||||
|
@ -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:
|
||||
|
@ -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('~')
|
||||
|
@ -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'))
|
||||
|
@ -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
|
||||
|
49
src/calibre/web/feeds/recipes/recipe_ftd.py
Normal file
49
src/calibre/web/feeds/recipes/recipe_ftd.py
Normal 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') ]
|
||||
|
||||
|
46
src/calibre/web/feeds/recipes/recipe_zdnet.py
Normal file
46
src/calibre/web/feeds/recipes/recipe_zdnet.py
Normal 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') ]
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user