Added CLI/GUI, sync to diagnostics

This commit is contained in:
GRiker 2010-01-30 05:34:37 -07:00
commit ef6902a58a
22 changed files with 347 additions and 53 deletions

View File

@ -33,7 +33,7 @@ p.description {
p.date_index {
font-size:x-large;
text-align:right;
text-align:center;
font-weight:bold;
margin-top:1em;
margin-bottom:0px;
@ -41,8 +41,9 @@ p.date_index {
p.letter_index {
font-size:x-large;
text-align:left;
margin-top:0px;
text-align:center;
font-weight:bold;
margin-top:1em;
margin-bottom:0px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

View File

@ -0,0 +1,50 @@
__license__ = 'GPL v3'
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
'''
information.dk
'''
from calibre.web.feeds.news import BasicNewsRecipe
class Information_dk(BasicNewsRecipe):
title = 'Information - Denmark'
__author__ = 'Darko Miletic'
description = 'News from Denmark'
publisher = 'information.dk'
category = 'news, politics, Denmark'
oldest_article = 2
max_articles_per_feed = 100
no_stylesheets = True
remove_empty_feeds = True
use_embedded_content = False
encoding = 'utf8'
language = 'da'
conversion_options = {
'comment' : description
, 'tags' : category
, 'publisher': publisher
, 'language' : language
}
feeds = [
(u'Nyheder fra' , u'http://www.information.dk/feed')
,(u'Bedst lige nu' , u'http://www.information.dk/bedstligenu/feed')
,(u'Politik og internationalt' , u'http://www.information.dk/politik/feed')
,(u'Kunst og kultur' , u'http://www.information.dk/kultur/feed')
,(u'Moderne Tider' , u'http://www.information.dk/modernetider/feed')
,(u'Klima' , u'http://www.information.dk/klima/feed')
,(u'Opinion' , u'http://www.information.dk/opinion/feed')
,(u'Literatur' , u'http://www.information.dk/litteratur/feed')
,(u'Film' , u'http://www.information.dk/film/feed')
,(u'Kunst' , u'http://www.information.dk/kunst/feed')
]
remove_tags_before = dict(name='h1',attrs={'class':'print-title'})
remove_tags_after = dict(name='div',attrs={'class':'print-footer'})
remove_tags = [dict(name=['object','link'])]
def print_version(self, url):
return url.replace('information.dk/','information.dk/print/')

View File

@ -0,0 +1,50 @@
__license__ = 'GPL v3'
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
'''
jp.dk
'''
from calibre.web.feeds.news import BasicNewsRecipe
class JP_dk(BasicNewsRecipe):
title = 'Jyllands-Posten'
__author__ = 'Darko Miletic'
description = 'News from Denmark'
publisher = 'jp.dk'
category = 'news, politics, Denmark'
oldest_article = 2
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
encoding = 'cp1252'
language = 'da'
extra_css = ' body{font-family: Arial,Verdana,Helvetica,Geneva,sans-serif } h1{font-family: Times,Georgia,Verdana,serif } '
conversion_options = {
'comment' : description
, 'tags' : category
, 'publisher': publisher
, 'language' : language
}
feeds = [
(u'Tophistorier', u'http://www.jp.dk/rss/topnyheder.jsp')
,(u'Seneste nyt' , u'http://jp.dk/index.jsp?service=rssfeed&submode=seneste')
,(u'Indland' , u'http://www.jp.dk/rss/indland.jsp')
,(u'Udland' , u'http://www.jp.dk/rss/udland.jsp')
,(u'Ny viden' , u'http://www.jp.dk/rss/nyviden.jsp')
,(u'Timeout' , u'http://www.jp.dk/rss/timeout.jsp')
,(u'Kultur' , u'http://www.jp.dk/rss/kultur.jsp')
,(u'Sport' , u'http://www.jp.dk/rss/sport.jsp')
]
remove_tags = [
dict(name=['object','link'])
,dict(name='p',attrs={'class':'artByline'})
]
def print_version(self, url):
return url + '?service=printversion'

View File

@ -4,7 +4,7 @@ class Metro_Montreal(BasicNewsRecipe):
title = u'M\xe9tro Montr\xe9al'
__author__ = 'Jerry Clapperton'
description = 'Le quotidien le plus branché sur le monde'
description = u'Le quotidien le plus branch\xe9 sur le monde'
language = 'fr'
oldest_article = 7

View File

@ -1,46 +1,42 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
__copyright__ = '2008-2010, Darko Miletic <darko.miletic at gmail.com>'
'''
nin.co.rs
www.nin.co.rs
'''
import re, urllib
from calibre import strftime
from calibre.web.feeds.news import BasicNewsRecipe
from calibre.ebooks.BeautifulSoup import Tag
class Nin(BasicNewsRecipe):
title = 'NIN online'
__author__ = 'Darko Miletic'
description = 'Nedeljne informativne novine'
publisher = 'NIN D.O.O.'
description = 'Nedeljne Informativne Novine'
publisher = 'NIN d.o.o.'
category = 'news, politics, Serbia'
no_stylesheets = True
oldest_article = 15
simultaneous_downloads = 1
delay = 1
encoding = 'utf-8'
needs_subscription = True
remove_empty_feeds = True
PREFIX = 'http://www.nin.co.rs'
INDEX = PREFIX + '/?change_lang=ls'
LOGIN = PREFIX + '/?logout=true'
use_embedded_content = False
language = 'sr'
lang = 'sr-Latn-RS'
direction = 'ltr'
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} .artTitle{font-size: x-large; font-weight: bold} .columnhead{font-size: small; font-weight: bold}'
extra_css = ' @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: Verdana, Lucida, sans1, sans-serif} .article_description{font-family: Verdana, Lucida, sans1, sans-serif} .artTitle{font-size: x-large; font-weight: bold; color: #900} .izjava{font-size: x-large; font-weight: bold} .columnhead{font-size: small; font-weight: bold;} img{margin-top:0.5em; margin-bottom: 0.7em} b{margin-top: 1em} '
conversion_options = {
'comment' : description
, 'tags' : category
, 'publisher' : publisher
, 'language' : language
, 'pretty_print' : True
, 'linearize_tables' : True
}
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
remove_attributes = ['height','width']
def get_browser(self):
br = BasicNewsRecipe.get_browser()
@ -65,35 +61,20 @@ class Nin(BasicNewsRecipe):
cover_url = self.PREFIX + link_item['src']
return cover_url
def preprocess_html(self, soup):
soup.html['lang'] = self.lang
soup.html['dir' ] = self.direction
mlang = Tag(soup,'meta',[("http-equiv","Content-Language"),("content",self.lang)])
mcharset = Tag(soup,'meta',[("http-equiv","Content-Type"),("content","text/html; charset=utf-8")])
soup.head.insert(0,mlang)
soup.head.insert(1,mcharset)
attribs = [ 'style','font','valign'
,'colspan','width','height'
,'rowspan','summary','align'
,'cellspacing','cellpadding'
,'frames','rules','border'
]
for item in soup.body.findAll(name=['table','td','tr','th','caption','thead','tfoot','tbody','colgroup','col']):
item.name = 'div'
for attrib in attribs:
if item.has_key(attrib):
del item[attrib]
return soup
def parse_index(self):
articles = []
count = 0
soup = self.index_to_soup(self.PREFIX)
for item in soup.findAll('a',attrs={'class':'lmeninavFont'}):
count = count +1
if self.test and count > 2:
return articles
section = self.tag_to_string(item)
feedlink = self.PREFIX + item['href']
feedpage = self.index_to_soup(feedlink)
self.report_progress(0, _('Fetching feed')+' %s...'%(section))
inarts = []
count2 = 0
for art in feedpage.findAll('span',attrs={'class':'artTitle'}):
alink = art.parent
url = self.PREFIX + alink['href']
@ -110,3 +91,4 @@ class Nin(BasicNewsRecipe):
})
articles.append((section,inarts))
return articles

View File

@ -0,0 +1,73 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__author__ = 'Lorenzo Vigentini'
__copyright__ = '2009, Lorenzo Vigentini <l.vigentini at gmail.com>'
description = 'News from the Orange county - v1.01 (29, January 2010)'
'''
http://www.ocregister.com/
'''
from calibre.web.feeds.news import BasicNewsRecipe
class ocRegister(BasicNewsRecipe):
author = 'Lorenzo Vigentini'
description = 'News from the Orange county'
cover_url = 'http://images.onset.freedom.com/ocregister/logo.gif'
title = u'Orange County Register'
publisher = 'Orange County Register Communication'
category = 'News, finance, economy, politics'
language = 'en'
timefmt = '[%a, %d %b, %Y]'
oldest_article = 1
max_articles_per_feed = 25
use_embedded_content = False
recursion = 10
remove_javascript = True
no_stylesheets = True
def print_version(self,url):
printUrl = 'http://www.ocregister.com/common/printer/view.php?db=ocregister&id='
segments = url.split('/')
subSegments = (segments[4]).split('.')
myArticle = (subSegments[0]).replace('-', '')
myURL= printUrl + myArticle
return myURL
keep_only_tags = [
dict(name='div', attrs={'id':'ArticleContentWrap'})
]
remove_tags = [
dict(name='div', attrs={'class':'hideForPrint'}),
dict(name='div', attrs={'id':'ContentFooter'})
]
feeds = [
(u'News', u'http://www.ocregister.com/common/rss/rss.php?catID=18800'),
(u'Today paper', u'http://www.ocregister.com/common/rss/rss.php?catID=18976'),
(u'Business', u'http://www.ocregister.com/common/rss/rss.php?catID=18909'),
(u'Cars', u'http://www.ocregister.com/common/rss/rss.php?catID=20128'),
(u'Entertainment', u'http://www.ocregister.com/common/rss/rss.php?catID=18926'),
(u'Home', u'http://www.ocregister.com/common/rss/rss.php?catID=19142'),
(u'Life', u'http://www.ocregister.com/common/rss/rss.php?catID=18936'),
(u'Opinion', u'http://www.ocregister.com/common/rss/rss.php?catID=18963'),
(u'Sports', u'http://www.ocregister.com/common/rss/rss.php?catID=18901'),
(u'Travel', u'http://www.ocregister.com/common/rss/rss.php?catID=18959')
]
extra_css = '''
h1 {color:#ff6600;font-family:Arial,Helvetica,sans-serif; font-size:20px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:20px;}
h2 {color:#4D4D4D;font-family:Arial,Helvetica,sans-serif; font-size:16px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:16px; }
h3 {color:#4D4D4D;font-family:Arial,Helvetica,sans-serif; font-size:15px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:15px;}
h4 {color:#333333; font-family:Arial,Helvetica,sans-serif;font-size:13px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:13px; }
h5 {color:#333333; font-family:Arial,Helvetica,sans-serif; font-size:11px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:11px; text-transform:uppercase;}
#articledate {color:#333333;font-family:Arial,Helvetica,sans-serif;font-size:10px; font-size-adjust:none; font-stretch:normal; font-style:italic; font-variant:normal; font-weight:bold; line-height:10px; text-decoration:none;}
#articlebyline {color:#4D4D4D;font-family:Arial,Helvetica,sans-serif;font-size:10px; font-size-adjust:none; font-stretch:normal; font-style:bold; font-variant:normal; font-weight:bold; line-height:10px; text-decoration:none;}
img {align:left;}
#topstoryhead {color:#ff6600;font-family:Arial,Helvetica,sans-serif; font-size:22px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:20px;}
'''

View File

@ -0,0 +1,55 @@
__license__ = 'GPL v3'
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
'''
politiken.dk
'''
from calibre.web.feeds.news import BasicNewsRecipe
class Politiken_dk(BasicNewsRecipe):
title = 'Politiken.dk'
__author__ = 'Darko Miletic'
description = 'News from Denmark'
publisher = 'politiken.dk'
category = 'news, politics, Denmark'
oldest_article = 2
max_articles_per_feed = 100
no_stylesheets = True
remove_empty_feeds = True
use_embedded_content = False
encoding = 'cp1252'
language = 'da'
extra_css = ' body{font-family: Arial,Helvetica,sans-serif } h1{font-family: Georgia,"Times New Roman",Times,serif } '
conversion_options = {
'comment' : description
, 'tags' : category
, 'publisher': publisher
, 'language' : language
}
feeds = [
(u'Tophistorier' , u'http://politiken.dk/rss/tophistorier.rss')
,(u'Seneste nyt' , u'http://politiken.dk/rss/senestenyt.rss')
,(u'Mest laeste' , u'http://politiken.dk/rss/mestlaeste.rss')
,(u'Danmark' , u'http://politiken.dk/rss/indland.rss')
,(u'Politik' , u'http://politiken.dk/rss/politik.rss')
,(u'Klima' , u'http://politiken.dk/rss/klima.rss')
,(u'Internationalt' , u'http://politiken.dk/rss/udland.rss')
,(u'Erhverv' , u'http://politiken.dk/rss/erhverv.rss')
,(u'Kultur' , u'http://politiken.dk/rss/kultur.rss')
,(u'Sport' , u'http://politiken.dk/rss/sport.rss')
,(u'Uddannelse' , u'http://politiken.dk/rss/uddannelse.rss')
,(u'Videnskab' , u'http://politiken.dk/rss/videnskab.rss')
]
remove_tags_before = dict(name='h1')
remove_tags = [
dict(name=['object','link'])
,dict(name='div',attrs={'class':'footer'})
]
def print_version(self, url):
return url + '?service=print'

View File

@ -46,3 +46,10 @@ class WashingtonPost(BasicNewsRecipe):
div['style'] = ''
return soup
def preprocess_html(self, soup):
for tag in soup.findAll('font'):
if tag.has_key('size'):
if tag['size'] == '+2':
if tag.b:
return soup
return None

View File

@ -89,6 +89,8 @@ def _config():
help=_('Maximum number of waiting worker processes'))
c.add_opt('get_social_metadata', default=True,
help=_('Download social metadata (tags/rating/etc.)'))
c.add_opt('overwrite_author_title_metadata', default=True,
help=_('Overwrite author and title with new metadata'))
c.add_opt('enforce_cpu_limit', default=True,
help=_('Limit max simultaneous jobs to number of CPUs'))

