mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 18:24:30 -04:00
Sync to trunk.
This commit is contained in:
commit
97c46ef41b
@ -118,7 +118,7 @@ EBVS
|
||||
<0x 00 00 00 00>
|
||||
<0x 00 00 00 10>
|
||||
...(rest of size of DATA block)
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
DATA
|
||||
<0x 4 bytes = size of <marked text (see 3rd note)> >
|
||||
<marked text (see 3rd note)>
|
||||
@ -155,7 +155,7 @@ EBVS
|
||||
<0x 00 00 00 00>
|
||||
<0x 00 00 00 10>
|
||||
...(rest of size of DATA block)
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
[fi MARK || BOOKMARK]
|
||||
//-------------------------------
|
||||
[if CORRECTION]
|
||||
@ -174,7 +174,7 @@ EBVS
|
||||
<0x 00 00 00 00>
|
||||
<0x 00 00 00 10>
|
||||
...(rest of size of DATA block)
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
DATA
|
||||
<0x 4 bytes = size of <marked text (see 3rd note)> >
|
||||
<marked text (see 3rd note)>
|
||||
@ -246,7 +246,7 @@ EBVS
|
||||
<0x 00 00 00 00>
|
||||
<0x 00 00 00 10>
|
||||
...(size of DATA block - 30)
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
[fi DRAWING]
|
||||
//-------------------------------
|
||||
[next {NOTE,MARK,CORRECTION,DRAWING}]
|
||||
@ -308,7 +308,7 @@ EBVS
|
||||
...4
|
||||
...4
|
||||
...4
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
<0x FD EA = PAD? (ýê)>
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// CATEGORY (if any)
|
||||
|
21
recipes/archeowiesci.recipe
Normal file
21
recipes/archeowiesci.recipe
Normal file
@ -0,0 +1,21 @@
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class Archeowiesci(BasicNewsRecipe):
|
||||
title = u'Archeowiesci'
|
||||
__author__ = 'fenuks'
|
||||
category = 'archeology'
|
||||
language = 'pl'
|
||||
cover_url='http://archeowiesci.pl/wp-content/uploads/2011/05/Archeowiesci2-115x115.jpg'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
auto_cleanup = True
|
||||
remove_tags=[dict(name='span', attrs={'class':['post-ratings', 'post-ratings-loading']})]
|
||||
feeds = [(u'Archeowieści', u'http://archeowiesci.pl/feed/')]
|
||||
|
||||
def parse_feeds (self):
|
||||
feeds = BasicNewsRecipe.parse_feeds(self)
|
||||
for feed in feeds:
|
||||
for article in feed.articles[:]:
|
||||
if 'subskrypcja' in article.title:
|
||||
feed.articles.remove(article)
|
||||
return feeds
|
@ -9,9 +9,10 @@ class CGM(BasicNewsRecipe):
|
||||
category = 'music'
|
||||
language = 'pl'
|
||||
use_embedded_content = False
|
||||
remove_empty_feeds= True
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheers=True
|
||||
extra_css = 'div {color:black;} strong {color:black;} span {color:black;} p {color:black;}'
|
||||
extra_css = 'div {color:black;} strong {color:black;} span {color:black;} p {color:black;} h2 {color:black;}'
|
||||
remove_tags_before=dict(id='mainContent')
|
||||
remove_tags_after=dict(name='div', attrs={'class':'fbContainer'})
|
||||
remove_tags=[dict(name='div', attrs={'class':'fbContainer'}),
|
||||
@ -22,10 +23,12 @@ class CGM(BasicNewsRecipe):
|
||||
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
ad=soup.findAll('img')
|
||||
for item in soup.findAll(style=True):
|
||||
del item['style']
|
||||
ad=soup.findAll('a')
|
||||
for r in ad:
|
||||
if '/_vault/_article_photos/5841.jpg' in r['src'] or '_vault/_article_photos/5807.jpg' in r['src'] or 'article_photos/5841.jpg' in r['src'] or 'article_photos/5825.jpg' in r['src'] or '_article_photos/5920.jpg' in r['src'] or '_article_photos/5919.jpg' in r['src'] or '_article_photos/5918.jpg' in r['src'] or '_article_photos/5914.jpg' in r['src'] or '_article_photos/5911.jpg' in r['src'] or '_article_photos/5923.jpg' in r['src'] or '_article_photos/5921.jpg' in r['src']:
|
||||
ad[ad.index(r)].extract()
|
||||
if 'http://www.hustla.pl' in r['href']:
|
||||
r.extract()
|
||||
gallery=soup.find('div', attrs={'class':'galleryFlash'})
|
||||
if gallery:
|
||||
img=gallery.find('embed')
|
||||
|
15
recipes/dark_horizons.recipe
Normal file
15
recipes/dark_horizons.recipe
Normal file
@ -0,0 +1,15 @@
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class AdvancedUserRecipe1317580312(BasicNewsRecipe):
|
||||
title = u'Dark Horizons'
|
||||
language = 'en'
|
||||
__author__ = 'Jaded'
|
||||
description ='News, images, video clips and reviews of current and upcoming blockbuster films. '
|
||||
category = 'movies, tv, news'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
cover_url = 'http://a4.sphotos.ak.fbcdn.net/hphotos-ak-ash2/164168_148419801879765_148410081880737_225532_464073_n.jpg'
|
||||
masthead_url = 'http://www.darkhorizons.com/graphics/2/logo_print.png'
|
||||
auto_cleanup = True
|
||||
|
||||
feeds = [(u'News', u'http://www.darkhorizons.com/feeds/news.atom'), (u'Features', u'http://www.darkhorizons.com/feeds/features.atom'), (u'Reviews', u'http://www.darkhorizons.com/feeds/reviews.atom')]
|
@ -22,6 +22,10 @@ class Descopera(BasicNewsRecipe):
|
||||
category = 'Ziare,Reviste,Descopera'
|
||||
encoding = 'utf-8'
|
||||
cover_url = 'http://www.descopera.ro/images/header_images/logo.gif'
|
||||
use_embedded_content = False
|
||||
|
||||
no_stylesheets = True
|
||||
auto_cleanup = True
|
||||
|
||||
conversion_options = {
|
||||
'comments' : description
|
||||
@ -30,28 +34,6 @@ class Descopera(BasicNewsRecipe):
|
||||
,'publisher' : publisher
|
||||
}
|
||||
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='h1', attrs={'style':'font-family: Arial,Helvetica,sans-serif; font-size: 18px; color: rgb(51, 51, 51); font-weight: bold; margin: 10px 0pt; clear: both; float: left;width: 610px;'})
|
||||
,dict(name='div', attrs={'style':'margin-right: 15px; margin-bottom: 15px; float: left;'})
|
||||
, dict(name='p', attrs={'id':'itemDescription'})
|
||||
,dict(name='div', attrs={'id':'itemBody'})
|
||||
]
|
||||
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'class':['tools']})
|
||||
, dict(name='div', attrs={'class':['share']})
|
||||
, dict(name='div', attrs={'class':['category']})
|
||||
, dict(name='div', attrs={'id':['comments']})
|
||||
]
|
||||
|
||||
remove_tags_after = [
|
||||
dict(name='div', attrs={'id':'comments'})
|
||||
]
|
||||
|
||||
feeds = [
|
||||
(u'Feeds', u'http://www.descopera.ro/rss')
|
||||
]
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
return self.adeify_images(soup)
|
||||
|
23
recipes/eioba.recipe
Normal file
23
recipes/eioba.recipe
Normal file
@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class eioba(BasicNewsRecipe):
|
||||
title = u'eioba'
|
||||
__author__ = 'fenuks'
|
||||
cover_url = 'http://www.eioba.org/lay/logo_pl_v3.png'
|
||||
language = 'pl'
|
||||
oldest_article = 7
|
||||
remove_empty_feeds= True
|
||||
max_articles_per_feed = 100
|
||||
extra_css = '#ctl0_body_Topic {font-weight: bold; font-size:30px;}'
|
||||
keep_only_tags=[dict(id=['ctl0_body_Topic', 'articleContent'])]
|
||||
feeds = [(u'Wszyskie kategorie', u'http://feeds.eioba.pl/eioba-pl-top'),
|
||||
(u'Technologia', u'http://www.eioba.pl/feed/categories/1.xml'),
|
||||
(u'Nauka', u'http://www.eioba.pl/feed/categories/12.xml'),
|
||||
(u'Finanse', u'http://www.eioba.pl/feed/categories/7.xml'),
|
||||
(u'Życie', u'http://www.eioba.pl/feed/categories/5.xml'),
|
||||
(u'Zainteresowania', u'http://www.eioba.pl/feed/categories/420.xml'),
|
||||
(u'Społeczeństwo', u'http://www.eioba.pl/feed/categories/8.xml'),
|
||||
(u'Rozrywka', u'http://www.eioba.pl/feed/categories/10.xml'),
|
||||
(u'Rożne', u'http://www.eioba.pl/feed/categories/9.xml')
|
||||
]
|
66
recipes/focus_pl.recipe
Normal file
66
recipes/focus_pl.recipe
Normal file
@ -0,0 +1,66 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class Focus_pl(BasicNewsRecipe):
|
||||
title = u'Focus.pl'
|
||||
oldest_article = 15
|
||||
max_articles_per_feed = 100
|
||||
__author__ = 'fenuks'
|
||||
language = 'pl'
|
||||
description ='polish scientific monthly magazine'
|
||||
category='magazine'
|
||||
cover_url=''
|
||||
remove_empty_feeds= True
|
||||
no_stylesheets=True
|
||||
remove_tags_before=dict(name='div', attrs={'class':'h2 h2f'})
|
||||
remove_tags_after=dict(name='div', attrs={'class':'clear'})
|
||||
feeds = [(u'Wszystkie kategorie', u'http://focus.pl.feedsportal.com/c/32992/f/532692/index.rss'),
|
||||
(u'Nauka', u'http://focus.pl.feedsportal.com/c/32992/f/532693/index.rss'),
|
||||
(u'Historia', u'http://focus.pl.feedsportal.com/c/32992/f/532694/index.rss'),
|
||||
(u'Cywilizacja', u'http://focus.pl.feedsportal.com/c/32992/f/532695/index.rss'),
|
||||
(u'Sport', u'http://focus.pl.feedsportal.com/c/32992/f/532696/index.rss'),
|
||||
(u'Technika', u'http://focus.pl.feedsportal.com/c/32992/f/532697/index.rss'),
|
||||
(u'Przyroda', u'http://focus.pl.feedsportal.com/c/32992/f/532698/index.rss'),
|
||||
(u'Technologie', u'http://focus.pl.feedsportal.com/c/32992/f/532699/index.rss'),
|
||||
(u'Warto wiedzieć', u'http://focus.pl.feedsportal.com/c/32992/f/532700/index.rss'),
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
def skip_ad_pages(self, soup):
|
||||
tag=soup.find(name='a')
|
||||
if tag:
|
||||
new_soup=self.index_to_soup(tag['href']+ 'do-druku/1/', raw=True)
|
||||
return new_soup
|
||||
|
||||
def append_page(self, appendtag):
|
||||
tag=appendtag.find(name='div', attrs={'class':'arrows'})
|
||||
if tag:
|
||||
nexturl='http://www.focus.pl/'+tag.a['href']
|
||||
for rem in appendtag.findAll(name='div', attrs={'class':'klik-nav'}):
|
||||
rem.extract()
|
||||
while nexturl:
|
||||
soup2=self.index_to_soup(nexturl)
|
||||
nexturl=None
|
||||
pagetext=soup2.find(name='div', attrs={'class':'txt'})
|
||||
tag=pagetext.find(name='div', attrs={'class':'arrows'})
|
||||
for r in tag.findAll(name='a'):
|
||||
if u'Następne' in r.string:
|
||||
nexturl='http://www.focus.pl/'+r['href']
|
||||
for rem in pagetext.findAll(name='div', attrs={'class':'klik-nav'}):
|
||||
rem.extract()
|
||||
pos = len(appendtag.contents)
|
||||
appendtag.insert(pos, pagetext)
|
||||
|
||||
def get_cover_url(self):
|
||||
soup=self.index_to_soup('http://www.focus.pl/magazyn/')
|
||||
tag=soup.find(name='div', attrs={'class':'clr fl'})
|
||||
if tag:
|
||||
self.cover_url='http://www.focus.pl/' + tag.a['href']
|
||||
return getattr(self, 'cover_url', self.cover_url)
|
||||
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
self.append_page(soup.body)
|
||||
return soup
|
83
recipes/gazeta_wyborcza.recipe
Normal file
83
recipes/gazeta_wyborcza.recipe
Normal file
@ -0,0 +1,83 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class Gazeta_Wyborcza(BasicNewsRecipe):
|
||||
title = u'Gazeta Wyborcza'
|
||||
__author__ = 'fenuks'
|
||||
cover_url = 'http://bi.gazeta.pl/im/5/10285/z10285445AA.jpg'
|
||||
language = 'pl'
|
||||
description ='news from gazeta.pl'
|
||||
category='newspaper'
|
||||
INDEX='http://wyborcza.pl'
|
||||
remove_empty_feeds= True
|
||||
oldest_article = 3
|
||||
max_articles_per_feed = 100
|
||||
remove_javascript=True
|
||||
no_stylesheets=True
|
||||
remove_tags_before=dict(id='k0')
|
||||
remove_tags_after=dict(id='banP4')
|
||||
remove_tags=[dict(name='div', attrs={'class':'rel_box'}), dict(attrs={'class':['date', 'zdjP', 'zdjM', 'pollCont', 'rel_video', 'brand', 'txt_upl']}), dict(name='div', attrs={'id':'footer'})]
|
||||
feeds = [(u'Kraj', u'http://rss.feedsportal.com/c/32739/f/530266/index.rss'), (u'\u015awiat', u'http://rss.feedsportal.com/c/32739/f/530270/index.rss'),
|
||||
(u'Wyborcza.biz', u'http://wyborcza.biz/pub/rss/wyborcza_biz_wiadomosci.htm'),
|
||||
(u'Komentarze', u'http://rss.feedsportal.com/c/32739/f/530312/index.rss'),
|
||||
(u'Kultura', u'http://rss.gazeta.pl/pub/rss/gazetawyborcza_kultura.xml'),
|
||||
(u'Nauka', u'http://rss.feedsportal.com/c/32739/f/530269/index.rss'), (u'Opinie', u'http://rss.gazeta.pl/pub/rss/opinie.xml'), (u'Gazeta \u015awi\u0105teczna', u'http://rss.feedsportal.com/c/32739/f/530431/index.rss'), (u'Du\u017cy Format', u'http://rss.feedsportal.com/c/32739/f/530265/index.rss'), (u'Witamy w Polsce', u'http://rss.feedsportal.com/c/32739/f/530476/index.rss'), (u'M\u0119ska Muzyka', u'http://rss.feedsportal.com/c/32739/f/530337/index.rss'), (u'Lata Lec\u0105', u'http://rss.feedsportal.com/c/32739/f/530326/index.rss'), (u'Solidarni z Tybetem', u'http://rss.feedsportal.com/c/32739/f/530461/index.rss'), (u'W pon. - \u017bakowski', u'http://rss.feedsportal.com/c/32739/f/530491/index.rss'), (u'We wt. - Kolenda-Zalewska', u'http://rss.feedsportal.com/c/32739/f/530310/index.rss'), (u'\u015aroda w \u015brod\u0119', u'http://rss.feedsportal.com/c/32739/f/530428/index.rss'), (u'W pi\u0105tek - Olejnik', u'http://rss.feedsportal.com/c/32739/f/530364/index.rss'), (u'Nekrologi', u'http://rss.feedsportal.com/c/32739/f/530358/index.rss')
|
||||
]
|
||||
|
||||
def skip_ad_pages(self, soup):
|
||||
tag=soup.find(name='a', attrs={'class':'btn'})
|
||||
if tag:
|
||||
new_soup=self.index_to_soup(tag['href'], raw=True)
|
||||
return new_soup
|
||||
|
||||
|
||||
def append_page(self, soup, appendtag):
|
||||
loop=False
|
||||
tag = soup.find('div', attrs={'id':'Str'})
|
||||
if appendtag.find('div', attrs={'id':'Str'}):
|
||||
nexturl=tag.findAll('a')
|
||||
appendtag.find('div', attrs={'id':'Str'}).extract()
|
||||
loop=True
|
||||
if appendtag.find(id='source'):
|
||||
appendtag.find(id='source').extract()
|
||||
while loop:
|
||||
loop=False
|
||||
for link in nexturl:
|
||||
if u'następne' in link.string:
|
||||
url= self.INDEX + link['href']
|
||||
soup2 = self.index_to_soup(url)
|
||||
pagetext = soup2.find(id='artykul')
|
||||
pos = len(appendtag.contents)
|
||||
appendtag.insert(pos, pagetext)
|
||||
tag = soup2.find('div', attrs={'id':'Str'})
|
||||
nexturl=tag.findAll('a')
|
||||
loop=True
|
||||
|
||||
def gallery_article(self, appendtag):
|
||||
tag=appendtag.find(id='container_gal')
|
||||
if tag:
|
||||
nexturl=appendtag.find(id='gal_btn_next').a['href']
|
||||
appendtag.find(id='gal_navi').extract()
|
||||
while nexturl:
|
||||
soup2=self.index_to_soup(nexturl)
|
||||
pagetext=soup2.find(id='container_gal')
|
||||
nexturl=pagetext.find(id='gal_btn_next')
|
||||
if nexturl:
|
||||
nexturl=nexturl.a['href']
|
||||
pos = len(appendtag.contents)
|
||||
appendtag.insert(pos, pagetext)
|
||||
rem=appendtag.find(id='gal_navi')
|
||||
if rem:
|
||||
rem.extract()
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
self.append_page(soup, soup.body)
|
||||
if soup.find(id='container_gal'):
|
||||
self.gallery_article(soup.body)
|
||||
return soup
|
||||
|
||||
def print_version(self, url):
|
||||
if 'http://wyborcza.biz/biznes/' not in url:
|
||||
return url
|
||||
else:
|
||||
return url.replace('http://wyborcza.biz/biznes/1', 'http://wyborcza.biz/biznes/2029020')
|
@ -9,8 +9,17 @@ class Gram_pl(BasicNewsRecipe):
|
||||
oldest_article = 8
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets= True
|
||||
extra_css = 'h2 {font-style: italic; font-size:20px;}'
|
||||
cover_url=u'http://www.gram.pl/www/01/img/grampl_zima.png'
|
||||
remove_tags= [dict(name='p', attrs={'class':['extraText', 'must-log-in']}), dict(attrs={'class':['el', 'headline', 'post-info']}), dict(name='div', attrs={'class':['twojaOcena', 'comment-body', 'comment-author vcard', 'comment-meta commentmetadata', 'tw_button']}), dict(id=['igit_rpwt_css', 'comments', 'reply-title', 'igit_title'])]
|
||||
keep_only_tags= [dict(name='div', attrs={'class':['main', 'arkh-postmetadataheader', 'arkh-postcontent', 'post', 'content', 'news_header', 'news_subheader', 'news_text']}), dict(attrs={'class':['contentheading', 'contentpaneopen']})]
|
||||
feeds = [(u'gram.pl - informacje', u'http://www.gram.pl/feed_news.asp'),
|
||||
(u'gram.pl - publikacje', u'http://www.gram.pl/feed_news.asp?type=articles')]
|
||||
|
||||
def parse_feeds (self):
|
||||
feeds = BasicNewsRecipe.parse_feeds(self)
|
||||
for feed in feeds:
|
||||
for article in feed.articles[:]:
|
||||
if 'REKLAMA SKLEP' in article.title.upper() or u'ARTYKUŁ:' in article.title.upper():
|
||||
feed.articles.remove(article)
|
||||
return feeds
|
||||
|
BIN
recipes/icons/archeowiesci.png
Normal file
BIN
recipes/icons/archeowiesci.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 718 B |
BIN
recipes/icons/dark_horizons.png
Normal file
BIN
recipes/icons/dark_horizons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 399 B |
BIN
recipes/icons/eioba.png
Normal file
BIN
recipes/icons/eioba.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 908 B |
BIN
recipes/icons/focus_pl.png
Normal file
BIN
recipes/icons/focus_pl.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 695 B |
BIN
recipes/icons/gazeta_wyborcza.png
Normal file
BIN
recipes/icons/gazeta_wyborcza.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 221 B |
BIN
recipes/icons/konflikty_zbrojne.png
Normal file
BIN
recipes/icons/konflikty_zbrojne.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 320 B |
15
recipes/konflikty_zbrojne.recipe
Normal file
15
recipes/konflikty_zbrojne.recipe
Normal file
@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class Konflikty(BasicNewsRecipe):
|
||||
title = u'Konflikty Zbrojne'
|
||||
__author__ = 'fenuks'
|
||||
cover_url = 'http://www.konflikty.pl/images/tapety_logo.jpg'
|
||||
language = 'pl'
|
||||
description ='military news'
|
||||
category='military, history'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
auto_cleanup = True
|
||||
|
||||
feeds = [(u'Aktualności', u'http://www.konflikty.pl/rss_aktualnosci_10.xml'), (u'Artyku\u0142y', u'http://www.konflikty.pl/rss_artykuly_10.xml'), (u'Relacje', u'http://www.konflikty.pl/rss_relacje_10.xml'), (u'Recenzje', u'http://www.konflikty.pl/rss_recenzje_10.xml')]
|
15
recipes/naczytniki.recipe
Normal file
15
recipes/naczytniki.recipe
Normal file
@ -0,0 +1,15 @@
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class naczytniki(BasicNewsRecipe):
|
||||
title = u'naczytniki.pl'
|
||||
__author__ = 'fenuks'
|
||||
cover_url = 'http://naczytniki.pl/wp-content/uploads/2010/08/logo_nc28.png'
|
||||
language = 'pl'
|
||||
description ='everything about e-readers'
|
||||
category='readers'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
remove_tags_after= dict(name='div', attrs={'class':'sociable'})
|
||||
keep_only_tags=[dict(name='div', attrs={'class':'post'})]
|
||||
remove_tags=[dict(name='span', attrs={'class':'comments'}), dict(name='div', attrs={'class':'sociable'})]
|
||||
feeds = [(u'Wpisy', u'http://naczytniki.pl/?feed=rss2')]
|
47
recipes/nowa_fantastyka.recipe
Normal file
47
recipes/nowa_fantastyka.recipe
Normal file
@ -0,0 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class Nowa_Fantastyka(BasicNewsRecipe):
|
||||
title = u'Nowa Fantastyka'
|
||||
oldest_article = 7
|
||||
__author__ = 'fenuks'
|
||||
language = 'pl'
|
||||
description ='site for fantasy readers'
|
||||
category='fantasy'
|
||||
max_articles_per_feed = 100
|
||||
INDEX='http://www.fantastyka.pl/'
|
||||
remove_tags_before=dict(attrs={'class':'belka1-tlo-md'})
|
||||
#remove_tags_after=dict(name='span', attrs={'class':'naglowek-oceny'})
|
||||
remove_tags_after=dict(name='td', attrs={'class':'belka1-bot'})
|
||||
remove_tags=[dict(attrs={'class':'avatar2'})]
|
||||
feeds = []
|
||||
|
||||
def find_articles(self, url):
|
||||
articles = []
|
||||
soup=self.index_to_soup(url)
|
||||
tag=soup.find(attrs={'class':'belka1-tlo-m'})
|
||||
art=tag.findAll(name='a', attrs={'class':'a-box'})
|
||||
for i in art:
|
||||
title=i.string
|
||||
url=self.INDEX+i['href']
|
||||
#date=soup.find(id='footer').ul.li.string[41:-1]
|
||||
articles.append({'title' : title,
|
||||
'url' : url,
|
||||
'date' : '',
|
||||
'description' : ''
|
||||
})
|
||||
return articles
|
||||
|
||||
def parse_index(self):
|
||||
feeds = []
|
||||
feeds.append((u"Opowiadania", self.find_articles('http://www.fantastyka.pl/3.html')))
|
||||
feeds.append((u"Publicystyka", self.find_articles('http://www.fantastyka.pl/6.html')))
|
||||
feeds.append((u"Hype Park", self.find_articles('http://www.fantastyka.pl/9.html')))
|
||||
|
||||
return feeds
|
||||
|
||||
def get_cover_url(self):
|
||||
soup = self.index_to_soup('http://www.fantastyka.pl/1.html')
|
||||
cover=soup.find(name='img', attrs={'class':'okladka'})
|
||||
self.cover_url=self.INDEX+ cover['src']
|
||||
return getattr(self, 'cover_url', self.cover_url)
|
@ -9,4 +9,6 @@ class Tablety_pl(BasicNewsRecipe):
|
||||
language = 'pl'
|
||||
oldest_article = 8
|
||||
max_articles_per_feed = 100
|
||||
keep_only_tags=[dict(name='header', attrs={'class':'entry-header'}), dict(name='div', attrs={'class':'entry-content clearfix'})]
|
||||
remove_tags=[dict(name='div', attrs={'class':'snap_nopreview sharing robots-nocontent'}), dict(name='span', attrs={'class':'dsq-postid'})]
|
||||
feeds = [(u'Najnowsze posty', u'http://www.tablety.pl/feed/')]
|
||||
|
@ -22,7 +22,7 @@ vipy.session.initialize(project_name='calibre', src_dir=src_dir,
|
||||
def recipe_title_callback(raw):
|
||||
return eval(raw.decode('utf-8')).replace(' ', '_')
|
||||
|
||||
vipy.session.add_content_browser('.r', ',r', 'Recipe',
|
||||
vipy.session.add_content_browser('<leader>r', 'Recipe',
|
||||
vipy.session.glob_based_iterator(os.path.join(project_dir, 'recipes', '*.recipe')),
|
||||
vipy.session.regexp_based_matcher(r'title\s*=\s*(?P<title>.+)', 'title', recipe_title_callback))
|
||||
EOFPY
|
||||
|
@ -8,7 +8,6 @@ __docformat__ = 'restructuredtext en'
|
||||
import os
|
||||
import sqlite3 as sqlite
|
||||
from contextlib import closing
|
||||
|
||||
from calibre.devices.usbms.books import BookList
|
||||
from calibre.devices.kobo.books import Book
|
||||
from calibre.devices.kobo.books import ImageWrapper
|
||||
@ -16,6 +15,7 @@ from calibre.devices.mime import mime_type_ext
|
||||
from calibre.devices.usbms.driver import USBMS, debug_print
|
||||
from calibre import prints
|
||||
from calibre.devices.usbms.books import CollectionsBookList
|
||||
from calibre.utils.magick.draw import save_cover_data_to
|
||||
|
||||
class KOBO(USBMS):
|
||||
|
||||
@ -53,11 +53,23 @@ class KOBO(USBMS):
|
||||
_('The Kobo supports several collections including ')+\
|
||||
'Read, Closed, Im_Reading. ' +\
|
||||
_('Create tags for automatic management'),
|
||||
_('Upload covers for books (newer readers)') +
|
||||
':::'+_('Normally, the KOBO readers get the cover image from the'
|
||||
' 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')
|
||||
]
|
||||
|
||||
EXTRA_CUSTOMIZATION_DEFAULT = [', '.join(['tags'])]
|
||||
EXTRA_CUSTOMIZATION_DEFAULT = [
|
||||
', '.join(['tags']),
|
||||
True,
|
||||
True
|
||||
]
|
||||
|
||||
OPT_COLLECTIONS = 0
|
||||
OPT_UPLOAD_COVERS = 1
|
||||
OPT_UPLOAD_GRAYSCALE_COVERS = 2
|
||||
|
||||
def initialize(self):
|
||||
USBMS.initialize(self)
|
||||
@ -593,7 +605,7 @@ class KOBO(USBMS):
|
||||
raise
|
||||
else:
|
||||
connection.commit()
|
||||
debug_print(' Commit: Reset ReadStatus list')
|
||||
# debug_print(' Commit: Reset ReadStatus list')
|
||||
|
||||
cursor.close()
|
||||
|
||||
@ -616,7 +628,7 @@ class KOBO(USBMS):
|
||||
raise
|
||||
else:
|
||||
connection.commit()
|
||||
debug_print(' Commit: Setting ReadStatus List')
|
||||
# debug_print(' Commit: Setting ReadStatus List')
|
||||
cursor.close()
|
||||
|
||||
def reset_favouritesindex(self, connection, oncard):
|
||||
@ -635,7 +647,7 @@ class KOBO(USBMS):
|
||||
raise
|
||||
else:
|
||||
connection.commit()
|
||||
debug_print(' Commit: Reset FavouritesIndex list')
|
||||
# debug_print(' Commit: Reset FavouritesIndex list')
|
||||
|
||||
def set_favouritesindex(self, connection, ContentID):
|
||||
cursor = connection.cursor()
|
||||
@ -650,7 +662,7 @@ class KOBO(USBMS):
|
||||
raise
|
||||
else:
|
||||
connection.commit()
|
||||
debug_print(' Commit: Set FavouritesIndex')
|
||||
# debug_print(' Commit: Set FavouritesIndex')
|
||||
|
||||
def update_device_database_collections(self, booklists, collections_attributes, oncard):
|
||||
# Only process categories in this list
|
||||
@ -702,9 +714,9 @@ class KOBO(USBMS):
|
||||
# Process any collections that exist
|
||||
for category, books in collections.items():
|
||||
if category in supportedcategories:
|
||||
debug_print("Category: ", category, " id = ", readstatuslist.get(category))
|
||||
# debug_print("Category: ", category, " id = ", readstatuslist.get(category))
|
||||
for book in books:
|
||||
debug_print(' Title:', book.title, 'category: ', category)
|
||||
# debug_print(' Title:', book.title, 'category: ', category)
|
||||
if category not in book.device_collections:
|
||||
book.device_collections.append(category)
|
||||
|
||||
@ -763,3 +775,93 @@ class KOBO(USBMS):
|
||||
collections_attributes = []
|
||||
self.update_device_database_collections(booklist, collections_attributes, oncard)
|
||||
|
||||
def upload_cover(self, path, filename, metadata, filepath):
|
||||
'''
|
||||
Upload book cover to the device. Default implementation does nothing.
|
||||
|
||||
:param path: The full path to the directory where the associated book is located.
|
||||
:param filename: The name of the book file without the extension.
|
||||
:param metadata: metadata belonging to the book. Use metadata.thumbnail
|
||||
for cover
|
||||
:param filepath: The full path to the ebook file
|
||||
|
||||
'''
|
||||
|
||||
opts = self.settings()
|
||||
if not opts.extra_customization[self.OPT_UPLOAD_COVERS]:
|
||||
# Building thumbnails disabled
|
||||
debug_print('KOBO: not uploading cover')
|
||||
return
|
||||
|
||||
if not opts.extra_customization[self.OPT_UPLOAD_GRAYSCALE_COVERS]:
|
||||
uploadgrayscale = False
|
||||
else:
|
||||
uploadgrayscale = True
|
||||
|
||||
debug_print('KOBO: uploading cover')
|
||||
try:
|
||||
self._upload_cover(path, filename, metadata, filepath, uploadgrayscale)
|
||||
except:
|
||||
debug_print('FAILED to upload cover', filepath)
|
||||
|
||||
def _upload_cover(self, path, filename, metadata, filepath, uploadgrayscale):
|
||||
if metadata.cover:
|
||||
cover = self.normalize_path(metadata.cover.replace('/', os.sep))
|
||||
|
||||
if os.path.exists(cover):
|
||||
# Get ContentID for Selected Book
|
||||
extension = os.path.splitext(filepath)[1]
|
||||
ContentType = self.get_content_type_from_extension(extension) if extension != '' else self.get_content_type_from_path(filepath)
|
||||
ContentID = self.contentid_from_path(filepath, ContentType)
|
||||
|
||||
with closing(sqlite.connect(self.normalize_path(self._main_prefix +
|
||||
'.kobo/KoboReader.sqlite'))) as connection:
|
||||
|
||||
# return bytestrings if the content cannot the decoded as unicode
|
||||
connection.text_factory = lambda x: unicode(x, "utf-8", "ignore")
|
||||
|
||||
cursor = connection.cursor()
|
||||
t = (ContentID,)
|
||||
cursor.execute('select ImageId from Content where BookID is Null and ContentID = ?', t)
|
||||
result = cursor.fetchone()
|
||||
if result is None:
|
||||
debug_print("No rows exist in the database - cannot upload")
|
||||
return
|
||||
else:
|
||||
ImageID = result[0]
|
||||
# debug_print("ImageId: ", result[0])
|
||||
|
||||
cursor.close()
|
||||
|
||||
if ImageID != None:
|
||||
path_prefix = '.kobo/images/'
|
||||
path = self._main_prefix + path_prefix + ImageID
|
||||
|
||||
file_endings = {' - iPhoneThumbnail.parsed':(103,150),
|
||||
' - bbMediumGridList.parsed':(93,135),
|
||||
' - NickelBookCover.parsed':(500,725),
|
||||
' - N3_LIBRARY_FULL.parsed':(355,530),
|
||||
' - N3_LIBRARY_GRID.parsed':(149,233),
|
||||
' - N3_LIBRARY_LIST.parsed':(60,90),
|
||||
' - N3_SOCIAL_CURRENTREAD.parsed':(120,186)}
|
||||
|
||||
for ending, resize in file_endings.items():
|
||||
fpath = path + ending
|
||||
fpath = self.normalize_path(fpath.replace('/', os.sep))
|
||||
|
||||
if os.path.exists(fpath):
|
||||
with open(cover, 'rb') as f:
|
||||
data = f.read()
|
||||
|
||||
# Return the data resized and in Grayscale if
|
||||
# required
|
||||
data = save_cover_data_to(data, 'dummy.jpg',
|
||||
grayscale=uploadgrayscale,
|
||||
resize_to=resize, return_data=True)
|
||||
|
||||
with open(fpath, 'wb') as f:
|
||||
f.write(data)
|
||||
|
||||
else:
|
||||
debug_print("ImageID could not be retreived from the database")
|
||||
|
||||
|
@ -100,7 +100,7 @@ gprefs.defaults['default_author_link'] = 'http://en.wikipedia.org/w/index.php?se
|
||||
gprefs.defaults['preserve_date_on_ctl'] = True
|
||||
gprefs.defaults['cb_fullscreen'] = False
|
||||
gprefs.defaults['worker_max_time'] = 0
|
||||
|
||||
gprefs.defaults['show_files_after_save'] = True
|
||||
# }}}
|
||||
|
||||
NONE = QVariant() #: Null value to return from the data function of item models
|
||||
|
@ -18,11 +18,15 @@ class GenerateCatalogAction(InterfaceAction):
|
||||
|
||||
name = 'Generate Catalog'
|
||||
action_spec = (_('Create catalog'), 'catalog.png', 'Catalog builder', ())
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
|
||||
def genesis(self):
|
||||
self.qaction.triggered.connect(self.generate_catalog)
|
||||
|
||||
def location_selected(self, loc):
|
||||
enabled = loc == 'library'
|
||||
self.qaction.setEnabled(enabled)
|
||||
|
||||
def generate_catalog(self):
|
||||
rows = self.gui.library_view.selectionModel().selectedRows()
|
||||
if not rows or len(rows) < 2:
|
||||
|
@ -138,7 +138,7 @@ class ChooseLibraryAction(InterfaceAction):
|
||||
name = 'Choose Library'
|
||||
action_spec = (_('Choose Library'), 'lt.png',
|
||||
_('Choose calibre library to work with'), None)
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
action_add_menu = True
|
||||
action_menu_clone_qaction = _('Switch/create library...')
|
||||
|
||||
|
@ -20,7 +20,7 @@ class ConvertAction(InterfaceAction):
|
||||
|
||||
name = 'Convert Books'
|
||||
action_spec = (_('Convert books'), 'convert.png', None, _('C'))
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
|
||||
|
@ -127,7 +127,7 @@ class CopyToLibraryAction(InterfaceAction):
|
||||
action_spec = (_('Copy to library'), 'lt.png',
|
||||
_('Copy selected books to the specified library'), None)
|
||||
popup_type = QToolButton.InstantPopup
|
||||
dont_add_to = frozenset(['toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
action_type = 'current'
|
||||
action_add_menu = True
|
||||
|
||||
|
@ -24,7 +24,7 @@ class ShareConnMenu(QMenu): # {{{
|
||||
|
||||
config_email = pyqtSignal()
|
||||
toggle_server = pyqtSignal()
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QMenu.__init__(self, parent)
|
||||
|
@ -11,7 +11,7 @@ class NextMatchAction(InterfaceAction):
|
||||
name = 'Move to next highlighted book'
|
||||
action_spec = (_('Move to next match'), 'arrow-down.png',
|
||||
_('Move to next highlighted match'), [_('N'), _('F3')])
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
action_type = 'current'
|
||||
|
||||
def genesis(self):
|
||||
|
@ -13,7 +13,7 @@ class OpenFolderAction(InterfaceAction):
|
||||
name = 'Open Folder'
|
||||
action_spec = (_('Open containing folder'), 'document_open.png', None,
|
||||
_('O'))
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
action_type = 'current'
|
||||
|
||||
def genesis(self):
|
||||
|
@ -16,11 +16,15 @@ class PickRandomAction(InterfaceAction):
|
||||
name = 'Pick Random Book'
|
||||
action_spec = (_('Pick a random book'), 'random.png',
|
||||
'Select a random book from your calibre library', ())
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
|
||||
def genesis(self):
|
||||
self.qaction.triggered.connect(self.pick_random)
|
||||
|
||||
def location_selected(self, loc):
|
||||
enabled = loc == 'library'
|
||||
self.qaction.setEnabled(enabled)
|
||||
|
||||
def pick_random(self):
|
||||
pick = random.randint(0, self.gui.library_view.model().rowCount(None))
|
||||
self.gui.library_view.set_current_row(pick)
|
||||
|
@ -11,8 +11,8 @@ from functools import partial
|
||||
from PyQt4.Qt import QMenu, pyqtSignal
|
||||
|
||||
from calibre.utils.config import prefs
|
||||
from calibre.gui2 import error_dialog, Dispatcher, \
|
||||
choose_dir, warning_dialog, open_local_file
|
||||
from calibre.gui2 import (error_dialog, Dispatcher, gprefs,
|
||||
choose_dir, warning_dialog, open_local_file)
|
||||
from calibre.gui2.actions import InterfaceAction
|
||||
from calibre.ebooks import BOOK_EXTENSIONS
|
||||
|
||||
@ -141,6 +141,7 @@ class SaveToDiskAction(InterfaceAction):
|
||||
_('Could not save some books') + ', ' +
|
||||
_('Click the show details button to see which ones.'),
|
||||
u'\n\n'.join(failures), show=True)
|
||||
if gprefs['show_files_after_save']:
|
||||
open_local_file(path)
|
||||
|
||||
def books_saved(self, job):
|
||||
|
@ -15,7 +15,7 @@ class ShowBookDetailsAction(InterfaceAction):
|
||||
name = 'Show Book Details'
|
||||
action_spec = (_('Show book details'), 'dialog_information.png', None,
|
||||
_('I'))
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
action_type = 'current'
|
||||
|
||||
def genesis(self):
|
||||
|
@ -14,7 +14,7 @@ class ShowQuickviewAction(InterfaceAction):
|
||||
|
||||
name = 'Show quickview'
|
||||
action_spec = (_('Show quickview'), 'search.png', None, _('Q'))
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
action_type = 'current'
|
||||
|
||||
current_instance = None
|
||||
|
@ -17,7 +17,7 @@ class TweakEpubAction(InterfaceAction):
|
||||
action_spec = (_('Tweak ePub'), 'trim.png',
|
||||
_('Make small changes to ePub format books'),
|
||||
_('T'))
|
||||
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
|
||||
dont_add_to = frozenset(['context-menu-device'])
|
||||
action_type = 'current'
|
||||
|
||||
def genesis(self):
|
||||
|
@ -310,7 +310,7 @@ class CheckLibraryDialog(QDialog):
|
||||
|
||||
tl = Item()
|
||||
tl.setText(0, h)
|
||||
if fixable:
|
||||
if fixable and list:
|
||||
tl.setText(1, _('(fixable)'))
|
||||
tl.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
|
||||
tl.setCheckState(1, False)
|
||||
|
@ -12,6 +12,7 @@ from calibre.gui2.preferences import ConfigWidgetBase, test_widget, \
|
||||
from calibre.gui2.preferences.saving_ui import Ui_Form
|
||||
from calibre.utils.config import ConfigProxy
|
||||
from calibre.library.save_to_disk import config
|
||||
from calibre.gui2 import gprefs
|
||||
|
||||
class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
|
||||
@ -24,6 +25,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
for x in ('asciiize', 'update_metadata', 'save_cover', 'write_opf',
|
||||
'replace_whitespace', 'to_lowercase', 'formats', 'timefmt'):
|
||||
r(x, self.proxy)
|
||||
r('show_files_after_save', gprefs)
|
||||
|
||||
self.save_template.changed_signal.connect(self.changed_signal.emit)
|
||||
|
||||
|
@ -95,6 +95,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="opt_show_files_after_save">
|
||||
<property name="text">
|
||||
<string>&Show files in file browser after saving to disk</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
@ -231,6 +231,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
|
||||
def genesis(self, gui):
|
||||
self.models = {}
|
||||
self.what.addItem(_('Click to choose toolbar or menu to customize'),
|
||||
'blank')
|
||||
for key, text in self.LOCATIONS:
|
||||
self.what.addItem(text, key)
|
||||
all_model = AllModel(key, gui)
|
||||
@ -247,6 +249,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
|
||||
def what_changed(self, idx):
|
||||
key = unicode(self.what.itemData(idx).toString())
|
||||
if key == 'blank':
|
||||
self.actions_widget.setVisible(False)
|
||||
self.spacer_widget.setVisible(True)
|
||||
else:
|
||||
self.actions_widget.setVisible(True)
|
||||
self.spacer_widget.setVisible(False)
|
||||
self.all_actions.setModel(self.models[key][0])
|
||||
self.current_actions.setModel(self.models[key][1])
|
||||
|
||||
|
@ -13,16 +13,19 @@
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="5">
|
||||
<widget class="QComboBox" name="what">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string><p>The toolbar in calibre is different depending on whether a device is connected or not. Choose <b>which toolbar</b> you would like to customize:</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="what">
|
||||
<property name="toolTip">
|
||||
<string>Choose the toolbar to customize</string>
|
||||
</property>
|
||||
@ -34,7 +37,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<item>
|
||||
<widget class="QWidget" name="actions_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>A&vailable actions</string>
|
||||
@ -42,6 +51,12 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QListView" name="all_actions">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>100</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
@ -62,7 +77,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QToolButton" name="add_action_button">
|
||||
@ -122,7 +137,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="3" colspan="2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>&Current actions</string>
|
||||
@ -130,6 +145,12 @@
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QListView" name="current_actions">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>100</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
@ -210,14 +231,26 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="5">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string><p>The toolbar in calibre is different depending on whether a device is connected or not. To customize the toolbar when a device is connected as well as customizing right click menus, <b>click the dropdown above</b> and select which toolbar/menu you want to customize.</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="spacer_widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>224</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -24,7 +24,7 @@ class LibreDEStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
url = 'http://ad.zanox.com/ppc/?18817073C15644254T'
|
||||
url_details = ('http://ad.zanox.com/ppc/?18848208C1197627693T&ULP=[['
|
||||
url_details = ('http://ad.zanox.com/ppc/?18817073C15644254T&ULP=[['
|
||||
'http://www.libri.de/shop/action/productDetails?artiId={0}]]')
|
||||
|
||||
if external or self.config.get('open_external', False):
|
||||
|
@ -112,8 +112,12 @@ class LibraryServer(ContentServer, MobileServer, XMLServer, OPDSServer, Cache,
|
||||
self.opts = opts
|
||||
self.embedded = embedded
|
||||
self.state_callback = None
|
||||
try:
|
||||
self.max_cover_width, self.max_cover_height = \
|
||||
map(int, self.opts.max_cover.split('x'))
|
||||
except:
|
||||
self.max_cover_width = 1200
|
||||
self.max_cover_height = 1600
|
||||
path = P('content_server')
|
||||
self.build_time = fromtimestamp(os.stat(path).st_mtime)
|
||||
self.default_cover = open(P('content_server/default_cover.jpg'), 'rb').read()
|
||||
|
@ -47,7 +47,8 @@ def normalize_format_name(fmt):
|
||||
return fmt
|
||||
|
||||
def save_cover_data_to(data, path, bgcolor='#ffffff', resize_to=None,
|
||||
return_data=False, compression_quality=90, minify_to=None):
|
||||
return_data=False, compression_quality=90, minify_to=None,
|
||||
grayscale=False):
|
||||
'''
|
||||
Saves image in data to path, in the format specified by the path
|
||||
extension. Removes any transparency. If there is no transparency and no
|
||||
@ -60,7 +61,8 @@ def save_cover_data_to(data, path, bgcolor='#ffffff', resize_to=None,
|
||||
compression (lossless).
|
||||
:param bgcolor: The color for transparent pixels. Must be specified in hex.
|
||||
:param resize_to: A tuple (width, height) or None for no resizing
|
||||
:param minify_to: A tuple (width, height) to specify target size. The image
|
||||
:param minify_to: A tuple (width, height) to specify maximum target size.
|
||||
:param grayscale: If True, the image is grayscaled
|
||||
will be resized to fit into this target size. If None the value from the
|
||||
tweak is used.
|
||||
|
||||
@ -71,6 +73,10 @@ def save_cover_data_to(data, path, bgcolor='#ffffff', resize_to=None,
|
||||
fmt = os.path.splitext(path)[1]
|
||||
fmt = normalize_format_name(fmt[1:])
|
||||
|
||||
if grayscale:
|
||||
img.type = "GrayscaleType"
|
||||
changed = True
|
||||
|
||||
if resize_to is not None:
|
||||
img.size = (resize_to[0], resize_to[1])
|
||||
changed = True
|
||||
|
Loading…
x
Reference in New Issue
Block a user