mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
GwR resolve conflicts after merge with KG latest
This commit is contained in:
commit
03a83560a4
BIN
icons/book.icns
Normal file
BIN
icons/book.icns
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
resources/images/news/michellemalkin_icon.png
Normal file
BIN
resources/images/news/michellemalkin_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 419 B |
49
resources/recipes/michellemalkin.recipe
Normal file
49
resources/recipes/michellemalkin.recipe
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010, Walt Anthony <workshop.northpole at gmail.com>'
|
||||||
|
'''
|
||||||
|
www.michellemalkin.com
|
||||||
|
'''
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class MichelleMalkin(BasicNewsRecipe):
|
||||||
|
title = u'Michelle Malkin'
|
||||||
|
description = "Michelle Malkin's take on events, a mother, wife, blogger, conservative syndicated columnist, author, and Fox News Channel contributor."
|
||||||
|
__author__ = 'Walt Anthony'
|
||||||
|
publisher = 'Michelle Malkin LLC'
|
||||||
|
category = 'news, politics, USA'
|
||||||
|
oldest_article = 7 #days
|
||||||
|
max_articles_per_feed = 50
|
||||||
|
summary_length = 150
|
||||||
|
language = 'en'
|
||||||
|
|
||||||
|
remove_javascript = True
|
||||||
|
no_stylesheets = True
|
||||||
|
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : category
|
||||||
|
, 'publisher' : publisher
|
||||||
|
, 'language' : language
|
||||||
|
, 'linearize_tables' : True
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'class':'article'})
|
||||||
|
]
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(name=['iframe', 'embed', 'object']),
|
||||||
|
dict(name='div', attrs={'id':['comments', 'commentForm']}),
|
||||||
|
dict(name='div', attrs={'class':['postCategories', 'comments', 'blogInfo', 'postInfo']})
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
feeds = [(u'http://feeds.feedburner.com/michellemalkin/posts')]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def print_version(self, url):
|
||||||
|
return url + '?print=1'
|
22
resources/recipes/open_left.recipe
Normal file
22
resources/recipes/open_left.recipe
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class OpenLeft(BasicNewsRecipe):
|
||||||
|
# Information about the recipe
|
||||||
|
|
||||||
|
title = 'Open Left'
|
||||||
|
description = 'Progressive American commentary on current events'
|
||||||
|
category = 'news, commentary'
|
||||||
|
language = 'en'
|
||||||
|
__author__ = 'Xanthan Gum'
|
||||||
|
|
||||||
|
# Fetch no article older than seven days
|
||||||
|
|
||||||
|
oldest_article = 7
|
||||||
|
|
||||||
|
# Fetch no more than 100 articles
|
||||||
|
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
|
||||||
|
# Fetch the articles from the RSS feed
|
||||||
|
|
||||||
|
feeds = [(u'Articles', u'http://www.openleft.com/rss/rss2.xml')]
|
@ -266,6 +266,7 @@ class Py2App(object):
|
|||||||
def get_local_dependencies(self, path_to_lib):
|
def get_local_dependencies(self, path_to_lib):
|
||||||
for x in self.get_dependencies(path_to_lib):
|
for x in self.get_dependencies(path_to_lib):
|
||||||
for y in (SW+'/lib/', '/usr/local/lib/', SW+'/qt/lib/',
|
for y in (SW+'/lib/', '/usr/local/lib/', SW+'/qt/lib/',
|
||||||
|
'/opt/local/lib/',
|
||||||
'/Library/Frameworks/Python.framework/', SW+'/freetype/lib/'):
|
'/Library/Frameworks/Python.framework/', SW+'/freetype/lib/'):
|
||||||
if x.startswith(y):
|
if x.startswith(y):
|
||||||
if y == '/Library/Frameworks/Python.framework/':
|
if y == '/Library/Frameworks/Python.framework/':
|
||||||
@ -338,8 +339,8 @@ class Py2App(object):
|
|||||||
c = join(self.build_dir, 'Contents')
|
c = join(self.build_dir, 'Contents')
|
||||||
for x in ('Frameworks', 'MacOS', 'Resources'):
|
for x in ('Frameworks', 'MacOS', 'Resources'):
|
||||||
os.makedirs(join(c, x))
|
os.makedirs(join(c, x))
|
||||||
x = 'library.icns'
|
for x in ('library.icns', 'book.icns'):
|
||||||
shutil.copyfile(join('icons', x), join(self.resources_dir, x))
|
shutil.copyfile(join('icons', x), join(self.resources_dir, x))
|
||||||
|
|
||||||
@flush
|
@flush
|
||||||
def add_calibre_plugins(self):
|
def add_calibre_plugins(self):
|
||||||
@ -355,8 +356,13 @@ class Py2App(object):
|
|||||||
|
|
||||||
@flush
|
@flush
|
||||||
def create_plist(self):
|
def create_plist(self):
|
||||||
|
from calibre.ebooks import BOOK_EXTENSIONS
|
||||||
env = dict(**ENV)
|
env = dict(**ENV)
|
||||||
env['CALIBRE_LAUNCHED_FROM_BUNDLE']='1';
|
env['CALIBRE_LAUNCHED_FROM_BUNDLE']='1';
|
||||||
|
docs = [{'CFBundleTypeName':'E-book',
|
||||||
|
'CFBundleTypeExtensions':list(BOOK_EXTENSIONS),
|
||||||
|
'CFBundleTypeRole':'Viewer',
|
||||||
|
}]
|
||||||
|
|
||||||
pl = dict(
|
pl = dict(
|
||||||
CFBundleDevelopmentRegion='English',
|
CFBundleDevelopmentRegion='English',
|
||||||
@ -367,10 +373,11 @@ class Py2App(object):
|
|||||||
CFBundlePackageType='APPL',
|
CFBundlePackageType='APPL',
|
||||||
CFBundleSignature='????',
|
CFBundleSignature='????',
|
||||||
CFBundleExecutable='calibre',
|
CFBundleExecutable='calibre',
|
||||||
|
CFBundleDocumentTypes=docs,
|
||||||
LSMinimumSystemVersion='10.4.2',
|
LSMinimumSystemVersion='10.4.2',
|
||||||
LSRequiresNativeExecution=True,
|
LSRequiresNativeExecution=True,
|
||||||
NSAppleScriptEnabled=False,
|
NSAppleScriptEnabled=False,
|
||||||
NSHumanReadableCopyright='Copyright 2008, Kovid Goyal',
|
NSHumanReadableCopyright='Copyright 2010, Kovid Goyal',
|
||||||
CFBundleGetInfoString=('calibre, an E-book management '
|
CFBundleGetInfoString=('calibre, an E-book management '
|
||||||
'application. Visit http://calibre-ebook.com for details.'),
|
'application. Visit http://calibre-ebook.com for details.'),
|
||||||
CFBundleIconFile='library.icns',
|
CFBundleIconFile='library.icns',
|
||||||
@ -594,6 +601,7 @@ class Py2App(object):
|
|||||||
if x == 'Info.plist':
|
if x == 'Info.plist':
|
||||||
plist = plistlib.readPlist(join(self.contents_dir, x))
|
plist = plistlib.readPlist(join(self.contents_dir, x))
|
||||||
plist['LSUIElement'] = '1'
|
plist['LSUIElement'] = '1'
|
||||||
|
plist.pop('CFBundleDocumentTypes')
|
||||||
plistlib.writePlist(plist, join(cc_dir, x))
|
plistlib.writePlist(plist, join(cc_dir, x))
|
||||||
else:
|
else:
|
||||||
os.symlink(join('../..', x),
|
os.symlink(join('../..', x),
|
||||||
|
@ -274,7 +274,7 @@ class BookList(_BookList):
|
|||||||
node.setAttribute(attr, attrs[attr])
|
node.setAttribute(attr, attrs[attr])
|
||||||
try:
|
try:
|
||||||
w, h, data = mi.thumbnail
|
w, h, data = mi.thumbnail
|
||||||
except TypeError:
|
except:
|
||||||
w, h, data = None, None, None
|
w, h, data = None, None, None
|
||||||
|
|
||||||
if data:
|
if data:
|
||||||
|
@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
Based on ideas from comiclrf created by FangornUK.
|
Based on ideas from comiclrf created by FangornUK.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os, shutil, traceback, textwrap, time
|
import os, shutil, traceback, textwrap, time, codecs
|
||||||
from ctypes import byref
|
from ctypes import byref
|
||||||
from Queue import Empty
|
from Queue import Empty
|
||||||
|
|
||||||
@ -338,8 +338,9 @@ class ComicInput(InputFormatPlugin):
|
|||||||
if not os.path.exists('comics.txt'):
|
if not os.path.exists('comics.txt'):
|
||||||
raise ValueError('%s is not a valid comic collection'
|
raise ValueError('%s is not a valid comic collection'
|
||||||
%stream.name)
|
%stream.name)
|
||||||
for line in open('comics.txt',
|
raw = open('comics.txt', 'rb').read().decode('utf-8')
|
||||||
'rb').read().decode('utf-8').splitlines():
|
raw.lstrip(unicode(codecs.BOM_UTF8, "utf8" ))
|
||||||
|
for line in raw.splitlines():
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line:
|
if not line:
|
||||||
continue
|
continue
|
||||||
|
@ -269,7 +269,7 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
bad = []
|
bad = []
|
||||||
for x in XPath('//h:img')(body):
|
for x in XPath('//h:img')(body):
|
||||||
src = x.get('src', '').strip()
|
src = x.get('src', '').strip()
|
||||||
if src in ('', '#'):
|
if src in ('', '#') or src.startswith('http:'):
|
||||||
bad.append(x)
|
bad.append(x)
|
||||||
for img in bad:
|
for img in bad:
|
||||||
img.getparent().remove(img)
|
img.getparent().remove(img)
|
||||||
|
@ -573,6 +573,8 @@ class MobiReader(object):
|
|||||||
attrib[attr] = "%dpx"%int(nval)
|
attrib[attr] = "%dpx"%int(nval)
|
||||||
except:
|
except:
|
||||||
del attrib[attr]
|
del attrib[attr]
|
||||||
|
elif val.lower().endswith('%'):
|
||||||
|
del attrib[attr]
|
||||||
elif tag.tag == 'pre':
|
elif tag.tag == 'pre':
|
||||||
if not tag.text:
|
if not tag.text:
|
||||||
tag.tag = 'div'
|
tag.tag = 'div'
|
||||||
|
@ -3,7 +3,8 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
""" The GUI """
|
""" The GUI """
|
||||||
import os
|
import os
|
||||||
from PyQt4.QtCore import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, QSize, \
|
from PyQt4.QtCore import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, QSize, \
|
||||||
QByteArray, QTranslator, QCoreApplication, QThread
|
QByteArray, QTranslator, QCoreApplication, QThread, \
|
||||||
|
QEvent
|
||||||
from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \
|
from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \
|
||||||
QIcon, QTableView, QApplication, QDialog, QPushButton
|
QIcon, QTableView, QApplication, QDialog, QPushButton
|
||||||
|
|
||||||
@ -524,6 +525,7 @@ class Application(QApplication):
|
|||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
qargs = [i.encode('utf-8') if isinstance(i, unicode) else i for i in args]
|
qargs = [i.encode('utf-8') if isinstance(i, unicode) else i for i in args]
|
||||||
QApplication.__init__(self, qargs)
|
QApplication.__init__(self, qargs)
|
||||||
|
self.file_event_hook = None
|
||||||
global gui_thread, qt_app
|
global gui_thread, qt_app
|
||||||
gui_thread = QThread.currentThread()
|
gui_thread = QThread.currentThread()
|
||||||
self._translator = None
|
self._translator = None
|
||||||
@ -549,6 +551,15 @@ class Application(QApplication):
|
|||||||
if set_qt_translator(self._translator):
|
if set_qt_translator(self._translator):
|
||||||
self.installTranslator(self._translator)
|
self.installTranslator(self._translator)
|
||||||
|
|
||||||
|
def event(self, e):
|
||||||
|
if callable(self.file_event_hook) and e.type() == QEvent.FileOpen:
|
||||||
|
path = unicode(e.file())
|
||||||
|
if os.access(path, os.R_OK):
|
||||||
|
self.file_event_hook(path)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return QApplication.event(self, e)
|
||||||
|
|
||||||
_store_app = None
|
_store_app = None
|
||||||
|
|
||||||
def is_ok_to_use_qt():
|
def is_ok_to_use_qt():
|
||||||
|
@ -12,7 +12,7 @@ from calibre.gui2.dialogs.progress import ProgressDialog
|
|||||||
from calibre.gui2 import question_dialog, error_dialog, info_dialog
|
from calibre.gui2 import question_dialog, error_dialog, info_dialog
|
||||||
from calibre.ebooks.metadata.opf2 import OPF
|
from calibre.ebooks.metadata.opf2 import OPF
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
from calibre.constants import preferred_encoding
|
from calibre.constants import preferred_encoding, filesystem_encoding
|
||||||
|
|
||||||
class DuplicatesAdder(QThread):
|
class DuplicatesAdder(QThread):
|
||||||
|
|
||||||
@ -46,6 +46,8 @@ class RecursiveFind(QThread):
|
|||||||
def run(self):
|
def run(self):
|
||||||
root = os.path.abspath(self.path)
|
root = os.path.abspath(self.path)
|
||||||
self.books = []
|
self.books = []
|
||||||
|
if isinstance(root, unicode):
|
||||||
|
root = root.encode(filesystem_encoding)
|
||||||
try:
|
try:
|
||||||
for dirpath in os.walk(root):
|
for dirpath in os.walk(root):
|
||||||
if self.canceled:
|
if self.canceled:
|
||||||
@ -55,6 +57,8 @@ class RecursiveFind(QThread):
|
|||||||
self.books += list(self.db.find_books_in_directory(dirpath[0],
|
self.books += list(self.db.find_books_in_directory(dirpath[0],
|
||||||
self.single_book_per_directory))
|
self.single_book_per_directory))
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
try:
|
try:
|
||||||
msg = unicode(err)
|
msg = unicode(err)
|
||||||
except:
|
except:
|
||||||
|
@ -20,10 +20,8 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
|
|||||||
self.db = db
|
self.db = db
|
||||||
self.ids = [ db.id(r) for r in rows]
|
self.ids = [ db.id(r) for r in rows]
|
||||||
self.write_series = False
|
self.write_series = False
|
||||||
self.write_rating = False
|
|
||||||
self.changed = False
|
self.changed = False
|
||||||
QObject.connect(self.button_box, SIGNAL("accepted()"), self.sync)
|
QObject.connect(self.button_box, SIGNAL("accepted()"), self.sync)
|
||||||
QObject.connect(self.rating, SIGNAL('valueChanged(int)'), self.rating_changed)
|
|
||||||
|
|
||||||
self.tags.update_tags_cache(self.db.all_tags())
|
self.tags.update_tags_cache(self.db.all_tags())
|
||||||
self.remove_tags.update_tags_cache(self.db.all_tags())
|
self.remove_tags.update_tags_cache(self.db.all_tags())
|
||||||
@ -99,7 +97,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
|
|||||||
aus = unicode(self.author_sort.text())
|
aus = unicode(self.author_sort.text())
|
||||||
if aus and self.author_sort.isEnabled():
|
if aus and self.author_sort.isEnabled():
|
||||||
self.db.set_author_sort(id, aus, notify=False)
|
self.db.set_author_sort(id, aus, notify=False)
|
||||||
if self.write_rating:
|
if self.rating.value() != -1:
|
||||||
self.db.set_rating(id, 2*self.rating.value(), notify=False)
|
self.db.set_rating(id, 2*self.rating.value(), notify=False)
|
||||||
pub = unicode(self.publisher.text())
|
pub = unicode(self.publisher.text())
|
||||||
if pub:
|
if pub:
|
||||||
@ -134,5 +132,3 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
|
|||||||
def series_changed(self):
|
def series_changed(self):
|
||||||
self.write_series = True
|
self.write_series = True
|
||||||
|
|
||||||
def rating_changed(self):
|
|
||||||
self.write_rating = True
|
|
||||||
|
@ -96,12 +96,21 @@
|
|||||||
<property name="buttonSymbols">
|
<property name="buttonSymbols">
|
||||||
<enum>QAbstractSpinBox::PlusMinus</enum>
|
<enum>QAbstractSpinBox::PlusMinus</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="specialValueText">
|
||||||
|
<string>No change</string>
|
||||||
|
</property>
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> stars</string>
|
<string> stars</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="4" column="0">
|
||||||
|
@ -2,6 +2,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
import sys, os, time, socket, traceback
|
import sys, os, time, socket, traceback
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
from PyQt4.Qt import QCoreApplication, QIcon, QMessageBox
|
from PyQt4.Qt import QCoreApplication, QIcon, QMessageBox
|
||||||
|
|
||||||
@ -52,10 +53,12 @@ def run_gui(opts, args, actions, listener, app):
|
|||||||
wizard().exec_()
|
wizard().exec_()
|
||||||
dynamic.set('welcome_wizard_was_run', True)
|
dynamic.set('welcome_wizard_was_run', True)
|
||||||
main = Main(listener, opts, actions)
|
main = Main(listener, opts, actions)
|
||||||
|
add_filesystem_book = partial(main.add_filesystem_book, allow_device=False)
|
||||||
sys.excepthook = main.unhandled_exception
|
sys.excepthook = main.unhandled_exception
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
args[1] = os.path.abspath(args[1])
|
args[1] = os.path.abspath(args[1])
|
||||||
main.add_filesystem_book(args[1])
|
add_filesystem_book(args[1])
|
||||||
|
app.file_event_hook = add_filesystem_book
|
||||||
ret = app.exec_()
|
ret = app.exec_()
|
||||||
if getattr(main, 'run_wizard_b4_shutdown', False):
|
if getattr(main, 'run_wizard_b4_shutdown', False):
|
||||||
from calibre.gui2.wizard import wizard
|
from calibre.gui2.wizard import wizard
|
||||||
|
@ -987,10 +987,10 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
|||||||
self.cover_cache.refresh([cid])
|
self.cover_cache.refresh([cid])
|
||||||
self.library_view.model().current_changed(current_idx, current_idx)
|
self.library_view.model().current_changed(current_idx, current_idx)
|
||||||
|
|
||||||
def add_filesystem_book(self, path):
|
def add_filesystem_book(self, path, allow_device=True):
|
||||||
if os.access(path, os.R_OK):
|
if os.access(path, os.R_OK):
|
||||||
books = [os.path.abspath(path)]
|
books = [os.path.abspath(path)]
|
||||||
to_device = self.stack.currentIndex() != 0
|
to_device = allow_device and self.stack.currentIndex() != 0
|
||||||
self._add_books(books, to_device)
|
self._add_books(books, to_device)
|
||||||
if to_device:
|
if to_device:
|
||||||
self.status_bar.showMessage(\
|
self.status_bar.showMessage(\
|
||||||
@ -1048,6 +1048,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
|||||||
if self._adder.critical:
|
if self._adder.critical:
|
||||||
det_msg = []
|
det_msg = []
|
||||||
for name, log in self._adder.critical.items():
|
for name, log in self._adder.critical.items():
|
||||||
|
if isinstance(name, str):
|
||||||
|
name = name.decode(filesystem_encoding, 'replace')
|
||||||
det_msg.append(name+'\n'+log)
|
det_msg.append(name+'\n'+log)
|
||||||
warning_dialog(self, _('Failed to read metadata'),
|
warning_dialog(self, _('Failed to read metadata'),
|
||||||
_('Failed to read metadata from the following')+':',
|
_('Failed to read metadata from the following')+':',
|
||||||
|
@ -514,7 +514,7 @@ class DocumentView(QWebView):
|
|||||||
mt = guess_type(path)[0]
|
mt = guess_type(path)[0]
|
||||||
html = open(path, 'rb').read().decode(path.encoding, 'replace')
|
html = open(path, 'rb').read().decode(path.encoding, 'replace')
|
||||||
html = EntityDeclarationProcessor(html).processed_html
|
html = EntityDeclarationProcessor(html).processed_html
|
||||||
has_svg = re.search(r'<[:a-z]*svg', html) is not None
|
has_svg = re.search(r'<[:a-zA-Z]*svg', html) is not None
|
||||||
|
|
||||||
if 'xhtml' in mt:
|
if 'xhtml' in mt:
|
||||||
html = self.self_closing_pat.sub(self.self_closing_sub, html)
|
html = self.self_closing_pat.sub(self.self_closing_sub, html)
|
||||||
|
@ -4,7 +4,7 @@ from collections import namedtuple
|
|||||||
from datetime import date
|
from datetime import date
|
||||||
from xml.sax.saxutils import escape
|
from xml.sax.saxutils import escape
|
||||||
|
|
||||||
from calibre import filesystem_encoding, prints
|
from calibre import filesystem_encoding, prints, strftime
|
||||||
from calibre.customize import CatalogPlugin
|
from calibre.customize import CatalogPlugin
|
||||||
from calibre.customize.conversion import OptionRecommendation, DummyReporter
|
from calibre.customize.conversion import OptionRecommendation, DummyReporter
|
||||||
from calibre.ebooks.BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag, NavigableString
|
from calibre.ebooks.BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag, NavigableString
|
||||||
@ -97,7 +97,7 @@ class CSV_XML(CatalogPlugin):
|
|||||||
item = ', '.join(item)
|
item = ', '.join(item)
|
||||||
elif field == 'isbn':
|
elif field == 'isbn':
|
||||||
# Could be 9, 10 or 13 digits
|
# Could be 9, 10 or 13 digits
|
||||||
field = '%s' % re.sub('[\D]','',field)
|
field = u'%s' % re.sub(r'[\D]','',field)
|
||||||
|
|
||||||
if x < len(fields) - 1:
|
if x < len(fields) - 1:
|
||||||
if item is not None:
|
if item is not None:
|
||||||
@ -488,9 +488,6 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
current_step = 0.0
|
current_step = 0.0
|
||||||
total_steps = 14.0
|
total_steps = 14.0
|
||||||
|
|
||||||
# Used to xlate pubdate to friendly format
|
|
||||||
MONTHS = ['','January', 'February','March','April','May','June',
|
|
||||||
'July','August','September','October','November','December']
|
|
||||||
THUMB_WIDTH = 75
|
THUMB_WIDTH = 75
|
||||||
THUMB_HEIGHT = 100
|
THUMB_HEIGHT = 100
|
||||||
|
|
||||||
@ -878,9 +875,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
this_title['publisher'] = re.sub('&', '&', record['publisher'])
|
this_title['publisher'] = re.sub('&', '&', record['publisher'])
|
||||||
|
|
||||||
this_title['rating'] = record['rating'] if record['rating'] else 0
|
this_title['rating'] = record['rating'] if record['rating'] else 0
|
||||||
# <pubdate>2009-11-05 09:29:37</pubdate>
|
this_title['date'] = strftime(u'%b %Y', record['pubdate'].timetuple())
|
||||||
date_strings = str(record['pubdate']).split("-")
|
|
||||||
this_title['date'] = '%s %s' % (self.MONTHS[int(date_strings[1])], date_strings[0])
|
|
||||||
this_title['timestamp'] = record['timestamp']
|
this_title['timestamp'] = record['timestamp']
|
||||||
if record['comments']:
|
if record['comments']:
|
||||||
this_title['description'] = re.sub('&', '&', record['comments'])
|
this_title['description'] = re.sub('&', '&', record['comments'])
|
||||||
@ -1332,11 +1327,11 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
|
|
||||||
def add_books_to_HTML(this_months_list, dtc):
|
def add_books_to_HTML(this_months_list, dtc):
|
||||||
if len(this_months_list):
|
if len(this_months_list):
|
||||||
|
date_string = strftime(u'%b %Y', current_date.timetuple())
|
||||||
this_months_list = sorted(this_months_list,
|
this_months_list = sorted(this_months_list,
|
||||||
key=lambda x:(x['title_sort'], x['title_sort']))
|
key=lambda x:(x['title_sort'], x['title_sort']))
|
||||||
this_months_list = sorted(this_months_list,
|
this_months_list = sorted(this_months_list,
|
||||||
key=lambda x:(x['author_sort'], x['author_sort']))
|
key=lambda x:(x['author_sort'], x['author_sort']))
|
||||||
|
|
||||||
# Create a new month anchor
|
# Create a new month anchor
|
||||||
pIndexTag = Tag(soup, "p")
|
pIndexTag = Tag(soup, "p")
|
||||||
pIndexTag['class'] = "date_index"
|
pIndexTag['class'] = "date_index"
|
||||||
@ -1435,7 +1430,6 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
dtc = 0
|
dtc = 0
|
||||||
|
|
||||||
current_date = date.fromordinal(1)
|
current_date = date.fromordinal(1)
|
||||||
current_author = None
|
|
||||||
|
|
||||||
# Loop through books by date
|
# Loop through books by date
|
||||||
this_months_list = []
|
this_months_list = []
|
||||||
@ -2066,7 +2060,6 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
# add description_preview_count titles
|
# add description_preview_count titles
|
||||||
# self.authors[0]:friendly [1]:author_sort [2]:book_count
|
# self.authors[0]:friendly [1]:author_sort [2]:book_count
|
||||||
current_titles_list = []
|
current_titles_list = []
|
||||||
current_author_list = []
|
|
||||||
master_month_list = []
|
master_month_list = []
|
||||||
current_date = self.booksByDate[0]['timestamp']
|
current_date = self.booksByDate[0]['timestamp']
|
||||||
|
|
||||||
@ -2088,6 +2081,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
# Add *article* entries for each populated month
|
# Add *article* entries for each populated month
|
||||||
# master_months_list{}: [0]:titles list [1]:date
|
# master_months_list{}: [0]:titles list [1]:date
|
||||||
for books_by_month in master_month_list:
|
for books_by_month in master_month_list:
|
||||||
|
datestr = strftime(u'%b %Y', books_by_month[1].timetuple())
|
||||||
navPointByMonthTag = Tag(soup, 'navPoint')
|
navPointByMonthTag = Tag(soup, 'navPoint')
|
||||||
navPointByMonthTag['class'] = "article"
|
navPointByMonthTag['class'] = "article"
|
||||||
navPointByMonthTag['id'] = "%s-%s-ID" % (books_by_month[1].year,books_by_month[1].month )
|
navPointByMonthTag['id'] = "%s-%s-ID" % (books_by_month[1].year,books_by_month[1].month )
|
||||||
@ -2095,8 +2089,7 @@ class EPUB_MOBI(CatalogPlugin):
|
|||||||
self.playOrder += 1
|
self.playOrder += 1
|
||||||
navLabelTag = Tag(soup, 'navLabel')
|
navLabelTag = Tag(soup, 'navLabel')
|
||||||
textTag = Tag(soup, 'text')
|
textTag = Tag(soup, 'text')
|
||||||
textTag.insert(0, NavigableString("Books added in %s %s" % \
|
textTag.insert(0, NavigableString("Books added in " + datestr))
|
||||||
(self.MONTHS[books_by_month[1].month], books_by_month[1].year)))
|
|
||||||
navLabelTag.insert(0, textTag)
|
navLabelTag.insert(0, textTag)
|
||||||
navPointByMonthTag.insert(0,navLabelTag)
|
navPointByMonthTag.insert(0,navLabelTag)
|
||||||
contentTag = Tag(soup, 'content')
|
contentTag = Tag(soup, 'content')
|
||||||
|
@ -84,6 +84,7 @@ if not _run_once:
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
os.path.abspath = my_abspath
|
os.path.abspath = my_abspath
|
||||||
|
|
||||||
_join = os.path.join
|
_join = os.path.join
|
||||||
def my_join(a, *p):
|
def my_join(a, *p):
|
||||||
encoding=sys.getfilesystemencoding()
|
encoding=sys.getfilesystemencoding()
|
||||||
|
@ -558,8 +558,6 @@ class BasicNewsRecipe(Recipe):
|
|||||||
'--max-recursions', str(self.recursions),
|
'--max-recursions', str(self.recursions),
|
||||||
'--delay', str(self.delay),
|
'--delay', str(self.delay),
|
||||||
]
|
]
|
||||||
if self.encoding is not None:
|
|
||||||
web2disk_cmdline.extend(['--encoding', self.encoding])
|
|
||||||
|
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
web2disk_cmdline.append('--verbose')
|
web2disk_cmdline.append('--verbose')
|
||||||
@ -578,6 +576,7 @@ class BasicNewsRecipe(Recipe):
|
|||||||
'preprocess_html', 'remove_tags_after', 'remove_tags_before'):
|
'preprocess_html', 'remove_tags_after', 'remove_tags_before'):
|
||||||
setattr(self.web2disk_options, extra, getattr(self, extra))
|
setattr(self.web2disk_options, extra, getattr(self, extra))
|
||||||
self.web2disk_options.postprocess_html = self._postprocess_html
|
self.web2disk_options.postprocess_html = self._postprocess_html
|
||||||
|
self.web2disk_options.encoding = self.encoding
|
||||||
|
|
||||||
if self.delay > 0:
|
if self.delay > 0:
|
||||||
self.simultaneous_downloads = 1
|
self.simultaneous_downloads = 1
|
||||||
@ -761,6 +760,7 @@ class BasicNewsRecipe(Recipe):
|
|||||||
self.report_progress(0, _('Trying to download cover...'))
|
self.report_progress(0, _('Trying to download cover...'))
|
||||||
self.download_cover()
|
self.download_cover()
|
||||||
self.report_progress(0, _('Generating masthead...'))
|
self.report_progress(0, _('Generating masthead...'))
|
||||||
|
self.masthead_path = None
|
||||||
try:
|
try:
|
||||||
murl = self.get_masthead_url()
|
murl = self.get_masthead_url()
|
||||||
except:
|
except:
|
||||||
@ -768,7 +768,7 @@ class BasicNewsRecipe(Recipe):
|
|||||||
murl = None
|
murl = None
|
||||||
if murl is not None:
|
if murl is not None:
|
||||||
self.download_masthead(murl)
|
self.download_masthead(murl)
|
||||||
else:
|
if self.masthead_path is None:
|
||||||
self.masthead_path = os.path.join(self.output_dir, 'mastheadImage.jpg')
|
self.masthead_path = os.path.join(self.output_dir, 'mastheadImage.jpg')
|
||||||
self.default_masthead_image(self.masthead_path)
|
self.default_masthead_image(self.masthead_path)
|
||||||
|
|
||||||
@ -894,7 +894,7 @@ class BasicNewsRecipe(Recipe):
|
|||||||
ext = ''
|
ext = ''
|
||||||
ext = ext.lower() if ext else 'jpg'
|
ext = ext.lower() if ext else 'jpg'
|
||||||
mpath = os.path.join(self.output_dir, 'masthead_source.'+ext)
|
mpath = os.path.join(self.output_dir, 'masthead_source.'+ext)
|
||||||
self.masthead_path = os.path.join(self.output_dir, 'mastheadImage.jpg')
|
outfile = os.path.join(self.output_dir, 'mastheadImage.jpg')
|
||||||
if os.access(mu, os.R_OK):
|
if os.access(mu, os.R_OK):
|
||||||
with open(mpath, 'wb') as mfile:
|
with open(mpath, 'wb') as mfile:
|
||||||
mfile.write(open(mu, 'rb').read())
|
mfile.write(open(mu, 'rb').read())
|
||||||
@ -902,20 +902,17 @@ class BasicNewsRecipe(Recipe):
|
|||||||
with nested(open(mpath, 'wb'), closing(self.browser.open(mu))) as (mfile, r):
|
with nested(open(mpath, 'wb'), closing(self.browser.open(mu))) as (mfile, r):
|
||||||
mfile.write(r.read())
|
mfile.write(r.read())
|
||||||
self.report_progress(1, _('Masthead image downloaded'))
|
self.report_progress(1, _('Masthead image downloaded'))
|
||||||
self.prepare_masthead_image(mpath, self.masthead_path)
|
self.prepare_masthead_image(mpath, outfile)
|
||||||
|
self.masthead_path = outfile
|
||||||
if os.path.exists(mpath):
|
if os.path.exists(mpath):
|
||||||
os.remove(mpath)
|
os.remove(mpath)
|
||||||
|
|
||||||
|
|
||||||
def download_masthead(self, url):
|
def download_masthead(self, url):
|
||||||
br = BasicNewsRecipe.get_browser()
|
|
||||||
try:
|
try:
|
||||||
br.open(url)
|
|
||||||
self._download_masthead(url)
|
self._download_masthead(url)
|
||||||
except:
|
except:
|
||||||
self.log.exception("Failed to download supplied masthead_url, synthesizing")
|
self.log.exception("Failed to download supplied masthead_url, synthesizing")
|
||||||
self.masthead_path = os.path.join(self.output_dir, 'mastheadImage.jpg')
|
|
||||||
self.default_masthead_image(self.masthead_path)
|
|
||||||
|
|
||||||
def default_cover(self, cover_file):
|
def default_cover(self, cover_file):
|
||||||
'''
|
'''
|
||||||
|
Loading…
x
Reference in New Issue
Block a user