View File

@ -23,7 +23,7 @@ def gui_convert(input, output, recommendations, notification=DummyReporter(),
plumber.run()
def gui_catalog(fmt, title, dbspec, ids, out_file_name, fmt_options,
def gui_catalog(fmt, title, dbspec, ids, out_file_name, sync, fmt_options,
notification=DummyReporter(), log=None):
if log is None:
log = Log()
@ -46,6 +46,7 @@ def gui_catalog(fmt, title, dbspec, ids, out_file_name, fmt_options,
opts.ids = ids
opts.search_text = None
opts.sort_by = None
opts.sync = sync
# Extract the option dictionary to comma-separated lists
for option in fmt_options:

View File

@ -458,6 +458,7 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
self.connect(self.button_open_config_dir, SIGNAL('clicked()'),
self.open_config_dir)
self.opt_get_social_metadata.setChecked(config['get_social_metadata'])
self.opt_overwrite_author_title_metadata.setChecked(config['overwrite_author_title_metadata'])
self.opt_enforce_cpu_limit.setChecked(config['enforce_cpu_limit'])
self.device_detection_button.clicked.connect(self.debug_device_detection)
@ -751,6 +752,7 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
config['upload_news_to_device'] = self.sync_news.isChecked()
config['search_as_you_type'] = self.search_as_you_type.isChecked()
config['get_social_metadata'] = self.opt_get_social_metadata.isChecked()
config['overwrite_author_title_metadata'] = self.opt_overwrite_author_title_metadata.isChecked()
config['enforce_cpu_limit'] = bool(self.opt_enforce_cpu_limit.isChecked())
fmts = []
for i in range(self.viewer.count()):

View File

@ -171,6 +171,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="opt_overwrite_author_title_metadata">
<property name="text">
<string>Overwrite &amp; author/title by default when fetching metadata</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">

View File

@ -119,6 +119,7 @@ class FetchMetadata(QDialog, Ui_FetchMetadata):
self.matches.setMouseTracking(True)
self.fetch_metadata()
self.opt_get_social_metadata.setChecked(config['get_social_metadata'])
self.opt_overwrite_author_title_metadata.setChecked(config['overwrite_author_title_metadata'])
def show_summary(self, current, *args):
@ -149,7 +150,8 @@ class FetchMetadata(QDialog, Ui_FetchMetadata):
self.fetcher.start()
self.pi.start(_('Finding metadata...'))
self._hangcheck = QTimer(self)
self.connect(self._hangcheck, SIGNAL('timeout()'), self.hangcheck)
self.connect(self._hangcheck, SIGNAL('timeout()'), self.hangcheck,
Qt.QueuedConnection)
self.start_time = time.time()
self._hangcheck.start(100)

View File

@ -116,6 +116,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="opt_overwrite_author_title_metadata">
<property name="text">
<string>Overwrite &amp;author/title with author/title of selected book</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">

View File

@ -574,9 +574,10 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
det_msg=det, show=True)
else:
book.tags = []
self.title.setText(book.title)
self.authors.setText(authors_to_string(book.authors))
if book.author_sort: self.author_sort.setText(book.author_sort)
if d.opt_overwrite_author_title_metadata.isChecked():
self.title.setText(book.title)
self.authors.setText(authors_to_string(book.authors))
if book.author_sort: self.author_sort.setText(book.author_sort)
if book.publisher: self.publisher.setEditText(book.publisher)
if book.isbn: self.isbn.setText(book.isbn)
if book.pubdate:

View File

@ -12,6 +12,7 @@ from Queue import Queue, Empty
from calibre.ebooks.metadata.fetch import search, get_social_metadata
from calibre.gui2 import config
from calibre.ebooks.metadata.library_thing import cover_from_isbn
from calibre.customize.ui import get_isbndb_key
@ -98,6 +99,10 @@ class DownloadMetadata(Thread):
self.fetched_metadata[id] = fmi
if fmi.isbn and self.get_covers:
self.worker.jobs.put(fmi.isbn)
if (not config['overwrite_author_title_metadata']):
fmi.authors = mi.authors
fmi.author_sort = mi.author_sort
fmi.title = mi.title
mi.smart_update(fmi)
if mi.isbn and self.get_social_metadata:
self.social_metadata_exceptions = get_social_metadata(mi)

View File

@ -254,11 +254,13 @@ def generate_catalog(parent, dbspec, ids):
dbspec,
ids,
out.name,
d.catalog_sync,
d.fmt_options
]
out.close()
# This calls gui2.convert.gui_conversion:gui_catalog()
# This returns to gui2.ui:generate_catalog()
# Which then calls gui2.convert.gui_conversion:gui_catalog()
return 'gui_catalog', args, _('Generate catalog'), out.name, d.catalog_sync, \
d.catalog_title

View File

@ -796,6 +796,12 @@ class EPUB_MOBI(CatalogPlugin):
shutil.copy(os.path.join(catalog_resources,file[1]),
os.path.join(self.catalogPath, file[0]))
# Create the custom masthead image overwriting default
try:
self.generate_masthead_image(os.path.join(self.catalogPath, 'images/mastheadImage.gif'))
except:
pass
def fetchBooksByTitle(self):
self.updateProgressFullStep("Fetching database")
@ -1794,7 +1800,11 @@ class EPUB_MOBI(CatalogPlugin):
# Add the author tag
cmTag = Tag(ncx_soup, '%s' % 'calibre:meta')
cmTag['name'] = "author"
cmTag.insert(0, NavigableString(self.formatNCXText(book['author'])))
navStr = '%s | %s' % (self.formatNCXText(book['author']),
book['date'].split()[1])
if 'tags' in book:
navStr += ' | %s' % self.formatNCXText(' &middot; '.join(sorted(book['tags'])))
cmTag.insert(0, NavigableString(navStr))
navPointVolumeTag.insert(2, cmTag)
# Add the description tag
@ -1996,9 +2006,10 @@ class EPUB_MOBI(CatalogPlugin):
self.updateProgressFullStep("NCX Recently Added")
def add_to_master_month_list(current_titles_list):
book_count = len(current_titles_list)
current_titles_list = " &bull; ".join(current_titles_list)
current_titles_list = self.generateShortDescription(self.formatNCXText(current_titles_list))
master_month_list.append((current_titles_list, current_date))
master_month_list.append((current_titles_list, current_date, book_count))
soup = self.ncxSoup
HTML_file = "content/ByDateAdded.html"
@ -2028,7 +2039,7 @@ class EPUB_MOBI(CatalogPlugin):
# Create an NCX article entry for each populated month
# Loop over the booksByDate list, find start of each month,
# add description_preview_count titles
# self.authors[0]:friendly [1]:author_sort [2]:book_count
# master_month_list(list,date,count)
current_titles_list = []
master_month_list = []
current_date = self.booksByDate[0]['timestamp']
@ -2074,6 +2085,13 @@ class EPUB_MOBI(CatalogPlugin):
cmTag.insert(0, NavigableString(books_by_month[0]))
navPointByMonthTag.insert(2, cmTag)
cmTag = Tag(soup, '%s' % 'calibre:meta')
cmTag['name'] = "author"
navStr = '%d titles' % books_by_month[2] if books_by_month[2] > 1 else \
'%d title' % books_by_month[2]
cmTag.insert(0, NavigableString(navStr))
navPointByMonthTag.insert(3, cmTag)
navPointTag.insert(nptc, navPointByMonthTag)
nptc += 1
@ -2172,7 +2190,7 @@ class EPUB_MOBI(CatalogPlugin):
for title in genre['books']:
titles.append(title['title'])
titles = sorted(titles, key=lambda x:(self.generateSortTitle(x),self.generateSortTitle(x)))
titles_list = self.generateShortDescription(" &bull; ".join(titles))
titles_list = self.generateShortDescription(u" &bull; ".join(titles))
cmTag.insert(0, NavigableString(self.formatNCXText(titles_list)))
navPointVolumeTag.insert(3, cmTag)
@ -2275,9 +2293,9 @@ class EPUB_MOBI(CatalogPlugin):
else:
continue
if self.verbose:
self.opts.log.info(' %d Genre tags (exclude_genre: %s):' % \
self.opts.log.info(u' %d Genre tags in database (exclude_genre: %s):' % \
(len(filtered_tags), self.opts.exclude_genre))
self.opts.log.info(' %s' % ', '.join(filtered_tags))
self.opts.log.info(u' %s' % ', '.join(filtered_tags))
return filtered_tags
@ -2479,6 +2497,26 @@ class EPUB_MOBI(CatalogPlugin):
titleTag.insert(0,escape(NavigableString(title)))
return soup
def generate_masthead_image(self, out_path):
MI_WIDTH = 600
MI_HEIGHT = 60
try:
from PIL import Image, ImageDraw, ImageFont
Image, ImageDraw, ImageFont
except ImportError:
import Image, ImageDraw, ImageFont
img = Image.new('RGB', (MI_WIDTH, MI_HEIGHT), 'white')
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(P('fonts/liberation/LiberationSerif-Bold.ttf'), 48)
text = self.title.encode('utf-8')
width, height = draw.textsize(text, font=font)
left = max(int((MI_WIDTH - width)/2.), 0)
top = max(int((MI_HEIGHT - height)/2.), 0)
draw.text((left, top), text, fill=(0,0,0), font=font)
img.save(open(out_path, 'wb'), 'GIF')
def generateShortDescription(self, description):
# Truncate the description to description_clip, on word boundaries if necessary
if not description:
@ -2611,13 +2649,18 @@ class EPUB_MOBI(CatalogPlugin):
# Add local options
opts.creator = "calibre"
opts.descriptionClip = 380 if self.opts.output_profile.endswith('dx') else 90
op = self.opts.output_profile
if op is None:
op = 'default'
opts.descriptionClip = 380 if op.endswith('dx') or 'kindle' not in op else 90
opts.basename = "Catalog"
opts.plugin_path = self.plugin_path
if opts.verbose:
opts_dict = vars(opts)
log("%s(): Generating %s for %s" % (self.name,self.fmt,opts.output_profile))
gui = True if 'sync' in opts_dict else False
log("%s(): Generating %s for %s in %s environment" % \
(self.name,self.fmt,opts.output_profile, 'GUI' if gui else 'CLI'))
if opts_dict['ids']:
log(" Book count: %d" % len(opts_dict['ids']))
# Display opts
@ -2627,7 +2670,7 @@ class EPUB_MOBI(CatalogPlugin):
for key in keys:
if key in ['catalog_title','exclude_genre','exclude_tags','note_tag',
'numbers_as_text','read_tag','search_text','sort_by']:
'numbers_as_text','read_tag','search_text','sort_by','sync']:
log(" %s: %s" % (key, opts_dict[key]))
# Launch the Catalog builder

View File

@ -770,7 +770,11 @@ class BasicNewsRecipe(Recipe):
self.download_masthead(murl)
if self.masthead_path is None:
self.masthead_path = os.path.join(self.output_dir, 'mastheadImage.jpg')
self.default_masthead_image(self.masthead_path)
try:
self.default_masthead_image(self.masthead_path)
except:
self.log.exception('Failed to generate default masthead image')
self.masthead_path = None
if self.test:
feeds = feeds[:2]
@ -1061,7 +1065,7 @@ class BasicNewsRecipe(Recipe):
opf = OPFCreator(dir, mi)
# Add mastheadImage entry to <guide> section
mp = getattr(self, 'masthead_path', None)
if mp is not None:
if mp is not None and os.access(mp, os.R_OK):
from calibre.ebooks.metadata.opf2 import Guide
ref = Guide.Reference(os.path.basename(self.masthead_path), os.getcwdu())
ref.type = 'masthead'