mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
KG updates
This commit is contained in:
commit
c88bcb7396
Binary file not shown.
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 124 KiB |
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
24sata.rs
|
24sata.rs
|
||||||
@ -9,7 +8,6 @@ __copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import Tag
|
|
||||||
|
|
||||||
class Ser24Sata(BasicNewsRecipe):
|
class Ser24Sata(BasicNewsRecipe):
|
||||||
title = '24 Sata - Sr'
|
title = '24 Sata - Sr'
|
||||||
@ -17,22 +15,20 @@ class Ser24Sata(BasicNewsRecipe):
|
|||||||
description = '24 sata portal vesti iz Srbije'
|
description = '24 sata portal vesti iz Srbije'
|
||||||
publisher = 'Ringier d.o.o.'
|
publisher = 'Ringier d.o.o.'
|
||||||
category = 'news, politics, entertainment, Serbia'
|
category = 'news, politics, entertainment, Serbia'
|
||||||
oldest_article = 7
|
oldest_article = 2
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
|
|
||||||
lang = 'sr-Latn-RS'
|
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: serif1, serif}'
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: serif1, serif}'
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
, 'tags' : category
|
, 'tags' : category
|
||||||
, 'publisher' : publisher
|
, 'publisher' : publisher
|
||||||
, 'language' : lang
|
, 'language' : language
|
||||||
, 'pretty_print' : True
|
, 'linearize_tables' : True
|
||||||
}
|
}
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
@ -40,25 +36,6 @@ class Ser24Sata(BasicNewsRecipe):
|
|||||||
feeds = [(u'Vesti Dana', u'http://www.24sata.rs/rss.php')]
|
feeds = [(u'Vesti Dana', u'http://www.24sata.rs/rss.php')]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
soup.html['xml:lang'] = self.lang
|
|
||||||
soup.html['lang'] = self.lang
|
|
||||||
|
|
||||||
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]
|
|
||||||
|
|
||||||
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)
|
|
||||||
return self.adeify_images(soup)
|
return self.adeify_images(soup)
|
||||||
|
|
||||||
def print_version(self, url):
|
def print_version(self, url):
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
b92.net
|
b92.net
|
||||||
'''
|
'''
|
||||||
@ -20,15 +19,14 @@ class B92(BasicNewsRecipe):
|
|||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
encoding = 'cp1250'
|
encoding = 'cp1250'
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
|
extra_css = ' @font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: serif1, serif} '
|
||||||
lang = 'sr-Latn-RS'
|
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: serif1, serif}'
|
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
, 'tags' : category
|
, 'tags' : category
|
||||||
, 'publisher' : publisher
|
, 'publisher' : publisher
|
||||||
, 'language' : lang
|
, 'language' : language
|
||||||
|
, 'linearize_tables' : True
|
||||||
}
|
}
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
@ -50,20 +48,5 @@ class B92(BasicNewsRecipe):
|
|||||||
return url + '&version=print'
|
return url + '&version=print'
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
del soup.body['onload']
|
return self.adeify_images(soup)
|
||||||
for item in soup.findAll('font'):
|
|
||||||
item.name='div'
|
|
||||||
if item.has_key('size'):
|
|
||||||
del item['size']
|
|
||||||
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
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
beta.rs
|
beta.rs
|
||||||
'''
|
'''
|
||||||
import re
|
import re
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import Tag
|
|
||||||
|
|
||||||
class Danas(BasicNewsRecipe):
|
class Danas(BasicNewsRecipe):
|
||||||
title = 'BETA'
|
title = 'BETA'
|
||||||
@ -20,17 +18,13 @@ class Danas(BasicNewsRecipe):
|
|||||||
no_stylesheets = False
|
no_stylesheets = False
|
||||||
use_embedded_content = True
|
use_embedded_content = True
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
|
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} img{margin-bottom: 0.8em} '
|
||||||
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}'
|
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
, 'tags' : category
|
, 'tags' : category
|
||||||
, 'publisher' : publisher
|
, 'publisher' : publisher
|
||||||
, 'language' : lang
|
, 'language' : language
|
||||||
, 'pretty_print' : True
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -43,9 +37,4 @@ class Danas(BasicNewsRecipe):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
soup.html['lang'] = self.lang
|
|
||||||
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)
|
|
||||||
return self.adeify_images(soup)
|
return self.adeify_images(soup)
|
||||||
|
@ -14,14 +14,13 @@ class Blic(BasicNewsRecipe):
|
|||||||
description = 'Blic.rs online verzija najtiraznije novine u Srbiji donosi najnovije vesti iz Srbije i sveta, komentare, politicke analize, poslovne i ekonomske vesti, vesti iz regiona, intervjue, informacije iz kulture, reportaze, pokriva sve sportske dogadjaje, detaljan tv program, nagradne igre, zabavu, fenomenalni Blic strip, dnevni horoskop, arhivu svih dogadjaja'
|
description = 'Blic.rs online verzija najtiraznije novine u Srbiji donosi najnovije vesti iz Srbije i sveta, komentare, politicke analize, poslovne i ekonomske vesti, vesti iz regiona, intervjue, informacije iz kulture, reportaze, pokriva sve sportske dogadjaje, detaljan tv program, nagradne igre, zabavu, fenomenalni Blic strip, dnevni horoskop, arhivu svih dogadjaja'
|
||||||
publisher = 'RINGIER d.o.o.'
|
publisher = 'RINGIER d.o.o.'
|
||||||
category = 'news, politics, Serbia'
|
category = 'news, politics, Serbia'
|
||||||
delay = 1
|
|
||||||
oldest_article = 2
|
oldest_article = 2
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
|
masthead_url = 'http://www.blic.rs/resources/images/header/header_back.png'
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
|
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: Georgia, serif1, serif} .article_description{font-family: Arial, sans1, sans-serif} .img_full{float: none} img{margin-bottom: 0.8em} '
|
||||||
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} '
|
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
@ -31,13 +30,15 @@ class Blic(BasicNewsRecipe):
|
|||||||
}
|
}
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
remove_tags_before = dict(name='div', attrs={'id':'article_info'})
|
remove_tags_before = dict(name='div', attrs={'id':'article_info'})
|
||||||
|
remove_tags = [dict(name=['object','link'])]
|
||||||
|
remove_attributes = ['width','height']
|
||||||
|
|
||||||
feeds = [(u'Danasnje Vesti', u'http://www.blic.rs/rss/danasnje-vesti')]
|
feeds = [(u'Danasnje Vesti', u'http://www.blic.rs/rss/danasnje-vesti')]
|
||||||
|
|
||||||
remove_tags = [dict(name=['object','link'])]
|
|
||||||
|
|
||||||
def print_version(self, url):
|
def print_version(self, url):
|
||||||
return url + '/print'
|
return url + '/print'
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
return self.adeify_images(soup)
|
||||||
|
36
resources/recipes/cetnixploitation.recipe
Normal file
36
resources/recipes/cetnixploitation.recipe
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
'''
|
||||||
|
chetnixploitation.blogspot.com
|
||||||
|
'''
|
||||||
|
|
||||||
|
import re
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class Chetnixploitation(BasicNewsRecipe):
|
||||||
|
title = 'Chetnixploitation'
|
||||||
|
__author__ = 'Darko Miletic'
|
||||||
|
description = 'Filmski blog'
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
language = 'sr'
|
||||||
|
encoding = 'utf-8'
|
||||||
|
no_stylesheets = True
|
||||||
|
use_embedded_content = True
|
||||||
|
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: "Trebuchet MS",Trebuchet,Verdana,sans1,sans-serif} .article_description{font-family: sans1, sans-serif} img{margin-bottom: 0.8em; border: 1px solid #333333; padding: 4px } '
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : 'film, blog, cetnici, srbija, ex-yu'
|
||||||
|
, 'publisher': 'Son of Man'
|
||||||
|
, 'language' : language
|
||||||
|
}
|
||||||
|
|
||||||
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
feeds = [(u'Posts', u'http://chetnixploitation.blogspot.com/feeds/posts/default')]
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
return self.adeify_images(soup)
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ class Danas(BasicNewsRecipe):
|
|||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
masthead_url = 'http://www.danas.rs/images/basic/danas.gif'
|
masthead_url = 'http://www.danas.rs/images/basic/danas.gif'
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
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)} .article_description,body,.lokacija{font-family: Tahoma,Arial,Helvetica,sans1,sans-serif} .nadNaslov,h1,.preamble{font-family: Georgia,"Times New Roman",Times,serif1,serif} .antrfileText{border-left: 2px solid #999999; color:#666666; margin-left: 0.8em; padding-left: 1.2em; margin-bottom: 0; margin-top: 0} h2,.datum,.lokacija,.autor{font-size: small} .antrfileNaslov{border-left: 2px solid #999999; color:#666666; margin-left: 0.8em; padding-left: 1.2em; font-weight:bold; margin-bottom: 0; margin-top: 0} img{margin-bottom: 0.8em} '
|
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)} .article_description,body,.lokacija{font-family: Tahoma,Arial,Helvetica,sans1,sans-serif} .nadNaslov,h1,.preamble{font-family: Georgia,"Times New Roman",Times,serif1,serif} .antrfileText{border-left: 2px solid #999999; margin-left: 0.8em; padding-left: 1.2em; margin-bottom: 0; margin-top: 0} h2,.datum,.lokacija,.autor{font-size: small} .antrfileNaslov{border-left: 2px solid #999999; margin-left: 0.8em; padding-left: 1.2em; font-weight:bold; margin-bottom: 0; margin-top: 0} img{margin-bottom: 0.8em} '
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
e-novine.com
|
e-novine.com
|
||||||
@ -9,7 +7,6 @@ e-novine.com
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import Tag
|
|
||||||
|
|
||||||
class E_novine(BasicNewsRecipe):
|
class E_novine(BasicNewsRecipe):
|
||||||
title = 'E-Novine'
|
title = 'E-Novine'
|
||||||
@ -20,40 +17,38 @@ class E_novine(BasicNewsRecipe):
|
|||||||
oldest_article = 2
|
oldest_article = 2
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
encoding = 'cp1250'
|
encoding = 'utf-8'
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
|
masthead_url = 'http://www.e-novine.com/themes/e_novine/img/logo.gif'
|
||||||
lang = 'sr'
|
extra_css = ' @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} .article_description,body{font-family: Arial,Helvetica,sans1,sans-serif} img{float: none; margin-bottom: 0.8em} '
|
||||||
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{text-align: justify; font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
, 'tags' : category
|
, 'tags' : category
|
||||||
, 'publisher' : publisher
|
, 'publisher' : publisher
|
||||||
, 'language' : lang
|
, 'language' : language
|
||||||
, 'pretty_print' : True
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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':['css_47_0_2844H']})]
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'class':'article_head'})
|
||||||
|
,dict(name='div', attrs={'id':'article_body'})
|
||||||
|
]
|
||||||
|
|
||||||
remove_tags = [dict(name=['object','link','embed','iframe'])]
|
remove_tags = [
|
||||||
|
dict(name=['object','link','embed','iframe'])
|
||||||
|
,dict(attrs={'id':'box_article_tools'})
|
||||||
|
]
|
||||||
|
remove_attributes = ['height','width','lang']
|
||||||
|
|
||||||
feeds = [(u'Sve vesti', u'http://www.e-novine.com/rss/e-novine.xml' )]
|
feeds = [(u'Sve vesti', u'http://www.e-novine.com/feed/index.1.rss' )]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
soup.html['xml:lang'] = self.lang
|
|
||||||
soup.html['lang'] = self.lang
|
|
||||||
mlang = Tag(soup,'meta',[("http-equiv","Content-Language"),("content",self.lang)])
|
|
||||||
soup.head.insert(0,mlang)
|
|
||||||
for item in soup.findAll(style=True):
|
for item in soup.findAll(style=True):
|
||||||
del item['style']
|
del item['style']
|
||||||
ftag = soup.find('div', attrs={'id':'css_47_0_2844H'})
|
return self.adeify_images(soup)
|
||||||
if ftag:
|
|
||||||
it = ftag.div
|
def print_version(self, url):
|
||||||
it.extract()
|
return url + '?print'
|
||||||
ftag.div.extract()
|
|
||||||
ftag.insert(0,it)
|
|
||||||
return soup
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
glassrpske.com
|
glassrpske.com
|
||||||
@ -9,7 +8,6 @@ glassrpske.com
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import Tag
|
|
||||||
|
|
||||||
class GlasSrpske(BasicNewsRecipe):
|
class GlasSrpske(BasicNewsRecipe):
|
||||||
title = 'Glas Srpske'
|
title = 'Glas Srpske'
|
||||||
@ -22,20 +20,16 @@ class GlasSrpske(BasicNewsRecipe):
|
|||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
cover_url = 'http://www.glassrpske.com/var/slike/glassrpske-logo.png'
|
masthead_url = 'http://www.glassrpske.com/var/slike/glassrpske-logo.png'
|
||||||
lang = 'sr-BA'
|
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
|
|
||||||
INDEX = 'http://www.glassrpske.com'
|
INDEX = 'http://www.glassrpske.com'
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: serif1, serif} img{margin-bottom: 0.8em} '
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: serif1, serif}'
|
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
, 'tags' : category
|
, 'tags' : category
|
||||||
, 'publisher' : publisher
|
, 'publisher' : publisher
|
||||||
, 'language' : lang
|
, 'language' : language
|
||||||
, 'pretty_print' : True
|
|
||||||
}
|
}
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
@ -63,11 +57,7 @@ class GlasSrpske(BasicNewsRecipe):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
soup.html['xml:lang'] = self.lang
|
return self.adeify_images(soup)
|
||||||
soup.html['lang'] = self.lang
|
|
||||||
mlang = Tag(soup,'meta',[("http-equiv","Content-Language"),("content",self.lang)])
|
|
||||||
soup.head.insert(0,mlang)
|
|
||||||
return soup
|
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
totalfeeds = []
|
totalfeeds = []
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
www.glas-javnosti.rs
|
www.glas-javnosti.rs
|
||||||
'''
|
'''
|
||||||
@ -19,17 +18,13 @@ class GlasJavnosti(BasicNewsRecipe):
|
|||||||
no_stylesheets = False
|
no_stylesheets = False
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
|
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} img{margin-bottom: 0.8em} '
|
||||||
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}'
|
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
, 'tags' : category
|
, 'tags' : category
|
||||||
, 'publisher' : publisher
|
, 'publisher' : publisher
|
||||||
, 'language' : lang
|
, 'language' : language
|
||||||
, 'pretty_print' : True
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
nspm.rs
|
nspm.rs
|
||||||
'''
|
'''
|
||||||
@ -22,16 +20,15 @@ class Nspm(BasicNewsRecipe):
|
|||||||
INDEX = 'http://www.nspm.rs/?alphabet=l'
|
INDEX = 'http://www.nspm.rs/?alphabet=l'
|
||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
|
masthead_url = 'http://www.nspm.rs/templates/jsn_epic_pro/images/logol.jpg'
|
||||||
lang = 'sr-Latn-RS'
|
|
||||||
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{text-align: justify; font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
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{text-align: justify; font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
, 'tags' : category
|
, 'tags' : category
|
||||||
, 'publisher' : publisher
|
, 'publisher' : publisher
|
||||||
, 'language' : lang
|
, 'language' : language
|
||||||
, 'pretty_print' : True
|
, 'linearize_tables' : True
|
||||||
}
|
}
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
@ -39,6 +36,8 @@ class Nspm(BasicNewsRecipe):
|
|||||||
dict(name=['link','object','embed'])
|
dict(name=['link','object','embed'])
|
||||||
,dict(name='td', attrs={'class':'buttonheading'})
|
,dict(name='td', attrs={'class':'buttonheading'})
|
||||||
]
|
]
|
||||||
|
remove_tags_after = dict(attrs={'class':'article_separator'})
|
||||||
|
remove_attributes = ['width','height']
|
||||||
|
|
||||||
def get_browser(self):
|
def get_browser(self):
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser()
|
||||||
@ -51,17 +50,6 @@ class Nspm(BasicNewsRecipe):
|
|||||||
return url.replace('.html','/stampa.html')
|
return url.replace('.html','/stampa.html')
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
soup.html['xml:lang'] = self.lang
|
for item in soup.body.findAll(style=True):
|
||||||
soup.html['lang'] = self.lang
|
del item['style']
|
||||||
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 self.adeify_images(soup)
|
return self.adeify_images(soup)
|
||||||
|
39
resources/recipes/thecultofghoul.recipe
Normal file
39
resources/recipes/thecultofghoul.recipe
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
'''
|
||||||
|
cultofghoul.blogspot.com
|
||||||
|
'''
|
||||||
|
|
||||||
|
import re
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class TheCultOfGhoul(BasicNewsRecipe):
|
||||||
|
title = 'The Cult of Ghoul'
|
||||||
|
__author__ = 'Darko Miletic'
|
||||||
|
description = 'Filmski blog'
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
language = 'sr'
|
||||||
|
encoding = 'utf-8'
|
||||||
|
no_stylesheets = True
|
||||||
|
use_embedded_content = True
|
||||||
|
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: "Trebuchet MS",Trebuchet,Verdana,sans1,sans-serif} .article_description{font-family: sans1, sans-serif} img{margin-bottom: 0.8em; border: 1px solid #333333; padding: 4px } '
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : 'film, blog, srbija, strava, uzas'
|
||||||
|
, 'publisher': 'Dejan Ognjanovic'
|
||||||
|
, 'language' : language
|
||||||
|
}
|
||||||
|
|
||||||
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
|
feeds = [(u'Posts', u'http://cultofghoul.blogspot.com/feeds/posts/default')]
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
for item in soup.findAll(style=True):
|
||||||
|
del item['style']
|
||||||
|
return self.adeify_images(soup)
|
||||||
|
|
||||||
|
|
@ -50,7 +50,11 @@ class WallStreetJournal(BasicNewsRecipe):
|
|||||||
br.select_form(nr=0)
|
br.select_form(nr=0)
|
||||||
br['user'] = self.username
|
br['user'] = self.username
|
||||||
br['password'] = self.password
|
br['password'] = self.password
|
||||||
br.submit()
|
res = br.submit()
|
||||||
|
raw = res.read()
|
||||||
|
if 'Welcome,' not in raw:
|
||||||
|
raise ValueError('Failed to log in to wsj.com, check your '
|
||||||
|
'username and password')
|
||||||
return br
|
return br
|
||||||
|
|
||||||
def postprocess_html(self, soup, first):
|
def postprocess_html(self, soup, first):
|
||||||
@ -69,8 +73,10 @@ class WallStreetJournal(BasicNewsRecipe):
|
|||||||
soup = self.wsj_get_index()
|
soup = self.wsj_get_index()
|
||||||
|
|
||||||
year = strftime('%Y')
|
year = strftime('%Y')
|
||||||
for x in soup.findAll('td', attrs={'class':'b14'}):
|
for x in soup.findAll('td', height='25', attrs={'class':'b14'}):
|
||||||
txt = self.tag_to_string(x).strip()
|
txt = self.tag_to_string(x).strip()
|
||||||
|
txt = txt.replace(u'\xa0', ' ')
|
||||||
|
txt = txt.encode('ascii', 'ignore')
|
||||||
if year in txt:
|
if year in txt:
|
||||||
self.timefmt = ' [%s]'%txt
|
self.timefmt = ' [%s]'%txt
|
||||||
break
|
break
|
||||||
|
@ -70,9 +70,10 @@ class PML2PMLZ(FileTypePlugin):
|
|||||||
pmlz = zipfile.ZipFile(of.name, 'w')
|
pmlz = zipfile.ZipFile(of.name, 'w')
|
||||||
pmlz.write(pmlfile, os.path.basename(pmlfile))
|
pmlz.write(pmlfile, os.path.basename(pmlfile))
|
||||||
|
|
||||||
pml_img = os.path.basename(pmlfile)[0] + '_img'
|
pml_img = os.path.splitext(pmlfile)[0] + '_img'
|
||||||
img_dir = pml_img if os.path.exists(pml_img) else 'images' if \
|
i_img = os.path.join(os.path.dirname(pmlfile),'images')
|
||||||
os.path.exists('images') else ''
|
img_dir = pml_img if os.path.isdir(pml_img) else i_img if \
|
||||||
|
os.path.isdir(i_img) else ''
|
||||||
if img_dir:
|
if img_dir:
|
||||||
for image in glob.glob(os.path.join(img_dir, '*.png')):
|
for image in glob.glob(os.path.join(img_dir, '*.png')):
|
||||||
pmlz.write(image, os.path.join('images', (os.path.basename(image))))
|
pmlz.write(image, os.path.join('images', (os.path.basename(image))))
|
||||||
|
@ -49,7 +49,7 @@ class CLI(object):
|
|||||||
d = os.path.dirname(path)
|
d = os.path.dirname(path)
|
||||||
if not os.path.exists(d):
|
if not os.path.exists(d):
|
||||||
os.makedirs(d)
|
os.makedirs(d)
|
||||||
with open(path, 'wb') as dest:
|
with open(path, 'w+b') as dest:
|
||||||
try:
|
try:
|
||||||
shutil.copyfileobj(infile, dest)
|
shutil.copyfileobj(infile, dest)
|
||||||
except IOError:
|
except IOError:
|
||||||
|
@ -70,10 +70,13 @@ def is_recipe(filename):
|
|||||||
filename.rpartition('.')[0].endswith('_recipe_out')
|
filename.rpartition('.')[0].endswith('_recipe_out')
|
||||||
|
|
||||||
def get_metadata(stream, stream_type='lrf', use_libprs_metadata=False):
|
def get_metadata(stream, stream_type='lrf', use_libprs_metadata=False):
|
||||||
|
pos = 0
|
||||||
|
if hasattr(stream, 'tell'):
|
||||||
pos = stream.tell()
|
pos = stream.tell()
|
||||||
try:
|
try:
|
||||||
return _get_metadata(stream, stream_type, use_libprs_metadata)
|
return _get_metadata(stream, stream_type, use_libprs_metadata)
|
||||||
finally:
|
finally:
|
||||||
|
if hasattr(stream, 'seek'):
|
||||||
stream.seek(pos)
|
stream.seek(pos)
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,9 +8,10 @@ Read metadata from RAR archives
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from cStringIO import StringIO
|
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile, TemporaryDirectory
|
||||||
from calibre.libunrar import extract_member, names
|
from calibre.libunrar import extract_member, names
|
||||||
|
from calibre import CurrentDir
|
||||||
|
|
||||||
def get_metadata(stream):
|
def get_metadata(stream):
|
||||||
from calibre.ebooks.metadata.archive import is_comic
|
from calibre.ebooks.metadata.archive import is_comic
|
||||||
@ -32,8 +33,10 @@ def get_metadata(stream):
|
|||||||
stream_type = stream_type[1:]
|
stream_type = stream_type[1:]
|
||||||
if stream_type in ('lit', 'opf', 'prc', 'mobi', 'fb2', 'epub',
|
if stream_type in ('lit', 'opf', 'prc', 'mobi', 'fb2', 'epub',
|
||||||
'rb', 'imp', 'pdf', 'lrf'):
|
'rb', 'imp', 'pdf', 'lrf'):
|
||||||
data = extract_member(path, match=None, name=f)[1]
|
with TemporaryDirectory() as tdir:
|
||||||
stream = StringIO(data)
|
with CurrentDir(tdir):
|
||||||
|
stream = extract_member(path, match=None, name=f,
|
||||||
|
as_file=True)[1]
|
||||||
return get_metadata(stream, stream_type)
|
return get_metadata(stream, stream_type)
|
||||||
raise ValueError('No ebook found in RAR archive')
|
raise ValueError('No ebook found in RAR archive')
|
||||||
|
|
||||||
|
@ -3,9 +3,10 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from zipfile import ZipFile
|
|
||||||
from cStringIO import StringIO
|
|
||||||
|
|
||||||
|
from calibre.utils.zipfile import ZipFile
|
||||||
|
from calibre.ptempfile import TemporaryDirectory
|
||||||
|
from calibre import CurrentDir
|
||||||
|
|
||||||
def get_metadata(stream):
|
def get_metadata(stream):
|
||||||
from calibre.ebooks.metadata.meta import get_metadata
|
from calibre.ebooks.metadata.meta import get_metadata
|
||||||
@ -23,8 +24,10 @@ def get_metadata(stream):
|
|||||||
stream_type = stream_type[1:]
|
stream_type = stream_type[1:]
|
||||||
if stream_type in ('lit', 'opf', 'prc', 'mobi', 'fb2', 'epub',
|
if stream_type in ('lit', 'opf', 'prc', 'mobi', 'fb2', 'epub',
|
||||||
'rb', 'imp', 'pdf', 'lrf'):
|
'rb', 'imp', 'pdf', 'lrf'):
|
||||||
stream = StringIO(zf.read(f))
|
with TemporaryDirectory() as tdir:
|
||||||
return get_metadata(stream, stream_type)
|
with CurrentDir(tdir):
|
||||||
|
path = zf.extract(f)
|
||||||
|
return get_metadata(open(path, 'rb'), stream_type)
|
||||||
raise ValueError('No ebook found in ZIP archive')
|
raise ValueError('No ebook found in ZIP archive')
|
||||||
|
|
||||||
|
|
||||||
|
@ -796,10 +796,11 @@ class MobiReader(object):
|
|||||||
def get_metadata(stream):
|
def get_metadata(stream):
|
||||||
from calibre.utils.logging import Log
|
from calibre.utils.logging import Log
|
||||||
log = Log()
|
log = Log()
|
||||||
|
|
||||||
mi = MetaInformation(os.path.basename(stream.name), [_('Unknown')])
|
mi = MetaInformation(os.path.basename(stream.name), [_('Unknown')])
|
||||||
try:
|
try:
|
||||||
mh = MetadataHeader(stream, log)
|
mh = MetadataHeader(stream, log)
|
||||||
|
if mh.title and mh.title != _('Unknown'):
|
||||||
|
mi.title = mh.title
|
||||||
|
|
||||||
if mh.exth is not None:
|
if mh.exth is not None:
|
||||||
if mh.exth.mi is not None:
|
if mh.exth.mi is not None:
|
||||||
@ -818,10 +819,15 @@ def get_metadata(stream):
|
|||||||
else:
|
else:
|
||||||
data = mh.section_data(mh.first_image_index)
|
data = mh.section_data(mh.first_image_index)
|
||||||
buf = cStringIO.StringIO(data)
|
buf = cStringIO.StringIO(data)
|
||||||
|
try:
|
||||||
im = PILImage.open(buf)
|
im = PILImage.open(buf)
|
||||||
|
except:
|
||||||
|
log.exception('Failed to read MOBI cover')
|
||||||
|
else:
|
||||||
obuf = cStringIO.StringIO()
|
obuf = cStringIO.StringIO()
|
||||||
im.convert('RGBA').save(obuf, format='JPEG')
|
im.convert('RGB').save(obuf, format='JPEG')
|
||||||
mi.cover_data = ('jpg', obuf.getvalue())
|
mi.cover_data = ('jpg', obuf.getvalue())
|
||||||
except:
|
except:
|
||||||
log.exception()
|
log.filter_level = Log.DEBUG
|
||||||
|
log.exception('Failed to read MOBI metadata')
|
||||||
return mi
|
return mi
|
||||||
|
@ -131,7 +131,7 @@ class PMLMLizer(object):
|
|||||||
if item.href in self.link_hrefs.keys():
|
if item.href in self.link_hrefs.keys():
|
||||||
toc.append('* \\q="#%s"%s\\q\n' % (self.link_hrefs[item.href], item.title))
|
toc.append('* \\q="#%s"%s\\q\n' % (self.link_hrefs[item.href], item.title))
|
||||||
else:
|
else:
|
||||||
self.oeb.warn('Ignoring toc item: %s not found in document.' % item)
|
self.oeb_book.warn('Ignoring toc item: %s not found in document.' % item)
|
||||||
return ''.join(toc)
|
return ''.join(toc)
|
||||||
|
|
||||||
def get_text(self):
|
def get_text(self):
|
||||||
|
@ -217,33 +217,55 @@ def names(path):
|
|||||||
finally:
|
finally:
|
||||||
_libunrar.RARCloseArchive(arc_data)
|
_libunrar.RARCloseArchive(arc_data)
|
||||||
|
|
||||||
def extract_member(path, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I), name=None):
|
def _extract_member(path, match, name):
|
||||||
if hasattr(path, 'read'):
|
|
||||||
data = path.read()
|
def is_match(fname):
|
||||||
f = NamedTemporaryFile(suffix='.rar')
|
return (name is not None and fname == name) or \
|
||||||
f.write(data)
|
(match is not None and match.search(fname) is not None)
|
||||||
f.flush()
|
|
||||||
path = f.name
|
|
||||||
with TemporaryDirectory('_libunrar') as dir:
|
|
||||||
with CurrentDir(dir):
|
|
||||||
open_archive_data = RAROpenArchiveDataEx(ArcName=path, OpenMode=RAR_OM_EXTRACT, CmtBuf=None)
|
open_archive_data = RAROpenArchiveDataEx(ArcName=path, OpenMode=RAR_OM_EXTRACT, CmtBuf=None)
|
||||||
arc_data = _libunrar.RAROpenArchiveEx(byref(open_archive_data))
|
arc_data = _libunrar.RAROpenArchiveEx(byref(open_archive_data))
|
||||||
try:
|
try:
|
||||||
if open_archive_data.OpenResult != 0:
|
if open_archive_data.OpenResult != 0:
|
||||||
raise UnRARException(_interpret_open_error(open_archive_data.OpenResult, path))
|
raise UnRARException(_interpret_open_error(open_archive_data.OpenResult, path))
|
||||||
header_data = RARHeaderDataEx(CmtBuf=None)
|
header_data = RARHeaderDataEx(CmtBuf=None)
|
||||||
|
first = True
|
||||||
while True:
|
while True:
|
||||||
if _libunrar.RARReadHeaderEx(arc_data, byref(header_data)) != 0:
|
if _libunrar.RARReadHeaderEx(arc_data, byref(header_data)) != 0:
|
||||||
raise UnRARException('%s has no files'%path)
|
raise UnRARException('%s has no files'%path if first
|
||||||
|
else 'No match found in %s'%path)
|
||||||
|
file_name = header_data.FileNameW
|
||||||
|
if is_match(file_name):
|
||||||
PFCode = _libunrar.RARProcessFileW(arc_data, RAR_EXTRACT, None, None)
|
PFCode = _libunrar.RARProcessFileW(arc_data, RAR_EXTRACT, None, None)
|
||||||
if PFCode != 0:
|
if PFCode != 0:
|
||||||
raise UnRARException(_interpret_process_file_error(PFCode))
|
raise UnRARException(_interpret_process_file_error(PFCode))
|
||||||
file_name = header_data.FileNameW
|
abspath = os.path.abspath(*file_name.split('/'))
|
||||||
if (name is not None and file_name == name) or \
|
return abspath
|
||||||
(match is not None and match.search(file_name)):
|
else:
|
||||||
return header_data.FileNameW.replace('/', os.sep), \
|
PFCode = _libunrar.RARProcessFileW(arc_data, RAR_SKIP, None, None)
|
||||||
open(os.path.join(dir, *header_data.FileNameW.split('/')), 'rb').read()
|
if PFCode != 0:
|
||||||
|
raise UnRARException(_interpret_process_file_error(PFCode))
|
||||||
|
first = False
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
_libunrar.RARCloseArchive(arc_data)
|
_libunrar.RARCloseArchive(arc_data)
|
||||||
|
|
||||||
|
def extract_member(path, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I),
|
||||||
|
name=None, as_file=False):
|
||||||
|
if hasattr(path, 'read'):
|
||||||
|
data = path.read()
|
||||||
|
f = NamedTemporaryFile(suffix='.rar')
|
||||||
|
f.write(data)
|
||||||
|
f.flush()
|
||||||
|
path = f.name
|
||||||
|
|
||||||
|
path = os.path.abspath(path)
|
||||||
|
if as_file:
|
||||||
|
path = _extract_member(path, match, name)
|
||||||
|
return path, open(path, 'rb')
|
||||||
|
else:
|
||||||
|
with TemporaryDirectory('_libunrar') as tdir:
|
||||||
|
with CurrentDir(tdir):
|
||||||
|
path = _extract_member(path, match, name)
|
||||||
|
return path, open(path, 'rb').read()
|
||||||
|
|
||||||
|
@ -19,15 +19,13 @@ from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString, CData,
|
|||||||
from calibre.ebooks.metadata.opf2 import OPFCreator
|
from calibre.ebooks.metadata.opf2 import OPFCreator
|
||||||
from calibre import entity_to_unicode
|
from calibre import entity_to_unicode
|
||||||
from calibre.web import Recipe
|
from calibre.web import Recipe
|
||||||
from calibre.ebooks import render_html
|
|
||||||
from calibre.ebooks.metadata.toc import TOC
|
from calibre.ebooks.metadata.toc import TOC
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
from calibre.web.feeds import feed_from_xml, templates, feeds_from_index, Feed
|
from calibre.web.feeds import feed_from_xml, templates, feeds_from_index, Feed
|
||||||
from calibre.web.fetch.simple import option_parser as web2disk_option_parser
|
from calibre.web.fetch.simple import option_parser as web2disk_option_parser
|
||||||
from calibre.web.fetch.simple import RecursiveFetcher
|
from calibre.web.fetch.simple import RecursiveFetcher
|
||||||
from calibre.utils.threadpool import WorkRequest, ThreadPool, NoResultsPending
|
from calibre.utils.threadpool import WorkRequest, ThreadPool, NoResultsPending
|
||||||
from calibre.ptempfile import PersistentTemporaryFile, \
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
PersistentTemporaryDirectory
|
|
||||||
from calibre.utils.date import now as nowf
|
from calibre.utils.date import now as nowf
|
||||||
|
|
||||||
class BasicNewsRecipe(Recipe):
|
class BasicNewsRecipe(Recipe):
|
||||||
@ -928,63 +926,52 @@ class BasicNewsRecipe(Recipe):
|
|||||||
'''
|
'''
|
||||||
Create a generic cover for recipes that dont have a cover
|
Create a generic cover for recipes that dont have a cover
|
||||||
'''
|
'''
|
||||||
from calibre.gui2 import is_ok_to_use_qt
|
try:
|
||||||
if not is_ok_to_use_qt():
|
try:
|
||||||
return False
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
img_data = open(I('library.png'), 'rb').read()
|
Image, ImageDraw, ImageFont
|
||||||
tdir = PersistentTemporaryDirectory('_default_cover')
|
except ImportError:
|
||||||
img = os.path.join(tdir, 'logo.png')
|
import Image, ImageDraw, ImageFont
|
||||||
with open(img, 'wb') as g:
|
font_path = P('fonts/liberation/LiberationSerif-Bold.ttf')
|
||||||
g.write(img_data)
|
title = self.title if isinstance(self.title, unicode) else \
|
||||||
img = os.path.basename(img)
|
self.title.decode(preferred_encoding, 'replace')
|
||||||
html= u'''\
|
date = strftime(self.timefmt)
|
||||||
<html>
|
app = '['+__appname__ +' '+__version__+']'
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
COVER_WIDTH, COVER_HEIGHT = 590, 750
|
||||||
<style type="text/css">
|
img = Image.new('RGB', (COVER_WIDTH, COVER_HEIGHT), 'white')
|
||||||
body {
|
draw = ImageDraw.Draw(img)
|
||||||
background: white no-repeat fixed center center;
|
# Title
|
||||||
text-align: center;
|
font = ImageFont.truetype(font_path, 44)
|
||||||
vertical-align: center;
|
width, height = draw.textsize(title, font=font)
|
||||||
overflow: hidden;
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
font-size: 18px;
|
top = 15
|
||||||
}
|
draw.text((left, top), title, fill=(0,0,0), font=font)
|
||||||
h1 { font-family: serif; }
|
bottom = top + height
|
||||||
h2, h4 { font-family: monospace; }
|
# Date
|
||||||
</style>
|
font = ImageFont.truetype(font_path, 32)
|
||||||
</head>
|
width, height = draw.textsize(date, font=font)
|
||||||
<body>
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
<h1>%(title)s</h1>
|
draw.text((left, bottom+15), date, fill=(0,0,0), font=font)
|
||||||
<br/><br/>
|
# Vanity
|
||||||
<div style="position:relative">
|
font = ImageFont.truetype(font_path, 28)
|
||||||
<div style="position: absolute; left: 0; top: 0; width:100%%; height:100%%; vertical-align:center">
|
width, height = draw.textsize(app, font=font)
|
||||||
<img src="%(img)s" alt="calibre" style="opacity:0.3"/>
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
</div>
|
top = COVER_HEIGHT - height - 15
|
||||||
<div style="position: absolute; left: 0; top: 0; width:100%%; height:100%%; vertical-align:center">
|
draw.text((left, top), app, fill=(0,0,0), font=font)
|
||||||
<h2>%(date)s</h2>
|
# Logo
|
||||||
<br/><br/><br/><br/><br/>
|
logo = Image.open(I('library.png'), 'r')
|
||||||
<h3>%(author)s</h3>
|
width, height = logo.size
|
||||||
<br/><br/></br/><br/><br/><br/><br/><br/><br/>
|
left = max(int((COVER_WIDTH - width)/2.), 0)
|
||||||
<h4>Produced by %(app)s</h4>
|
top = max(int((COVER_HEIGHT - height)/2.), 0)
|
||||||
</div>
|
img.paste(logo, (left, top))
|
||||||
</div>
|
img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE)
|
||||||
</body>
|
|
||||||
</html>
|
img.convert('RGB').save(cover_file, 'JPEG')
|
||||||
'''%dict(title=self.title if isinstance(self.title, unicode) else self.title.decode(preferred_encoding, 'replace'),
|
|
||||||
author=self.__author__ if isinstance(self.__author__, unicode) else self.__author__.decode(preferred_encoding, 'replace'),
|
|
||||||
date=strftime(self.timefmt),
|
|
||||||
app=__appname__ +' '+__version__,
|
|
||||||
img=img)
|
|
||||||
hf = os.path.join(tdir, 'cover.htm')
|
|
||||||
with open(hf, 'wb') as f:
|
|
||||||
f.write(html.encode('utf-8'))
|
|
||||||
renderer = render_html(hf)
|
|
||||||
if renderer.tb is not None:
|
|
||||||
self.log.warning('Failed to render default cover')
|
|
||||||
self.log.debug(renderer.tb)
|
|
||||||
else:
|
|
||||||
cover_file.write(renderer.data)
|
|
||||||
cover_file.flush()
|
cover_file.flush()
|
||||||
|
except:
|
||||||
|
self.log.exception('Failed to generate default cover')
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_masthead_title(self):
|
def get_masthead_title(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user