mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Sync to trunk.
This commit is contained in:
commit
20a8d6ecd3
@ -18,3 +18,6 @@ class EndgadgetJapan(BasicNewsRecipe):
|
|||||||
language = 'ja'
|
language = 'ja'
|
||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
feeds = [(u'engadget', u'http://japanese.engadget.com/rss.xml')]
|
feeds = [(u'engadget', u'http://japanese.engadget.com/rss.xml')]
|
||||||
|
|
||||||
|
remove_tags_before = dict(name="div", attrs={'id':"content_wrap"})
|
||||||
|
remove_tags_after = dict(name='h3', attrs={'id':'addcomments'})
|
||||||
|
@ -9,6 +9,8 @@ __description__ = 'Canadian Paper '
|
|||||||
http://www.ledevoir.com/
|
http://www.ledevoir.com/
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class ledevoir(BasicNewsRecipe):
|
class ledevoir(BasicNewsRecipe):
|
||||||
@ -32,6 +34,8 @@ class ledevoir(BasicNewsRecipe):
|
|||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
|
|
||||||
|
preprocess_regexps = [(re.compile(r'(title|alt)=".*?>.*?"', re.DOTALL), lambda m: '')]
|
||||||
|
|
||||||
keep_only_tags = [
|
keep_only_tags = [
|
||||||
dict(name='div', attrs={'id':'article'}),
|
dict(name='div', attrs={'id':'article'}),
|
||||||
dict(name='ul', attrs={'id':'ariane'})
|
dict(name='ul', attrs={'id':'ariane'})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2011, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
vijesti.me
|
vijesti.me
|
||||||
@ -18,12 +18,16 @@ class Vijesti(BasicNewsRecipe):
|
|||||||
oldest_article = 2
|
oldest_article = 2
|
||||||
max_articles_per_feed = 150
|
max_articles_per_feed = 150
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
encoding = 'cp1250'
|
encoding = 'utf8'
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
publication_type = 'newspaper'
|
publication_type = 'newspaper'
|
||||||
masthead_url = 'http://www.vijesti.me/img/logo.gif'
|
extra_css = """
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)}
|
||||||
|
@font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
|
||||||
|
body{font-family: Georgia,"Times New Roman",Times,serif1,serif}
|
||||||
|
.articledescription,.article,.chapter{font-family: sans1, sans-serif}
|
||||||
|
"""
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
@ -34,11 +38,11 @@ class Vijesti(BasicNewsRecipe):
|
|||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
keep_only_tags = [dict(name='div', attrs={'id':'mainnews'})]
|
keep_only_tags = [dict(name='div', attrs={'id':['article_intro_text','article_text']})]
|
||||||
|
|
||||||
remove_tags = [dict(name=['object','link','embed','form'])]
|
remove_tags = [dict(name=['object','link','embed','form'])]
|
||||||
|
|
||||||
feeds = [(u'Sve vijesti', u'http://www.vijesti.me/rss.php' )]
|
feeds = [(u'Sve vijesti', u'http://www.vijesti.me/rss/' )]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
return self.adeify_images(soup)
|
return self.adeify_images(soup)
|
||||||
|
@ -21,6 +21,7 @@ from calibre.devices.usbms.driver import USBMS
|
|||||||
class EB600(USBMS):
|
class EB600(USBMS):
|
||||||
|
|
||||||
name = 'Netronix EB600 Device Interface'
|
name = 'Netronix EB600 Device Interface'
|
||||||
|
gui_name = 'Netronix EB600'
|
||||||
description = _('Communicate with the EB600 eBook reader.')
|
description = _('Communicate with the EB600 eBook reader.')
|
||||||
author = 'Kovid Goyal'
|
author = 'Kovid Goyal'
|
||||||
supported_platforms = ['windows', 'osx', 'linux']
|
supported_platforms = ['windows', 'osx', 'linux']
|
||||||
|
@ -38,13 +38,16 @@ class LITInput(InputFormatPlugin):
|
|||||||
if len(body) == 1 and body[0].tag == XHTML('pre'):
|
if len(body) == 1 and body[0].tag == XHTML('pre'):
|
||||||
pre = body[0]
|
pre = body[0]
|
||||||
from calibre.ebooks.txt.processor import convert_basic, preserve_spaces, \
|
from calibre.ebooks.txt.processor import convert_basic, preserve_spaces, \
|
||||||
separate_paragraphs_single_line
|
separate_paragraphs_single_line
|
||||||
|
from calibre.ebooks.chardet import xml_to_unicode
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
import copy
|
import copy
|
||||||
html = separate_paragraphs_single_line(pre.text)
|
html = separate_paragraphs_single_line(pre.text)
|
||||||
html = preserve_spaces(html)
|
html = preserve_spaces(html)
|
||||||
html = convert_basic(html).replace('<html>',
|
html = convert_basic(html).replace('<html>',
|
||||||
'<html xmlns="%s">'%XHTML_NS)
|
'<html xmlns="%s">'%XHTML_NS)
|
||||||
|
html = xml_to_unicode(html, strip_encoding_pats=True,
|
||||||
|
resolve_entities=True)[0]
|
||||||
root = etree.fromstring(html)
|
root = etree.fromstring(html)
|
||||||
body = XPath('//h:body')(root)
|
body = XPath('//h:body')(root)
|
||||||
pre.tag = XHTML('div')
|
pre.tag = XHTML('div')
|
||||||
|
@ -488,7 +488,7 @@ class MobiReader(object):
|
|||||||
|
|
||||||
|
|
||||||
def remove_random_bytes(self, html):
|
def remove_random_bytes(self, html):
|
||||||
return re.sub('\x14|\x15|\x19|\x1c|\x1d|\xef|\x12|\x13|\xec|\x08',
|
return re.sub('\x14|\x15|\x19|\x1c|\x1d|\xef|\x12|\x13|\xec|\x08|\x01|\x02|\x03|\x04|\x05|\x06|\x07',
|
||||||
'', html)
|
'', html)
|
||||||
|
|
||||||
def ensure_unit(self, raw, unit='px'):
|
def ensure_unit(self, raw, unit='px'):
|
||||||
|
@ -687,7 +687,7 @@ class DeviceMixin(object): # {{{
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if not self.device_error_dialog.isVisible():
|
if not self.device_error_dialog.isVisible():
|
||||||
self.device_error_dialog.setDetailedText(job.details)
|
self.device_error_dialog.set_details(job.details)
|
||||||
self.device_error_dialog.show()
|
self.device_error_dialog.show()
|
||||||
|
|
||||||
# Device connected {{{
|
# Device connected {{{
|
||||||
|
@ -74,21 +74,27 @@ class DBCheck(QDialog):
|
|||||||
self.reject()
|
self.reject()
|
||||||
|
|
||||||
def start_load(self):
|
def start_load(self):
|
||||||
self.conn.close()
|
try:
|
||||||
self.pb.setMaximum(self.count)
|
self.conn.close()
|
||||||
self.pb.setValue(0)
|
self.pb.setMaximum(self.count)
|
||||||
self.msg.setText(_('Loading database from SQL'))
|
self.pb.setValue(0)
|
||||||
self.db.conn.close()
|
self.msg.setText(_('Loading database from SQL'))
|
||||||
self.ndbpath = PersistentTemporaryFile('.db')
|
self.db.conn.close()
|
||||||
self.ndbpath.close()
|
self.ndbpath = PersistentTemporaryFile('.db')
|
||||||
self.ndbpath = self.ndbpath.name
|
self.ndbpath.close()
|
||||||
t = DBThread(self.ndbpath, False)
|
self.ndbpath = self.ndbpath.name
|
||||||
t.connect()
|
t = DBThread(self.ndbpath, False)
|
||||||
self.conn = t.conn
|
t.connect()
|
||||||
self.conn.execute('create temporary table temp_sequence(id INTEGER PRIMARY KEY AUTOINCREMENT)')
|
self.conn = t.conn
|
||||||
self.conn.commit()
|
self.conn.execute('create temporary table temp_sequence(id INTEGER PRIMARY KEY AUTOINCREMENT)')
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
QTimer.singleShot(0, self.do_one_load)
|
||||||
|
except Exception, e:
|
||||||
|
import traceback
|
||||||
|
self.error = (as_unicode(e), traceback.format_exc())
|
||||||
|
self.reject()
|
||||||
|
|
||||||
QTimer.singleShot(0, self.do_one_load)
|
|
||||||
|
|
||||||
def do_one_load(self):
|
def do_one_load(self):
|
||||||
if self.rejected:
|
if self.rejected:
|
||||||
|
@ -45,14 +45,12 @@ class MessageBox(QDialog, Ui_Dialog):
|
|||||||
self.ctc_button.clicked.connect(self.copy_to_clipboard)
|
self.ctc_button.clicked.connect(self.copy_to_clipboard)
|
||||||
|
|
||||||
|
|
||||||
if det_msg:
|
self.show_det_msg = _('Show &details')
|
||||||
self.show_det_msg = _('Show &details')
|
self.hide_det_msg = _('Hide &details')
|
||||||
self.hide_det_msg = _('Hide &details')
|
self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
|
||||||
self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
|
self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
|
||||||
self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
|
self.det_msg_toggle.setToolTip(
|
||||||
self.det_msg_toggle.setToolTip(
|
_('Show detailed information about this error'))
|
||||||
_('Show detailed information about this error'))
|
|
||||||
|
|
||||||
|
|
||||||
self.copy_action = QAction(self)
|
self.copy_action = QAction(self)
|
||||||
self.addAction(self.copy_action)
|
self.addAction(self.copy_action)
|
||||||
@ -66,10 +64,14 @@ class MessageBox(QDialog, Ui_Dialog):
|
|||||||
else:
|
else:
|
||||||
self.bb.button(self.bb.Ok).setDefault(True)
|
self.bb.button(self.bb.Ok).setDefault(True)
|
||||||
|
|
||||||
|
if not det_msg:
|
||||||
|
self.det_msg_toggle.setVisible(False)
|
||||||
|
|
||||||
self.do_resize()
|
self.do_resize()
|
||||||
|
|
||||||
|
|
||||||
def toggle_det_msg(self, *args):
|
def toggle_det_msg(self, *args):
|
||||||
vis = self.det_msg.isVisible()
|
vis = unicode(self.det_msg_toggle.text()) == self.hide_det_msg
|
||||||
self.det_msg_toggle.setText(self.show_det_msg if vis else
|
self.det_msg_toggle.setText(self.show_det_msg if vis else
|
||||||
self.hide_det_msg)
|
self.hide_det_msg)
|
||||||
self.det_msg.setVisible(not vis)
|
self.det_msg.setVisible(not vis)
|
||||||
@ -100,6 +102,15 @@ class MessageBox(QDialog, Ui_Dialog):
|
|||||||
self.bb.button(self.bb.Ok).setFocus(Qt.OtherFocusReason)
|
self.bb.button(self.bb.Ok).setFocus(Qt.OtherFocusReason)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def set_details(self, msg):
|
||||||
|
if not msg:
|
||||||
|
msg = ''
|
||||||
|
self.det_msg.setPlainText(msg)
|
||||||
|
self.det_msg_toggle.setText(self.show_det_msg)
|
||||||
|
self.det_msg_toggle.setVisible(bool(msg))
|
||||||
|
self.det_msg.setVisible(False)
|
||||||
|
self.do_resize()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = QApplication([])
|
app = QApplication([])
|
||||||
from calibre.gui2 import question_dialog
|
from calibre.gui2 import question_dialog
|
||||||
|
@ -21,7 +21,7 @@ class DBRestore(QDialog):
|
|||||||
self.l = QVBoxLayout()
|
self.l = QVBoxLayout()
|
||||||
self.setLayout(self.l)
|
self.setLayout(self.l)
|
||||||
self.l1 = QLabel('<b>'+_('Restoring database from backups, do not'
|
self.l1 = QLabel('<b>'+_('Restoring database from backups, do not'
|
||||||
' interrupt, this will happen in two stages')+'...')
|
' interrupt, this will happen in three stages')+'...')
|
||||||
self.setWindowTitle(_('Restoring database'))
|
self.setWindowTitle(_('Restoring database'))
|
||||||
self.l.addWidget(self.l1)
|
self.l.addWidget(self.l1)
|
||||||
self.pb = QProgressBar(self)
|
self.pb = QProgressBar(self)
|
||||||
@ -104,7 +104,7 @@ def restore_database(db, parent=None):
|
|||||||
else:
|
else:
|
||||||
if r.errors_occurred:
|
if r.errors_occurred:
|
||||||
warning_dialog(parent, _('Success'),
|
warning_dialog(parent, _('Success'),
|
||||||
_('Restoring the database succeeded with some warnings',
|
_('Restoring the database succeeded with some warnings'
|
||||||
' click Show details to see the details.'),
|
' click Show details to see the details.'),
|
||||||
det_msg=r.report, show=True)
|
det_msg=r.report, show=True)
|
||||||
else:
|
else:
|
||||||
|
@ -275,7 +275,7 @@ def generate_catalog(parent, dbspec, ids, device_manager, db):
|
|||||||
|
|
||||||
if device_manager.is_device_connected:
|
if device_manager.is_device_connected:
|
||||||
device = device_manager.device
|
device = device_manager.device
|
||||||
connected_device['name'] = device.gui_name
|
connected_device['name'] = device.get_gui_name()
|
||||||
try:
|
try:
|
||||||
storage = []
|
storage = []
|
||||||
if device._main_prefix:
|
if device._main_prefix:
|
||||||
|
@ -30,8 +30,8 @@ CHECKS = [('invalid_titles', _('Invalid titles'), True, False),
|
|||||||
('missing_formats', _('Missing book formats'), False, False),
|
('missing_formats', _('Missing book formats'), False, False),
|
||||||
('extra_formats', _('Extra book formats'), True, False),
|
('extra_formats', _('Extra book formats'), True, False),
|
||||||
('extra_files', _('Unknown files in books'), True, False),
|
('extra_files', _('Unknown files in books'), True, False),
|
||||||
('missing_covers', _('Missing covers in books'), False, True),
|
('missing_covers', _('Missing covers files'), False, True),
|
||||||
('extra_covers', _('Extra covers in books'), True, True),
|
('extra_covers', _('Cover files not in database'), True, True),
|
||||||
('failed_folders', _('Folders raising exception'), False, False)
|
('failed_folders', _('Folders raising exception'), False, False)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1549,7 +1549,9 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
elif mi.cover is not None:
|
elif mi.cover is not None:
|
||||||
if os.access(mi.cover, os.R_OK):
|
if os.access(mi.cover, os.R_OK):
|
||||||
with lopen(mi.cover, 'rb') as f:
|
with lopen(mi.cover, 'rb') as f:
|
||||||
doit(self.set_cover, id, f, commit=False)
|
raw = f.read()
|
||||||
|
if raw:
|
||||||
|
doit(self.set_cover, id, raw, commit=False)
|
||||||
if mi.tags:
|
if mi.tags:
|
||||||
doit(self.set_tags, id, mi.tags, notify=False, commit=False)
|
doit(self.set_tags, id, mi.tags, notify=False, commit=False)
|
||||||
if mi.comments:
|
if mi.comments:
|
||||||
|
@ -141,7 +141,7 @@ class Restore(Thread):
|
|||||||
sizes = [os.path.getsize(os.path.join(dirpath, x)) for x in formats]
|
sizes = [os.path.getsize(os.path.join(dirpath, x)) for x in formats]
|
||||||
names = [os.path.splitext(x)[0] for x in formats]
|
names = [os.path.splitext(x)[0] for x in formats]
|
||||||
opf = os.path.join(dirpath, 'metadata.opf')
|
opf = os.path.join(dirpath, 'metadata.opf')
|
||||||
mi = OPF(opf).to_book_metadata()
|
mi = OPF(opf, basedir=dirpath).to_book_metadata()
|
||||||
timestamp = os.path.getmtime(opf)
|
timestamp = os.path.getmtime(opf)
|
||||||
path = os.path.relpath(dirpath, self.src_library_path).replace(os.sep,
|
path = os.path.relpath(dirpath, self.src_library_path).replace(os.sep,
|
||||||
'/')
|
'/')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user