mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Sync to trunk.
This commit is contained in:
commit
771b4845c1
52
recipes/b365realitatea.recipe
Normal file
52
recipes/b365realitatea.recipe
Normal file
@ -0,0 +1,52 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = u'2011, Silviu Cotoar\u0103'
|
||||
'''
|
||||
b365.realitatea.net
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class b365Realitatea(BasicNewsRecipe):
|
||||
title = u'b365 Realitatea'
|
||||
__author__ = u'Silviu Cotoar\u0103'
|
||||
publisher = u'b365 Realitatea'
|
||||
description = u'b365 Realitatea'
|
||||
oldest_article = 5
|
||||
language = 'ro'
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
category = 'Ziare,Romania,Bucuresti'
|
||||
encoding = 'utf-8'
|
||||
cover_url = 'http://b365.realitatea.net/wp-content/themes/b/images/b365-logo.png'
|
||||
|
||||
conversion_options = {
|
||||
'comments' : description
|
||||
,'tags' : category
|
||||
,'language' : language
|
||||
,'publisher' : publisher
|
||||
}
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='div', attrs={'class':'newsArticle'})
|
||||
]
|
||||
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'class':'date'})
|
||||
, dict(name='dic', attrs={'class':'addthis_toolbox addthis_default_style'})
|
||||
, dict(name='div', attrs={'class':'related_posts'})
|
||||
, dict(name='div', attrs={'id':'RelevantiWidget'})
|
||||
]
|
||||
|
||||
remove_tags_after = [
|
||||
dict(name='div', attrs={'id':'RelevantiWidget'})
|
||||
]
|
||||
feeds = [
|
||||
(u'\u0218tiri', u'http://b365.realitatea.net/rss-full/')
|
||||
]
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
return self.adeify_images(soup)
|
||||
|
35
recipes/capital_gr.recipe
Normal file
35
recipes/capital_gr.recipe
Normal file
@ -0,0 +1,35 @@
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
class Capital(BasicNewsRecipe):
|
||||
title = 'Capital.gr'
|
||||
__author__ ='Stelios'
|
||||
description = 'Financial News from Greece'
|
||||
#max_articles_per_feed = 100
|
||||
oldest_article = 3
|
||||
publisher = 'Capital.gr'
|
||||
category = 'news, GR'
|
||||
language = 'el'
|
||||
encoding = 'windows-1253'
|
||||
cover_url = 'http://files.capital.gr/images/caplogo.gif'
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
remove_empty_feeds = True
|
||||
keep_only_tags = [
|
||||
dict(name='h1'),
|
||||
dict(name='p'),
|
||||
dict(name='span', attrs={'id' : ["textbody"]})
|
||||
]
|
||||
|
||||
#3 posts seemed to have utf8 encoding
|
||||
feeds = [
|
||||
(u'\u039F\u039B\u0395\u03A3 \u039F\u0399 \u0395\u0399\u0394\u0397\u03A3\u0395\u0399\u03A3', 'http://www.capital.gr/news/newsrss.asp?s=-1'),
|
||||
(u'\u0395\u03A0\u0399\u03A7\u0395\u0399\u03A1\u0397\u03A3\u0395\u0399\u03A3', 'http://www.capital.gr/news/newsrss.asp?s=-2'),
|
||||
(u'\u0391\u0393\u039F\u03A1\u0395\u03A3', 'http://www.capital.gr/news/newsrss.asp?s=-3'),
|
||||
(u'\u039F\u0399\u039A\u039F\u039D\u039F\u039C\u0399\u0391', 'http://www.capital.gr/news/newsrss.asp?s=-4'),
|
||||
(u'\u03A7\u03A1\u0397\u039C. \u0391\u039D\u0391\u039A\u039F\u0399\u039D\u03A9\u03A3\u0395\u0399\u03A3', 'http://www.capital.gr/news/newsrss.asp?s=-6'),
|
||||
(u'\u039C\u03CC\u03BD\u03B9\u03BC\u03B5\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B5\u03C2: \u039C\u0395 \u0391\u03A0\u039F\u03A8\u0397', 'http://www.capital.gr/articles/articlesrss.asp?catid=4'),
|
||||
(u'\u039C\u03CC\u03BD\u03B9\u03BC\u03B5\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B5\u03C2: \u03A3\u0399\u03A9\u03A0\u0397\u03A4\u0397\u03A1\u0399\u039F', 'http://www.capital.gr/articles/articlesrss.asp?catid=6'),
|
||||
(u'\u039C\u03CC\u03BD\u03B9\u03BC\u03B5\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B5\u03C2: \u03A0\u0399\u03A3\u03A9 \u0391\u03A0\u039F \u03A4\u0399\u03A3 \u0393\u03A1\u0391\u039C\u039C\u0395\u03A3', 'http://www.capital.gr/articles/articlesrss.asp?catid=8'),
|
||||
#(u'\u039C\u03CC\u03BD\u03B9\u03BC\u03B5\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B5\u03C2: \u03A4\u0395\u03A7\u039D\u039F\u039B\u039F\u0393\u0399\u0391', 'http://www.capital.gr/news/newsrss.asp?s=-8') not working for now
|
||||
]
|
||||
|
51
recipes/catavencii.recipe
Normal file
51
recipes/catavencii.recipe
Normal file
@ -0,0 +1,51 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = u'2011, Silviu Cotoar\u0103'
|
||||
'''
|
||||
catavencii.ro
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class Catavencii(BasicNewsRecipe):
|
||||
title = u'Ca\u0163avencii'
|
||||
__author__ = u'Silviu Cotoar\u0103'
|
||||
publisher = u'Ca\u0163avencii'
|
||||
description = u'Ca\u0163avencii'
|
||||
oldest_article = 5
|
||||
language = 'ro'
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
category = 'Ziare,Romania'
|
||||
encoding = 'utf-8'
|
||||
cover_url = 'http://www.simonatache.ro/wp-content/uploads/2011/06/catavencii-logo.png'
|
||||
|
||||
conversion_options = {
|
||||
'comments' : description
|
||||
,'tags' : category
|
||||
,'language' : language
|
||||
,'publisher' : publisher
|
||||
}
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='div', attrs={'id':'content'})
|
||||
]
|
||||
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'id':'breadcrumbs'})
|
||||
, dict(name='span', attrs={'class':'info'})
|
||||
, dict(name='div', attrs={'id':'social-media-article'})
|
||||
]
|
||||
|
||||
remove_tags_after = [
|
||||
dict(name='div', attrs={'id':'social-media-article'})
|
||||
]
|
||||
feeds = [
|
||||
(u'\u0218tiri', u'http://www.catavencii.ro/rss')
|
||||
]
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
return self.adeify_images(soup)
|
@ -1,10 +1,11 @@
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
import re
|
||||
class AdvancedUserRecipe1306061239(BasicNewsRecipe):
|
||||
title = u'The Daily Mirror'
|
||||
description = 'News as provide by The Daily Mirror -UK'
|
||||
|
||||
__author__ = 'Dave Asbury'
|
||||
# last updated 30/10/11
|
||||
language = 'en_GB'
|
||||
|
||||
cover_url = 'http://yookeo.com/screens/m/i/mirror.co.uk.jpg'
|
||||
@ -12,26 +13,30 @@ class AdvancedUserRecipe1306061239(BasicNewsRecipe):
|
||||
masthead_url = 'http://www.nmauk.co.uk/nma/images/daily_mirror.gif'
|
||||
|
||||
|
||||
oldest_article = 1
|
||||
max_articles_per_feed = 100
|
||||
oldest_article = 2
|
||||
max_articles_per_feed = 30
|
||||
remove_empty_feeds = True
|
||||
remove_javascript = True
|
||||
no_stylesheets = True
|
||||
extra_css = '''
|
||||
body{ text-align: justify; font-family:Arial,Helvetica,sans-serif; font-size:11px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:normal;}
|
||||
'''
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='h1'),
|
||||
dict(attrs={'class':['article-attr']}),
|
||||
dict(name='div', attrs={'class' : [ 'article-body', 'crosshead']})
|
||||
|
||||
|
||||
dict(name='div',attrs={'id' : 'body-content'})
|
||||
]
|
||||
|
||||
remove_tags_after = [dict (name='div',attrs={'class' : 'related'})]
|
||||
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'class' : ['caption', 'article-resize']}),
|
||||
dict( attrs={'class':'append-html'})
|
||||
dict(name='div',attrs={'id' : ['sidebar','menu','search-box','roffers-top']}),
|
||||
dict(name='div',attrs={'class' :['inline-ad span-16 last','article-resize','related','list teasers']}),
|
||||
dict(attrs={'class' : ['channellink','article-tags','replace','append-html']}),
|
||||
dict(name='div',attrs={'class' : 'span-12 last sl-others addthis_toolbox addthis_default_style'})
|
||||
]
|
||||
|
||||
|
||||
preprocess_regexps = [
|
||||
(re.compile(r'<dl class="q-search">.*?</dl>', re.IGNORECASE | re.DOTALL), lambda match: '')]
|
||||
|
||||
|
||||
feeds = [
|
||||
@ -48,5 +53,5 @@ class AdvancedUserRecipe1306061239(BasicNewsRecipe):
|
||||
,(u'Travel','http://www.mirror.co.uk/advice/travel/rss.xml')
|
||||
|
||||
# example of commented out feed not needed ,(u'Travel','http://www.mirror.co.uk/advice/travel/rss.xml')
|
||||
]
|
||||
|
||||
]
|
||||
|
@ -16,7 +16,7 @@ class DeutscheWelle_es(BasicNewsRecipe):
|
||||
max_articles_per_feed = 100
|
||||
use_embedded_content = False
|
||||
no_stylesheets = True
|
||||
language = 'de_ES'
|
||||
language = 'de'
|
||||
publication_type = 'newsportal'
|
||||
remove_empty_feeds = True
|
||||
masthead_url = 'http://www.dw-world.de/skins/std/channel1/pics/dw_logo1024.gif'
|
||||
|
BIN
recipes/icons/b365realitatea.png
Normal file
BIN
recipes/icons/b365realitatea.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 323 B |
BIN
recipes/icons/catavencii.png
Normal file
BIN
recipes/icons/catavencii.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 600 B |
34
recipes/in_gr.recipe
Normal file
34
recipes/in_gr.recipe
Normal file
@ -0,0 +1,34 @@
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
class ingr(BasicNewsRecipe):
|
||||
title = 'in.gr'
|
||||
__author__ = 'Stelios'
|
||||
description = 'News from Greece'
|
||||
# max_articles_per_feed = 100
|
||||
oldest_article = 4
|
||||
publisher = 'in.gr'
|
||||
category = 'news, GR'
|
||||
language = 'el'
|
||||
encoding = 'utf8'
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
remove_empty_feeds = True
|
||||
encoding = 'utf8'
|
||||
keep_only_tags = [
|
||||
dict(name='h1'),
|
||||
|
||||
dict(name='div', attrs={'id' : ['in-news-article']})
|
||||
]
|
||||
remove_tags = [
|
||||
dict(name='em', attrs={'class' : ['credits']}),
|
||||
dict(name='div', attrs={'class' : ['article-tools-hor', 'promo-banners gAds', 'main', 'article-listen-player', 'article-tools-hor-bttm', 'tools-sec', 'article-tools', 'article-listen-player-ver']})
|
||||
]
|
||||
|
||||
|
||||
feeds = [
|
||||
(u'\u0395\u03BB\u03BB\u03AC\u03B4\u03B1', 'http://rss.in.gr/feed/news/greece'),
|
||||
(u'\u0395\u03B9\u03B4\u03AE\u03C3\u03B5\u03B9\u03C2', 'http://rss.in.gr/feed/news'),
|
||||
(u'\u039A\u03CC\u03C3\u03BC\u03BF\u03C2', 'http://rss.in.gr/feed/news/world'),
|
||||
(u'\u0395\u03C0\u03B9\u03C3\u03C4\u03AE\u03BC\u03B7', 'http://rss.in.gr/feed/news/science'),
|
||||
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://rss.in.gr/feed/news/culture')
|
||||
]
|
43
recipes/men24_gr.recipe
Normal file
43
recipes/men24_gr.recipe
Normal file
@ -0,0 +1,43 @@
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
class Men24(BasicNewsRecipe):
|
||||
title = 'Men24.gr'
|
||||
__author__ = 'Stelios'
|
||||
description = 'Greek Mens portal'
|
||||
oldest_article = 14
|
||||
max_articles_per_feed = 100
|
||||
language = 'el'
|
||||
cover_url = 'http://www.men24.gr/ast/img/men24Logo.jpg'
|
||||
category = 'magazines, GR'
|
||||
language = 'el'
|
||||
encoding = 'windows-1253'
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
remove_empty_feeds = True
|
||||
extra_css = '''
|
||||
.artPrintTitle{font-family :Arial,Helvetica,sans-serif; font-weight: bold; font-size:large;}
|
||||
.artPrintSubtitle{font-family :Arial,Helvetica,sans-serif; font-size:x-small;}
|
||||
'''
|
||||
remove_tags = [
|
||||
dict(name='td', attrs={'class':['artPrintCategory']}),
|
||||
dict(name='table', attrs={'class':['footer']}),
|
||||
dict(name='img')
|
||||
]
|
||||
feeds = [
|
||||
(u'\u038C\u03BB\u03B5\u03C2 \u03BF\u03B9 \u03B5\u03B9\u03B4\u03AE\u03C3\u03B5\u03B9\u03C2', 'http://www.men24.gr/svc/rss/lastNews/'),
|
||||
(u'\u03A3\u03C4\u03C5\u03BB', 'http://www.men24.gr/svc/rss/categoryNews/?category=style'),
|
||||
(u'Fitness', 'http://www.men24.gr/svc/rss/categoryNews/?category=fitness'),
|
||||
(u'Gadgets', 'http://www.men24.gr/svc/rss/categoryNews/?category=gadgets'),
|
||||
(u'\u0394\u03B9\u03B1\u03C3\u03BA\u03AD\u03B4\u03B1\u03C3\u03B7', 'http://www.men24.gr/svc/rss/categoryNews/?category=fun'),
|
||||
(u'\u03A7\u03C1\u03AE\u03BC\u03B1 \u03BA\u03B1\u03B9 \u039A\u03B1\u03C1\u03B9\u03AD\u03C1\u03B1', 'http://www.men24.gr/svc/rss/categoryNews/?category=money'),
|
||||
(u'Special Edition', 'http://www.men24.gr/svc/rss/categoryNews/?category=special'),
|
||||
(u'\u0388\u03C1\u03C9\u03C4\u03B1\u03C2 \u03BA\u03B1\u03B9 Sex', 'http://www.men24.gr/svc/rss/categoryNews/?category=love'),
|
||||
(u'\u0386\u03BD\u03C4\u03C1\u03B5\u03C2 \u03C4\u03BF\u03C5 24', 'http://www.men24.gr/svc/rss/categoryNews/?category=men'),
|
||||
(u'\u0393\u03C5\u03BD\u03B1\u03AF\u03BA\u03B5\u03C2', 'http://www.men24.gr/svc/rss/categoryNews/?category=women'),
|
||||
(u'\u039F\u03B4\u03B7\u03B3\u03BF\u03AF', 'http://www.men24.gr/svc/rss/categoryNews/?category=guides'),
|
||||
(u'\u03A4\u03B6\u03CC\u03B3\u03BF\u03C2', 'http://www.men24.gr/svc/rss/categoryNews/?category=gamble')
|
||||
|
||||
]
|
||||
|
||||
def print_version(self, url):
|
||||
return url.replace('.asp', '.print.asp')
|
48
recipes/newsbeast.recipe
Normal file
48
recipes/newsbeast.recipe
Normal file
@ -0,0 +1,48 @@
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
|
||||
class newsbeast(BasicNewsRecipe):
|
||||
title = 'Newsbeast'
|
||||
__author__ = 'Stelios'
|
||||
description = 'News from Greece'
|
||||
oldest_article = 2
|
||||
max_articles_per_feed = 100
|
||||
publisher = 'newsbeast'
|
||||
category = 'news, GR'
|
||||
language = 'el'
|
||||
encoding = 'utf8'
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
remove_empty_feeds = True
|
||||
encoding = 'utf8'
|
||||
keep_only_tags = [
|
||||
dict(name='div', attrs={'class' : ['article-title']}),
|
||||
# dict(name='img', attrs={'class' : ['article_photo']}),
|
||||
#If enabled feeds exceede 15MB
|
||||
dict(name='div', attrs={'class' : ['txt']})
|
||||
]
|
||||
remove_tags = [
|
||||
dict(name='table', attrs={'id':['artFoot']}),
|
||||
dict(name='img'),
|
||||
#If removed feeds exceede 15MB
|
||||
dict(name='p', attrs={'class':['article-details']})
|
||||
]
|
||||
|
||||
feeds = [
|
||||
(u'\u0395\u03BB\u03BB\u03AC\u03B4\u03B1', 'http://www.newsbeast.gr/feeds/greece'),
|
||||
(u'\u039A\u03CC\u03C3\u03BC\u03BF\u03C2', 'http://www.newsbeast.gr/feeds/world'),
|
||||
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03BA\u03AE', 'http://www.newsbeast.gr/feeds/politiki'),
|
||||
(u'\u039F\u03B9\u03BA\u03BF\u03BD\u03BF\u03BC\u03AF\u03B1', 'http://www.newsbeast.gr/feeds/financial'),
|
||||
(u'\u0391\u03B8\u03BB\u03B7\u03C4\u03B9\u03BA\u03AC', 'http://www.newsbeast.gr/feeds/sports'),
|
||||
(u'\u039A\u03BF\u03B9\u03BD\u03C9\u03BD\u03AF\u03B1', 'http://www.newsbeast.gr/feeds/society'),
|
||||
(u'\u03A0\u03B5\u03C1\u03B9\u03B2\u03AC\u03BB\u03BB\u03BF\u03BD', 'http://www.newsbeast.gr/feeds/environment'),
|
||||
(u'Media', 'http://www.newsbeast.gr/feeds/media'),
|
||||
(u'\u0394\u03B9\u03B1\u03C3\u03BA\u03AD\u03B4\u03B1\u03C3\u03B7', 'http://www.newsbeast.gr/feeds/entertainment'),
|
||||
(u'Lifestyle', 'http://www.newsbeast.gr/feeds/lifestyle'),
|
||||
(u'\u03A4\u03B5\u03C7\u03BD\u03BF\u03BB\u03BF\u03B3\u03AF\u03B1', 'http://www.newsbeast.gr/feeds/technology'),
|
||||
(u'\u0391\u03C5\u03C4\u03BF\u03BA\u03AF\u03BD\u03B7\u03C4\u03BF', 'http://www.newsbeast.gr/feeds/car'),
|
||||
(u'\u0393\u03C5\u03BD\u03B1\u03AF\u03BA\u03B1', 'http://www.newsbeast.gr/feeds/woman'),
|
||||
(u'\u03A5\u03B3\u03B5\u03AF\u03B1', 'http://www.newsbeast.gr/feeds/health'),
|
||||
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://www.newsbeast.gr/feeds/culture'),
|
||||
(u'\u038C,\u03C4\u03B9 \u03BD\u03B1 \u03BD\u03B1\u03B9', 'http://www.newsbeast.gr/feeds/weird')
|
||||
]
|
@ -1,6 +1,6 @@
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||
__copyright__ = '2008-2011, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
www.nin.co.rs
|
||||
'''
|
||||
@ -29,6 +29,7 @@ class Nin(BasicNewsRecipe):
|
||||
use_embedded_content = False
|
||||
language = 'sr'
|
||||
publication_type = 'magazine'
|
||||
masthead_url = 'http://www.nin.co.rs/img/head/logo.jpg'
|
||||
extra_css = """
|
||||
@font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
|
||||
body{font-family: Verdana, Lucida, sans1, sans-serif}
|
||||
@ -72,9 +73,11 @@ class Nin(BasicNewsRecipe):
|
||||
def get_cover_url(self):
|
||||
cover_url = None
|
||||
soup = self.index_to_soup(self.INDEX)
|
||||
link_item = soup.find('img',attrs={'width':'100','border':'0'})
|
||||
if link_item:
|
||||
cover_url = self.PREFIX + link_item['src']
|
||||
for item in soup.findAll('a', href=True):
|
||||
if item['href'].startswith('/pages/issue.php?id='):
|
||||
simg = item.find('img')
|
||||
if simg:
|
||||
return self.PREFIX + item.img['src']
|
||||
return cover_url
|
||||
|
||||
def parse_index(self):
|
||||
|
26
recipes/protagon.recipe
Normal file
26
recipes/protagon.recipe
Normal file
@ -0,0 +1,26 @@
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
|
||||
class protagon(BasicNewsRecipe):
|
||||
title = 'Protagon'
|
||||
__author__ = 'Stelios'
|
||||
description = 'Opinion articles in Greek'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
publisher = 'Various'
|
||||
category = 'GR'
|
||||
language = 'el'
|
||||
encoding = 'utf8'
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
remove_empty_feeds = True
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='h1', attrs={'id' : ['title']}),
|
||||
dict(name='div', attrs={'class' : ['freetext']})
|
||||
]
|
||||
|
||||
feeds = [
|
||||
(u'\u0398\u03AD\u03BC\u03B1\u03C4\u03B1', 'http://www.protagon.gr/rss?i=protagon.el.8emata')
|
||||
]
|
||||
|
@ -40,7 +40,7 @@ class Sciencenews(BasicNewsRecipe):
|
||||
,dict(name='div', attrs={'class': 'embiggen'})
|
||||
]
|
||||
|
||||
feeds = [(u"Science News / News Items", u'http://sciencenews.org/view/feed/type/news/name/news.rss')]
|
||||
feeds = [(u"Science News / News Items", u'http://sciencenews.org/index.php/feed/type/news/name/news.rss/view/feed/name/all.rss')]
|
||||
|
||||
def get_cover_url(self):
|
||||
cover_url = None
|
||||
|
14
recipes/sigma_live.recipe
Normal file
14
recipes/sigma_live.recipe
Normal file
@ -0,0 +1,14 @@
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class sigmalive(BasicNewsRecipe):
|
||||
title = u'SigmaLive'
|
||||
__author__ = 'Stelios'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
auto_cleanup = True
|
||||
category = 'news, CY'
|
||||
description = 'Cypriot News'
|
||||
language = 'el'
|
||||
encoding = 'utf8'
|
||||
feeds = [(u'sigmalive', u'http://sigmalive.com/rss/latest')]
|
||||
|
37
recipes/skai.recipe
Normal file
37
recipes/skai.recipe
Normal file
@ -0,0 +1,37 @@
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
|
||||
class SKAI(BasicNewsRecipe):
|
||||
title = 'SKAI'
|
||||
__author__ = 'Stelios'
|
||||
description = 'News from Greece'
|
||||
oldest_article = 2
|
||||
max_articles_per_feed = 100
|
||||
publisher = 'skai.gr'
|
||||
category = 'news, GR'
|
||||
language = 'el'
|
||||
encoding = 'utf8'
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
remove_empty_feeds = True
|
||||
encoding = 'utf8'
|
||||
keep_only_tags = [
|
||||
dict(name='h1'),
|
||||
dict(name='div', attrs={'class' : ['articleText']})
|
||||
]
|
||||
|
||||
|
||||
feeds = [
|
||||
(u'\u039A\u03C5\u03C1\u03B9\u03CC\u03C4\u03B5\u03C1\u03B5\u03C2 \u0395\u03B9\u03B4\u03AE\u03C3\u03B5\u03B9\u03C2', 'http://feeds.feedburner.com/skai/Uulu'),
|
||||
(u'\u0395\u03BB\u03BB\u03AC\u03B4\u03B1', 'http://feeds.feedburner.com/skai/PLwa'),
|
||||
(u'\u039A\u03CC\u03C3\u03BC\u03BF\u03C2', 'http://feeds.feedburner.com/skai/aqOL'),
|
||||
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03BA\u03AE','http://feeds.feedburner.com/skai/yinm'),
|
||||
(u'\u039F\u03B9\u03BA\u03BF\u03BD\u03BF\u03BC\u03AF\u03B1', 'http://feeds.feedburner.com/skai/oPUt'),
|
||||
(u'\u03A4\u03B5\u03C7\u03BD\u03BF\u03BB\u03BF\u03B3\u03AF\u03B1', 'http://feeds.feedburner.com/skai/fqsg'),
|
||||
(u'\u0391\u03B8\u03BB\u03B7\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://feeds.feedburner.com/skai/TfmK'),
|
||||
(u'\u03A5\u03B3\u03B5\u03AF\u03B1', 'http://feeds.feedburner.com/skai/TABn'),
|
||||
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://feeds.feedburner.com/skai/ppGl'),
|
||||
(u'\u0391\u03C5\u03C4\u03BF\u03BA\u03AF\u03BD\u03B7\u03C3\u03B7', 'http://feeds.feedburner.com/skai/HCCc'),
|
||||
(u'\u03A0\u03B5\u03C1\u03B9\u03B2\u03AC\u03BB\u03BB\u03BF\u03BD', 'http://feeds.feedburner.com/skai/jVWs'),
|
||||
(u'\u03A0\u03B1\u03C1\u03AC\u03BE\u03B5\u03BD\u03B1', 'http://feeds.feedburner.com/skai/bpAR')
|
||||
]
|
39
recipes/tovima.recipe
Normal file
39
recipes/tovima.recipe
Normal file
@ -0,0 +1,39 @@
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
class Tovima(BasicNewsRecipe):
|
||||
title = 'To Vima'
|
||||
__author__ = 'Stelios'
|
||||
description = ' News from Greece'
|
||||
#max_articles_per_feed = 100
|
||||
oldest_article = 3
|
||||
publisher = 'To Vima'
|
||||
category = 'news, GR'
|
||||
language = 'el'
|
||||
encoding = 'utf8'
|
||||
cover_url = 'http://www.tovima.gr/Themes/1/Default/Media/Home//small-n-short-logo.jpg'
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
remove_empty_feeds = True
|
||||
extra_css = '''
|
||||
.article_title{font-family :Arial,Helvetica,sans-serif; font-weight: bold; font-size:large;}
|
||||
.article_text{font-family :Arial,Helvetica,sans-serif; font-size:x-small;}
|
||||
'''
|
||||
keep_only_tags = [
|
||||
|
||||
dict(name='div', attrs={'class' : ['article_title']}),
|
||||
dict(name='div', attrs={'class' : ['article_text']})
|
||||
]
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'class' : ['article_cat']})
|
||||
]
|
||||
feeds = [
|
||||
(u'\u03C0\u03BF\u03BB\u03B9\u03C4\u03B9\u03BA\u03AE', 'http://www.tovima.gr/feed/politics/'),
|
||||
(u'\u03BF\u03B9\u03BA\u03BF\u03BD\u03BF\u03BC\u03AF\u03B1', 'http://www.tovima.gr/feed/finance/'),
|
||||
(u'\u03B3\u03BD\u03CE\u03BC\u03B5\u03C2', 'http://www.tovima.gr/feed/opinions/'),
|
||||
(u'blogs', 'http://www.tovima.gr/feed/blogs/'),
|
||||
(u'\u03BA\u03CC\u03C3\u03BC\u03BF\u03C2','http://www.tovima.gr/feed/world/'),
|
||||
(u'science', 'http://www.tovima.gr/feed/science/'),
|
||||
(u'\u03BA\u03BF\u03B9\u03BD\u03C9\u03BD\u03AF\u03B1', 'http://www.tovima.gr/feed/society/'),
|
||||
(u'\u03C0\u03BF\u03BB\u03B9\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://www.tovima.gr/feed/culture/'),
|
||||
(u'\u03B1\u03B8\u03BB\u03B7\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://www.tovima.gr/feed/sports/')
|
||||
]
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 mode: python -*-
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
@ -123,6 +123,9 @@ class ZeitEPUBAbo(BasicNewsRecipe):
|
||||
|
||||
# new login process
|
||||
response = browser.open(url)
|
||||
# Get rid of nested form
|
||||
response.set_data(response.get_data().replace('<div><form action="/abo/zeit_digital?destination=node%2F94" accept-charset="UTF-8" method="post" id="user-login-form" class="zol_inlinelabel">', ''))
|
||||
browser.set_response(response)
|
||||
browser.select_form(nr=2)
|
||||
browser.form['name']=self.username
|
||||
browser.form['pass']=self.password
|
||||
@ -178,7 +181,11 @@ class ZeitEPUBAbo(BasicNewsRecipe):
|
||||
browser = self.get_browser()
|
||||
|
||||
# new login process
|
||||
browser.open(url)
|
||||
response=browser.open(url)
|
||||
# Get rid of nested form
|
||||
response.set_data(response.get_data().replace('<div><form action="/abo/zeit_digital?destination=node%2F94" accept-charset="UTF-8" method="post" id="user-login-form" class="zol_inlinelabel">', ''))
|
||||
browser.set_response(response)
|
||||
|
||||
browser.select_form(nr=2)
|
||||
browser.form['name']=self.username
|
||||
browser.form['pass']=self.password
|
||||
@ -211,4 +218,3 @@ class ZeitEPUBAbo(BasicNewsRecipe):
|
||||
self.log.warning('Using static old low-res cover')
|
||||
cover_url = 'http://images.zeit.de/bilder/titelseiten_zeit/1946/001_001.jpg'
|
||||
return cover_url
|
||||
|
||||
|
12
recipes/zougla.recipe
Normal file
12
recipes/zougla.recipe
Normal file
@ -0,0 +1,12 @@
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class AdvancedUserRecipe1320264153(BasicNewsRecipe):
|
||||
title = u'zougla'
|
||||
__author__ = 'Stelios'
|
||||
language = 'el'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
auto_cleanup = True
|
||||
|
||||
feeds = [(u'zougla', u'http://www.zougla.gr/ArticleRss.xml')]
|
||||
|
@ -36,7 +36,8 @@ class ANDROID(USBMS):
|
||||
0xca2 : [0x100, 0x0227, 0x0226, 0x222],
|
||||
0xca3 : [0x100, 0x0227, 0x0226, 0x222],
|
||||
0xca4 : [0x100, 0x0227, 0x0226, 0x222],
|
||||
0xca9 : [0x100, 0x0227, 0x0226, 0x222]
|
||||
0xca9 : [0x100, 0x0227, 0x0226, 0x222],
|
||||
0xcac : [0x100, 0x0227, 0x0226, 0x222],
|
||||
},
|
||||
|
||||
# Eken
|
||||
@ -138,8 +139,12 @@ class ANDROID(USBMS):
|
||||
# Advent
|
||||
0x0955 : { 0x7100 : [0x9999] }, # This is the same as the Notion Ink Adam
|
||||
|
||||
# Kobo
|
||||
0x2237: { 0x2208 : [0x0226] },
|
||||
|
||||
}
|
||||
EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books']
|
||||
EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books',
|
||||
'sdcard/ebooks']
|
||||
EXTRA_CUSTOMIZATION_MESSAGE = _('Comma separated list of directories to '
|
||||
'send e-books to on the device. The first one that exists will '
|
||||
'be used')
|
||||
@ -149,7 +154,7 @@ class ANDROID(USBMS):
|
||||
'GT-I5700', 'SAMSUNG', 'DELL', 'LINUX', 'GOOGLE', 'ARCHOS',
|
||||
'TELECHIP', 'HUAWEI', 'T-MOBILE', 'SEMC', 'LGE', 'NVIDIA',
|
||||
'GENERIC-', 'ZTE', 'MID', 'QUALCOMM', 'PANDIGIT', 'HYSTON',
|
||||
'VIZIO', 'GOOGLE', 'FREESCAL']
|
||||
'VIZIO', 'GOOGLE', 'FREESCAL', 'KOBO_INC']
|
||||
WINDOWS_MAIN_MEM = ['ANDROID_PHONE', 'A855', 'A853', 'INC.NEXUS_ONE',
|
||||
'__UMS_COMPOSITE', '_MB200', 'MASS_STORAGE', '_-_CARD', 'SGH-I897',
|
||||
'GT-I9000', 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID',
|
||||
@ -160,7 +165,8 @@ class ANDROID(USBMS):
|
||||
'MB860', 'MULTI-CARD', 'MID7015A', 'INCREDIBLE', 'A7EB', 'STREAK',
|
||||
'MB525', 'ANDROID2.3', 'SGH-I997', 'GT-I5800_CARD', 'MB612',
|
||||
'GT-S5830_CARD', 'GT-S5570_CARD', 'MB870', 'MID7015A',
|
||||
'ALPANDIGITAL', 'ANDROID_MID', 'VTAB1008', 'EMX51_BBG_ANDROI']
|
||||
'ALPANDIGITAL', 'ANDROID_MID', 'VTAB1008', 'EMX51_BBG_ANDROI',
|
||||
'UMS', '.K080']
|
||||
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
||||
'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
||||
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',
|
||||
|
@ -61,18 +61,25 @@ class KOBO(USBMS):
|
||||
' ebook file itself. With this option, calibre will send a '
|
||||
'separate cover image to the reader, useful if you '
|
||||
'have modified the cover.'),
|
||||
_('Upload Black and White Covers')
|
||||
_('Upload Black and White Covers'),
|
||||
_('Show expired books') +
|
||||
':::'+_('A bug in an earlier version left non kepubs book records'
|
||||
' in the datbase. With this option Calibre will show the '
|
||||
'expired records and allow you to delete them with '
|
||||
'the new delete logic.'),
|
||||
]
|
||||
|
||||
EXTRA_CUSTOMIZATION_DEFAULT = [
|
||||
', '.join(['tags']),
|
||||
True,
|
||||
True,
|
||||
True
|
||||
]
|
||||
|
||||
OPT_COLLECTIONS = 0
|
||||
OPT_UPLOAD_COVERS = 1
|
||||
OPT_UPLOAD_GRAYSCALE_COVERS = 2
|
||||
OPT_SHOW_EXPIRED_BOOK_RECORDS = 3
|
||||
|
||||
def initialize(self):
|
||||
USBMS.initialize(self)
|
||||
@ -232,18 +239,23 @@ class KOBO(USBMS):
|
||||
self.dbversion = result[0]
|
||||
|
||||
debug_print("Database Version: ", self.dbversion)
|
||||
|
||||
opts = self.settings()
|
||||
if self.dbversion >= 16:
|
||||
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
|
||||
query= ('select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
|
||||
'ImageID, ReadStatus, ___ExpirationStatus, FavouritesIndex, Accessibility from content where ' \
|
||||
'BookID is Null and ( ___ExpirationStatus <> "3" or ___ExpirationStatus is Null)'
|
||||
'BookID is Null and not ((___ExpirationStatus=3 or ___ExpirationStatus is Null) %(expiry)s') % dict(expiry=' and ContentType = 6)' \
|
||||
if opts.extra_customization[self.OPT_SHOW_EXPIRED_BOOK_RECORDS] else ')')
|
||||
elif self.dbversion < 16 and self.dbversion >= 14:
|
||||
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
|
||||
query= ('select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
|
||||
'ImageID, ReadStatus, ___ExpirationStatus, FavouritesIndex, "-1" as Accessibility from content where ' \
|
||||
'BookID is Null and ( ___ExpirationStatus <> "3" or ___ExpirationStatus is Null)'
|
||||
'BookID is Null and not ((___ExpirationStatus=3 or ___ExpirationStatus is Null) %(expiry)s') % dict(expiry=' and ContentType = 6)' \
|
||||
if opts.extra_customization[self.OPT_SHOW_EXPIRED_BOOK_RECORDS] else ')')
|
||||
elif self.dbversion < 14 and self.dbversion >= 8:
|
||||
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
|
||||
query= ('select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
|
||||
'ImageID, ReadStatus, ___ExpirationStatus, "-1" as FavouritesIndex, "-1" as Accessibility from content where ' \
|
||||
'BookID is Null and ( ___ExpirationStatus <> "3" or ___ExpirationStatus is Null)'
|
||||
'BookID is Null and not ((___ExpirationStatus=3 or ___ExpirationStatus is Null) %(expiry)s') % dict(expiry=' and ContentType = 6)' \
|
||||
if opts.extra_customization[self.OPT_SHOW_EXPIRED_BOOK_RECORDS] else ')')
|
||||
else:
|
||||
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
|
||||
'ImageID, ReadStatus, "-1" as ___ExpirationStatus, "-1" as FavouritesIndex, "-1" as Accessibility from content where BookID is Null'
|
||||
@ -343,6 +355,7 @@ class KOBO(USBMS):
|
||||
# Kobo does not delete the Book row (ie the row where the BookID is Null)
|
||||
# The next server sync should remove the row
|
||||
cursor.execute('delete from content where BookID = ?', t)
|
||||
if ContentType == 6:
|
||||
try:
|
||||
cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0, ___ExpirationStatus=3 ' \
|
||||
'where BookID is Null and ContentID =?',t)
|
||||
@ -357,7 +370,8 @@ class KOBO(USBMS):
|
||||
raise
|
||||
cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\' ' \
|
||||
'where BookID is Null and ContentID =?',t)
|
||||
|
||||
else:
|
||||
cursor.execute('delete from content where BookID is Null and ContentID =?',t)
|
||||
|
||||
connection.commit()
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
@ -7,8 +8,11 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <strings.h>
|
||||
|
||||
#define MARKER ".created_by_calibre_mount_helper"
|
||||
#define DEV "/dev/"
|
||||
#define MEDIA "/media/"
|
||||
#define False 0
|
||||
#define True 1
|
||||
|
||||
@ -33,6 +37,20 @@ void ensure_root() {
|
||||
}
|
||||
}
|
||||
|
||||
void check_mount_point(const char *mp) {
|
||||
|
||||
if (mp == NULL || strlen(mp) < strlen(MEDIA)) {
|
||||
fprintf(stderr, "Invalid arguments\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strncmp(MEDIA, mp, strlen(MEDIA)) != 0) {
|
||||
fprintf(stderr, "Trying to operate on a mount point not under /media is not allowed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int do_mount(const char *dev, const char *mp) {
|
||||
char options[1000], marker[2000];
|
||||
#ifdef __NetBSD__
|
||||
@ -44,12 +62,24 @@ int do_mount(const char *dev, const char *mp) {
|
||||
fprintf(stderr, "Specified device node does not exist\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!exists(mp)) {
|
||||
if (mkdir(mp, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0) {
|
||||
errsv = errno;
|
||||
fprintf(stderr, "Failed to create mount point with error: %s\n", strerror(errsv));
|
||||
}
|
||||
}
|
||||
/* only mount if mp is under /media */
|
||||
mp = realpath(mp, NULL);
|
||||
if (mp == NULL) {
|
||||
fprintf(stderr, "realpath on mp failed.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (strncmp(MEDIA, mp, strlen(MEDIA)) != 0) {
|
||||
fprintf(stderr, "mount point is not under /media\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
snprintf(marker, 2000, "%s/%s", mp, MARKER);
|
||||
if (!exists(marker)) {
|
||||
int fd = creat(marker, S_IRUSR|S_IWUSR);
|
||||
@ -195,10 +225,42 @@ int cleanup(const char *dev, const char *mp) {
|
||||
return cleanup_mount_point(mp);
|
||||
}
|
||||
|
||||
void check_dev(const char *dev) {
|
||||
struct stat file_info;
|
||||
|
||||
if (dev == NULL || strlen(dev) < strlen(DEV)) {
|
||||
fprintf(stderr, "Invalid arguments\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strncmp(DEV, dev, strlen(DEV)) != 0) {
|
||||
fprintf(stderr, "Trying to operate on a dev node not under /dev\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (stat(dev, &file_info) != 0) {
|
||||
fprintf(stderr, "stat call on dev node failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strstr(dev, "/shm/") != NULL) {
|
||||
fprintf(stderr, "naughty, naughty!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!S_ISBLK(file_info.st_mode)) {
|
||||
fprintf(stderr, "dev node is not a block device\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char *action, *dev, *mp;
|
||||
char *action, *dev, *mp, *temp;
|
||||
int status = EXIT_FAILURE;
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
/*printf("Real UID\t= %d\n", getuid());
|
||||
printf("Effective UID\t= %d\n", geteuid());
|
||||
@ -211,11 +273,46 @@ int main(int argc, char** argv)
|
||||
}
|
||||
action = argv[1]; dev = argv[2]; mp = argv[3];
|
||||
|
||||
/* Ensure that PATH only contains system directories to prevent execution of
|
||||
arbitrary executables as root */
|
||||
if (setenv("PATH",
|
||||
"/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin\0",
|
||||
1) != 0) {
|
||||
fprintf(stderr, "Failed to restrict PATH env var, aborting.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strncmp(action, "mount", 5) == 0) {
|
||||
dev = realpath(argv[2], NULL);
|
||||
if (dev == NULL) {
|
||||
fprintf(stderr, "Failed to resolve device node.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
mp = get_real_mount_point(mp);
|
||||
check_dev(dev); check_mount_point(mp);
|
||||
status = do_mount(dev, mp);
|
||||
} else if (strncmp(action, "eject", 5) == 0) {
|
||||
dev = realpath(argv[2], NULL);
|
||||
if (dev == NULL) {
|
||||
fprintf(stderr, "Failed to resolve device node.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
temp = realpath(mp, NULL);
|
||||
if (temp == NULL) {
|
||||
fprintf(stderr, "Mount point does not exist\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
chdir(temp);
|
||||
check_dev(dev); check_mount_point(mp);
|
||||
status = do_eject(dev, mp);
|
||||
} else if (strncmp(action, "cleanup", 7) == 0) {
|
||||
temp = realpath(mp, NULL);
|
||||
if (temp == NULL) {
|
||||
fprintf(stderr, "Mount point does not exist\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
mp = temp;
|
||||
check_mount_point(mp);
|
||||
status = cleanup(dev, mp);
|
||||
} else {
|
||||
fprintf(stderr, "Unrecognized action: must be mount, eject or cleanup\n");
|
||||
|
@ -560,14 +560,21 @@ class PRST1(USBMS):
|
||||
|
||||
cursor = connection.cursor()
|
||||
|
||||
periodical_schema = \
|
||||
"'http://xmlns.sony.net/e-book/prs/periodicals/1.0/newspaper/1.0'"
|
||||
# Setting this to the SONY periodical schema apparently causes errors
|
||||
# with some periodicals, therefore set it to null, since the special
|
||||
# periodical navigation doesn't work anyway.
|
||||
periodical_schema = 'null'
|
||||
|
||||
query = '''
|
||||
UPDATE books
|
||||
SET conforms_to = 'http://xmlns.sony.net/e-book/prs/periodicals/1.0/newspaper/1.0',
|
||||
SET conforms_to = %s,
|
||||
periodical_name = ?,
|
||||
description = ?,
|
||||
publication_date = ?
|
||||
WHERE _id = ?
|
||||
'''
|
||||
'''%periodical_schema
|
||||
t = (name, None, pubdate, book.bookId,)
|
||||
cursor.execute(query, t)
|
||||
|
||||
|
@ -622,8 +622,11 @@ class Device(DeviceConfig, DevicePlugin):
|
||||
if getattr(sys, 'frozen', False):
|
||||
cmd = os.path.join(sys.executables_location, 'bin', cmd)
|
||||
cmd = [cmd, 'mount']
|
||||
mlabel = label
|
||||
if mlabel.endswith('/'):
|
||||
mlabel = mlabel[:-1]
|
||||
try:
|
||||
p = subprocess.Popen(cmd + [node, '/media/'+label])
|
||||
p = subprocess.Popen(cmd + [node, '/media/'+mlabel])
|
||||
except OSError:
|
||||
raise DeviceError(
|
||||
_('Could not find mount helper: %s.')%cmd[0])
|
||||
@ -777,9 +780,12 @@ class Device(DeviceConfig, DevicePlugin):
|
||||
# try all the nodes to see what we can mount
|
||||
for dev in devs[i].split():
|
||||
mp='/media/'+label+'-'+dev
|
||||
mmp = mp
|
||||
if mmp.endswith('/'):
|
||||
mmp = mmp[:-1]
|
||||
#print "trying ", dev, "on", mp
|
||||
try:
|
||||
p = subprocess.Popen(cmd + ["/dev/"+dev, mp])
|
||||
p = subprocess.Popen(cmd + ["/dev/"+dev, mmp])
|
||||
except OSError:
|
||||
raise DeviceError(_('Could not find mount helper: %s.')%cmd[0])
|
||||
while p.poll() is None:
|
||||
|
@ -109,14 +109,16 @@ class HTMLFile(object):
|
||||
|
||||
try:
|
||||
with open(self.path, 'rb') as f:
|
||||
src = f.read()
|
||||
src = f.read(4096)
|
||||
self.is_binary = level > 0 and not bool(self.HTML_PAT.search(src))
|
||||
if not self.is_binary:
|
||||
src += f.read()
|
||||
except IOError as err:
|
||||
msg = 'Could not read from file: %s with error: %s'%(self.path, as_unicode(err))
|
||||
if level == 0:
|
||||
raise IOError(msg)
|
||||
raise IgnoreFile(msg, err.errno)
|
||||
|
||||
self.is_binary = level > 0 and not bool(self.HTML_PAT.search(src[:4096]))
|
||||
if not self.is_binary:
|
||||
if not encoding:
|
||||
encoding = xml_to_unicode(src[:4096], verbose=verbose)[-1]
|
||||
|
@ -116,7 +116,11 @@ def title_sort(title, order=None):
|
||||
title = title[1:]
|
||||
match = _title_pat.search(title)
|
||||
if match:
|
||||
try:
|
||||
prep = match.group(1)
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
title = title[len(prep):] + ', ' + prep
|
||||
if title[0] in _ignore_starts:
|
||||
title = title[1:]
|
||||
|
@ -15,7 +15,6 @@ from calibre.customize.conversion import OutputFormatPlugin, \
|
||||
OptionRecommendation
|
||||
from calibre.ebooks.metadata.opf2 import OPF
|
||||
from calibre.ptempfile import TemporaryDirectory
|
||||
from calibre.ebooks.pdf.writer import PDFWriter, ImagePDFWriter, PDFMetadata
|
||||
from calibre.ebooks.pdf.pageoptions import UNITS, PAPER_SIZES, \
|
||||
ORIENTATIONS
|
||||
|
||||
@ -90,6 +89,7 @@ class PDFOutput(OutputFormatPlugin):
|
||||
self.convert_text(oeb_book)
|
||||
|
||||
def convert_images(self, images):
|
||||
from calibre.ebooks.pdf.writer import ImagePDFWriter
|
||||
self.write(ImagePDFWriter, images)
|
||||
|
||||
def get_cover_data(self):
|
||||
@ -105,6 +105,7 @@ class PDFOutput(OutputFormatPlugin):
|
||||
self.cover_data = None
|
||||
|
||||
def convert_text(self, oeb_book):
|
||||
from calibre.ebooks.pdf.writer import PDFWriter
|
||||
self.log.debug('Serializing oeb input to disk for processing...')
|
||||
self.get_cover_data()
|
||||
|
||||
@ -119,6 +120,7 @@ class PDFOutput(OutputFormatPlugin):
|
||||
self.write(PDFWriter, [s.path for s in opf.spine])
|
||||
|
||||
def write(self, Writer, items):
|
||||
from calibre.ebooks.pdf.writer import PDFMetadata
|
||||
writer = Writer(self.opts, self.log, cover_data=self.cover_data)
|
||||
|
||||
close = False
|
||||
|
@ -587,7 +587,6 @@ class CoversModel(QAbstractListModel): # {{{
|
||||
return 1
|
||||
return pmap.width()*pmap.height()
|
||||
|
||||
|
||||
def clear_failed(self):
|
||||
good = []
|
||||
pmap = {}
|
||||
@ -729,6 +728,7 @@ class CoversWidget(QWidget): # {{{
|
||||
except Empty:
|
||||
break
|
||||
|
||||
if self.continue_processing:
|
||||
self.covers_view.clear_failed()
|
||||
|
||||
if self.worker.error is not None:
|
||||
@ -759,7 +759,7 @@ class CoversWidget(QWidget): # {{{
|
||||
self.continue_processing = False
|
||||
|
||||
def cancel(self):
|
||||
self.continue_processing = False
|
||||
self.cleanup()
|
||||
self.abort.set()
|
||||
|
||||
def cover_pixmap(self):
|
||||
|
@ -146,9 +146,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
r('default_author_link', gprefs)
|
||||
|
||||
choices = set([k for k in db.field_metadata.all_field_keys()
|
||||
if db.field_metadata[k]['is_category'] and
|
||||
if (db.field_metadata[k]['is_category'] and
|
||||
(db.field_metadata[k]['datatype'] in ['text', 'series', 'enumeration']) and
|
||||
not db.field_metadata[k]['display'].get('is_names', False)])
|
||||
not db.field_metadata[k]['display'].get('is_names', False))
|
||||
or
|
||||
(db.field_metadata[k]['datatype'] in ['composite'] and
|
||||
db.field_metadata[k]['display'].get('make_category', False))])
|
||||
choices -= set(['authors', 'publisher', 'formats', 'news', 'identifiers'])
|
||||
choices |= set(['search'])
|
||||
self.opt_categories_using_hierarchy.update_items_cache(choices)
|
||||
|
@ -156,7 +156,7 @@ def build_index(books, num, search, sort, order, start, total, url_base, CKEYS,
|
||||
body.append(HR())
|
||||
body.append(DIV(
|
||||
A(_('Switch to the full interface (non-mobile interface)'),
|
||||
href="/browse",
|
||||
href=prefix+"/browse",
|
||||
style="text-decoration: none; color: blue",
|
||||
title=_('The full interface gives you many more features, '
|
||||
'but it may not work well on a small screen')),
|
||||
|
@ -258,6 +258,14 @@ The following functions are available in addition to those described in single-f
|
||||
MMMM : the long localized month name (e.g. "January" to "December").
|
||||
yy : the year as two digit number (00 to 99).
|
||||
yyyy : the year as four digit number.
|
||||
h : the hours without a leading 0 (0 to 11 or 0 to 23, depending on am/pm)
|
||||
hh : the hours with a leading 0 (00 to 11 or 00 to 23, depending on am/pm)
|
||||
m : the minutes without a leading 0 (0 to 59)
|
||||
mm : the minutes with a leading 0 (00 to 59)
|
||||
s : the seconds without a leading 0 (0 to 59)
|
||||
ss : the seconds with a leading 0 (00 to 59)
|
||||
ap : use a 12-hour clock instead of a 24-hour clock, with 'ap' replaced by the localized string for am or pm.
|
||||
AP : use a 12-hour clock instead of a 24-hour clock, with 'AP' replaced by the localized string for AM or PM.
|
||||
iso : the date with time and timezone. Must be the only format present.
|
||||
|
||||
* ``eval(string)`` -- evaluates the string as a program, passing the local variables (those ``assign`` ed to). This permits using the template processor to construct complex results from local variables.
|
||||
|
@ -194,4 +194,8 @@ class SpooledTemporaryFile(tempfile.SpooledTemporaryFile):
|
||||
tempfile.SpooledTemporaryFile.__init__(self, max_size=max_size, suffix=suffix,
|
||||
prefix=prefix, dir=dir, mode=mode, bufsize=bufsize)
|
||||
|
||||
def better_mktemp(*args, **kwargs):
|
||||
fd, path = tempfile.mkstemp(*args, **kwargs)
|
||||
os.close(fd)
|
||||
return path
|
||||
|
||||
|
@ -170,11 +170,37 @@ def format_date(dt, format, assume_utc=False, as_utc=False):
|
||||
if format == 'iso':
|
||||
return isoformat(dt, assume_utc=assume_utc, as_utc=as_utc)
|
||||
|
||||
ampm = 'ap' in format.lower()
|
||||
|
||||
if dt == UNDEFINED_DATE:
|
||||
return ''
|
||||
|
||||
strf = partial(strftime, t=dt.timetuple())
|
||||
|
||||
def format_hour(hr):
|
||||
l = len(hr)
|
||||
h = dt.hour
|
||||
if ampm:
|
||||
h = h%12
|
||||
if l == 1: return '%d'%h
|
||||
return '%02d'%h
|
||||
|
||||
def format_minute(min):
|
||||
l = len(min)
|
||||
if l == 1: return '%d'%dt.minute
|
||||
return '%02d'%dt.minute
|
||||
|
||||
def format_second(min):
|
||||
l = len(min)
|
||||
if l == 1: return '%d'%dt.second
|
||||
return '%02d'%dt.second
|
||||
|
||||
def format_ampm(ap):
|
||||
res = strf('%p')
|
||||
if ap == 'AP':
|
||||
return res
|
||||
return res.lower()
|
||||
|
||||
def format_day(dy):
|
||||
l = len(dy)
|
||||
if l == 1: return '%d'%dt.day
|
||||
@ -193,17 +219,25 @@ def format_date(dt, format, assume_utc=False, as_utc=False):
|
||||
if len(yr) == 2: return '%02d'%(dt.year % 100)
|
||||
return '%04d'%dt.year
|
||||
|
||||
function_index = {
|
||||
'd': format_day,
|
||||
'M': format_month,
|
||||
'y': format_year,
|
||||
'h': format_hour,
|
||||
'm': format_minute,
|
||||
's': format_second,
|
||||
'a': format_ampm,
|
||||
'A': format_ampm,
|
||||
}
|
||||
def repl_func(mo):
|
||||
s = mo.group(0)
|
||||
if s is None:
|
||||
return ''
|
||||
if s[0] == 'd':
|
||||
return format_day(s)
|
||||
if s[0] == 'M':
|
||||
return format_month(s)
|
||||
return format_year(s)
|
||||
return function_index[s[0]](s)
|
||||
|
||||
return re.sub('(d{1,4}|M{1,4}|(?:yyyy|yy))', repl_func, format)
|
||||
return re.sub(
|
||||
'(s{1,2})|(m{1,2})|(h{1,2})|(ap)|(AP)|(d{1,4}|M{1,4}|(?:yyyy|yy))',
|
||||
repl_func, format)
|
||||
|
||||
def replace_months(datestr, clang):
|
||||
# Replace months by english equivalent for parse_date
|
||||
|
@ -747,6 +747,14 @@ class BuiltinFormatDate(BuiltinFormatterFunction):
|
||||
'MMMM : the long localized month name (e.g. "January" to "December"). '
|
||||
'yy : the year as two digit number (00 to 99). '
|
||||
'yyyy : the year as four digit number. '
|
||||
'h : the hours without a leading 0 (0 to 11 or 0 to 23, depending on am/pm) '
|
||||
'hh : the hours with a leading 0 (00 to 11 or 00 to 23, depending on am/pm) '
|
||||
'm : the minutes without a leading 0 (0 to 59) '
|
||||
'mm : the minutes with a leading 0 (00 to 59) '
|
||||
's : the seconds without a leading 0 (0 to 59) '
|
||||
'ss : the seconds with a leading 0 (00 to 59) '
|
||||
'ap : use a 12-hour clock instead of a 24-hour clock, with "ap" replaced by the localized string for am or pm '
|
||||
'AP : use a 12-hour clock instead of a 24-hour clock, with "AP" replaced by the localized string for AM or PM '
|
||||
'iso : the date with time and timezone. Must be the only format present')
|
||||
|
||||
def evaluate(self, formatter, kwargs, mi, locals, val, format_string):
|
||||
|
@ -121,7 +121,7 @@ _extra_lang_codes = {
|
||||
'en_TH' : _('English (Thailand)'),
|
||||
'en_TR' : _('English (Turkey)'),
|
||||
'en_CY' : _('English (Cyprus)'),
|
||||
'en_CZ' : _('English (Czechoslovakia)'),
|
||||
'en_CZ' : _('English (Czech Republic)'),
|
||||
'en_PK' : _('English (Pakistan)'),
|
||||
'en_HR' : _('English (Croatia)'),
|
||||
'en_ID' : _('English (Indonesia)'),
|
||||
|
Loading…
x
Reference in New Issue
Block a user