mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-31 14:33:54 -04:00
0.9.0
This commit is contained in:
commit
a6f73264d6
@ -19,6 +19,51 @@
|
|||||||
# new recipes:
|
# new recipes:
|
||||||
# - title:
|
# - title:
|
||||||
|
|
||||||
|
- version: 0.9.0
|
||||||
|
date: 2012-09-28
|
||||||
|
|
||||||
|
new features:
|
||||||
|
- title: "For a summary of the major changes in calibre between 0.8 and 0.9, see http://calibre-ebook.com/new-in/nine"
|
||||||
|
type: major
|
||||||
|
|
||||||
|
bug fixes:
|
||||||
|
- title: "KF8 Output: Fix handling of & < and > entities in the text. They were sometimes being incorrectly unescaped."
|
||||||
|
|
||||||
|
- title: "Calibre portable: Add a manifest to the portable installer exe to prevent the application compatibility wizard from warning about a possible failed installation on windows 7. Also fixes installer requiring admin privileges on some computers"
|
||||||
|
tickets: [1057042]
|
||||||
|
|
||||||
|
- title: "EPUB metadata: Fix book producer not being set when updating EPUB metadata"
|
||||||
|
|
||||||
|
- title: "EPUB metadata: Fix incorrect namespace on the role attribute of <dc:creator> tags when updating the metadata in EPUB"
|
||||||
|
|
||||||
|
- title: "Get Books: Fix incorrect price retrieval from ebooks.com."
|
||||||
|
tickets: [1055785]
|
||||||
|
|
||||||
|
- title: "MTP windows driver: Fix main memory and storage card sometimes swapped"
|
||||||
|
tickets: [1055129]
|
||||||
|
|
||||||
|
- title: "PDF Output: On windows, remove any embedded fonts before generating the PDF as on windows, Qt generates image based PDFs when embedded fonts are present."
|
||||||
|
tickets: [1053906]
|
||||||
|
|
||||||
|
- title: "MTP windows driver: Do not try to connect to unsuitable devices such as the iPhone."
|
||||||
|
tickets: [1054562]
|
||||||
|
|
||||||
|
- title: "KF8 Input: Handle files that use non ascii paths/anchor names in the guide entries."
|
||||||
|
tickets: [1053751]
|
||||||
|
|
||||||
|
new recipes:
|
||||||
|
- title: Pubblico Giornale
|
||||||
|
author: iusvar
|
||||||
|
|
||||||
|
improved recipes:
|
||||||
|
- Monitor Online
|
||||||
|
- El Pais
|
||||||
|
- Chronicle of Higher Education
|
||||||
|
- Baltimore Sun
|
||||||
|
- Mac World
|
||||||
|
- Maximum PC
|
||||||
|
- Financial Times UK
|
||||||
|
|
||||||
- version: 0.8.70
|
- version: 0.8.70
|
||||||
date: 2012-09-21
|
date: 2012-09-21
|
||||||
|
|
||||||
|
@ -59,10 +59,10 @@
|
|||||||
<a href="http://calibre-ebook.com"><img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/></a>
|
<a href="http://calibre-ebook.com"><img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" title="Contribute to support calibre development">
|
||||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||||
<input type="hidden" name="hosted_button_id" value="AF4H3B8QVDG6N" />
|
<input type="hidden" name="hosted_button_id" value="AF4H3B8QVDG6N" />
|
||||||
<input type="image" src="http://manual.calibre-ebook.com/simple_donate_button.gif" border="0" name="submit" alt="Donate to support calibre development" style="border:0pt" />
|
<input type="image" src="http://manual.calibre-ebook.com/simple_donate_button.gif" border="0" name="submit" alt="Contribute to support calibre development" style="border:0pt" />
|
||||||
<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1" />
|
<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1" />
|
||||||
</form>
|
</form>
|
||||||
<hr/>
|
<hr/>
|
||||||
|
@ -1,45 +1,37 @@
|
|||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
__license__ = 'GPL 3'
|
__license__ = 'GPL 3'
|
||||||
__copyright__ = 'Original 2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__copyright__= 'Modified 2011, Josh Hall <jwtheiv@gmail.com>'
|
__copyright__ = '2012 Josh Hall<jwtheiv@gmail.com>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
'''
|
import urllib, re
|
||||||
www.baltimoresun.com
|
|
||||||
'''
|
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class BaltimoreSun(BasicNewsRecipe):
|
class BaltimoreSun(BasicNewsRecipe):
|
||||||
|
|
||||||
title = 'The Baltimore Sun'
|
title = 'The Baltimore Sun'
|
||||||
__author__ = 'Josh Hall'
|
__author__ = 'Josh Hall'
|
||||||
description = 'Politics, local and business news from Baltimore'
|
|
||||||
language = 'en'
|
description = 'Complete local news and blogs from Baltimore'
|
||||||
|
language = 'en'
|
||||||
|
version = 2
|
||||||
oldest_article = 1
|
oldest_article = 1
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
remove_empty_feeds = True
|
use_embedded_content = False
|
||||||
use_embedded_content = False
|
no_stylesheets = True
|
||||||
no_stylesheets = True
|
remove_javascript = True
|
||||||
remove_javascript = True
|
recursions = 1
|
||||||
#masthead_url = 'http://www.baltimoresun.com/images/thirdpartylogo.gif'
|
|
||||||
|
|
||||||
remove_tags_before = dict(name='div', attrs={'class':['story', 'entry']})
|
|
||||||
remove_tags_after = [
|
|
||||||
{'class':['photo_article',]},
|
|
||||||
dict(name='div', attrs={'class':'shirttail-promo right clearfix'}),
|
|
||||||
]
|
|
||||||
|
|
||||||
keep_only_tags = [dict(name='div', attrs={'class':["story","entry-asset asset hentry"]}),
|
keep_only_tags = [dict(name='div', attrs={'class':["story","entry-asset asset hentry"]}),
|
||||||
dict(name='div', attrs={'id':["pagebody","story","maincontentcontainer"]}),
|
dict(name='div', attrs={'id':["pagebody","story","maincontentcontainer"]}),
|
||||||
]
|
]
|
||||||
|
remove_tags_after = [{'class':['photo_article',]}]
|
||||||
|
|
||||||
|
match_regexps = [r'page=[0-9]+']
|
||||||
|
|
||||||
remove_tags = [{'id':["moduleArticleTools","content-bottom","rail","articleRelates module","toolSet","relatedrailcontent","div-wrapper","beta","atp-comments","footer","article-promo"]},
|
remove_tags = [{'id':["moduleArticleTools","content-bottom","rail","articleRelates module","toolSet","relatedrailcontent","div-wrapper","beta","atp-comments","footer",'gallery-subcontent','subFooter']},
|
||||||
{'class':["entry-footer-left","entry-footer-right","shirttail-promo right clearfix","clearfix","relatedTitle","articleRelates module","asset-footer","tools","comments","featurePromo","featurePromo fp-topjobs brownBackground","clearfix fullSpan brownBackground","curvedContent","toppaginate","module","module-header","module-content"]},
|
{'class':["clearfix","relatedTitle","articleRelates module","asset-footer","tools","comments","featurePromo","featurePromo fp-topjobs brownBackground","clearfix fullSpan brownBackground","curvedContent",'nextgen-share-tools','outbrainTools', 'google-ad-story-bottom']},
|
||||||
dict(name='font',attrs={'id':["cr-other-headlines"]}),
|
dict(name='font',attrs={'id':["cr-other-headlines"]})]
|
||||||
dict(name=['iframe']),
|
|
||||||
]
|
|
||||||
extra_css = '''
|
extra_css = '''
|
||||||
h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;}
|
h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;}
|
||||||
h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;}
|
h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;}
|
||||||
@ -53,8 +45,9 @@ class BaltimoreSun(BasicNewsRecipe):
|
|||||||
.maincontentcontainer{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
.maincontentcontainer{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
||||||
.story-body{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
.story-body{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
||||||
body{font-family:Helvetica,Arial,sans-serif;font-size:small;}
|
body{font-family:Helvetica,Arial,sans-serif;font-size:small;}
|
||||||
'''
|
'''
|
||||||
feeds = [
|
feeds = [
|
||||||
|
## News ##
|
||||||
(u'Top Headlines', u'http://www.baltimoresun.com/rss2.0.xml'),
|
(u'Top Headlines', u'http://www.baltimoresun.com/rss2.0.xml'),
|
||||||
(u'Breaking News', u'http://www.baltimoresun.com/news/breaking/rss2.0.xml'),
|
(u'Breaking News', u'http://www.baltimoresun.com/news/breaking/rss2.0.xml'),
|
||||||
(u'Top Maryland', u'http://www.baltimoresun.com/news/maryland/rss2.0.xml'),
|
(u'Top Maryland', u'http://www.baltimoresun.com/news/maryland/rss2.0.xml'),
|
||||||
@ -69,10 +62,10 @@ class BaltimoreSun(BasicNewsRecipe):
|
|||||||
(u'Local Politics', u'http://www.baltimoresun.com/news/maryland/politics/rss2.0.xml'),
|
(u'Local Politics', u'http://www.baltimoresun.com/news/maryland/politics/rss2.0.xml'),
|
||||||
(u'Weather', u'http://www.baltimoresun.com/news/weather/rss2.0.xml'),
|
(u'Weather', u'http://www.baltimoresun.com/news/weather/rss2.0.xml'),
|
||||||
#(u'Traffic', u'http://www.baltimoresun.com/features/commuting/rss2.0.xml'),
|
#(u'Traffic', u'http://www.baltimoresun.com/features/commuting/rss2.0.xml'),
|
||||||
(u'Nation/world', u'http://feeds.chicagotribune.com/chicagotribune/news/nationworld/'),
|
(u'Nation/world', u'http://feeds.feedburner.com/baltimoresun/news/nationworld/rss2'),
|
||||||
(u'Weird News', u'http://www.baltimoresun.com/news/offbeat/rss2.0.xml'),
|
(u'Weird News', u'http://www.baltimoresun.com/news/offbeat/rss2.0.xml'),
|
||||||
|
|
||||||
|
##Sports##
|
||||||
(u'Top Sports', u'http://www.baltimoresun.com/sports/rss2.0.xml'),
|
(u'Top Sports', u'http://www.baltimoresun.com/sports/rss2.0.xml'),
|
||||||
(u'Orioles/Baseball', u'http://www.baltimoresun.com/sports/orioles/rss2.0.xml'),
|
(u'Orioles/Baseball', u'http://www.baltimoresun.com/sports/orioles/rss2.0.xml'),
|
||||||
(u'Ravens/Football', u'http://www.baltimoresun.com/sports/ravens/rss2.0.xml'),
|
(u'Ravens/Football', u'http://www.baltimoresun.com/sports/ravens/rss2.0.xml'),
|
||||||
@ -85,6 +78,7 @@ class BaltimoreSun(BasicNewsRecipe):
|
|||||||
#(u'High School', u'http://www.baltimoresun.com/sports/high-school/rss2.0.xml'),
|
#(u'High School', u'http://www.baltimoresun.com/sports/high-school/rss2.0.xml'),
|
||||||
#(u'Outdoors', u'http://www.baltimoresun.com/sports/outdoors/rss2.0.xml'),
|
#(u'Outdoors', u'http://www.baltimoresun.com/sports/outdoors/rss2.0.xml'),
|
||||||
|
|
||||||
|
## Entertainment ##
|
||||||
(u'Celebrity News', u'http://www.baltimoresun.com/entertainment/celebrities/rss2.0.xml'),
|
(u'Celebrity News', u'http://www.baltimoresun.com/entertainment/celebrities/rss2.0.xml'),
|
||||||
(u'Arts & Theater', u'http://www.baltimoresun.com/entertainment/arts/rss2.0.xml'),
|
(u'Arts & Theater', u'http://www.baltimoresun.com/entertainment/arts/rss2.0.xml'),
|
||||||
(u'Movies', u'http://www.baltimoresun.com/entertainment/movies/rss2.0.xml'),
|
(u'Movies', u'http://www.baltimoresun.com/entertainment/movies/rss2.0.xml'),
|
||||||
@ -92,14 +86,16 @@ class BaltimoreSun(BasicNewsRecipe):
|
|||||||
(u'Restaurants & Food', u'http://www.baltimoresun.com/entertainment/dining/rss2.0.xml'),
|
(u'Restaurants & Food', u'http://www.baltimoresun.com/entertainment/dining/rss2.0.xml'),
|
||||||
(u'TV/Media', u'http://www.baltimoresun.com/entertainment/tv/rss2.0.xml'),
|
(u'TV/Media', u'http://www.baltimoresun.com/entertainment/tv/rss2.0.xml'),
|
||||||
|
|
||||||
|
## Life ##
|
||||||
(u'Health&Wellness', u'http://www.baltimoresun.com/health/rss2.0.xml'),
|
(u'Health&Wellness', u'http://www.baltimoresun.com/health/rss2.0.xml'),
|
||||||
(u'Home & Garden', u'http://www.baltimoresun.com/features/home-garden/rss2.0.xml'),
|
(u'Home & Garden', u'http://www.baltimoresun.com/features/home-garden/rss2.0.xml'),
|
||||||
(u'Living Green', u'http://www.baltimoresun.com/features/green/rss2.0.xml'),
|
(u'Living Green', u'http://www.baltimoresun.com/features/green/rss2.0.xml'),
|
||||||
(u'Parenting', u'http://www.baltimoresun.com/features/parenting/rss2.0.xml'),
|
(u'Parenting', u'http://www.baltimoresun.com/features/parenting/rss2.0.xml'),
|
||||||
(u'Fashion', u'http://www.baltimoresun.com/features/fashion/rss2.0.xml'),
|
(u'Fashion', u'http://www.baltimoresun.com/features/fashion/rss2.0.xml'),
|
||||||
(u'Travel', u'http://www.baltimoresun.com/travel/rss2.0.xml'),
|
(u'Travel', u'http://www.baltimoresun.com/travel/rss2.0.xml'),
|
||||||
(u'Faith', u'http://www.baltimoresun.com/features/faith/rss2.0.xml'),
|
#(u'Faith', u'http://www.baltimoresun.com/features/faith/rss2.0.xml'),
|
||||||
|
|
||||||
|
## Business ##
|
||||||
(u'Top Business', u'http://www.baltimoresun.com/business/rss2.0.xml'),
|
(u'Top Business', u'http://www.baltimoresun.com/business/rss2.0.xml'),
|
||||||
(u'Technology', u'http://www.baltimoresun.com/business/technology/rss2.0.xml'),
|
(u'Technology', u'http://www.baltimoresun.com/business/technology/rss2.0.xml'),
|
||||||
(u'Personal finance', u'http://www.baltimoresun.com/business/money/rss2.0.xml'),
|
(u'Personal finance', u'http://www.baltimoresun.com/business/money/rss2.0.xml'),
|
||||||
@ -109,12 +105,14 @@ class BaltimoreSun(BasicNewsRecipe):
|
|||||||
(u'Consumer Safety', u'http://www.baltimoresun.com/business/consumer-safety/rss2.0.xml'),
|
(u'Consumer Safety', u'http://www.baltimoresun.com/business/consumer-safety/rss2.0.xml'),
|
||||||
(u'Investing', u'http://www.baltimoresun.com/business/money/rss2.0.xml'),
|
(u'Investing', u'http://www.baltimoresun.com/business/money/rss2.0.xml'),
|
||||||
|
|
||||||
|
## Opinion##
|
||||||
(u'Sun Editorials', u'http://www.baltimoresun.com/news/opinion/editorial/rss2.0.xml'),
|
(u'Sun Editorials', u'http://www.baltimoresun.com/news/opinion/editorial/rss2.0.xml'),
|
||||||
(u'Op/Ed', u'http://www.baltimoresun.com/news/opinion/oped/rss2.0.xml'),
|
(u'Op/Ed', u'http://www.baltimoresun.com/news/opinion/oped/rss2.0.xml'),
|
||||||
(u'Readers Respond', u'http://www.baltimoresun.com/news/opinion/readersrespond/'),
|
(u'Readers Respond', u'http://www.baltimoresun.com/news/opinion/readersrespond/'),
|
||||||
|
|
||||||
(u'Kevin Cowherd', 'http://www.baltimoresun.com/sports/bal-columnist-cowherd,0,6829726.columnist-rss2.0.xml'),
|
## Columnists ##
|
||||||
(u'Jay Hancock', u'http://www.baltimoresun.com/business/money/bal-columnist-hancock,0,6673611.columnist-rss2.0.xml'),
|
(u'Kevin Cowherd', u'http://www.baltimoresun.com/sports/bal-columnist-cowherd,0,6829726.columnist-rss2.0.xml'),
|
||||||
|
(u'Robert Ehrlich', u'http://www.baltimoresun.com/news/opinion/columnists/bal-columnist-ehrlich,0,1825227.columnist-rss2.0.xml'),
|
||||||
(u'Jacques Kelly', u'http://www.baltimoresun.com/news/maryland/bal-columnist-kelly,0,1154701.columnist-rss2.0.xml'),
|
(u'Jacques Kelly', u'http://www.baltimoresun.com/news/maryland/bal-columnist-kelly,0,1154701.columnist-rss2.0.xml'),
|
||||||
(u'Marta H. Mossburg', u'http://www.baltimoresun.com/news/opinion/oped/bal-columnist-mossburg,0,7982155.columnist-rss2.0.xml'),
|
(u'Marta H. Mossburg', u'http://www.baltimoresun.com/news/opinion/oped/bal-columnist-mossburg,0,7982155.columnist-rss2.0.xml'),
|
||||||
(u'Mike Preston', u'http://www.baltimoresun.com/sports/bal-columnist-preston,0,6169796.columnist-rss2.0.xml'),
|
(u'Mike Preston', u'http://www.baltimoresun.com/sports/bal-columnist-preston,0,6169796.columnist-rss2.0.xml'),
|
||||||
@ -122,59 +120,80 @@ class BaltimoreSun(BasicNewsRecipe):
|
|||||||
(u'Dan Rodricks', u'http://www.baltimoresun.com/news/maryland/bal-columnist-rodricks,0,7089843.columnist-rss2.0.xml'),
|
(u'Dan Rodricks', u'http://www.baltimoresun.com/news/maryland/bal-columnist-rodricks,0,7089843.columnist-rss2.0.xml'),
|
||||||
(u'Thomas F. Schaller', u'http://www.baltimoresun.com/news/opinion/columnists/bal-columnist-schaller,0,897397.columnist-rss2.0.xml'),
|
(u'Thomas F. Schaller', u'http://www.baltimoresun.com/news/opinion/columnists/bal-columnist-schaller,0,897397.columnist-rss2.0.xml'),
|
||||||
(u'Peter Schmuck', u'http://www.baltimoresun.com/sports/bal-columnist-schmuck,0,7485088.columnist-rss2.0.xml'),
|
(u'Peter Schmuck', u'http://www.baltimoresun.com/sports/bal-columnist-schmuck,0,7485088.columnist-rss2.0.xml'),
|
||||||
(u'Ron Smith', u'http://www.baltimoresun.com/news/opinion/bal-columnist-ronsmith,0,3964803.columnist-rss2.0.xml'),
|
|
||||||
|
|
||||||
(u'Baltimore Crime Beat', u'http://weblogs.baltimoresun.com/news/crime/blog/index.xml'),
|
## News Blogs ##
|
||||||
(u'Getting There', u'http://weblogs.baltimoresun.com/news/traffic/index.xml'),
|
(u'Baltimore Crime Beat', u'http://baltimore.feedsportal.com/c/34255/f/623075/index.rss'),
|
||||||
(u'InsideEd', u'http://weblogs.baltimoresun.com/news/education/blog/index.xml'),
|
(u'InsideEd', u'http://www.baltimoresun.com/news/maryland/education/blog/rss2.0.xml'),
|
||||||
(u'Maryland Politics', u'http://weblogs.baltimoresun.com/news/local/politics/index.xml'),
|
(u'Maryland Politics', u'http://www.baltimoresun.com/news/maryland/politics/blog/rss2.0.xml'),
|
||||||
(u'Maryland Weather', u'http://weblogs.marylandweather.com/index.xml'),
|
(u'Maryland Weather', u'http://www.baltimoresun.com/news/weather/weather-blog/rss2.0.xml'),
|
||||||
(u'Second Opinion', u'http://weblogs.baltimoresun.com/news/opinion/index.xml'),
|
(u'Second Opinion', u'http://www.baltimoresun.com/news/opinion/second-opinion-blog/rss2.0.xml'),
|
||||||
(u'You Dont Say', u'http://weblogs.baltimoresun.com/news/mcintyre/blog/index.xml'),
|
(u'Sun Investigates', u'http://www.baltimoresun.com/news/maryland/sun-investigates/rss2.0.xml'),
|
||||||
|
(u'You Dont Say', u'http://www.baltimoresun.com/news/language-blog/rss2.0.xml'),
|
||||||
|
|
||||||
(u'BaltTech', u'http://weblogs.baltimoresun.com/news/technology/index.xml'),
|
## Business Blogs ##
|
||||||
(u'Consuming Interests', u'http://weblogs.baltimoresun.com/business/consuminginterests/blog/index.xml'),
|
(u'BaltTech', u'http://www.baltimoresun.com/business/technology/blog/rss2.0.xml'),
|
||||||
(u'Jay Hancocks Blog', u'http://weblogs.baltimoresun.com/business/hancock/blog/index.xml'),
|
(u'Consuming Interests', u'http://www.baltimoresun.com/business/consuming-interests-blog/rss2.0.xml'),
|
||||||
(u'The Real Estate Wonk', u'http://weblogs.baltimoresun.com/business/realestate/blog/index.xml'),
|
(u'The Real Estate Wonk', u'http://www.baltimoresun.com/business/real-estate/wonk/rss2.0.xml'),
|
||||||
|
|
||||||
(u'Clef Notes', 'http://weblogs.baltimoresun.com/entertainment/classicalmusic/index.xml'),
|
## Entertainment Blogs ##
|
||||||
(u'Dining at Large', u'http://weblogs.baltimoresun.com/entertainment/dining/reviews/blog/index.xml'),
|
(u'Clef Notes & Drama Queens', 'http://weblogs.baltimoresun.com/entertainment/classicalmusic/index.xml'),
|
||||||
(u'Midnight Sun', u'http://weblogs.baltimoresun.com/entertainment/midnight_sun/blog/index.xml'),
|
(u'Baltimore Diner', u'http://baltimore.feedsportal.com/c/34255/f/623088/index.rss'),
|
||||||
(u'Mike Sragow Gets Reel', u'http://weblogs.baltimoresun.com/entertainment/movies/blog/index.xml'),
|
(u'Midnight Sun', u'http://www.baltimoresun.com/entertainment/music/midnight-sun-blog/rss2.0.xml'),
|
||||||
(u'Read Street', u'http://weblogs.baltimoresun.com/entertainment/books/blog/index.xml'),
|
(u'Read Street', u'http://www.baltimoresun.com/features/books/read-street/rss2.0.xml'),
|
||||||
(u'Reality Check', u'http://weblogs.baltimoresun.com/entertainment/realitycheck/blog/index.xml'),
|
(u'Z on TV', u'http://www.baltimoresun.com/entertainment/tv/z-on-tv-blog/rss2.0.xml'),
|
||||||
(u'Z on TV', u'http://weblogs.baltimoresun.com/entertainment/zontv/index.xml'),
|
|
||||||
|
|
||||||
|
## Life Blogs ##
|
||||||
(u'BMore Green', u'http://weblogs.baltimoresun.com/features/green/index.xml'),
|
(u'BMore Green', u'http://weblogs.baltimoresun.com/features/green/index.xml'),
|
||||||
(u'Charm City Moms', u'http://weblogs.baltimoresun.com/features/baltimoremomblog/index.xml'),
|
(u'Baltimore Insider',u'http://www.baltimoresun.com/features/baltimore-insider-blog/rss2.0.xml'),
|
||||||
(u'Exercists', u'http://weblogs.baltimoresun.com/health/fitness/index.xml'),
|
(u'Homefront', u'http://www.baltimoresun.com/features/parenting/homefront/rss2.0.xml'),
|
||||||
(u'Garden Variety', 'http://weblogs.baltimoresun.com/features/gardening/index.xml'),
|
(u'Picture of Health', u'http://www.baltimoresun.com/health/blog/rss2.0.xml'),
|
||||||
#(u'In Good Faith', u'http://weblogs.baltimoresun.com/news/faith/index.xml'),
|
|
||||||
(u'Picture of Health', u'http://weblogs.baltimoresun.com/health/index.xml'),
|
|
||||||
(u'Unleashed', u'http://weblogs.baltimoresun.com/features/mutts/blog/index.xml'),
|
(u'Unleashed', u'http://weblogs.baltimoresun.com/features/mutts/blog/index.xml'),
|
||||||
|
|
||||||
|
## b the site blogs ##
|
||||||
|
(u'Game Cache', u'http://www.baltimoresun.com/entertainment/bthesite/game-cache/rss2.0.xml'),
|
||||||
|
(u'TV Lust', u'http://www.baltimoresun.com/entertainment/bthesite/tv-lust/rss2.0.xml'),
|
||||||
|
|
||||||
|
## Sports Blogs ##
|
||||||
|
(u'Baltimore Sports Blitz', u'http://baltimore.feedsportal.com/c/34255/f/623097/index.rss'),
|
||||||
#(u'Faceoff', u'http://weblogs.baltimoresun.com/sports/lacrosse/blog/index.xml'),
|
#(u'Faceoff', u'http://weblogs.baltimoresun.com/sports/lacrosse/blog/index.xml'),
|
||||||
#(u'MMA Stomping Grounds', u'http://weblogs.baltimoresun.com/sports/mma/blog/index.xml'),
|
#(u'MMA Stomping Grounds', u'http://weblogs.baltimoresun.com/sports/mma/blog/index.xml'),
|
||||||
(u'Orioles Insider', u'http://weblogs.baltimoresun.com/sports/orioles/blog/index.xml'),
|
(u'Orioles Insider', u'http://baltimore.feedsportal.com/c/34255/f/623100/index.rss'),
|
||||||
#(u'Outdoors Girl', u'http://weblogs.baltimoresun.com/sports/outdoors/blog/index.xml'),
|
(u'Ravens Insider', u'http://www.baltimoresun.com/sports/ravens/ravens-insider/rss2.0.xml'),
|
||||||
(u'Ravens Insider', u'http://weblogs.baltimoresun.com/sports/ravens/blog/index.xml'),
|
|
||||||
#(u'Recruiting Report', u'http://weblogs.baltimoresun.com/sports/college/recruiting/index.xml'),
|
#(u'Recruiting Report', u'http://weblogs.baltimoresun.com/sports/college/recruiting/index.xml'),
|
||||||
#(u'Ring Posts', u'http://weblogs.baltimoresun.com/sports/wrestling/blog/index.xml'),
|
#(u'Ring Posts', u'http://weblogs.baltimoresun.com/sports/wrestling/blog/index.xml'),
|
||||||
(u'The Schmuck Stops Here', u'http://weblogs.baltimoresun.com/sports/schmuck/index.xml'),
|
(u'The Schmuck Stops Here', u'http://www.baltimoresun.com/sports/schmuck-blog/rss2.0.xml'),
|
||||||
(u'Toy Department', u'http://weblogs.baltimoresun.com/sports/thetoydepartment/index.xml'),
|
|
||||||
#(u'Tracking the Terps', u'http://weblogs.baltimoresun.com/sports/college/maryland_terps/blog/index.xml'),
|
#(u'Tracking the Terps', u'http://weblogs.baltimoresun.com/sports/college/maryland_terps/blog/index.xml'),
|
||||||
#(u'Varsity Letters', u'http://weblogs.baltimoresun.com/sports/highschool/varsityletters/index.xml'),
|
#(u'Varsity Letters', u'http://weblogs.baltimoresun.com/sports/highschool/varsityletters/index.xml'),
|
||||||
(u'Virtual Vensanity', u'http://weblogs.baltimoresun.com/entertainment/bthesite/vensel/index.xml'),
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def get_article_url(self, article):
|
def get_article_url(self, article):
|
||||||
print article.get('feedburner_origlink', article.get('guid', article.get('link')))
|
ans = None
|
||||||
return article.get('feedburner_origlink', article.get('guid', article.get('link')))
|
try:
|
||||||
|
s = article.summary
|
||||||
|
ans = urllib.unquote(
|
||||||
|
re.search(r'href=".+?bookmark.cfm.+?link=(.+?)"', s).group(1))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if ans is None:
|
||||||
|
ans = article.get('feedburner_origlink', article.get('guid', article.get('link')))
|
||||||
|
if ans is not None:
|
||||||
|
return ans.replace('?track=rss', '')
|
||||||
|
|
||||||
|
def skip_ad_pages(self, soup):
|
||||||
|
text = soup.find(text='click here to continue to article')
|
||||||
|
if text:
|
||||||
|
a = text.parent
|
||||||
|
url = a.get('href')
|
||||||
|
if url:
|
||||||
|
return self.index_to_soup(url, raw=True)
|
||||||
|
|
||||||
def postprocess_html(self, soup, first_fetch):
|
def postprocess_html(self, soup, first_fetch):
|
||||||
|
# Remove the navigation bar. It was kept until now to be able to follow
|
||||||
|
# the links to further pages. But now we don't need them anymore.
|
||||||
|
for nav in soup.findAll(attrs={'class':['toppaginate','article-nav clearfix']}):
|
||||||
|
nav.extract()
|
||||||
|
|
||||||
for t in soup.findAll(['table', 'tr', 'td']):
|
for t in soup.findAll(['table', 'tr', 'td']):
|
||||||
t.name = 'div'
|
t.name = 'div'
|
||||||
|
|
||||||
@ -182,5 +201,3 @@ class BaltimoreSun(BasicNewsRecipe):
|
|||||||
tag.extract()
|
tag.extract()
|
||||||
for tag in soup.findAll('font', dict(attrs={'id':["cr-other-headlines"]})):
|
for tag in soup.findAll('font', dict(attrs={'id':["cr-other-headlines"]})):
|
||||||
tag.extract()
|
tag.extract()
|
||||||
|
|
||||||
return soup
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import re
|
||||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
@ -14,7 +15,8 @@ class Chronicle(BasicNewsRecipe):
|
|||||||
dict(name='div', attrs={'class':'article'}),
|
dict(name='div', attrs={'class':'article'}),
|
||||||
]
|
]
|
||||||
remove_tags = [dict(name='div',attrs={'class':['related module1','maintitle']}),
|
remove_tags = [dict(name='div',attrs={'class':['related module1','maintitle']}),
|
||||||
dict(name='div', attrs={'id':['section-nav','icon-row']})]
|
dict(name='div', attrs={'id':['section-nav','icon-row', 'enlarge-popup']}),
|
||||||
|
dict(name='a', attrs={'class':'show-enlarge enlarge'})]
|
||||||
no_javascript = True
|
no_javascript = True
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
|
|
||||||
@ -31,7 +33,6 @@ class Chronicle(BasicNewsRecipe):
|
|||||||
return br
|
return br
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
|
|
||||||
#Go to the issue
|
#Go to the issue
|
||||||
soup0 = self.index_to_soup('http://chronicle.com/section/Archives/39/')
|
soup0 = self.index_to_soup('http://chronicle.com/section/Archives/39/')
|
||||||
issue = soup0.find('ul',attrs={'class':'feature-promo-list'}).li
|
issue = soup0.find('ul',attrs={'class':'feature-promo-list'}).li
|
||||||
@ -42,9 +43,12 @@ class Chronicle(BasicNewsRecipe):
|
|||||||
self.timefmt = u' [%s]'%dates
|
self.timefmt = u' [%s]'%dates
|
||||||
|
|
||||||
#Find cover
|
#Find cover
|
||||||
cover=soup0.find('div',attrs={'class':'promo'}).findNext('div')
|
cover=soup0.find('div',attrs={'class':'side-content'}).find(attrs={'src':re.compile("photos/biz/Current")})
|
||||||
self.cover_url="http://chronicle.com"+cover.find('img')['src']
|
if cover is not None:
|
||||||
|
if "chronicle.com" in cover['src']:
|
||||||
|
self.cover_url=cover['src']
|
||||||
|
else:
|
||||||
|
self.cover_url="http://chronicle.com" + cover['src']
|
||||||
#Go to the main body
|
#Go to the main body
|
||||||
soup = self.index_to_soup(issueurl)
|
soup = self.index_to_soup(issueurl)
|
||||||
div = soup.find ('div', attrs={'id':'article-body'})
|
div = soup.find ('div', attrs={'id':'article-body'})
|
||||||
@ -74,8 +78,10 @@ class Chronicle(BasicNewsRecipe):
|
|||||||
def preprocess_html(self,soup):
|
def preprocess_html(self,soup):
|
||||||
#process all the images
|
#process all the images
|
||||||
for div in soup.findAll('div', attrs={'class':'tableauPlaceholder'}):
|
for div in soup.findAll('div', attrs={'class':'tableauPlaceholder'}):
|
||||||
|
|
||||||
noscripts=div.find('noscript').a
|
noscripts=div.find('noscript').a
|
||||||
div.replaceWith(noscripts)
|
div.replaceWith(noscripts)
|
||||||
for div0 in soup.findAll('div',text='Powered by Tableau'):
|
for div0 in soup.findAll('div',text='Powered by Tableau'):
|
||||||
div0.extract()
|
div0.extract()
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class ElPais_RSS(BasicNewsRecipe):
|
|||||||
,dict(attrs={'class':['firma','columna_texto','entrevista_p_r']})
|
,dict(attrs={'class':['firma','columna_texto','entrevista_p_r']})
|
||||||
]
|
]
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
dict(name=['meta','link','base','iframe','embed','object'])
|
dict(name=['iframe','embed','object'])
|
||||||
,dict(attrs={'class':'disposicion_vertical'})
|
,dict(attrs={'class':'disposicion_vertical'})
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -74,13 +74,14 @@ class ElPais_RSS(BasicNewsRecipe):
|
|||||||
,(u'Justicia y Leyes' , u'http://elpais.com/tag/rss/justicia/a/' )
|
,(u'Justicia y Leyes' , u'http://elpais.com/tag/rss/justicia/a/' )
|
||||||
,(u'Guerras y conflictos' , u'http://elpais.com/tag/rss/conflictos/a/' )
|
,(u'Guerras y conflictos' , u'http://elpais.com/tag/rss/conflictos/a/' )
|
||||||
,(u'Politica' , u'http://ep00.epimg.net/rss/politica/portada.xml' )
|
,(u'Politica' , u'http://ep00.epimg.net/rss/politica/portada.xml' )
|
||||||
,(u'Opinion' , u'http://ep01.epimg.net/rss/politica/opinion.xml' )
|
,(u'Opinion' , u'http://ep01.epimg.net/rss/elpais/opinion.xml' )
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_article_url(self, article):
|
def get_article_url(self, article):
|
||||||
url = BasicNewsRecipe.get_article_url(self, article)
|
url = BasicNewsRecipe.get_article_url(self, article)
|
||||||
if url and (not('/album/' in url) and not('/futbol/partido/' in url)):
|
if url and (not('/album/' in url) and not('/futbol/partido/' in url)):
|
||||||
return url
|
urlverified = self.browser.open_novisit(url).geturl()
|
||||||
|
return urlverified
|
||||||
self.log('Skipping non-article', url)
|
self.log('Skipping non-article', url)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -107,3 +108,7 @@ class ElPais_RSS(BasicNewsRecipe):
|
|||||||
for item in soup.findAll('img',alt=False):
|
for item in soup.findAll('img',alt=False):
|
||||||
item['alt'] = 'image'
|
item['alt'] = 'image'
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
|
def preprocess_raw_html(self, raw, url):
|
||||||
|
return '<html><head><title>Untitled</title>'+raw[raw.find('</head>'):]
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010-2011, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2010-2012, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
www.ft.com/uk-edition
|
www.ft.com/uk-edition
|
||||||
'''
|
'''
|
||||||
@ -51,10 +51,15 @@ class FinancialTimes(BasicNewsRecipe):
|
|||||||
return br
|
return br
|
||||||
|
|
||||||
keep_only_tags = [
|
keep_only_tags = [
|
||||||
dict(name='div', attrs={'class':['fullstory fullstoryHeader', 'ft-story-header']})
|
dict(name='div' , attrs={'class':['fullstory fullstoryHeader', 'ft-story-header']})
|
||||||
,dict(name='div', attrs={'class':'standfirst'})
|
,dict(name='div' , attrs={'class':'standfirst'})
|
||||||
,dict(name='div', attrs={'id' :'storyContent'})
|
,dict(name='div' , attrs={'id' :'storyContent'})
|
||||||
,dict(name='div', attrs={'class':['ft-story-body','index-detail']})
|
,dict(name='div' , attrs={'class':['ft-story-body','index-detail']})
|
||||||
|
,dict(name='div' , attrs={'class':['ft-story-body','index-detail']})
|
||||||
|
,dict(name='h2' , attrs={'class':'entry-title'} )
|
||||||
|
,dict(name='span', attrs={'class':lambda x: x and 'posted-on' in x.split()} )
|
||||||
|
,dict(name='span', attrs={'class':'author_byline'} )
|
||||||
|
,dict(name='div' , attrs={'class':'entry-content'} )
|
||||||
]
|
]
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
dict(name='div', attrs={'id':'floating-con'})
|
dict(name='div', attrs={'id':'floating-con'})
|
||||||
@ -83,10 +88,9 @@ class FinancialTimes(BasicNewsRecipe):
|
|||||||
if self.test and count > 2:
|
if self.test and count > 2:
|
||||||
return articles
|
return articles
|
||||||
rawlink = item['href']
|
rawlink = item['href']
|
||||||
if rawlink.startswith('http://'):
|
url = rawlink
|
||||||
url = rawlink
|
if not rawlink.startswith('http://'):
|
||||||
else:
|
url = self.PREFIX + rawlink
|
||||||
url = self.PREFIX + rawlink
|
|
||||||
urlverified = self.browser.open_novisit(url).geturl() # resolve redirect.
|
urlverified = self.browser.open_novisit(url).geturl() # resolve redirect.
|
||||||
title = self.tag_to_string(item)
|
title = self.tag_to_string(item)
|
||||||
date = strftime(self.timefmt)
|
date = strftime(self.timefmt)
|
||||||
@ -106,20 +110,20 @@ class FinancialTimes(BasicNewsRecipe):
|
|||||||
wide = soup.find('div',attrs={'class':'wide'})
|
wide = soup.find('div',attrs={'class':'wide'})
|
||||||
if not wide:
|
if not wide:
|
||||||
return feeds
|
return feeds
|
||||||
strest = wide.findAll('h3', attrs={'class':'section'})
|
allsections = wide.findAll(attrs={'class':lambda x: x and 'footwell' in x.split()})
|
||||||
if not strest:
|
if not allsections:
|
||||||
return feeds
|
return feeds
|
||||||
st = wide.findAll('h4',attrs={'class':'section-no-arrow'})
|
|
||||||
if st:
|
|
||||||
st.extend(strest)
|
|
||||||
count = 0
|
count = 0
|
||||||
for item in st:
|
for item in allsections:
|
||||||
count = count + 1
|
count = count + 1
|
||||||
if self.test and count > 2:
|
if self.test and count > 2:
|
||||||
return feeds
|
return feeds
|
||||||
ftitle = self.tag_to_string(item)
|
fitem = item.h3
|
||||||
|
if not fitem:
|
||||||
|
fitem = item.h4
|
||||||
|
ftitle = self.tag_to_string(fitem)
|
||||||
self.report_progress(0, _('Fetching feed')+' %s...'%(ftitle))
|
self.report_progress(0, _('Fetching feed')+' %s...'%(ftitle))
|
||||||
feedarts = self.get_artlinks(item.parent.ul)
|
feedarts = self.get_artlinks(item.ul)
|
||||||
feeds.append((ftitle,feedarts))
|
feeds.append((ftitle,feedarts))
|
||||||
return feeds
|
return feeds
|
||||||
|
|
||||||
@ -166,7 +170,8 @@ class FinancialTimes(BasicNewsRecipe):
|
|||||||
except:
|
except:
|
||||||
print "Retrying download..."
|
print "Retrying download..."
|
||||||
count += 1
|
count += 1
|
||||||
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
tfile = PersistentTemporaryFile('_fa.html')
|
||||||
self.temp_files[-1].write(html)
|
tfile.write(html)
|
||||||
self.temp_files[-1].close()
|
tfile.close()
|
||||||
return self.temp_files[-1].name
|
self.temp_files.append(tfile)
|
||||||
|
return tfile.name
|
||||||
|
BIN
recipes/icons/monitor.png
Normal file
BIN
recipes/icons/monitor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
@ -34,20 +34,21 @@ class macWorld(BasicNewsRecipe):
|
|||||||
|
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
|
auto_cleanup = True
|
||||||
|
|
||||||
keep_only_tags = [
|
#keep_only_tags = [
|
||||||
dict(name='div', attrs={'id':'content'})
|
#dict(name='div', attrs={'id':'content'})
|
||||||
]
|
#]
|
||||||
|
|
||||||
remove_tags = [
|
#remove_tags = [
|
||||||
{'class':['toolBar','mac_tags','toolBar btmTools','textAds']},
|
#{'class':['toolBar','mac_tags','toolBar btmTools','textAds']},
|
||||||
dict(name='p', attrs={'class':'breadcrumbs'}),
|
#dict(name='p', attrs={'class':'breadcrumbs'}),
|
||||||
dict(id=['breadcrumb','sidebar','comments','topContentWrapper',
|
#dict(id=['breadcrumb','sidebar','comments','topContentWrapper',
|
||||||
'rightColumn', 'aboveFootPromo', 'storyCarousel']),
|
#'rightColumn', 'aboveFootPromo', 'storyCarousel']),
|
||||||
{'class':lambda x: x and ('tools' in x or 'toolBar'
|
#{'class':lambda x: x and ('tools' in x or 'toolBar'
|
||||||
in x)}
|
#in x)}
|
||||||
|
|
||||||
]
|
#]
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
(u'MacWorld Headlines', u'http://rss.macworld.com/macworld/news'),
|
(u'MacWorld Headlines', u'http://rss.macworld.com/macworld/news'),
|
||||||
@ -82,3 +83,4 @@ class macWorld(BasicNewsRecipe):
|
|||||||
.articleInfo {color:#4D4D4D;font-family:Arial,Helvetica,sans-serif;font-size:10px; font-size-adjust:none; font-stretch:normal; font-style:bold; font-variant:normal; font-weight:bold; line-height:10px; text-decoration:none;}
|
.articleInfo {color:#4D4D4D;font-family:Arial,Helvetica,sans-serif;font-size:10px; font-size-adjust:none; font-stretch:normal; font-style:bold; font-variant:normal; font-weight:bold; line-height:10px; text-decoration:none;}
|
||||||
img {align:left;}
|
img {align:left;}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
from calibre.ptempfile import PersistentTemporaryFile
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class AdvancedUserRecipe1276930924(BasicNewsRecipe):
|
class AdvancedUserRecipe1276930924(BasicNewsRecipe):
|
||||||
@ -14,30 +13,30 @@ class AdvancedUserRecipe1276930924(BasicNewsRecipe):
|
|||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
language = 'en'
|
language = 'en'
|
||||||
temp_files = []
|
auto_cleanup = True
|
||||||
articles_are_obfuscated = True
|
feeds = [#(u'News', u'http://www.maximumpc.com/articles/all/feed'),
|
||||||
feeds = [(u'News', u'http://www.maximumpc.com/articles/4/feed'),
|
(u'News', u'http://www.maximumpc.com/articles/4/feed'),
|
||||||
(u'Reviews', u'http://www.maximumpc.com/articles/40/feed'),
|
(u'Reviews', u'http://www.maximumpc.com/articles/40/feed'),
|
||||||
(u'Editors Blog', u'http://www.maximumpc.com/articles/6/feed'),
|
(u'Editors Blog', u'http://www.maximumpc.com/articles/6/feed'),
|
||||||
(u'How-to', u'http://www.maximumpc.com/articles/32/feed'),
|
(u'How-to', u'http://www.maximumpc.com/articles/32/feed'),
|
||||||
(u'Features', u'http://www.maximumpc.com/articles/31/feed'),
|
(u'Features', u'http://www.maximumpc.com/articles/31/feed'),
|
||||||
(u'From the Magazine', u'http://www.maximumpc.com/articles/72/feed')
|
(u'From the Magazine', u'http://www.maximumpc.com/articles/72/feed')
|
||||||
]
|
]
|
||||||
keep_only_tags = [
|
#keep_only_tags = [
|
||||||
dict(name='div', attrs={'class':['print-title','article_body']}),
|
#dict(name='div', attrs={'class':['print-title','article_body']}),
|
||||||
]
|
#]
|
||||||
remove_tags = [
|
#remove_tags = [
|
||||||
dict(name='div', attrs={'class':'comments-tags-actions'}),
|
#dict(name='div', attrs={'class':'comments-tags-actions'}),
|
||||||
]
|
#]
|
||||||
remove_tags_before = dict(name='div', attrs={'class':'print-title'})
|
#remove_tags_before = dict(name='div', attrs={'class':'print-title'})
|
||||||
remove_tags_after = dict(name='div', attrs={'class':'meta-content'})
|
#remove_tags_after = dict(name='div', attrs={'class':'meta-content'})
|
||||||
|
|
||||||
def get_obfuscated_article(self, url):
|
#def get_obfuscated_article(self, url):
|
||||||
br = self.get_browser()
|
#br = self.get_browser()
|
||||||
br.open(url)
|
#br.open(url)
|
||||||
response = br.follow_link(url_regex = r'/print/[0-9]+', nr = 0)
|
#response = br.follow_link(url_regex = r'/print/[0-9]+', nr = 0)
|
||||||
html = response.read()
|
#html = response.read()
|
||||||
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
#self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
||||||
self.temp_files[-1].write(html)
|
#self.temp_files[-1].write(html)
|
||||||
self.temp_files[-1].close()
|
#self.temp_files[-1].close()
|
||||||
return self.temp_files[-1].name
|
#return self.temp_files[-1].name
|
||||||
|
@ -1,99 +1,66 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2012, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
monitorcg.com
|
www.monitor.co.me
|
||||||
'''
|
'''
|
||||||
|
|
||||||
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 MonitorCG(BasicNewsRecipe):
|
class MonitorCG(BasicNewsRecipe):
|
||||||
title = 'Monitor online'
|
title = 'MONITOR online'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
description = 'News from Montenegro'
|
description = 'Nezavisni nedjeljnik Monitor'
|
||||||
publisher = 'MONITOR d.o.o. Podgorica'
|
publisher = '"Monitor" D.O.O. Podgorica'
|
||||||
category = 'news, politics, Montenegro'
|
category = 'news, politics, Montenegro'
|
||||||
oldest_article = 15
|
oldest_article = 15
|
||||||
max_articles_per_feed = 150
|
max_articles_per_feed = 150
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
|
auto_cleanup = False
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
language = 'sr'
|
language = 'sr'
|
||||||
|
remove_empty_feeds = True
|
||||||
lang ='sr-Latn-Me'
|
extra_css = """
|
||||||
INDEX = 'http://www.monitorcg.com'
|
@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)}
|
||||||
extra_css = ' @font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} body{font-family: serif1, serif} '
|
h2{font-family: Cambria,"Times New Roman",Times,serif1,serif}
|
||||||
|
body{font-family: Arial,sans1,sans-serif}
|
||||||
|
img{display: block}
|
||||||
|
"""
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
, 'tags' : category
|
, 'tags' : category
|
||||||
, 'publisher' : publisher
|
, 'publisher' : publisher
|
||||||
, 'language' : lang
|
, 'language' : language
|
||||||
, 'pretty_print' : True
|
, '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(attrs={'class':['contentheading','article-meta','article-content']})]
|
||||||
|
remove_attributes = ['width','height','font','border','align']
|
||||||
|
|
||||||
keep_only_tags = [dict(name='div', attrs={'id':'ja-current-content'})]
|
feeds = [
|
||||||
|
(u'Danas, Sjutra' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=5&Itemid=27&format=feed&type=rss')
|
||||||
remove_tags = [ dict(name=['object','link','embed'])
|
,(u'Duhankesa' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=13&Itemid=37&format=feed&type=rss')
|
||||||
, dict(attrs={'class':['buttonheading','article-section']})]
|
,(u'Znaci prepoznavanja', u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=6&Itemid=358&format=feed&type=rss')
|
||||||
|
,(u'Paralele' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=8&Itemid=359&format=feed&type=rss')
|
||||||
remove_attributes = ['style','width','height','font','border','align']
|
,(u'Razbijeno ogledalo' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=18&Itemid=354&format=feed&type=rss')
|
||||||
|
,(u'Tržište' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=26&Itemid=371&format=feed&type=rss')
|
||||||
def adeify_images2(cls, soup):
|
,(u'Feljton' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=29&Itemid=471&format=feed&type=rss')
|
||||||
for item in soup.findAll('img'):
|
,(u'Monitor' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=1&Itemid=1852&format=feed&type=rss')
|
||||||
for attrib in ['height','width','border','align','style']:
|
,(u'Altervizija' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=31&Itemid=2623&format=feed&type=rss')
|
||||||
if item.has_key(attrib):
|
,(u'Fenomeni' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=35&Itemid=3549&format=feed&type=rss')
|
||||||
del item[attrib]
|
,(u'Fokus' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=19&Itemid=252&format=feed&type=rss')
|
||||||
oldParent = item.parent
|
,(u'Monitoring' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=19&Itemid=252&format=feed&type=rss')
|
||||||
if oldParent.name == 'a':
|
,(u'Profil' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=21&Itemid=256&format=feed&type=rss')
|
||||||
oldParent.name == 'p'
|
,(u'Intervju' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=27&Itemid=404&format=feed&type=rss')
|
||||||
myIndex = oldParent.contents.index(item)
|
,(u'Društvo' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=14&Itemid=2&format=feed&type=rss')
|
||||||
brtag = Tag(soup,'br')
|
,(u'Region' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=12&Itemid=53&format=feed&type=rss')
|
||||||
oldParent.insert(myIndex+1,brtag)
|
,(u'Svijet' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=11&Itemid=360&format=feed&type=rss')
|
||||||
return soup
|
,(u'Kultura' , u'http://www.monitor.co.me/index.php?option=com_content&view=section&layout=blog&id=9&Itemid=361&format=feed&type=rss')
|
||||||
|
]
|
||||||
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.html.insert(0,mlang)
|
|
||||||
return self.adeify_images2(soup)
|
|
||||||
|
|
||||||
def parse_index(self):
|
|
||||||
totalfeeds = []
|
|
||||||
soup = self.index_to_soup(self.INDEX)
|
|
||||||
cover_item = soup.find('div',attrs={'class':'ja-catslwi'})
|
|
||||||
if cover_item:
|
|
||||||
dt = cover_item['onclick'].partition("location.href=")[2]
|
|
||||||
curl = self.INDEX + dt.strip("'")
|
|
||||||
lfeeds = [(u'Svi clanci', curl)]
|
|
||||||
for feedobj in lfeeds:
|
|
||||||
feedtitle, feedurl = feedobj
|
|
||||||
self.report_progress(0, _('Fetching feed')+' %s...'%(feedtitle if feedtitle else feedurl))
|
|
||||||
articles = []
|
|
||||||
soup = self.index_to_soup(feedurl)
|
|
||||||
contitem = soup.find('div',attrs={'class':'article-content'})
|
|
||||||
if contitem:
|
|
||||||
img = contitem.find('img')
|
|
||||||
if img:
|
|
||||||
self.cover_url = self.INDEX + img['src']
|
|
||||||
for item in contitem.findAll('a'):
|
|
||||||
url = self.INDEX + item['href']
|
|
||||||
title = self.tag_to_string(item)
|
|
||||||
articles.append({
|
|
||||||
'title' :title
|
|
||||||
,'date' :''
|
|
||||||
,'url' :url
|
|
||||||
,'description':''
|
|
||||||
})
|
|
||||||
totalfeeds.append((feedtitle, articles))
|
|
||||||
return totalfeeds
|
|
||||||
|
|
||||||
|
|
||||||
|
21
recipes/pubblico_giornale.recipe
Normal file
21
recipes/pubblico_giornale.recipe
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__author__ = 'iusvar'
|
||||||
|
__description__ = 'Pubblico giornale'
|
||||||
|
|
||||||
|
'''
|
||||||
|
http://pubblicogiornale.it/
|
||||||
|
'''
|
||||||
|
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class Pubblicogiornale(BasicNewsRecipe):
|
||||||
|
description = 'Italian newspaper directed by Luca Telese'
|
||||||
|
cover_url = 'http://pubblicogiornale.it/wp-content/uploads/logo_n.png?84cd58'
|
||||||
|
title = u'Pubblico giornale'
|
||||||
|
publisher = 'PUBBLICO EDIZIONI Srl'
|
||||||
|
category = 'News'
|
||||||
|
language = 'it'
|
||||||
|
__author__ = 'iusvar'
|
||||||
|
|
||||||
|
feeds = [(u'Pubblico giornale', u'http://pubblicogiornale.it/feed/')]
|
Binary file not shown.
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 5.7 KiB |
@ -6,7 +6,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import sys, os, shutil, glob, py_compile, subprocess, re, zipfile, time
|
import sys, os, shutil, glob, py_compile, subprocess, re, zipfile, time, textwrap
|
||||||
|
|
||||||
from setup import (Command, modules, functions, basenames, __version__,
|
from setup import (Command, modules, functions, basenames, __version__,
|
||||||
__appname__)
|
__appname__)
|
||||||
@ -407,7 +407,7 @@ class Win32Freeze(Command, WixMixIn):
|
|||||||
cmd = [msvc.linker] + ['/INCREMENTAL:NO', '/MACHINE:X86',
|
cmd = [msvc.linker] + ['/INCREMENTAL:NO', '/MACHINE:X86',
|
||||||
'/LIBPATH:'+self.obj_dir, '/SUBSYSTEM:WINDOWS',
|
'/LIBPATH:'+self.obj_dir, '/SUBSYSTEM:WINDOWS',
|
||||||
'/LIBPATH:'+(LZMA+r'\lib\Release'),
|
'/LIBPATH:'+(LZMA+r'\lib\Release'),
|
||||||
'/RELEASE',
|
'/RELEASE', '/MANIFEST', '/MANIFESTUAC:level="asInvoker" uiAccess="false"',
|
||||||
'/ENTRY:wWinMainCRTStartup',
|
'/ENTRY:wWinMainCRTStartup',
|
||||||
'/OUT:'+exe, self.embed_resources(exe,
|
'/OUT:'+exe, self.embed_resources(exe,
|
||||||
desc='Calibre Portable Installer', extra_data=zf,
|
desc='Calibre Portable Installer', extra_data=zf,
|
||||||
@ -415,6 +415,31 @@ class Win32Freeze(Command, WixMixIn):
|
|||||||
xobj, obj, 'User32.lib', 'Shell32.lib', 'easylzma_s.lib',
|
xobj, obj, 'User32.lib', 'Shell32.lib', 'easylzma_s.lib',
|
||||||
'Ole32.lib', 'Shlwapi.lib', 'Kernel32.lib', 'Psapi.lib']
|
'Ole32.lib', 'Shlwapi.lib', 'Kernel32.lib', 'Psapi.lib']
|
||||||
self.run_builder(cmd)
|
self.run_builder(cmd)
|
||||||
|
manifest = exe + '.manifest'
|
||||||
|
with open(manifest, 'r+b') as f:
|
||||||
|
raw = f.read()
|
||||||
|
f.seek(0)
|
||||||
|
f.truncate()
|
||||||
|
# TODO: Add the windows 8 GUID to the compatibility section
|
||||||
|
# after windows 8 is released, see:
|
||||||
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/hh848036(v=vs.85).aspx
|
||||||
|
raw = raw.replace(b'</assembly>', textwrap.dedent(
|
||||||
|
b'''\
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<!--The ID below indicates app support for Windows Vista -->
|
||||||
|
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||||
|
<!--The ID below indicates app support for Windows 7 -->
|
||||||
|
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
</assembly>
|
||||||
|
'''))
|
||||||
|
f.write(raw)
|
||||||
|
|
||||||
|
self.run_builder([MT, '-manifest', manifest,
|
||||||
|
'-outputresource:%s;1'%exe])
|
||||||
|
os.remove(manifest)
|
||||||
|
|
||||||
os.remove(zf)
|
os.remove(zf)
|
||||||
|
|
||||||
|
@ -9,33 +9,33 @@ msgstr ""
|
|||||||
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
||||||
"devel@lists.alioth.debian.org>\n"
|
"devel@lists.alioth.debian.org>\n"
|
||||||
"POT-Creation-Date: 2011-11-25 14:01+0000\n"
|
"POT-Creation-Date: 2011-11-25 14:01+0000\n"
|
||||||
"PO-Revision-Date: 2011-11-12 07:52+0000\n"
|
"PO-Revision-Date: 2012-09-25 20:15+0000\n"
|
||||||
"Last-Translator: Devilinside <Unknown>\n"
|
"Last-Translator: Gergely Szarka <szarka.honved@gmail.com>\n"
|
||||||
"Language-Team: Hungarian <debian-l10n-hungarian@lists.d.o>\n"
|
"Language-Team: Hungarian <debian-l10n-hungarian@lists.d.o>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Launchpad-Export-Date: 2011-11-26 05:19+0000\n"
|
"X-Launchpad-Export-Date: 2012-09-26 04:36+0000\n"
|
||||||
"X-Generator: Launchpad (build 14381)\n"
|
"X-Generator: Launchpad (build 16022)\n"
|
||||||
"X-Poedit-Country: HUNGARY\n"
|
"X-Poedit-Country: HUNGARY\n"
|
||||||
"Language: hu\n"
|
"Language: hu\n"
|
||||||
"X-Poedit-Language: Hungarian\n"
|
"X-Poedit-Language: Hungarian\n"
|
||||||
|
|
||||||
#. name for aaa
|
#. name for aaa
|
||||||
msgid "Ghotuo"
|
msgid "Ghotuo"
|
||||||
msgstr "ghotuo"
|
msgstr "Ghotuo"
|
||||||
|
|
||||||
#. name for aab
|
#. name for aab
|
||||||
msgid "Alumu-Tesu"
|
msgid "Alumu-Tesu"
|
||||||
msgstr "alumu-tesu"
|
msgstr "Alumu-Tesu"
|
||||||
|
|
||||||
#. name for aac
|
#. name for aac
|
||||||
msgid "Ari"
|
msgid "Ari"
|
||||||
msgstr "ari"
|
msgstr "Ari"
|
||||||
|
|
||||||
#. name for aad
|
#. name for aad
|
||||||
msgid "Amal"
|
msgid "Amal"
|
||||||
msgstr "amal"
|
msgstr "Amal"
|
||||||
|
|
||||||
#. name for aae
|
#. name for aae
|
||||||
msgid "Albanian; Arbëreshë"
|
msgid "Albanian; Arbëreshë"
|
||||||
@ -43,11 +43,11 @@ msgstr "albán; Arbëreshë"
|
|||||||
|
|
||||||
#. name for aaf
|
#. name for aaf
|
||||||
msgid "Aranadan"
|
msgid "Aranadan"
|
||||||
msgstr "aranadan"
|
msgstr "Aranadan"
|
||||||
|
|
||||||
#. name for aag
|
#. name for aag
|
||||||
msgid "Ambrak"
|
msgid "Ambrak"
|
||||||
msgstr "ambrak"
|
msgstr "Ambrak"
|
||||||
|
|
||||||
#. name for aah
|
#. name for aah
|
||||||
msgid "Arapesh; Abu'"
|
msgid "Arapesh; Abu'"
|
||||||
@ -55,11 +55,11 @@ msgstr "arapesh; Abu'"
|
|||||||
|
|
||||||
#. name for aai
|
#. name for aai
|
||||||
msgid "Arifama-Miniafia"
|
msgid "Arifama-Miniafia"
|
||||||
msgstr "arifama-miniafia"
|
msgstr "Arifama-Miniafia"
|
||||||
|
|
||||||
#. name for aak
|
#. name for aak
|
||||||
msgid "Ankave"
|
msgid "Ankave"
|
||||||
msgstr "ankave"
|
msgstr "Ankave"
|
||||||
|
|
||||||
#. name for aal
|
#. name for aal
|
||||||
msgid "Afade"
|
msgid "Afade"
|
||||||
@ -107,11 +107,11 @@ msgstr "szolong"
|
|||||||
|
|
||||||
#. name for aax
|
#. name for aax
|
||||||
msgid "Mandobo Atas"
|
msgid "Mandobo Atas"
|
||||||
msgstr ""
|
msgstr "Mandobo Atas"
|
||||||
|
|
||||||
#. name for aaz
|
#. name for aaz
|
||||||
msgid "Amarasi"
|
msgid "Amarasi"
|
||||||
msgstr ""
|
msgstr "Amarasi"
|
||||||
|
|
||||||
#. name for aba
|
#. name for aba
|
||||||
msgid "Abé"
|
msgid "Abé"
|
||||||
@ -119,7 +119,7 @@ msgstr "abé"
|
|||||||
|
|
||||||
#. name for abb
|
#. name for abb
|
||||||
msgid "Bankon"
|
msgid "Bankon"
|
||||||
msgstr ""
|
msgstr "Bankon"
|
||||||
|
|
||||||
#. name for abc
|
#. name for abc
|
||||||
msgid "Ayta; Ambala"
|
msgid "Ayta; Ambala"
|
||||||
@ -127,7 +127,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for abd
|
#. name for abd
|
||||||
msgid "Manide"
|
msgid "Manide"
|
||||||
msgstr ""
|
msgstr "Manide"
|
||||||
|
|
||||||
#. name for abe
|
#. name for abe
|
||||||
msgid "Abnaki; Western"
|
msgid "Abnaki; Western"
|
||||||
@ -135,11 +135,11 @@ msgstr "abnaki; nyugati"
|
|||||||
|
|
||||||
#. name for abf
|
#. name for abf
|
||||||
msgid "Abai Sungai"
|
msgid "Abai Sungai"
|
||||||
msgstr ""
|
msgstr "Abai Sungai"
|
||||||
|
|
||||||
#. name for abg
|
#. name for abg
|
||||||
msgid "Abaga"
|
msgid "Abaga"
|
||||||
msgstr ""
|
msgstr "Abaga"
|
||||||
|
|
||||||
#. name for abh
|
#. name for abh
|
||||||
msgid "Arabic; Tajiki"
|
msgid "Arabic; Tajiki"
|
||||||
@ -147,7 +147,7 @@ msgstr "arab; tadzsik"
|
|||||||
|
|
||||||
#. name for abi
|
#. name for abi
|
||||||
msgid "Abidji"
|
msgid "Abidji"
|
||||||
msgstr ""
|
msgstr "Abidji"
|
||||||
|
|
||||||
#. name for abj
|
#. name for abj
|
||||||
msgid "Aka-Bea"
|
msgid "Aka-Bea"
|
||||||
@ -159,19 +159,19 @@ msgstr "abház"
|
|||||||
|
|
||||||
#. name for abl
|
#. name for abl
|
||||||
msgid "Lampung Nyo"
|
msgid "Lampung Nyo"
|
||||||
msgstr ""
|
msgstr "Lampung Nyo"
|
||||||
|
|
||||||
#. name for abm
|
#. name for abm
|
||||||
msgid "Abanyom"
|
msgid "Abanyom"
|
||||||
msgstr ""
|
msgstr "Abanyom"
|
||||||
|
|
||||||
#. name for abn
|
#. name for abn
|
||||||
msgid "Abua"
|
msgid "Abua"
|
||||||
msgstr ""
|
msgstr "Abua"
|
||||||
|
|
||||||
#. name for abo
|
#. name for abo
|
||||||
msgid "Abon"
|
msgid "Abon"
|
||||||
msgstr ""
|
msgstr "Abon"
|
||||||
|
|
||||||
#. name for abp
|
#. name for abp
|
||||||
msgid "Ayta; Abellen"
|
msgid "Ayta; Abellen"
|
||||||
@ -179,11 +179,11 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for abq
|
#. name for abq
|
||||||
msgid "Abaza"
|
msgid "Abaza"
|
||||||
msgstr ""
|
msgstr "Abaza"
|
||||||
|
|
||||||
#. name for abr
|
#. name for abr
|
||||||
msgid "Abron"
|
msgid "Abron"
|
||||||
msgstr ""
|
msgstr "Abron"
|
||||||
|
|
||||||
#. name for abs
|
#. name for abs
|
||||||
msgid "Malay; Ambonese"
|
msgid "Malay; Ambonese"
|
||||||
@ -191,11 +191,11 @@ msgstr "maláj; amboni"
|
|||||||
|
|
||||||
#. name for abt
|
#. name for abt
|
||||||
msgid "Ambulas"
|
msgid "Ambulas"
|
||||||
msgstr ""
|
msgstr "Ambulas"
|
||||||
|
|
||||||
#. name for abu
|
#. name for abu
|
||||||
msgid "Abure"
|
msgid "Abure"
|
||||||
msgstr ""
|
msgstr "Abure"
|
||||||
|
|
||||||
#. name for abv
|
#. name for abv
|
||||||
msgid "Arabic; Baharna"
|
msgid "Arabic; Baharna"
|
||||||
@ -203,31 +203,31 @@ msgstr "arab; Baharna"
|
|||||||
|
|
||||||
#. name for abw
|
#. name for abw
|
||||||
msgid "Pal"
|
msgid "Pal"
|
||||||
msgstr ""
|
msgstr "Pal"
|
||||||
|
|
||||||
#. name for abx
|
#. name for abx
|
||||||
msgid "Inabaknon"
|
msgid "Inabaknon"
|
||||||
msgstr ""
|
msgstr "Inabaknon"
|
||||||
|
|
||||||
#. name for aby
|
#. name for aby
|
||||||
msgid "Aneme Wake"
|
msgid "Aneme Wake"
|
||||||
msgstr ""
|
msgstr "Aneme Wake"
|
||||||
|
|
||||||
#. name for abz
|
#. name for abz
|
||||||
msgid "Abui"
|
msgid "Abui"
|
||||||
msgstr ""
|
msgstr "Abui"
|
||||||
|
|
||||||
#. name for aca
|
#. name for aca
|
||||||
msgid "Achagua"
|
msgid "Achagua"
|
||||||
msgstr ""
|
msgstr "Achagua"
|
||||||
|
|
||||||
#. name for acb
|
#. name for acb
|
||||||
msgid "Áncá"
|
msgid "Áncá"
|
||||||
msgstr ""
|
msgstr "Áncá"
|
||||||
|
|
||||||
#. name for acd
|
#. name for acd
|
||||||
msgid "Gikyode"
|
msgid "Gikyode"
|
||||||
msgstr ""
|
msgstr "Gikyode"
|
||||||
|
|
||||||
# src/trans.h:220
|
# src/trans.h:220
|
||||||
#. name for ace
|
#. name for ace
|
||||||
@ -244,15 +244,15 @@ msgstr "acoli"
|
|||||||
|
|
||||||
#. name for aci
|
#. name for aci
|
||||||
msgid "Aka-Cari"
|
msgid "Aka-Cari"
|
||||||
msgstr ""
|
msgstr "Aka-Cari"
|
||||||
|
|
||||||
#. name for ack
|
#. name for ack
|
||||||
msgid "Aka-Kora"
|
msgid "Aka-Kora"
|
||||||
msgstr ""
|
msgstr "Aka-Kora"
|
||||||
|
|
||||||
#. name for acl
|
#. name for acl
|
||||||
msgid "Akar-Bale"
|
msgid "Akar-Bale"
|
||||||
msgstr ""
|
msgstr "Akar-Bale"
|
||||||
|
|
||||||
#. name for acm
|
#. name for acm
|
||||||
msgid "Arabic; Mesopotamian"
|
msgid "Arabic; Mesopotamian"
|
||||||
@ -264,7 +264,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for acp
|
#. name for acp
|
||||||
msgid "Acipa; Eastern"
|
msgid "Acipa; Eastern"
|
||||||
msgstr ""
|
msgstr "Acipa; Keleti"
|
||||||
|
|
||||||
#. name for acq
|
#. name for acq
|
||||||
msgid "Arabic; Ta'izzi-Adeni"
|
msgid "Arabic; Ta'izzi-Adeni"
|
||||||
@ -272,7 +272,7 @@ msgstr "arabic; ta'izzi-adeni"
|
|||||||
|
|
||||||
#. name for acr
|
#. name for acr
|
||||||
msgid "Achi"
|
msgid "Achi"
|
||||||
msgstr ""
|
msgstr "Achi"
|
||||||
|
|
||||||
#. name for acs
|
#. name for acs
|
||||||
msgid "Acroá"
|
msgid "Acroá"
|
||||||
|
@ -4,7 +4,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
__appname__ = u'calibre'
|
__appname__ = u'calibre'
|
||||||
numeric_version = (0, 8, 70)
|
numeric_version = (0, 9, 0)
|
||||||
__version__ = u'.'.join(map(unicode, numeric_version))
|
__version__ = u'.'.join(map(unicode, numeric_version))
|
||||||
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
|
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ class ANDROID(USBMS):
|
|||||||
'THINKPAD_TABLET', 'SGH-T989', 'YP-G70', 'STORAGE_DEVICE',
|
'THINKPAD_TABLET', 'SGH-T989', 'YP-G70', 'STORAGE_DEVICE',
|
||||||
'ADVANCED', 'SGH-I727', 'USB_FLASH_DRIVER', 'ANDROID',
|
'ADVANCED', 'SGH-I727', 'USB_FLASH_DRIVER', 'ANDROID',
|
||||||
'S5830I_CARD', 'MID7042', 'LINK-CREATE', '7035', 'VIEWPAD_7E',
|
'S5830I_CARD', 'MID7042', 'LINK-CREATE', '7035', 'VIEWPAD_7E',
|
||||||
'NOVO7']
|
'NOVO7', 'MB526']
|
||||||
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
||||||
'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
||||||
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',
|
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',
|
||||||
|
@ -288,7 +288,7 @@ class KINDLE2(KINDLE):
|
|||||||
name = 'Kindle 2/3/4/Touch Device Interface'
|
name = 'Kindle 2/3/4/Touch Device Interface'
|
||||||
description = _('Communicate with the Kindle 2/3/4/Touch eBook reader.')
|
description = _('Communicate with the Kindle 2/3/4/Touch eBook reader.')
|
||||||
|
|
||||||
FORMATS = ['azw3'] + KINDLE.FORMATS + ['pdf', 'azw4', 'pobi']
|
FORMATS = ['azw', 'mobi', 'azw3', 'prc', 'azw1', 'tpz', 'azw4', 'pobi', 'pdf', 'txt']
|
||||||
DELETE_EXTS = KINDLE.DELETE_EXTS + ['.mbp1', '.mbs', '.sdr', '.han']
|
DELETE_EXTS = KINDLE.DELETE_EXTS + ['.mbp1', '.mbs', '.sdr', '.han']
|
||||||
# On the Touch, there's also .asc files, but not using the same basename (for X-Ray & End Actions), azw3f & azw3r files, but all of them are in the .sdr sidecar folder
|
# On the Touch, there's also .asc files, but not using the same basename (for X-Ray & End Actions), azw3f & azw3r files, but all of them are in the .sdr sidecar folder
|
||||||
|
|
||||||
@ -450,7 +450,7 @@ class KINDLE_DX(KINDLE2):
|
|||||||
name = 'Kindle DX Device Interface'
|
name = 'Kindle DX Device Interface'
|
||||||
description = _('Communicate with the Kindle DX eBook reader.')
|
description = _('Communicate with the Kindle DX eBook reader.')
|
||||||
|
|
||||||
FORMATS = KINDLE2.FORMATS[1:]
|
FORMATS = ['azw', 'mobi', 'prc', 'azw1', 'tpz', 'azw4', 'pobi', 'pdf', 'txt']
|
||||||
PRODUCT_ID = [0x0003]
|
PRODUCT_ID = [0x0003]
|
||||||
BCD = [0x0100]
|
BCD = [0x0100]
|
||||||
|
|
||||||
@ -462,7 +462,7 @@ class KINDLE_FIRE(KINDLE2):
|
|||||||
name = 'Kindle Fire Device Interface'
|
name = 'Kindle Fire Device Interface'
|
||||||
description = _('Communicate with the Kindle Fire')
|
description = _('Communicate with the Kindle Fire')
|
||||||
gui_name = 'Fire'
|
gui_name = 'Fire'
|
||||||
FORMATS = list(KINDLE2.FORMATS)
|
FORMATS = ['azw3', 'azw', 'mobi', 'prc', 'azw1', 'tpz', 'azw4', 'pobi', 'pdf', 'txt']
|
||||||
|
|
||||||
PRODUCT_ID = [0x0006]
|
PRODUCT_ID = [0x0006]
|
||||||
BCD = [0x216, 0x100]
|
BCD = [0x216, 0x100]
|
||||||
|
@ -151,9 +151,9 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
else:
|
else:
|
||||||
self.known_devices = frozenset(self.libmtp.known_devices())
|
self.known_devices = frozenset(self.libmtp.known_devices())
|
||||||
|
|
||||||
for x in vars(self.libmtp):
|
for x in vars(self.libmtp):
|
||||||
if x.startswith('LIBMTP'):
|
if x.startswith('LIBMTP'):
|
||||||
setattr(self, x, getattr(self.libmtp, x))
|
setattr(self, x, getattr(self.libmtp, x))
|
||||||
|
|
||||||
@synchronous
|
@synchronous
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
@ -169,6 +169,7 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
try:
|
try:
|
||||||
self.dev = self.create_device(connected_device)
|
self.dev = self.create_device(connected_device)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
self.blacklisted_devices.add(connected_device)
|
||||||
raise OpenFailed('Failed to open %s: Error: %s'%(
|
raise OpenFailed('Failed to open %s: Error: %s'%(
|
||||||
connected_device, as_unicode(e)))
|
connected_device, as_unicode(e)))
|
||||||
|
|
||||||
@ -195,6 +196,19 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
self.current_serial_num = snum
|
self.current_serial_num = snum
|
||||||
self.currently_connected_dev = connected_device
|
self.currently_connected_dev = connected_device
|
||||||
|
|
||||||
|
@synchronous
|
||||||
|
def device_debug_info(self):
|
||||||
|
ans = self.get_gui_name()
|
||||||
|
ans += '\nSerial number: %s'%self.current_serial_num
|
||||||
|
ans += '\nManufacturer: %s'%self.dev.manufacturer_name
|
||||||
|
ans += '\nModel: %s'%self.dev.model_name
|
||||||
|
ans += '\nids: %s'%(self.dev.ids,)
|
||||||
|
ans += '\nDevice version: %s'%self.dev.device_version
|
||||||
|
ans += '\nStorage:\n'
|
||||||
|
storage = sorted(self.dev.storage_info, key=operator.itemgetter('id'))
|
||||||
|
ans += pprint.pformat(storage)
|
||||||
|
return ans
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def filesystem_cache(self):
|
def filesystem_cache(self):
|
||||||
if self._filesystem_cache is None:
|
if self._filesystem_cache is None:
|
||||||
|
@ -84,8 +84,8 @@ PyObject* get_storage_info(IPortableDevice *device) { // {{{
|
|||||||
PWSTR object_ids[10];
|
PWSTR object_ids[10];
|
||||||
GUID guid;
|
GUID guid;
|
||||||
ULONGLONG capacity, free_space, capacity_objects, free_objects;
|
ULONGLONG capacity, free_space, capacity_objects, free_objects;
|
||||||
ULONG access;
|
ULONG access, storage_type = WPD_STORAGE_TYPE_UNDEFINED;
|
||||||
LPWSTR storage_desc = NULL;
|
LPWSTR storage_desc = NULL, st = NULL;
|
||||||
|
|
||||||
storage = PyList_New(0);
|
storage = PyList_New(0);
|
||||||
if (storage == NULL) { PyErr_NoMemory(); goto end; }
|
if (storage == NULL) { PyErr_NoMemory(); goto end; }
|
||||||
@ -116,6 +116,7 @@ PyObject* get_storage_info(IPortableDevice *device) { // {{{
|
|||||||
hr = storage_properties->Add(WPD_STORAGE_FREE_SPACE_IN_OBJECTS);
|
hr = storage_properties->Add(WPD_STORAGE_FREE_SPACE_IN_OBJECTS);
|
||||||
hr = storage_properties->Add(WPD_STORAGE_ACCESS_CAPABILITY);
|
hr = storage_properties->Add(WPD_STORAGE_ACCESS_CAPABILITY);
|
||||||
hr = storage_properties->Add(WPD_STORAGE_FILE_SYSTEM_TYPE);
|
hr = storage_properties->Add(WPD_STORAGE_FILE_SYSTEM_TYPE);
|
||||||
|
hr = storage_properties->Add(WPD_STORAGE_TYPE);
|
||||||
hr = storage_properties->Add(WPD_OBJECT_NAME);
|
hr = storage_properties->Add(WPD_OBJECT_NAME);
|
||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
if (FAILED(hr)) {hresult_set_exc("Failed to create collection of properties for storage query", hr); goto end; }
|
if (FAILED(hr)) {hresult_set_exc("Failed to create collection of properties for storage query", hr); goto end; }
|
||||||
@ -145,6 +146,7 @@ PyObject* get_storage_info(IPortableDevice *device) { // {{{
|
|||||||
values->GetUnsignedLargeIntegerValue(WPD_STORAGE_CAPACITY_IN_OBJECTS, &capacity_objects);
|
values->GetUnsignedLargeIntegerValue(WPD_STORAGE_CAPACITY_IN_OBJECTS, &capacity_objects);
|
||||||
values->GetUnsignedLargeIntegerValue(WPD_STORAGE_FREE_SPACE_IN_BYTES, &free_space);
|
values->GetUnsignedLargeIntegerValue(WPD_STORAGE_FREE_SPACE_IN_BYTES, &free_space);
|
||||||
values->GetUnsignedLargeIntegerValue(WPD_STORAGE_FREE_SPACE_IN_OBJECTS, &free_objects);
|
values->GetUnsignedLargeIntegerValue(WPD_STORAGE_FREE_SPACE_IN_OBJECTS, &free_objects);
|
||||||
|
values->GetUnsignedIntegerValue(WPD_STORAGE_TYPE, &storage_type);
|
||||||
desc = Py_False;
|
desc = Py_False;
|
||||||
if (SUCCEEDED(values->GetUnsignedIntegerValue(WPD_STORAGE_ACCESS_CAPABILITY, &access)) && access == WPD_STORAGE_ACCESS_CAPABILITY_READWRITE) desc = Py_True;
|
if (SUCCEEDED(values->GetUnsignedIntegerValue(WPD_STORAGE_ACCESS_CAPABILITY, &access)) && access == WPD_STORAGE_ACCESS_CAPABILITY_READWRITE) desc = Py_True;
|
||||||
soid = PyUnicode_FromWideChar(object_ids[i], wcslen(object_ids[i]));
|
soid = PyUnicode_FromWideChar(object_ids[i], wcslen(object_ids[i]));
|
||||||
@ -167,6 +169,25 @@ PyObject* get_storage_info(IPortableDevice *device) { // {{{
|
|||||||
if (desc != NULL) { PyDict_SetItemString(so, "filesystem", desc); Py_DECREF(desc);}
|
if (desc != NULL) { PyDict_SetItemString(so, "filesystem", desc); Py_DECREF(desc);}
|
||||||
CoTaskMemFree(storage_desc); storage_desc = NULL;
|
CoTaskMemFree(storage_desc); storage_desc = NULL;
|
||||||
}
|
}
|
||||||
|
switch(storage_type) {
|
||||||
|
case WPD_STORAGE_TYPE_REMOVABLE_RAM:
|
||||||
|
st = L"removable_ram";
|
||||||
|
break;
|
||||||
|
case WPD_STORAGE_TYPE_REMOVABLE_ROM:
|
||||||
|
st = L"removable_rom";
|
||||||
|
break;
|
||||||
|
case WPD_STORAGE_TYPE_FIXED_RAM:
|
||||||
|
st = L"fixed_ram";
|
||||||
|
break;
|
||||||
|
case WPD_STORAGE_TYPE_FIXED_ROM:
|
||||||
|
st = L"fixed_rom";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
st = L"unknown_unknown";
|
||||||
|
}
|
||||||
|
desc = PyUnicode_FromWideChar(st, wcslen(st));
|
||||||
|
if (desc != NULL) {PyDict_SetItemString(so, "type", desc); Py_DECREF(desc);}
|
||||||
|
desc = NULL;
|
||||||
PyList_Append(storage, so);
|
PyList_Append(storage, so);
|
||||||
Py_DECREF(so);
|
Py_DECREF(so);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ from future_builtins import zip
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from calibre import as_unicode, prints
|
from calibre import as_unicode, prints
|
||||||
from calibre.constants import plugins, __appname__, numeric_version
|
from calibre.constants import plugins, __appname__, numeric_version, isxp
|
||||||
from calibre.ptempfile import SpooledTemporaryFile
|
from calibre.ptempfile import SpooledTemporaryFile
|
||||||
from calibre.devices.errors import OpenFailed, DeviceError, BlacklistedDevice
|
from calibre.devices.errors import OpenFailed, DeviceError, BlacklistedDevice
|
||||||
from calibre.devices.mtp.base import MTPDeviceBase, debug
|
from calibre.devices.mtp.base import MTPDeviceBase, debug
|
||||||
@ -52,10 +52,15 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
self.start_thread = None
|
self.start_thread = None
|
||||||
self._filesystem_cache = None
|
self._filesystem_cache = None
|
||||||
self.eject_dev_on_next_scan = False
|
self.eject_dev_on_next_scan = False
|
||||||
|
self.current_device_data = {}
|
||||||
|
|
||||||
def startup(self):
|
def startup(self):
|
||||||
self.start_thread = threading.current_thread()
|
self.start_thread = threading.current_thread()
|
||||||
self.wpd, self.wpd_error = plugins['wpd']
|
if isxp:
|
||||||
|
self.wpd = None
|
||||||
|
self.wpd_error = _('MTP devices are not supported on Windows XP')
|
||||||
|
else:
|
||||||
|
self.wpd, self.wpd_error = plugins['wpd']
|
||||||
if self.wpd is not None:
|
if self.wpd is not None:
|
||||||
try:
|
try:
|
||||||
self.wpd.init(__appname__, *(numeric_version[:3]))
|
self.wpd.init(__appname__, *(numeric_version[:3]))
|
||||||
@ -196,6 +201,12 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
if not devdata.get('has_storage', False): return False
|
if not devdata.get('has_storage', False): return False
|
||||||
has_rw_storage = False
|
has_rw_storage = False
|
||||||
for s in devdata.get('storage', []):
|
for s in devdata.get('storage', []):
|
||||||
|
if s.get('filesystem', None) == 'DCF':
|
||||||
|
# DCF filesystem indicates a camera or an iPhone
|
||||||
|
# See https://bugs.launchpad.net/calibre/+bug/1054562
|
||||||
|
continue
|
||||||
|
if s.get('type', 'unknown_unknown').split('_')[-1] == 'rom':
|
||||||
|
continue # Read only storage
|
||||||
if s.get('rw', False):
|
if s.get('rw', False):
|
||||||
has_rw_storage = True
|
has_rw_storage = True
|
||||||
break
|
break
|
||||||
@ -280,6 +291,8 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
raise BlacklistedDevice(
|
raise BlacklistedDevice(
|
||||||
'The %s device has been blacklisted by the user'%(connected_device,))
|
'The %s device has been blacklisted by the user'%(connected_device,))
|
||||||
|
|
||||||
|
storage.sort(key=lambda x:x.get('id', 'zzzzz'))
|
||||||
|
|
||||||
self._main_id = storage[0]['id']
|
self._main_id = storage[0]['id']
|
||||||
if len(storage) > 1:
|
if len(storage) > 1:
|
||||||
self._carda_id = storage[1]['id']
|
self._carda_id = storage[1]['id']
|
||||||
@ -291,6 +304,11 @@ class MTP_DEVICE(MTPDeviceBase):
|
|||||||
_('Unknown MTP device'))
|
_('Unknown MTP device'))
|
||||||
self.currently_connected_pnp_id = connected_device
|
self.currently_connected_pnp_id = connected_device
|
||||||
self.current_serial_num = snum
|
self.current_serial_num = snum
|
||||||
|
self.current_device_data = devdata.copy()
|
||||||
|
|
||||||
|
def device_debug_info(self):
|
||||||
|
import pprint
|
||||||
|
return pprint.pformat(self.current_device_data)
|
||||||
|
|
||||||
@same_thread
|
@same_thread
|
||||||
def get_basic_device_information(self):
|
def get_basic_device_information(self):
|
||||||
|
@ -687,7 +687,7 @@ class PRST1(USBMS):
|
|||||||
'WHERE _id = ?')
|
'WHERE _id = ?')
|
||||||
t = (collectionId,)
|
t = (collectionId,)
|
||||||
cursor.execute(query, t)
|
cursor.execute(query, t)
|
||||||
debug_print('Deleted Collection: ' + collection)
|
debug_print('Deleted Collection: ' + repr(collection))
|
||||||
|
|
||||||
connection.commit()
|
connection.commit()
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
@ -744,22 +744,6 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
except:
|
except:
|
||||||
self._close_device_socket()
|
self._close_device_socket()
|
||||||
return (self.is_connected, self)
|
return (self.is_connected, self)
|
||||||
if getattr(self, 'broadcast_socket', None) is not None:
|
|
||||||
while True:
|
|
||||||
ans = select.select((self.broadcast_socket,), (), (), 0)
|
|
||||||
if len(ans[0]) > 0:
|
|
||||||
try:
|
|
||||||
packet = self.broadcast_socket.recvfrom(100)
|
|
||||||
remote = packet[1]
|
|
||||||
message = str(self.ZEROCONF_CLIENT_STRING + b' (on ' +
|
|
||||||
str(socket.gethostname().partition('.')[0]) +
|
|
||||||
b'),' + str(self.port))
|
|
||||||
self._debug('received broadcast', packet, message)
|
|
||||||
self.broadcast_socket.sendto(message, remote)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
if getattr(self, 'listen_socket', None) is not None:
|
if getattr(self, 'listen_socket', None) is not None:
|
||||||
try:
|
try:
|
||||||
@ -902,10 +886,16 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def get_gui_name(self):
|
def get_gui_name(self):
|
||||||
if self.client_device_kind:
|
if getattr(self, 'client_device_kind', None):
|
||||||
return self.gui_name_template%(self.gui_name, self.client_device_kind)
|
return self.gui_name_template%(self.gui_name, self.client_device_kind)
|
||||||
return self.gui_name
|
return self.gui_name
|
||||||
|
|
||||||
|
def config_widget(self):
|
||||||
|
from calibre.gui2.device_drivers.configwidget import ConfigWidget
|
||||||
|
cw = ConfigWidget(self.settings(), self.FORMATS, self.SUPPORTS_SUB_DIRS,
|
||||||
|
self.MUST_READ_METADATA, self.SUPPORTS_USE_AUTHOR_SORT,
|
||||||
|
self.EXTRA_CUSTOMIZATION_MESSAGE, self)
|
||||||
|
return cw
|
||||||
|
|
||||||
@synchronous('sync_lock')
|
@synchronous('sync_lock')
|
||||||
def get_device_information(self, end_session=True):
|
def get_device_information(self, end_session=True):
|
||||||
|
@ -14,6 +14,8 @@ import os
|
|||||||
from calibre.customize.conversion import OutputFormatPlugin, \
|
from calibre.customize.conversion import OutputFormatPlugin, \
|
||||||
OptionRecommendation
|
OptionRecommendation
|
||||||
from calibre.ptempfile import TemporaryDirectory
|
from calibre.ptempfile import TemporaryDirectory
|
||||||
|
from calibre.constants import iswindows
|
||||||
|
from calibre import walk
|
||||||
|
|
||||||
UNITS = [
|
UNITS = [
|
||||||
'millimeter',
|
'millimeter',
|
||||||
@ -148,6 +150,16 @@ class PDFOutput(OutputFormatPlugin):
|
|||||||
oeb_output = plugin_for_output_format('oeb')
|
oeb_output = plugin_for_output_format('oeb')
|
||||||
oeb_output.convert(oeb_book, oeb_dir, self.input_plugin, self.opts, self.log)
|
oeb_output.convert(oeb_book, oeb_dir, self.input_plugin, self.opts, self.log)
|
||||||
|
|
||||||
|
if iswindows:
|
||||||
|
# On windows Qt generates an image based PDF if the html uses
|
||||||
|
# embedded fonts. See https://launchpad.net/bugs/1053906
|
||||||
|
for f in walk(oeb_dir):
|
||||||
|
if f.rpartition('.')[-1].lower() in {'ttf', 'otf'}:
|
||||||
|
self.log.warn('Found embedded font %s, removing it, as '
|
||||||
|
'embedded fonts on windows are not supported by '
|
||||||
|
'the PDF Output plugin'%os.path.basename(f))
|
||||||
|
os.remove(f)
|
||||||
|
|
||||||
opfpath = glob.glob(os.path.join(oeb_dir, '*.opf'))[0]
|
opfpath = glob.glob(os.path.join(oeb_dir, '*.opf'))[0]
|
||||||
opf = OPF(opfpath, os.path.dirname(opfpath))
|
opf = OPF(opfpath, os.path.dirname(opfpath))
|
||||||
|
|
||||||
|
@ -792,19 +792,16 @@ class OPF(object): # {{{
|
|||||||
remove = list(self.authors_path(self.metadata))
|
remove = list(self.authors_path(self.metadata))
|
||||||
for elem in remove:
|
for elem in remove:
|
||||||
elem.getparent().remove(elem)
|
elem.getparent().remove(elem)
|
||||||
elems = []
|
# Ensure new author element is at the top of the list
|
||||||
for author in val:
|
# for broken implementations that always use the first
|
||||||
attrib = {'{%s}role'%self.NAMESPACES['opf']: 'aut'}
|
# <dc:creator> element with no attention to the role
|
||||||
elem = self.create_metadata_element('creator', attrib=attrib)
|
for author in reversed(val):
|
||||||
|
elem = self.metadata.makeelement('{%s}creator'%
|
||||||
|
self.NAMESPACES['dc'], nsmap=self.NAMESPACES)
|
||||||
|
elem.tail = '\n'
|
||||||
|
self.metadata.insert(0, elem)
|
||||||
|
elem.set('{%s}role'%self.NAMESPACES['opf'], 'aut')
|
||||||
self.set_text(elem, author.strip())
|
self.set_text(elem, author.strip())
|
||||||
# Ensure new author element is at the top of the list
|
|
||||||
# for broken implementations that always use the first
|
|
||||||
# <dc:creator> element with no attention to the role
|
|
||||||
elems.append(elem)
|
|
||||||
for elem in reversed(elems):
|
|
||||||
parent = elem.getparent()
|
|
||||||
parent.remove(elem)
|
|
||||||
parent.insert(0, elem)
|
|
||||||
|
|
||||||
return property(fget=fget, fset=fset)
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
@ -1020,9 +1017,8 @@ class OPF(object): # {{{
|
|||||||
def fset(self, val):
|
def fset(self, val):
|
||||||
matches = self.bkp_path(self.metadata)
|
matches = self.bkp_path(self.metadata)
|
||||||
if not matches:
|
if not matches:
|
||||||
attrib = {'{%s}role'%self.NAMESPACES['opf']: 'bkp'}
|
matches = [self.create_metadata_element('contributor')]
|
||||||
matches = [self.create_metadata_element('contributor',
|
matches[0].set('{%s}role'%self.NAMESPACES['opf'], 'bkp')
|
||||||
attrib=attrib)]
|
|
||||||
self.set_text(matches[0], unicode(val))
|
self.set_text(matches[0], unicode(val))
|
||||||
return property(fget=fget, fset=fset)
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
@ -1155,7 +1151,7 @@ class OPF(object): # {{{
|
|||||||
def smart_update(self, mi, replace_metadata=False):
|
def smart_update(self, mi, replace_metadata=False):
|
||||||
for attr in ('title', 'authors', 'author_sort', 'title_sort',
|
for attr in ('title', 'authors', 'author_sort', 'title_sort',
|
||||||
'publisher', 'series', 'series_index', 'rating',
|
'publisher', 'series', 'series_index', 'rating',
|
||||||
'isbn', 'tags', 'category', 'comments',
|
'isbn', 'tags', 'category', 'comments', 'book_producer',
|
||||||
'pubdate', 'user_categories', 'author_link_map'):
|
'pubdate', 'user_categories', 'author_link_map'):
|
||||||
val = getattr(mi, attr, None)
|
val = getattr(mi, attr, None)
|
||||||
if val is not None and val != [] and val != (None, None):
|
if val is not None and val != [] and val != (None, None):
|
||||||
|
@ -10,6 +10,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
import re
|
import re
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from xml.sax.saxutils import escape
|
||||||
|
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
@ -289,6 +290,7 @@ class Chunker(object):
|
|||||||
self.chunk_selector = ('S', aid)
|
self.chunk_selector = ('S', aid)
|
||||||
|
|
||||||
def chunk_up_text(self, text):
|
def chunk_up_text(self, text):
|
||||||
|
text = escape(text)
|
||||||
text = text.encode('utf-8')
|
text = text.encode('utf-8')
|
||||||
ans = []
|
ans = []
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ from calibre.customize.ui import is_disabled
|
|||||||
from calibre.devices.bambook.driver import BAMBOOK
|
from calibre.devices.bambook.driver import BAMBOOK
|
||||||
from calibre.gui2.dialogs.smartdevice import SmartdeviceDialog
|
from calibre.gui2.dialogs.smartdevice import SmartdeviceDialog
|
||||||
from calibre.gui2 import info_dialog, question_dialog
|
from calibre.gui2 import info_dialog, question_dialog
|
||||||
|
from calibre.library.server import server_config as content_server_config
|
||||||
|
|
||||||
class ShareConnMenu(QMenu): # {{{
|
class ShareConnMenu(QMenu): # {{{
|
||||||
|
|
||||||
@ -90,7 +91,12 @@ class ShareConnMenu(QMenu): # {{{
|
|||||||
if running:
|
if running:
|
||||||
listen_on = (verify_ipV4_address(tweaks['server_listen_on']) or
|
listen_on = (verify_ipV4_address(tweaks['server_listen_on']) or
|
||||||
get_external_ip())
|
get_external_ip())
|
||||||
text = _('Stop Content Server') + ' [%s]'%listen_on
|
try :
|
||||||
|
cs_port = content_server_config().parse().port
|
||||||
|
ip_text = _(' [%s, port %d]')%(listen_on, cs_port)
|
||||||
|
except:
|
||||||
|
ip_text = ' [%s]'%listen_on
|
||||||
|
text = _('Stop Content Server') + ip_text
|
||||||
self.toggle_server_action.setText(text)
|
self.toggle_server_action.setText(text)
|
||||||
|
|
||||||
def hide_smartdevice_menus(self):
|
def hide_smartdevice_menus(self):
|
||||||
|
@ -12,7 +12,8 @@ import weakref
|
|||||||
from PyQt4.Qt import (QWidget, QListWidgetItem, Qt, QToolButton, QLabel,
|
from PyQt4.Qt import (QWidget, QListWidgetItem, Qt, QToolButton, QLabel,
|
||||||
QTabWidget, QGridLayout, QListWidget, QIcon, QLineEdit, QVBoxLayout,
|
QTabWidget, QGridLayout, QListWidget, QIcon, QLineEdit, QVBoxLayout,
|
||||||
QPushButton, QGroupBox, QScrollArea, QHBoxLayout, QComboBox,
|
QPushButton, QGroupBox, QScrollArea, QHBoxLayout, QComboBox,
|
||||||
pyqtSignal, QSizePolicy, QDialog, QDialogButtonBox)
|
pyqtSignal, QSizePolicy, QDialog, QDialogButtonBox, QPlainTextEdit,
|
||||||
|
QApplication)
|
||||||
|
|
||||||
from calibre.ebooks import BOOK_EXTENSIONS
|
from calibre.ebooks import BOOK_EXTENSIONS
|
||||||
from calibre.gui2 import error_dialog
|
from calibre.gui2 import error_dialog
|
||||||
@ -372,15 +373,19 @@ class MTPConfig(QTabWidget):
|
|||||||
_('&Ignore the %s in calibre')%device.current_friendly_name,
|
_('&Ignore the %s in calibre')%device.current_friendly_name,
|
||||||
self.base)
|
self.base)
|
||||||
b.clicked.connect(self.ignore_device)
|
b.clicked.connect(self.ignore_device)
|
||||||
|
self.show_debug_button = bd = QPushButton(QIcon(I('debug.png')),
|
||||||
|
_('Show device information'))
|
||||||
|
bd.clicked.connect(self.show_debug_info)
|
||||||
|
|
||||||
l.addWidget(b, 0, 0, 1, 2)
|
l.addWidget(b, 0, 0, 1, 2)
|
||||||
l.addWidget(la, 1, 0, 1, 1)
|
l.addWidget(la, 1, 0, 1, 1)
|
||||||
l.addWidget(self.formats, 2, 0, 3, 1)
|
l.addWidget(self.formats, 2, 0, 4, 1)
|
||||||
l.addWidget(self.send_to, 2, 1, 1, 1)
|
l.addWidget(self.send_to, 2, 1, 1, 1)
|
||||||
l.addWidget(self.template, 3, 1, 1, 1)
|
l.addWidget(self.template, 3, 1, 1, 1)
|
||||||
l.setRowStretch(4, 10)
|
l.addWidget(self.show_debug_button, 4, 1, 1, 1)
|
||||||
l.addWidget(r, 5, 0, 1, 2)
|
l.setRowStretch(5, 10)
|
||||||
l.setRowStretch(5, 100)
|
l.addWidget(r, 6, 0, 1, 2)
|
||||||
|
l.setRowStretch(6, 100)
|
||||||
|
|
||||||
self.igntab = IgnoredDevices(self.device.prefs['history'],
|
self.igntab = IgnoredDevices(self.device.prefs['history'],
|
||||||
self.device.prefs['blacklist'])
|
self.device.prefs['blacklist'])
|
||||||
@ -388,6 +393,26 @@ class MTPConfig(QTabWidget):
|
|||||||
|
|
||||||
self.setCurrentIndex(1 if msg else 0)
|
self.setCurrentIndex(1 if msg else 0)
|
||||||
|
|
||||||
|
def show_debug_info(self):
|
||||||
|
info = self.device.device_debug_info()
|
||||||
|
d = QDialog(self)
|
||||||
|
d.l = l = QVBoxLayout()
|
||||||
|
d.setLayout(l)
|
||||||
|
d.v = v = QPlainTextEdit()
|
||||||
|
d.setWindowTitle(self.device.get_gui_name())
|
||||||
|
v.setPlainText(info)
|
||||||
|
v.setMinimumWidth(400)
|
||||||
|
v.setMinimumHeight(350)
|
||||||
|
l.addWidget(v)
|
||||||
|
bb = d.bb = QDialogButtonBox(QDialogButtonBox.Close)
|
||||||
|
bb.accepted.connect(d.accept)
|
||||||
|
bb.rejected.connect(d.reject)
|
||||||
|
l.addWidget(bb)
|
||||||
|
bb.addButton(_('Copy to clipboard'), bb.ActionRole)
|
||||||
|
bb.clicked.connect(lambda :
|
||||||
|
QApplication.clipboard().setText(v.toPlainText()))
|
||||||
|
d.exec_()
|
||||||
|
|
||||||
def ignore_device(self):
|
def ignore_device(self):
|
||||||
self.igntab.ignore_device(self.device.current_serial_num)
|
self.igntab.ignore_device(self.device.current_serial_num)
|
||||||
self.base.b.setEnabled(False)
|
self.base.b.setEnabled(False)
|
||||||
|
@ -10,7 +10,7 @@ import copy
|
|||||||
from PyQt4.Qt import Qt, QComboBox, QListWidgetItem
|
from PyQt4.Qt import Qt, QComboBox, QListWidgetItem
|
||||||
|
|
||||||
from calibre.customize.ui import is_disabled
|
from calibre.customize.ui import is_disabled
|
||||||
from calibre.gui2 import error_dialog, question_dialog
|
from calibre.gui2 import error_dialog, question_dialog, warning_dialog
|
||||||
from calibre.gui2.device import device_name_for_plugboards
|
from calibre.gui2.device import device_name_for_plugboards
|
||||||
from calibre.gui2.dialogs.template_line_editor import TemplateLineEditor
|
from calibre.gui2.dialogs.template_line_editor import TemplateLineEditor
|
||||||
from calibre.gui2.preferences import ConfigWidgetBase, test_widget
|
from calibre.gui2.preferences import ConfigWidgetBase, test_widget
|
||||||
@ -254,6 +254,15 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
show=True)
|
show=True)
|
||||||
self.new_device.setCurrentIndex(0)
|
self.new_device.setCurrentIndex(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.current_format == plugboard_any_format_value and \
|
||||||
|
self.current_device == plugboard_content_server_value:
|
||||||
|
warning_dialog(self, '',
|
||||||
|
_('The {0} device supports only the {1} format(s).').
|
||||||
|
format(plugboard_content_server_value,
|
||||||
|
', '.join(plugboard_content_server_formats)),
|
||||||
|
show=True)
|
||||||
|
|
||||||
self.set_fields()
|
self.set_fields()
|
||||||
|
|
||||||
def new_format_changed(self, txt):
|
def new_format_changed(self, txt):
|
||||||
|
@ -97,7 +97,7 @@ class EbookscomStore(BasicStoreConfig, StorePlugin):
|
|||||||
with closing(br.open(url + id, timeout=timeout)) as nf:
|
with closing(br.open(url + id, timeout=timeout)) as nf:
|
||||||
pdoc = html.fromstring(nf.read())
|
pdoc = html.fromstring(nf.read())
|
||||||
|
|
||||||
price_l = pdoc.xpath('//span[@class="price"]/text()')
|
price_l = pdoc.xpath('//div[@class="book-info"]/div[@class="price"]/text()')
|
||||||
if price_l:
|
if price_l:
|
||||||
price = price_l[0]
|
price = price_l[0]
|
||||||
search_result.price = price.strip()
|
search_result.price = price.strip()
|
||||||
|
@ -15,7 +15,8 @@ from binascii import hexlify, unhexlify
|
|||||||
import cherrypy
|
import cherrypy
|
||||||
|
|
||||||
from calibre.utils.date import isoformat
|
from calibre.utils.date import isoformat
|
||||||
from calibre.utils.config import prefs
|
from calibre.utils.config import prefs, tweaks
|
||||||
|
from calibre.ebooks.metadata import title_sort
|
||||||
from calibre.ebooks.metadata.book.json_codec import JsonCodec
|
from calibre.ebooks.metadata.book.json_codec import JsonCodec
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
from calibre.library.server import custom_fields_to_display
|
from calibre.library.server import custom_fields_to_display
|
||||||
@ -118,12 +119,16 @@ class AjaxServer(object):
|
|||||||
|
|
||||||
|
|
||||||
# Get book metadata {{{
|
# Get book metadata {{{
|
||||||
def ajax_book_to_json(self, book_id, get_category_urls=True):
|
def ajax_book_to_json(self, book_id, get_category_urls=True,
|
||||||
|
device_compatible=False):
|
||||||
mi = self.db.get_metadata(book_id, index_is_id=True)
|
mi = self.db.get_metadata(book_id, index_is_id=True)
|
||||||
try:
|
|
||||||
mi.rating = mi.rating/2.
|
if not device_compatible:
|
||||||
except:
|
try:
|
||||||
mi.rating = 0.0
|
mi.rating = mi.rating/2.
|
||||||
|
except:
|
||||||
|
mi.rating = 0.0
|
||||||
|
|
||||||
data = self.ajax_json_codec.encode_book_metadata(mi)
|
data = self.ajax_json_codec.encode_book_metadata(mi)
|
||||||
for x in ('publication_type', 'size', 'db_id', 'lpath', 'mime',
|
for x in ('publication_type', 'size', 'db_id', 'lpath', 'mime',
|
||||||
'rights', 'book_producer'):
|
'rights', 'book_producer'):
|
||||||
@ -131,57 +136,68 @@ class AjaxServer(object):
|
|||||||
|
|
||||||
data['cover'] = absurl(self.opts.url_prefix, u'/get/cover/%d'%book_id)
|
data['cover'] = absurl(self.opts.url_prefix, u'/get/cover/%d'%book_id)
|
||||||
data['thumbnail'] = absurl(self.opts.url_prefix, u'/get/thumb/%d'%book_id)
|
data['thumbnail'] = absurl(self.opts.url_prefix, u'/get/thumb/%d'%book_id)
|
||||||
mi.format_metadata = {k.lower():dict(v) for k, v in
|
|
||||||
mi.format_metadata.iteritems()}
|
|
||||||
for v in mi.format_metadata.itervalues():
|
|
||||||
mtime = v.get('mtime', None)
|
|
||||||
if mtime is not None:
|
|
||||||
v['mtime'] = isoformat(mtime, as_utc=True)
|
|
||||||
data['format_metadata'] = mi.format_metadata
|
|
||||||
fmts = set(x.lower() for x in mi.format_metadata.iterkeys())
|
|
||||||
pf = prefs['output_format'].lower()
|
|
||||||
other_fmts = list(fmts)
|
|
||||||
try:
|
|
||||||
fmt = pf if pf in fmts else other_fmts[0]
|
|
||||||
except:
|
|
||||||
fmt = None
|
|
||||||
if fmts and fmt:
|
|
||||||
other_fmts = [x for x in fmts if x != fmt]
|
|
||||||
data['formats'] = sorted(fmts)
|
|
||||||
if fmt:
|
|
||||||
data['main_format'] = {fmt: absurl(self.opts.url_prefix, u'/get/%s/%d'%(fmt, book_id))}
|
|
||||||
else:
|
|
||||||
data['main_format'] = None
|
|
||||||
data['other_formats'] = {fmt: absurl(self.opts.url_prefix, u'/get/%s/%d'%(fmt, book_id)) for fmt
|
|
||||||
in other_fmts}
|
|
||||||
|
|
||||||
if get_category_urls:
|
if not device_compatible:
|
||||||
category_urls = data['category_urls'] = {}
|
mi.format_metadata = {k.lower():dict(v) for k, v in
|
||||||
ccache = self.categories_cache()
|
mi.format_metadata.iteritems()}
|
||||||
for key in mi.all_field_keys():
|
for v in mi.format_metadata.itervalues():
|
||||||
fm = mi.metadata_for_field(key)
|
mtime = v.get('mtime', None)
|
||||||
if (fm and fm['is_category'] and not fm['is_csp'] and
|
if mtime is not None:
|
||||||
key != 'formats' and fm['datatype'] not in ['rating']):
|
v['mtime'] = isoformat(mtime, as_utc=True)
|
||||||
categories = mi.get(key)
|
data['format_metadata'] = mi.format_metadata
|
||||||
if isinstance(categories, basestring):
|
fmts = set(x.lower() for x in mi.format_metadata.iterkeys())
|
||||||
categories = [categories]
|
pf = prefs['output_format'].lower()
|
||||||
if categories is None:
|
other_fmts = list(fmts)
|
||||||
categories = []
|
try:
|
||||||
dbtags = {}
|
fmt = pf if pf in fmts else other_fmts[0]
|
||||||
for category in categories:
|
except:
|
||||||
for tag in ccache.get(key, []):
|
fmt = None
|
||||||
if tag.original_name == category:
|
if fmts and fmt:
|
||||||
dbtags[category] = books_in_url(self.opts.url_prefix,
|
other_fmts = [x for x in fmts if x != fmt]
|
||||||
tag.category if tag.category else key,
|
data['formats'] = sorted(fmts)
|
||||||
tag.original_name if tag.id is None else
|
if fmt:
|
||||||
unicode(tag.id))
|
data['main_format'] = {fmt: absurl(self.opts.url_prefix, u'/get/%s/%d'%(fmt, book_id))}
|
||||||
break
|
else:
|
||||||
category_urls[key] = dbtags
|
data['main_format'] = None
|
||||||
|
data['other_formats'] = {fmt: absurl(self.opts.url_prefix, u'/get/%s/%d'%(fmt, book_id)) for fmt
|
||||||
|
in other_fmts}
|
||||||
|
|
||||||
|
if get_category_urls:
|
||||||
|
category_urls = data['category_urls'] = {}
|
||||||
|
ccache = self.categories_cache()
|
||||||
|
for key in mi.all_field_keys():
|
||||||
|
fm = mi.metadata_for_field(key)
|
||||||
|
if (fm and fm['is_category'] and not fm['is_csp'] and
|
||||||
|
key != 'formats' and fm['datatype'] not in ['rating']):
|
||||||
|
categories = mi.get(key)
|
||||||
|
if isinstance(categories, basestring):
|
||||||
|
categories = [categories]
|
||||||
|
if categories is None:
|
||||||
|
categories = []
|
||||||
|
dbtags = {}
|
||||||
|
for category in categories:
|
||||||
|
for tag in ccache.get(key, []):
|
||||||
|
if tag.original_name == category:
|
||||||
|
dbtags[category] = books_in_url(self.opts.url_prefix,
|
||||||
|
tag.category if tag.category else key,
|
||||||
|
tag.original_name if tag.id is None else
|
||||||
|
unicode(tag.id))
|
||||||
|
break
|
||||||
|
category_urls[key] = dbtags
|
||||||
|
else:
|
||||||
|
series = data.get('series', None)
|
||||||
|
if series:
|
||||||
|
tsorder = tweaks['save_template_title_series_sorting']
|
||||||
|
series = title_sort(series, order=tsorder)
|
||||||
|
else:
|
||||||
|
series = ''
|
||||||
|
data['_series_sort_'] = series
|
||||||
|
|
||||||
return data, mi.last_modified
|
return data, mi.last_modified
|
||||||
|
|
||||||
@Endpoint(set_last_modified=False)
|
@Endpoint(set_last_modified=False)
|
||||||
def ajax_book(self, book_id, category_urls='true', id_is_uuid='false'):
|
def ajax_book(self, book_id, category_urls='true', id_is_uuid='false',
|
||||||
|
device_compatible='false'):
|
||||||
'''
|
'''
|
||||||
Return the metadata of the book as a JSON dictionary.
|
Return the metadata of the book as a JSON dictionary.
|
||||||
|
|
||||||
@ -197,7 +213,8 @@ class AjaxServer(object):
|
|||||||
else:
|
else:
|
||||||
book_id = int(book_id)
|
book_id = int(book_id)
|
||||||
data, last_modified = self.ajax_book_to_json(book_id,
|
data, last_modified = self.ajax_book_to_json(book_id,
|
||||||
get_category_urls=category_urls.lower()=='true')
|
get_category_urls=category_urls.lower()=='true',
|
||||||
|
device_compatible=device_compatible.lower()=='true');
|
||||||
except:
|
except:
|
||||||
raise cherrypy.HTTPError(404, 'No book with id: %r'%book_id)
|
raise cherrypy.HTTPError(404, 'No book with id: %r'%book_id)
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -4,9 +4,9 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: calibre 0.8.70\n"
|
"Project-Id-Version: calibre 0.9.0\n"
|
||||||
"POT-Creation-Date: 2012-09-21 13:10+IST\n"
|
"POT-Creation-Date: 2012-09-28 10:04+IST\n"
|
||||||
"PO-Revision-Date: 2012-09-21 13:10+IST\n"
|
"PO-Revision-Date: 2012-09-28 10:04+IST\n"
|
||||||
"Last-Translator: Automatically generated\n"
|
"Last-Translator: Automatically generated\n"
|
||||||
"Language-Team: LANGUAGE\n"
|
"Language-Team: LANGUAGE\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -33,8 +33,8 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/books.py:27
|
#: /home/kovid/work/calibre/src/calibre/devices/kobo/books.py:27
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:656
|
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:656
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/books.py:44
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/books.py:44
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/unix/driver.py:209
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/unix/driver.py:223
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:218
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:229
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:70
|
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:70
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:71
|
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:71
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:661
|
#: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:661
|
||||||
@ -79,8 +79,8 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:472
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:472
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:474
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:474
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:476
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/mobi.py:476
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1188
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1184
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1299
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1295
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdb.py:44
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdb.py:44
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:88
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/pdf.py:88
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/plucker.py:25
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/plucker.py:25
|
||||||
@ -204,7 +204,7 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:156
|
#: /home/kovid/work/calibre/src/calibre/customize/__init__.py:156
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:54
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:54
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:59
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/preferences.py:59
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:356
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:357
|
||||||
msgid "Cannot configure"
|
msgid "Cannot configure"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -586,7 +586,7 @@ msgid "Control how calibre downloads ebook metadata from the net"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1125
|
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:1125
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:387
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:392
|
||||||
msgid "Ignored devices"
|
msgid "Ignored devices"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -1109,8 +1109,8 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:268
|
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:268
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:324
|
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:324
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/driver.py:361
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/driver.py:361
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1088
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1078
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1090
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1080
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:277
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:277
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:279
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:279
|
||||||
msgid "Transferring books to device..."
|
msgid "Transferring books to device..."
|
||||||
@ -1121,8 +1121,8 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:480
|
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:480
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:515
|
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:515
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/driver.py:398
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/driver.py:398
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1101
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1091
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1112
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1102
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:301
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:301
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:332
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:332
|
||||||
msgid "Adding books to device metadata listing..."
|
msgid "Adding books to device metadata listing..."
|
||||||
@ -1144,8 +1144,8 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:374
|
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:374
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:468
|
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:468
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:475
|
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:475
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1140
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1130
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1146
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1136
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:366
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:366
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:371
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:371
|
||||||
msgid "Removing books from device metadata listing..."
|
msgid "Removing books from device metadata listing..."
|
||||||
@ -1578,7 +1578,7 @@ msgid "Communicate with MTP devices"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/driver.py:141
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/driver.py:141
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:913
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:903
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:95
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:95
|
||||||
msgid "Get device information..."
|
msgid "Get device information..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -1644,12 +1644,16 @@ msgstr ""
|
|||||||
msgid "All books removed"
|
msgid "All books removed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/unix/driver.py:194
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/unix/driver.py:195
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:291
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:304
|
||||||
msgid "Unknown MTP device"
|
msgid "Unknown MTP device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:64
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:61
|
||||||
|
msgid "MTP devices are not supported on Windows XP"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:69
|
||||||
msgid "The Windows Portable Devices service is not available on your computer. You may need to install Windows Media Player 11 or newer and/or restart your computer"
|
msgid "The Windows Portable Devices service is not available on your computer. You may need to install Windows Media Player 11 or newer and/or restart your computer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -1850,22 +1854,22 @@ msgstr ""
|
|||||||
msgid "Use this option if you want to force the driver to listen on a particular IP address. The driver will listen only on the entered address, and this address will be the one advertized over mDNS (bonjour)."
|
msgid "Use this option if you want to force the driver to listen on a particular IP address. The driver will listen only on the entered address, and this address will be the one advertized over mDNS (bonjour)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:775
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:759
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Too many connection attempts from %s"
|
msgid "Too many connection attempts from %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1250
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1240
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Invalid port in options: %s"
|
msgid "Invalid port in options: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1258
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1248
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to connect to port %d. Try a different value."
|
msgid "Failed to connect to port %d. Try a different value."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1270
|
#: /home/kovid/work/calibre/src/calibre/devices/smart_device_app/driver.py:1260
|
||||||
msgid "Failed to allocate a random port"
|
msgid "Failed to allocate a random port"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -2491,47 +2495,47 @@ msgstr ""
|
|||||||
msgid "Use the new PDF conversion engine."
|
msgid "Use the new PDF conversion engine."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:70
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:72
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "The unit of measure. Default is inch. Choices are %s Note: This does not override the unit for margins!"
|
msgid "The unit of measure. Default is inch. Choices are %s Note: This does not override the unit for margins!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:75
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:77
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "The size of the paper. This size will be overridden when a non default output profile is used. Default is letter. Choices are %s"
|
msgid "The size of the paper. This size will be overridden when a non default output profile is used. Default is letter. Choices are %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:79
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:81
|
||||||
msgid "Custom size of the document. Use the form widthxheight EG. `123x321` to specify the width and height. This overrides any specified paper-size."
|
msgid "Custom size of the document. Use the form widthxheight EG. `123x321` to specify the width and height. This overrides any specified paper-size."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:84
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:86
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "The orientation of the page. Default is portrait. Choices are %s"
|
msgid "The orientation of the page. Default is portrait. Choices are %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:88
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:90
|
||||||
msgid "Preserve the aspect ratio of the cover, instead of stretching it to fill the full first page of the generated pdf."
|
msgid "Preserve the aspect ratio of the cover, instead of stretching it to fill the full first page of the generated pdf."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:93
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:95
|
||||||
msgid "The font family used to render serif fonts"
|
msgid "The font family used to render serif fonts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:96
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:98
|
||||||
msgid "The font family used to render sans-serif fonts"
|
msgid "The font family used to render sans-serif fonts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:99
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:101
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:103
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:105
|
||||||
msgid "The font family used to render monospaced fonts"
|
msgid "The font family used to render monospaced fonts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:106
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:108
|
||||||
msgid "The default font size"
|
msgid "The default font size"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:109
|
#: /home/kovid/work/calibre/src/calibre/ebooks/conversion/plugins/pdf_output.py:111
|
||||||
msgid "The default font size for monospaced text"
|
msgid "The default font size for monospaced text"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -3485,7 +3489,7 @@ msgid ""
|
|||||||
"Fetch a cover image/social metadata for the book identified by ISBN from LibraryThing.com\n"
|
"Fetch a cover image/social metadata for the book identified by ISBN from LibraryThing.com\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1491
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1487
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1279
|
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1279
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:958
|
#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single.py:958
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41
|
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:41
|
||||||
@ -4647,87 +4651,92 @@ msgstr ""
|
|||||||
msgid "The selected books will be <b>permanently deleted</b> from your device. Are you sure?"
|
msgid "The selected books will be <b>permanently deleted</b> from your device. Are you sure?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:32
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:33
|
||||||
msgid "Start wireless device connection"
|
msgid "Start wireless device connection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:33
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:34
|
||||||
msgid "Stop wireless device connection"
|
msgid "Stop wireless device connection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:37
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:38
|
||||||
msgid "Connect to folder"
|
msgid "Connect to folder"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:42
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:43
|
||||||
msgid "Connect to iTunes"
|
msgid "Connect to iTunes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:48
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:49
|
||||||
msgid "Connect to Bambook"
|
msgid "Connect to Bambook"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:62
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:63
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:89
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:90
|
||||||
msgid "Start Content Server"
|
msgid "Start Content Server"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:84
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:85
|
||||||
msgid "Start/stop content server"
|
msgid "Start/stop content server"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:93
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:96
|
||||||
|
#, python-format
|
||||||
|
msgid " [%s, port %d]"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:99
|
||||||
msgid "Stop Content Server"
|
msgid "Stop Content Server"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:107
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:113
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:126
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:132
|
||||||
msgid "Email to"
|
msgid "Email to"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:111
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:117
|
||||||
msgid "Email to and delete from library"
|
msgid "Email to and delete from library"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:120
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:126
|
||||||
msgid "(delete from library)"
|
msgid "(delete from library)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:135
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:141
|
||||||
msgid "Setup email based sharing of books"
|
msgid "Setup email based sharing of books"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:153
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:159
|
||||||
msgid "D"
|
msgid "D"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:153
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:159
|
||||||
msgid "Send to device"
|
msgid "Send to device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:171
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:177
|
||||||
msgid "Connect/share"
|
msgid "Connect/share"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:209
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:215
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:85
|
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:85
|
||||||
msgid "Stopping"
|
msgid "Stopping"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:210
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:216
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:86
|
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:86
|
||||||
msgid "Stopping server, this could take upto a minute, please wait..."
|
msgid "Stopping server, this could take upto a minute, please wait..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:229
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:235
|
||||||
msgid "Disable autostart"
|
msgid "Disable autostart"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:230
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:236
|
||||||
msgid "Do you want wireless device connections to be started automatically when calibre starts?"
|
msgid "Do you want wireless device connections to be started automatically when calibre starts?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:253
|
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:259
|
||||||
msgid "Many IP addresses. See Start/Stop dialog."
|
msgid "Many IP addresses. See Start/Stop dialog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -7854,7 +7863,7 @@ msgid "Cannot configure the device while there are running device jobs."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:920
|
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:920
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:359
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:360
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Configure %s"
|
msgid "Configure %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -7964,7 +7973,7 @@ msgid "You have enabled the <b>{0}</b> formats for your {1}. The {1} may not sup
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget.py:155
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget.py:155
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:112
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:113
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:456
|
#: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:456
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:279
|
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:279
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:70
|
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:70
|
||||||
@ -7972,7 +7981,7 @@ msgid "Invalid template"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget.py:156
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/configwidget.py:156
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:113
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:114
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:457
|
#: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:457
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:280
|
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugboard.py:280
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:71
|
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:71
|
||||||
@ -8000,100 +8009,112 @@ msgstr ""
|
|||||||
msgid "Save &template:"
|
msgid "Save &template:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:56
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:57
|
||||||
msgid "No formats selected"
|
msgid "No formats selected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:57
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:58
|
||||||
msgid "You must choose at least one format to send to the device"
|
msgid "You must choose at least one format to send to the device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:85
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:86
|
||||||
msgid ""
|
msgid ""
|
||||||
"<b>Save &template</b> to control the filename and\n"
|
"<b>Save &template</b> to control the filename and\n"
|
||||||
" location of files sent to the device:"
|
" location of files sent to the device:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:91
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:92
|
||||||
msgid "&Template editor"
|
msgid "&Template editor"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:101
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:102
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/template_line_editor.py:41
|
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/template_line_editor.py:41
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:443
|
#: /home/kovid/work/calibre/src/calibre/gui2/library/delegates.py:443
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:48
|
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:48
|
||||||
msgid "Edit template"
|
msgid "Edit template"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:128
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:129
|
||||||
msgid ""
|
msgid ""
|
||||||
"A <b>list of &folders</b> on the device to\n"
|
"A <b>list of &folders</b> on the device to\n"
|
||||||
" which to send ebooks. The first one that exists will be used:"
|
" which to send ebooks. The first one that exists will be used:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:138
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:139
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:225
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:226
|
||||||
msgid "Browse for a folder on the device"
|
msgid "Browse for a folder on the device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:166
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:167
|
||||||
msgid ""
|
msgid ""
|
||||||
"Select the devices to be <b>ignored</b>. calibre <b>will not</b>\n"
|
"Select the devices to be <b>ignored</b>. calibre <b>will not</b>\n"
|
||||||
" connect to devices with a checkmark next to their names."
|
" connect to devices with a checkmark next to their names."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:211
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:212
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Send the %s format to the folder:"
|
msgid "Send the %s format to the folder:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:219
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:220
|
||||||
msgid "Folder on the device"
|
msgid "Folder on the device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:227
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:228
|
||||||
msgid "&Remove rule"
|
msgid "&Remove rule"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:272
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:273
|
||||||
msgid "Format specific sending"
|
msgid "Format specific sending"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:277
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:278
|
||||||
msgid ""
|
msgid ""
|
||||||
"You can create rules that control where ebooks of a specific\n"
|
"You can create rules that control where ebooks of a specific\n"
|
||||||
" format are sent to on the device. These will take precedence over\n"
|
" format are sent to on the device. These will take precedence over\n"
|
||||||
" the folders specified above."
|
" the folders specified above."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:299
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:300
|
||||||
msgid "Add a &new rule"
|
msgid "Add a &new rule"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:337
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:338
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "The <b>%s</b> device has no serial number, it cannot be configured"
|
msgid "The <b>%s</b> device has no serial number, it cannot be configured"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:342
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:343
|
||||||
msgid "<b>No MTP device connected.</b><p> You can only configure the MTP device plugin when a device is connected."
|
msgid "<b>No MTP device connected.</b><p> You can only configure the MTP device plugin when a device is connected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:349
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:350
|
||||||
msgid "If you want to un-ignore a previously ignored MTP device, use the \"Ignored devices\" tab."
|
msgid "If you want to un-ignore a previously ignored MTP device, use the \"Ignored devices\" tab."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:369
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:370
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Choose the formats to send to the %s"
|
msgid "Choose the formats to send to the %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:372
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:373
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "&Ignore the %s in calibre"
|
msgid "&Ignore the %s in calibre"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:394
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:377
|
||||||
|
msgid "Show device information"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:411
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:141
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:880
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/tweaks.py:344
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:220
|
||||||
|
msgid "Copy to clipboard"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/device_drivers/mtp_config.py:419
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "The %s will be ignored in calibre"
|
msgid "The %s will be ignored in calibre"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -8818,13 +8839,6 @@ msgstr ""
|
|||||||
msgid "Copied"
|
msgid "Copied"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:141
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:880
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/tweaks.py:344
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:220
|
|
||||||
msgid "Copy to clipboard"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:196
|
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:196
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:251
|
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/message_box.py:251
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:944
|
#: /home/kovid/work/calibre/src/calibre/gui2/metadata/single_download.py:944
|
||||||
@ -17466,13 +17480,13 @@ msgstr ""
|
|||||||
msgid "Prefix to prepend to all URLs. Useful for reverseproxying to this server from Apache/nginx/etc."
|
msgid "Prefix to prepend to all URLs. Useful for reverseproxying to this server from Apache/nginx/etc."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/library/server/ajax.py:300
|
#: /home/kovid/work/calibre/src/calibre/library/server/ajax.py:317
|
||||||
#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:342
|
#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:342
|
||||||
#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:626
|
#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:626
|
||||||
msgid "All books"
|
msgid "All books"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/library/server/ajax.py:301
|
#: /home/kovid/work/calibre/src/calibre/library/server/ajax.py:318
|
||||||
#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:341
|
#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:341
|
||||||
#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:625
|
#: /home/kovid/work/calibre/src/calibre/library/server/browse.py:625
|
||||||
#: /home/kovid/work/calibre/src/calibre/library/server/opds.py:584
|
#: /home/kovid/work/calibre/src/calibre/library/server/opds.py:584
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user