mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-30 21:41:57 -04:00
0.9.0
This commit is contained in:
commit
a6f73264d6
@ -19,6 +19,51 @@
|
||||
# new recipes:
|
||||
# - 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
|
||||
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>
|
||||
</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="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" />
|
||||
</form>
|
||||
<hr/>
|
||||
|
@ -1,45 +1,37 @@
|
||||
from __future__ import with_statement
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = 'Original 2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__copyright__= 'Modified 2011, Josh Hall <jwtheiv@gmail.com>'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__copyright__ = '2012 Josh Hall<jwtheiv@gmail.com>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
'''
|
||||
www.baltimoresun.com
|
||||
'''
|
||||
|
||||
import urllib, re
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class BaltimoreSun(BasicNewsRecipe):
|
||||
|
||||
title = 'The Baltimore Sun'
|
||||
__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
|
||||
max_articles_per_feed = 100
|
||||
remove_empty_feeds = True
|
||||
use_embedded_content = False
|
||||
no_stylesheets = True
|
||||
remove_javascript = True
|
||||
#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'}),
|
||||
]
|
||||
use_embedded_content = False
|
||||
no_stylesheets = True
|
||||
remove_javascript = True
|
||||
recursions = 1
|
||||
|
||||
keep_only_tags = [dict(name='div', attrs={'class':["story","entry-asset asset hentry"]}),
|
||||
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"]},
|
||||
{'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"]},
|
||||
dict(name='font',attrs={'id':["cr-other-headlines"]}),
|
||||
dict(name=['iframe']),
|
||||
]
|
||||
remove_tags = [{'id':["moduleArticleTools","content-bottom","rail","articleRelates module","toolSet","relatedrailcontent","div-wrapper","beta","atp-comments","footer",'gallery-subcontent','subFooter']},
|
||||
{'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"]})]
|
||||
extra_css = '''
|
||||
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;}
|
||||
@ -53,8 +45,9 @@ class BaltimoreSun(BasicNewsRecipe):
|
||||
.maincontentcontainer{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;}
|
||||
'''
|
||||
'''
|
||||
feeds = [
|
||||
## News ##
|
||||
(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'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'Weather', u'http://www.baltimoresun.com/news/weather/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'),
|
||||
|
||||
|
||||
##Sports##
|
||||
(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'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'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'Arts & Theater', u'http://www.baltimoresun.com/entertainment/arts/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'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'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'Parenting', u'http://www.baltimoresun.com/features/parenting/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'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'Technology', u'http://www.baltimoresun.com/business/technology/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'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'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'Kevin Cowherd', 'http://www.baltimoresun.com/sports/bal-columnist-cowherd,0,6829726.columnist-rss2.0.xml'),
|
||||
(u'Jay Hancock', u'http://www.baltimoresun.com/business/money/bal-columnist-hancock,0,6673611.columnist-rss2.0.xml'),
|
||||
## Columnists ##
|
||||
(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'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'),
|
||||
@ -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'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'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'),
|
||||
(u'Getting There', u'http://weblogs.baltimoresun.com/news/traffic/index.xml'),
|
||||
(u'InsideEd', u'http://weblogs.baltimoresun.com/news/education/blog/index.xml'),
|
||||
(u'Maryland Politics', u'http://weblogs.baltimoresun.com/news/local/politics/index.xml'),
|
||||
(u'Maryland Weather', u'http://weblogs.marylandweather.com/index.xml'),
|
||||
(u'Second Opinion', u'http://weblogs.baltimoresun.com/news/opinion/index.xml'),
|
||||
(u'You Dont Say', u'http://weblogs.baltimoresun.com/news/mcintyre/blog/index.xml'),
|
||||
## News Blogs ##
|
||||
(u'Baltimore Crime Beat', u'http://baltimore.feedsportal.com/c/34255/f/623075/index.rss'),
|
||||
(u'InsideEd', u'http://www.baltimoresun.com/news/maryland/education/blog/rss2.0.xml'),
|
||||
(u'Maryland Politics', u'http://www.baltimoresun.com/news/maryland/politics/blog/rss2.0.xml'),
|
||||
(u'Maryland Weather', u'http://www.baltimoresun.com/news/weather/weather-blog/rss2.0.xml'),
|
||||
(u'Second Opinion', u'http://www.baltimoresun.com/news/opinion/second-opinion-blog/rss2.0.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'),
|
||||
(u'Consuming Interests', u'http://weblogs.baltimoresun.com/business/consuminginterests/blog/index.xml'),
|
||||
(u'Jay Hancocks Blog', u'http://weblogs.baltimoresun.com/business/hancock/blog/index.xml'),
|
||||
(u'The Real Estate Wonk', u'http://weblogs.baltimoresun.com/business/realestate/blog/index.xml'),
|
||||
## Business Blogs ##
|
||||
(u'BaltTech', u'http://www.baltimoresun.com/business/technology/blog/rss2.0.xml'),
|
||||
(u'Consuming Interests', u'http://www.baltimoresun.com/business/consuming-interests-blog/rss2.0.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'),
|
||||
(u'Dining at Large', u'http://weblogs.baltimoresun.com/entertainment/dining/reviews/blog/index.xml'),
|
||||
(u'Midnight Sun', u'http://weblogs.baltimoresun.com/entertainment/midnight_sun/blog/index.xml'),
|
||||
(u'Mike Sragow Gets Reel', u'http://weblogs.baltimoresun.com/entertainment/movies/blog/index.xml'),
|
||||
(u'Read Street', u'http://weblogs.baltimoresun.com/entertainment/books/blog/index.xml'),
|
||||
(u'Reality Check', u'http://weblogs.baltimoresun.com/entertainment/realitycheck/blog/index.xml'),
|
||||
(u'Z on TV', u'http://weblogs.baltimoresun.com/entertainment/zontv/index.xml'),
|
||||
## Entertainment Blogs ##
|
||||
(u'Clef Notes & Drama Queens', 'http://weblogs.baltimoresun.com/entertainment/classicalmusic/index.xml'),
|
||||
(u'Baltimore Diner', u'http://baltimore.feedsportal.com/c/34255/f/623088/index.rss'),
|
||||
(u'Midnight Sun', u'http://www.baltimoresun.com/entertainment/music/midnight-sun-blog/rss2.0.xml'),
|
||||
(u'Read Street', u'http://www.baltimoresun.com/features/books/read-street/rss2.0.xml'),
|
||||
(u'Z on TV', u'http://www.baltimoresun.com/entertainment/tv/z-on-tv-blog/rss2.0.xml'),
|
||||
|
||||
## Life Blogs ##
|
||||
(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'Exercists', u'http://weblogs.baltimoresun.com/health/fitness/index.xml'),
|
||||
(u'Garden Variety', 'http://weblogs.baltimoresun.com/features/gardening/index.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'Baltimore Insider',u'http://www.baltimoresun.com/features/baltimore-insider-blog/rss2.0.xml'),
|
||||
(u'Homefront', u'http://www.baltimoresun.com/features/parenting/homefront/rss2.0.xml'),
|
||||
(u'Picture of Health', u'http://www.baltimoresun.com/health/blog/rss2.0.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'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'Outdoors Girl', u'http://weblogs.baltimoresun.com/sports/outdoors/blog/index.xml'),
|
||||
(u'Ravens Insider', u'http://weblogs.baltimoresun.com/sports/ravens/blog/index.xml'),
|
||||
(u'Orioles Insider', u'http://baltimore.feedsportal.com/c/34255/f/623100/index.rss'),
|
||||
(u'Ravens Insider', u'http://www.baltimoresun.com/sports/ravens/ravens-insider/rss2.0.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'The Schmuck Stops Here', u'http://weblogs.baltimoresun.com/sports/schmuck/index.xml'),
|
||||
(u'Toy Department', u'http://weblogs.baltimoresun.com/sports/thetoydepartment/index.xml'),
|
||||
(u'The Schmuck Stops Here', u'http://www.baltimoresun.com/sports/schmuck-blog/rss2.0.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'Virtual Vensanity', u'http://weblogs.baltimoresun.com/entertainment/bthesite/vensel/index.xml'),
|
||||
|
||||
]
|
||||
|
||||
|
||||
def get_article_url(self, article):
|
||||
print article.get('feedburner_origlink', article.get('guid', article.get('link')))
|
||||
return article.get('feedburner_origlink', article.get('guid', article.get('link')))
|
||||
ans = None
|
||||
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):
|
||||
# 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']):
|
||||
t.name = 'div'
|
||||
|
||||
@ -182,5 +201,3 @@ class BaltimoreSun(BasicNewsRecipe):
|
||||
tag.extract()
|
||||
for tag in soup.findAll('font', dict(attrs={'id':["cr-other-headlines"]})):
|
||||
tag.extract()
|
||||
|
||||
return soup
|
||||
|
@ -1,3 +1,4 @@
|
||||
import re
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
from collections import OrderedDict
|
||||
|
||||
@ -14,7 +15,8 @@ class Chronicle(BasicNewsRecipe):
|
||||
dict(name='div', attrs={'class':'article'}),
|
||||
]
|
||||
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_stylesheets = True
|
||||
|
||||
@ -31,7 +33,6 @@ class Chronicle(BasicNewsRecipe):
|
||||
return br
|
||||
|
||||
def parse_index(self):
|
||||
|
||||
#Go to the issue
|
||||
soup0 = self.index_to_soup('http://chronicle.com/section/Archives/39/')
|
||||
issue = soup0.find('ul',attrs={'class':'feature-promo-list'}).li
|
||||
@ -42,9 +43,12 @@ class Chronicle(BasicNewsRecipe):
|
||||
self.timefmt = u' [%s]'%dates
|
||||
|
||||
#Find cover
|
||||
cover=soup0.find('div',attrs={'class':'promo'}).findNext('div')
|
||||
self.cover_url="http://chronicle.com"+cover.find('img')['src']
|
||||
|
||||
cover=soup0.find('div',attrs={'class':'side-content'}).find(attrs={'src':re.compile("photos/biz/Current")})
|
||||
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
|
||||
soup = self.index_to_soup(issueurl)
|
||||
div = soup.find ('div', attrs={'id':'article-body'})
|
||||
@ -74,8 +78,10 @@ class Chronicle(BasicNewsRecipe):
|
||||
def preprocess_html(self,soup):
|
||||
#process all the images
|
||||
for div in soup.findAll('div', attrs={'class':'tableauPlaceholder'}):
|
||||
|
||||
noscripts=div.find('noscript').a
|
||||
div.replaceWith(noscripts)
|
||||
for div0 in soup.findAll('div',text='Powered by Tableau'):
|
||||
div0.extract()
|
||||
return soup
|
||||
|
||||
|
@ -41,7 +41,7 @@ class ElPais_RSS(BasicNewsRecipe):
|
||||
,dict(attrs={'class':['firma','columna_texto','entrevista_p_r']})
|
||||
]
|
||||
remove_tags = [
|
||||
dict(name=['meta','link','base','iframe','embed','object'])
|
||||
dict(name=['iframe','embed','object'])
|
||||
,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'Guerras y conflictos' , u'http://elpais.com/tag/rss/conflictos/a/' )
|
||||
,(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):
|
||||
url = BasicNewsRecipe.get_article_url(self, article)
|
||||
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)
|
||||
return None
|
||||
|
||||
@ -107,3 +108,7 @@ class ElPais_RSS(BasicNewsRecipe):
|
||||
for item in soup.findAll('img',alt=False):
|
||||
item['alt'] = 'image'
|
||||
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'
|
||||
__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
|
||||
'''
|
||||
@ -51,10 +51,15 @@ class FinancialTimes(BasicNewsRecipe):
|
||||
return br
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='div', attrs={'class':['fullstory fullstoryHeader', 'ft-story-header']})
|
||||
,dict(name='div', attrs={'class':'standfirst'})
|
||||
,dict(name='div', attrs={'id' :'storyContent'})
|
||||
,dict(name='div', attrs={'class':['ft-story-body','index-detail']})
|
||||
dict(name='div' , attrs={'class':['fullstory fullstoryHeader', 'ft-story-header']})
|
||||
,dict(name='div' , attrs={'class':'standfirst'})
|
||||
,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='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 = [
|
||||
dict(name='div', attrs={'id':'floating-con'})
|
||||
@ -83,10 +88,9 @@ class FinancialTimes(BasicNewsRecipe):
|
||||
if self.test and count > 2:
|
||||
return articles
|
||||
rawlink = item['href']
|
||||
if rawlink.startswith('http://'):
|
||||
url = rawlink
|
||||
else:
|
||||
url = self.PREFIX + rawlink
|
||||
url = rawlink
|
||||
if not rawlink.startswith('http://'):
|
||||
url = self.PREFIX + rawlink
|
||||
urlverified = self.browser.open_novisit(url).geturl() # resolve redirect.
|
||||
title = self.tag_to_string(item)
|
||||
date = strftime(self.timefmt)
|
||||
@ -106,20 +110,20 @@ class FinancialTimes(BasicNewsRecipe):
|
||||
wide = soup.find('div',attrs={'class':'wide'})
|
||||
if not wide:
|
||||
return feeds
|
||||
strest = wide.findAll('h3', attrs={'class':'section'})
|
||||
if not strest:
|
||||
allsections = wide.findAll(attrs={'class':lambda x: x and 'footwell' in x.split()})
|
||||
if not allsections:
|
||||
return feeds
|
||||
st = wide.findAll('h4',attrs={'class':'section-no-arrow'})
|
||||
if st:
|
||||
st.extend(strest)
|
||||
count = 0
|
||||
for item in st:
|
||||
for item in allsections:
|
||||
count = count + 1
|
||||
if self.test and count > 2:
|
||||
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))
|
||||
feedarts = self.get_artlinks(item.parent.ul)
|
||||
feedarts = self.get_artlinks(item.ul)
|
||||
feeds.append((ftitle,feedarts))
|
||||
return feeds
|
||||
|
||||
@ -166,7 +170,8 @@ class FinancialTimes(BasicNewsRecipe):
|
||||
except:
|
||||
print "Retrying download..."
|
||||
count += 1
|
||||
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
||||
self.temp_files[-1].write(html)
|
||||
self.temp_files[-1].close()
|
||||
return self.temp_files[-1].name
|
||||
tfile = PersistentTemporaryFile('_fa.html')
|
||||
tfile.write(html)
|
||||
tfile.close()
|
||||
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
|
||||
no_stylesheets = True
|
||||
auto_cleanup = True
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='div', attrs={'id':'content'})
|
||||
]
|
||||
#keep_only_tags = [
|
||||
#dict(name='div', attrs={'id':'content'})
|
||||
#]
|
||||
|
||||
remove_tags = [
|
||||
{'class':['toolBar','mac_tags','toolBar btmTools','textAds']},
|
||||
dict(name='p', attrs={'class':'breadcrumbs'}),
|
||||
dict(id=['breadcrumb','sidebar','comments','topContentWrapper',
|
||||
'rightColumn', 'aboveFootPromo', 'storyCarousel']),
|
||||
{'class':lambda x: x and ('tools' in x or 'toolBar'
|
||||
in x)}
|
||||
#remove_tags = [
|
||||
#{'class':['toolBar','mac_tags','toolBar btmTools','textAds']},
|
||||
#dict(name='p', attrs={'class':'breadcrumbs'}),
|
||||
#dict(id=['breadcrumb','sidebar','comments','topContentWrapper',
|
||||
#'rightColumn', 'aboveFootPromo', 'storyCarousel']),
|
||||
#{'class':lambda x: x and ('tools' in x or 'toolBar'
|
||||
#in x)}
|
||||
|
||||
]
|
||||
#]
|
||||
|
||||
feeds = [
|
||||
(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;}
|
||||
img {align:left;}
|
||||
'''
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
from calibre.ptempfile import PersistentTemporaryFile
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class AdvancedUserRecipe1276930924(BasicNewsRecipe):
|
||||
@ -14,30 +13,30 @@ class AdvancedUserRecipe1276930924(BasicNewsRecipe):
|
||||
use_embedded_content = False
|
||||
no_stylesheets = True
|
||||
language = 'en'
|
||||
temp_files = []
|
||||
articles_are_obfuscated = True
|
||||
feeds = [(u'News', u'http://www.maximumpc.com/articles/4/feed'),
|
||||
auto_cleanup = True
|
||||
feeds = [#(u'News', u'http://www.maximumpc.com/articles/all/feed'),
|
||||
(u'News', u'http://www.maximumpc.com/articles/4/feed'),
|
||||
(u'Reviews', u'http://www.maximumpc.com/articles/40/feed'),
|
||||
(u'Editors Blog', u'http://www.maximumpc.com/articles/6/feed'),
|
||||
(u'How-to', u'http://www.maximumpc.com/articles/32/feed'),
|
||||
(u'Features', u'http://www.maximumpc.com/articles/31/feed'),
|
||||
(u'From the Magazine', u'http://www.maximumpc.com/articles/72/feed')
|
||||
]
|
||||
keep_only_tags = [
|
||||
dict(name='div', attrs={'class':['print-title','article_body']}),
|
||||
]
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'class':'comments-tags-actions'}),
|
||||
]
|
||||
remove_tags_before = dict(name='div', attrs={'class':'print-title'})
|
||||
remove_tags_after = dict(name='div', attrs={'class':'meta-content'})
|
||||
#keep_only_tags = [
|
||||
#dict(name='div', attrs={'class':['print-title','article_body']}),
|
||||
#]
|
||||
#remove_tags = [
|
||||
#dict(name='div', attrs={'class':'comments-tags-actions'}),
|
||||
#]
|
||||
#remove_tags_before = dict(name='div', attrs={'class':'print-title'})
|
||||
#remove_tags_after = dict(name='div', attrs={'class':'meta-content'})
|
||||
|
||||
def get_obfuscated_article(self, url):
|
||||
br = self.get_browser()
|
||||
br.open(url)
|
||||
response = br.follow_link(url_regex = r'/print/[0-9]+', nr = 0)
|
||||
html = response.read()
|
||||
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
||||
self.temp_files[-1].write(html)
|
||||
self.temp_files[-1].close()
|
||||
return self.temp_files[-1].name
|
||||
#def get_obfuscated_article(self, url):
|
||||
#br = self.get_browser()
|
||||
#br.open(url)
|
||||
#response = br.follow_link(url_regex = r'/print/[0-9]+', nr = 0)
|
||||
#html = response.read()
|
||||
#self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
||||
#self.temp_files[-1].write(html)
|
||||
#self.temp_files[-1].close()
|
||||
#return self.temp_files[-1].name
|
||||
|
@ -1,99 +1,66 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__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
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
from calibre.ebooks.BeautifulSoup import Tag
|
||||
|
||||
class MonitorCG(BasicNewsRecipe):
|
||||
title = 'Monitor online'
|
||||
title = 'MONITOR online'
|
||||
__author__ = 'Darko Miletic'
|
||||
description = 'News from Montenegro'
|
||||
publisher = 'MONITOR d.o.o. Podgorica'
|
||||
description = 'Nezavisni nedjeljnik Monitor'
|
||||
publisher = '"Monitor" D.O.O. Podgorica'
|
||||
category = 'news, politics, Montenegro'
|
||||
oldest_article = 15
|
||||
max_articles_per_feed = 150
|
||||
no_stylesheets = True
|
||||
encoding = 'utf-8'
|
||||
auto_cleanup = False
|
||||
use_embedded_content = False
|
||||
language = 'sr'
|
||||
|
||||
lang ='sr-Latn-Me'
|
||||
INDEX = 'http://www.monitorcg.com'
|
||||
|
||||
extra_css = ' @font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} body{font-family: serif1, serif} '
|
||||
language = 'sr'
|
||||
remove_empty_feeds = True
|
||||
extra_css = """
|
||||
@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)}
|
||||
@font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
|
||||
h2{font-family: Cambria,"Times New Roman",Times,serif1,serif}
|
||||
body{font-family: Arial,sans1,sans-serif}
|
||||
img{display: block}
|
||||
"""
|
||||
|
||||
conversion_options = {
|
||||
'comment' : description
|
||||
, 'tags' : category
|
||||
, 'publisher' : publisher
|
||||
, 'language' : lang
|
||||
, 'pretty_print' : True
|
||||
'comment' : description
|
||||
, 'tags' : category
|
||||
, 'publisher' : publisher
|
||||
, 'language' : language
|
||||
, 'pretty_print': True
|
||||
}
|
||||
|
||||
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'})]
|
||||
|
||||
remove_tags = [ dict(name=['object','link','embed'])
|
||||
, dict(attrs={'class':['buttonheading','article-section']})]
|
||||
|
||||
remove_attributes = ['style','width','height','font','border','align']
|
||||
|
||||
def adeify_images2(cls, soup):
|
||||
for item in soup.findAll('img'):
|
||||
for attrib in ['height','width','border','align','style']:
|
||||
if item.has_key(attrib):
|
||||
del item[attrib]
|
||||
oldParent = item.parent
|
||||
if oldParent.name == 'a':
|
||||
oldParent.name == 'p'
|
||||
myIndex = oldParent.contents.index(item)
|
||||
brtag = Tag(soup,'br')
|
||||
oldParent.insert(myIndex+1,brtag)
|
||||
return soup
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
soup.html['xml:lang'] = self.lang
|
||||
soup.html['lang'] = self.lang
|
||||
mlang = Tag(soup,'meta',[("http-equiv","Content-Language"),("content",self.lang)])
|
||||
soup.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
|
||||
|
||||
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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
,(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')
|
||||
]
|
||||
|
||||
|
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>'
|
||||
__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__,
|
||||
__appname__)
|
||||
@ -407,7 +407,7 @@ class Win32Freeze(Command, WixMixIn):
|
||||
cmd = [msvc.linker] + ['/INCREMENTAL:NO', '/MACHINE:X86',
|
||||
'/LIBPATH:'+self.obj_dir, '/SUBSYSTEM:WINDOWS',
|
||||
'/LIBPATH:'+(LZMA+r'\lib\Release'),
|
||||
'/RELEASE',
|
||||
'/RELEASE', '/MANIFEST', '/MANIFESTUAC:level="asInvoker" uiAccess="false"',
|
||||
'/ENTRY:wWinMainCRTStartup',
|
||||
'/OUT:'+exe, self.embed_resources(exe,
|
||||
desc='Calibre Portable Installer', extra_data=zf,
|
||||
@ -415,6 +415,31 @@ class Win32Freeze(Command, WixMixIn):
|
||||
xobj, obj, 'User32.lib', 'Shell32.lib', 'easylzma_s.lib',
|
||||
'Ole32.lib', 'Shlwapi.lib', 'Kernel32.lib', 'Psapi.lib']
|
||||
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)
|
||||
|
||||
|
@ -9,33 +9,33 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
||||
"devel@lists.alioth.debian.org>\n"
|
||||
"POT-Creation-Date: 2011-11-25 14:01+0000\n"
|
||||
"PO-Revision-Date: 2011-11-12 07:52+0000\n"
|
||||
"Last-Translator: Devilinside <Unknown>\n"
|
||||
"PO-Revision-Date: 2012-09-25 20:15+0000\n"
|
||||
"Last-Translator: Gergely Szarka <szarka.honved@gmail.com>\n"
|
||||
"Language-Team: Hungarian <debian-l10n-hungarian@lists.d.o>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-11-26 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 14381)\n"
|
||||
"X-Launchpad-Export-Date: 2012-09-26 04:36+0000\n"
|
||||
"X-Generator: Launchpad (build 16022)\n"
|
||||
"X-Poedit-Country: HUNGARY\n"
|
||||
"Language: hu\n"
|
||||
"X-Poedit-Language: Hungarian\n"
|
||||
|
||||
#. name for aaa
|
||||
msgid "Ghotuo"
|
||||
msgstr "ghotuo"
|
||||
msgstr "Ghotuo"
|
||||
|
||||
#. name for aab
|
||||
msgid "Alumu-Tesu"
|
||||
msgstr "alumu-tesu"
|
||||
msgstr "Alumu-Tesu"
|
||||
|
||||
#. name for aac
|
||||
msgid "Ari"
|
||||
msgstr "ari"
|
||||
msgstr "Ari"
|
||||
|
||||
#. name for aad
|
||||
msgid "Amal"
|
||||
msgstr "amal"
|
||||
msgstr "Amal"
|
||||
|
||||
#. name for aae
|
||||
msgid "Albanian; Arbëreshë"
|
||||
@ -43,11 +43,11 @@ msgstr "albán; Arbëreshë"
|
||||
|
||||
#. name for aaf
|
||||
msgid "Aranadan"
|
||||
msgstr "aranadan"
|
||||
msgstr "Aranadan"
|
||||
|
||||
#. name for aag
|
||||
msgid "Ambrak"
|
||||
msgstr "ambrak"
|
||||
msgstr "Ambrak"
|
||||
|
||||
#. name for aah
|
||||
msgid "Arapesh; Abu'"
|
||||
@ -55,11 +55,11 @@ msgstr "arapesh; Abu'"
|
||||
|
||||
#. name for aai
|
||||
msgid "Arifama-Miniafia"
|
||||
msgstr "arifama-miniafia"
|
||||
msgstr "Arifama-Miniafia"
|
||||
|
||||
#. name for aak
|
||||
msgid "Ankave"
|
||||
msgstr "ankave"
|
||||
msgstr "Ankave"
|
||||
|
||||
#. name for aal
|
||||
msgid "Afade"
|
||||
@ -107,11 +107,11 @@ msgstr "szolong"
|
||||
|
||||
#. name for aax
|
||||
msgid "Mandobo Atas"
|
||||
msgstr ""
|
||||
msgstr "Mandobo Atas"
|
||||
|
||||
#. name for aaz
|
||||
msgid "Amarasi"
|
||||
msgstr ""
|
||||
msgstr "Amarasi"
|
||||
|
||||
#. name for aba
|
||||
msgid "Abé"
|
||||
@ -119,7 +119,7 @@ msgstr "abé"
|
||||
|
||||
#. name for abb
|
||||
msgid "Bankon"
|
||||
msgstr ""
|
||||
msgstr "Bankon"
|
||||
|
||||
#. name for abc
|
||||
msgid "Ayta; Ambala"
|
||||
@ -127,7 +127,7 @@ msgstr ""
|
||||
|
||||
#. name for abd
|
||||
msgid "Manide"
|
||||
msgstr ""
|
||||
msgstr "Manide"
|
||||
|
||||
#. name for abe
|
||||
msgid "Abnaki; Western"
|
||||
@ -135,11 +135,11 @@ msgstr "abnaki; nyugati"
|
||||
|
||||
#. name for abf
|
||||
msgid "Abai Sungai"
|
||||
msgstr ""
|
||||
msgstr "Abai Sungai"
|
||||
|
||||
#. name for abg
|
||||
msgid "Abaga"
|
||||
msgstr ""
|
||||
msgstr "Abaga"
|
||||
|
||||
#. name for abh
|
||||
msgid "Arabic; Tajiki"
|
||||
@ -147,7 +147,7 @@ msgstr "arab; tadzsik"
|
||||
|
||||
#. name for abi
|
||||
msgid "Abidji"
|
||||
msgstr ""
|
||||
msgstr "Abidji"
|
||||
|
||||
#. name for abj
|
||||
msgid "Aka-Bea"
|
||||
@ -159,19 +159,19 @@ msgstr "abház"
|
||||
|
||||
#. name for abl
|
||||
msgid "Lampung Nyo"
|
||||
msgstr ""
|
||||
msgstr "Lampung Nyo"
|
||||
|
||||
#. name for abm
|
||||
msgid "Abanyom"
|
||||
msgstr ""
|
||||
msgstr "Abanyom"
|
||||
|
||||
#. name for abn
|
||||
msgid "Abua"
|
||||
msgstr ""
|
||||
msgstr "Abua"
|
||||
|
||||
#. name for abo
|
||||
msgid "Abon"
|
||||
msgstr ""
|
||||
msgstr "Abon"
|
||||
|
||||
#. name for abp
|
||||
msgid "Ayta; Abellen"
|
||||
@ -179,11 +179,11 @@ msgstr ""
|
||||
|
||||
#. name for abq
|
||||
msgid "Abaza"
|
||||
msgstr ""
|
||||
msgstr "Abaza"
|
||||
|
||||
#. name for abr
|
||||
msgid "Abron"
|
||||
msgstr ""
|
||||
msgstr "Abron"
|
||||
|
||||
#. name for abs
|
||||
msgid "Malay; Ambonese"
|
||||
@ -191,11 +191,11 @@ msgstr "maláj; amboni"
|
||||
|
||||
#. name for abt
|
||||
msgid "Ambulas"
|
||||
msgstr ""
|
||||
msgstr "Ambulas"
|
||||
|
||||
#. name for abu
|
||||
msgid "Abure"
|
||||
msgstr ""
|
||||
msgstr "Abure"
|
||||
|
||||
#. name for abv
|
||||
msgid "Arabic; Baharna"
|
||||
@ -203,31 +203,31 @@ msgstr "arab; Baharna"
|
||||
|
||||
#. name for abw
|
||||
msgid "Pal"
|
||||
msgstr ""
|
||||
msgstr "Pal"
|
||||
|
||||
#. name for abx
|
||||
msgid "Inabaknon"
|
||||
msgstr ""
|
||||
msgstr "Inabaknon"
|
||||
|
||||
#. name for aby
|
||||
msgid "Aneme Wake"
|
||||
msgstr ""
|
||||
msgstr "Aneme Wake"
|
||||
|
||||
#. name for abz
|
||||
msgid "Abui"
|
||||
msgstr ""
|
||||
msgstr "Abui"
|
||||
|
||||
#. name for aca
|
||||
msgid "Achagua"
|
||||
msgstr ""
|
||||
msgstr "Achagua"
|
||||
|
||||
#. name for acb
|
||||
msgid "Áncá"
|
||||
msgstr ""
|
||||
msgstr "Áncá"
|
||||
|
||||
#. name for acd
|
||||
msgid "Gikyode"
|
||||
msgstr ""
|
||||
msgstr "Gikyode"
|
||||
|
||||
# src/trans.h:220
|
||||
#. name for ace
|
||||
@ -244,15 +244,15 @@ msgstr "acoli"
|
||||
|
||||
#. name for aci
|
||||
msgid "Aka-Cari"
|
||||
msgstr ""
|
||||
msgstr "Aka-Cari"
|
||||
|
||||
#. name for ack
|
||||
msgid "Aka-Kora"
|
||||
msgstr ""
|
||||
msgstr "Aka-Kora"
|
||||
|
||||
#. name for acl
|
||||
msgid "Akar-Bale"
|
||||
msgstr ""
|
||||
msgstr "Akar-Bale"
|
||||
|
||||
#. name for acm
|
||||
msgid "Arabic; Mesopotamian"
|
||||
@ -264,7 +264,7 @@ msgstr ""
|
||||
|
||||
#. name for acp
|
||||
msgid "Acipa; Eastern"
|
||||
msgstr ""
|
||||
msgstr "Acipa; Keleti"
|
||||
|
||||
#. name for acq
|
||||
msgid "Arabic; Ta'izzi-Adeni"
|
||||
@ -272,7 +272,7 @@ msgstr "arabic; ta'izzi-adeni"
|
||||
|
||||
#. name for acr
|
||||
msgid "Achi"
|
||||
msgstr ""
|
||||
msgstr "Achi"
|
||||
|
||||
#. name for acs
|
||||
msgid "Acroá"
|
||||
|
@ -4,7 +4,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = u'calibre'
|
||||
numeric_version = (0, 8, 70)
|
||||
numeric_version = (0, 9, 0)
|
||||
__version__ = u'.'.join(map(unicode, numeric_version))
|
||||
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
|
||||
|
@ -230,7 +230,7 @@ class ANDROID(USBMS):
|
||||
'THINKPAD_TABLET', 'SGH-T989', 'YP-G70', 'STORAGE_DEVICE',
|
||||
'ADVANCED', 'SGH-I727', 'USB_FLASH_DRIVER', 'ANDROID',
|
||||
'S5830I_CARD', 'MID7042', 'LINK-CREATE', '7035', 'VIEWPAD_7E',
|
||||
'NOVO7']
|
||||
'NOVO7', 'MB526']
|
||||
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
||||
'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
||||
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',
|
||||
|
@ -288,7 +288,7 @@ class KINDLE2(KINDLE):
|
||||
name = 'Kindle 2/3/4/Touch Device Interface'
|
||||
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']
|
||||
# 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'
|
||||
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]
|
||||
BCD = [0x0100]
|
||||
|
||||
@ -462,7 +462,7 @@ class KINDLE_FIRE(KINDLE2):
|
||||
name = 'Kindle Fire Device Interface'
|
||||
description = _('Communicate with the Kindle Fire')
|
||||
gui_name = 'Fire'
|
||||
FORMATS = list(KINDLE2.FORMATS)
|
||||
FORMATS = ['azw3', 'azw', 'mobi', 'prc', 'azw1', 'tpz', 'azw4', 'pobi', 'pdf', 'txt']
|
||||
|
||||
PRODUCT_ID = [0x0006]
|
||||
BCD = [0x216, 0x100]
|
||||
|
@ -151,9 +151,9 @@ class MTP_DEVICE(MTPDeviceBase):
|
||||
else:
|
||||
self.known_devices = frozenset(self.libmtp.known_devices())
|
||||
|
||||
for x in vars(self.libmtp):
|
||||
if x.startswith('LIBMTP'):
|
||||
setattr(self, x, getattr(self.libmtp, x))
|
||||
for x in vars(self.libmtp):
|
||||
if x.startswith('LIBMTP'):
|
||||
setattr(self, x, getattr(self.libmtp, x))
|
||||
|
||||
@synchronous
|
||||
def shutdown(self):
|
||||
@ -169,6 +169,7 @@ class MTP_DEVICE(MTPDeviceBase):
|
||||
try:
|
||||
self.dev = self.create_device(connected_device)
|
||||
except Exception as e:
|
||||
self.blacklisted_devices.add(connected_device)
|
||||
raise OpenFailed('Failed to open %s: Error: %s'%(
|
||||
connected_device, as_unicode(e)))
|
||||
|
||||
@ -195,6 +196,19 @@ class MTP_DEVICE(MTPDeviceBase):
|
||||
self.current_serial_num = snum
|
||||
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
|
||||
def filesystem_cache(self):
|
||||
if self._filesystem_cache is None:
|
||||
|
@ -84,8 +84,8 @@ PyObject* get_storage_info(IPortableDevice *device) { // {{{
|
||||
PWSTR object_ids[10];
|
||||
GUID guid;
|
||||
ULONGLONG capacity, free_space, capacity_objects, free_objects;
|
||||
ULONG access;
|
||||
LPWSTR storage_desc = NULL;
|
||||
ULONG access, storage_type = WPD_STORAGE_TYPE_UNDEFINED;
|
||||
LPWSTR storage_desc = NULL, st = NULL;
|
||||
|
||||
storage = PyList_New(0);
|
||||
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_ACCESS_CAPABILITY);
|
||||
hr = storage_properties->Add(WPD_STORAGE_FILE_SYSTEM_TYPE);
|
||||
hr = storage_properties->Add(WPD_STORAGE_TYPE);
|
||||
hr = storage_properties->Add(WPD_OBJECT_NAME);
|
||||
Py_END_ALLOW_THREADS;
|
||||
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_FREE_SPACE_IN_BYTES, &free_space);
|
||||
values->GetUnsignedLargeIntegerValue(WPD_STORAGE_FREE_SPACE_IN_OBJECTS, &free_objects);
|
||||
values->GetUnsignedIntegerValue(WPD_STORAGE_TYPE, &storage_type);
|
||||
desc = Py_False;
|
||||
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]));
|
||||
@ -167,6 +169,25 @@ PyObject* get_storage_info(IPortableDevice *device) { // {{{
|
||||
if (desc != NULL) { PyDict_SetItemString(so, "filesystem", desc); Py_DECREF(desc);}
|
||||
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);
|
||||
Py_DECREF(so);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ from future_builtins import zip
|
||||
from itertools import chain
|
||||
|
||||
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.devices.errors import OpenFailed, DeviceError, BlacklistedDevice
|
||||
from calibre.devices.mtp.base import MTPDeviceBase, debug
|
||||
@ -52,10 +52,15 @@ class MTP_DEVICE(MTPDeviceBase):
|
||||
self.start_thread = None
|
||||
self._filesystem_cache = None
|
||||
self.eject_dev_on_next_scan = False
|
||||
self.current_device_data = {}
|
||||
|
||||
def startup(self):
|
||||
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:
|
||||
try:
|
||||
self.wpd.init(__appname__, *(numeric_version[:3]))
|
||||
@ -196,6 +201,12 @@ class MTP_DEVICE(MTPDeviceBase):
|
||||
if not devdata.get('has_storage', False): return False
|
||||
has_rw_storage = False
|
||||
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):
|
||||
has_rw_storage = True
|
||||
break
|
||||
@ -280,6 +291,8 @@ class MTP_DEVICE(MTPDeviceBase):
|
||||
raise BlacklistedDevice(
|
||||
'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']
|
||||
if len(storage) > 1:
|
||||
self._carda_id = storage[1]['id']
|
||||
@ -291,6 +304,11 @@ class MTP_DEVICE(MTPDeviceBase):
|
||||
_('Unknown MTP device'))
|
||||
self.currently_connected_pnp_id = connected_device
|
||||
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
|
||||
def get_basic_device_information(self):
|
||||
|
@ -687,7 +687,7 @@ class PRST1(USBMS):
|
||||
'WHERE _id = ?')
|
||||
t = (collectionId,)
|
||||
cursor.execute(query, t)
|
||||
debug_print('Deleted Collection: ' + collection)
|
||||
debug_print('Deleted Collection: ' + repr(collection))
|
||||
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
|
@ -744,22 +744,6 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
except:
|
||||
self._close_device_socket()
|
||||
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:
|
||||
try:
|
||||
@ -902,10 +886,16 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin):
|
||||
return False
|
||||
|
||||
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
|
||||
|
||||
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')
|
||||
def get_device_information(self, end_session=True):
|
||||
|
@ -14,6 +14,8 @@ import os
|
||||
from calibre.customize.conversion import OutputFormatPlugin, \
|
||||
OptionRecommendation
|
||||
from calibre.ptempfile import TemporaryDirectory
|
||||
from calibre.constants import iswindows
|
||||
from calibre import walk
|
||||
|
||||
UNITS = [
|
||||
'millimeter',
|
||||
@ -148,6 +150,16 @@ class PDFOutput(OutputFormatPlugin):
|
||||
oeb_output = plugin_for_output_format('oeb')
|
||||
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]
|
||||
opf = OPF(opfpath, os.path.dirname(opfpath))
|
||||
|
||||
|
@ -792,19 +792,16 @@ class OPF(object): # {{{
|
||||
remove = list(self.authors_path(self.metadata))
|
||||
for elem in remove:
|
||||
elem.getparent().remove(elem)
|
||||
elems = []
|
||||
for author in val:
|
||||
attrib = {'{%s}role'%self.NAMESPACES['opf']: 'aut'}
|
||||
elem = self.create_metadata_element('creator', attrib=attrib)
|
||||
# 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
|
||||
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())
|
||||
# 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)
|
||||
|
||||
@ -1020,9 +1017,8 @@ class OPF(object): # {{{
|
||||
def fset(self, val):
|
||||
matches = self.bkp_path(self.metadata)
|
||||
if not matches:
|
||||
attrib = {'{%s}role'%self.NAMESPACES['opf']: 'bkp'}
|
||||
matches = [self.create_metadata_element('contributor',
|
||||
attrib=attrib)]
|
||||
matches = [self.create_metadata_element('contributor')]
|
||||
matches[0].set('{%s}role'%self.NAMESPACES['opf'], 'bkp')
|
||||
self.set_text(matches[0], unicode(val))
|
||||
return property(fget=fget, fset=fset)
|
||||
|
||||
@ -1155,7 +1151,7 @@ class OPF(object): # {{{
|
||||
def smart_update(self, mi, replace_metadata=False):
|
||||
for attr in ('title', 'authors', 'author_sort', 'title_sort',
|
||||
'publisher', 'series', 'series_index', 'rating',
|
||||
'isbn', 'tags', 'category', 'comments',
|
||||
'isbn', 'tags', 'category', 'comments', 'book_producer',
|
||||
'pubdate', 'user_categories', 'author_link_map'):
|
||||
val = getattr(mi, attr, None)
|
||||
if val is not None and val != [] and val != (None, None):
|
||||
|
@ -10,6 +10,7 @@ __docformat__ = 'restructuredtext en'
|
||||
import re
|
||||
from collections import namedtuple
|
||||
from functools import partial
|
||||
from xml.sax.saxutils import escape
|
||||
|
||||
from lxml import etree
|
||||
|
||||
@ -289,6 +290,7 @@ class Chunker(object):
|
||||
self.chunk_selector = ('S', aid)
|
||||
|
||||
def chunk_up_text(self, text):
|
||||
text = escape(text)
|
||||
text = text.encode('utf-8')
|
||||
ans = []
|
||||
|
||||
|
@ -17,6 +17,7 @@ from calibre.customize.ui import is_disabled
|
||||
from calibre.devices.bambook.driver import BAMBOOK
|
||||
from calibre.gui2.dialogs.smartdevice import SmartdeviceDialog
|
||||
from calibre.gui2 import info_dialog, question_dialog
|
||||
from calibre.library.server import server_config as content_server_config
|
||||
|
||||
class ShareConnMenu(QMenu): # {{{
|
||||
|
||||
@ -90,7 +91,12 @@ class ShareConnMenu(QMenu): # {{{
|
||||
if running:
|
||||
listen_on = (verify_ipV4_address(tweaks['server_listen_on']) or
|
||||
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)
|
||||
|
||||
def hide_smartdevice_menus(self):
|
||||
|
@ -12,7 +12,8 @@ import weakref
|
||||
from PyQt4.Qt import (QWidget, QListWidgetItem, Qt, QToolButton, QLabel,
|
||||
QTabWidget, QGridLayout, QListWidget, QIcon, QLineEdit, QVBoxLayout,
|
||||
QPushButton, QGroupBox, QScrollArea, QHBoxLayout, QComboBox,
|
||||
pyqtSignal, QSizePolicy, QDialog, QDialogButtonBox)
|
||||
pyqtSignal, QSizePolicy, QDialog, QDialogButtonBox, QPlainTextEdit,
|
||||
QApplication)
|
||||
|
||||
from calibre.ebooks import BOOK_EXTENSIONS
|
||||
from calibre.gui2 import error_dialog
|
||||
@ -372,15 +373,19 @@ class MTPConfig(QTabWidget):
|
||||
_('&Ignore the %s in calibre')%device.current_friendly_name,
|
||||
self.base)
|
||||
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(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.template, 3, 1, 1, 1)
|
||||
l.setRowStretch(4, 10)
|
||||
l.addWidget(r, 5, 0, 1, 2)
|
||||
l.setRowStretch(5, 100)
|
||||
l.addWidget(self.show_debug_button, 4, 1, 1, 1)
|
||||
l.setRowStretch(5, 10)
|
||||
l.addWidget(r, 6, 0, 1, 2)
|
||||
l.setRowStretch(6, 100)
|
||||
|
||||
self.igntab = IgnoredDevices(self.device.prefs['history'],
|
||||
self.device.prefs['blacklist'])
|
||||
@ -388,6 +393,26 @@ class MTPConfig(QTabWidget):
|
||||
|
||||
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):
|
||||
self.igntab.ignore_device(self.device.current_serial_num)
|
||||
self.base.b.setEnabled(False)
|
||||
|
@ -10,7 +10,7 @@ import copy
|
||||
from PyQt4.Qt import Qt, QComboBox, QListWidgetItem
|
||||
|
||||
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.dialogs.template_line_editor import TemplateLineEditor
|
||||
from calibre.gui2.preferences import ConfigWidgetBase, test_widget
|
||||
@ -254,6 +254,15 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
show=True)
|
||||
self.new_device.setCurrentIndex(0)
|
||||
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()
|
||||
|
||||
def new_format_changed(self, txt):
|
||||
|
@ -97,7 +97,7 @@ class EbookscomStore(BasicStoreConfig, StorePlugin):
|
||||
with closing(br.open(url + id, timeout=timeout)) as nf:
|
||||
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:
|
||||
price = price_l[0]
|
||||
search_result.price = price.strip()
|
||||
|
@ -15,7 +15,8 @@ from binascii import hexlify, unhexlify
|
||||
import cherrypy
|
||||
|
||||
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.utils.icu import sort_key
|
||||
from calibre.library.server import custom_fields_to_display
|
||||
@ -118,12 +119,16 @@ class AjaxServer(object):
|
||||
|
||||
|
||||
# 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)
|
||||
try:
|
||||
mi.rating = mi.rating/2.
|
||||
except:
|
||||
mi.rating = 0.0
|
||||
|
||||
if not device_compatible:
|
||||
try:
|
||||
mi.rating = mi.rating/2.
|
||||
except:
|
||||
mi.rating = 0.0
|
||||
|
||||
data = self.ajax_json_codec.encode_book_metadata(mi)
|
||||
for x in ('publication_type', 'size', 'db_id', 'lpath', 'mime',
|
||||
'rights', 'book_producer'):
|
||||
@ -131,57 +136,68 @@ class AjaxServer(object):
|
||||
|
||||
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)
|
||||
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:
|
||||
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
|
||||
if not device_compatible:
|
||||
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:
|
||||
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
|
||||
|
||||
@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.
|
||||
|
||||
@ -197,7 +213,8 @@ class AjaxServer(object):
|
||||
else:
|
||||
book_id = int(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:
|
||||
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 ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: calibre 0.8.70\n"
|
||||
"POT-Creation-Date: 2012-09-21 13:10+IST\n"
|
||||
"PO-Revision-Date: 2012-09-21 13:10+IST\n"
|
||||
"Project-Id-Version: calibre 0.9.0\n"
|
||||
"POT-Creation-Date: 2012-09-28 10:04+IST\n"
|
||||
"PO-Revision-Date: 2012-09-28 10:04+IST\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: LANGUAGE\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/driver.py:656
|
||||
#: /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/windows/driver.py:218
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/unix/driver.py:223
|
||||
#: /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:71
|
||||
#: /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:474
|
||||
#: /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:1299
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1184
|
||||
#: /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/pdf.py:88
|
||||
#: /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/gui2/actions/preferences.py:54
|
||||
#: /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"
|
||||
msgstr ""
|
||||
|
||||
@ -586,7 +586,7 @@ msgid "Control how calibre downloads ebook metadata from the net"
|
||||
msgstr ""
|
||||
|
||||
#: /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"
|
||||
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:324
|
||||
#: /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:1090
|
||||
#: /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:1080
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:277
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:279
|
||||
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:515
|
||||
#: /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:1112
|
||||
#: /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:1102
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:301
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:332
|
||||
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/kobo/driver.py:468
|
||||
#: /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:1146
|
||||
#: /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:1136
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:366
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:371
|
||||
msgid "Removing books from device metadata listing..."
|
||||
@ -1578,7 +1578,7 @@ msgid "Communicate with MTP devices"
|
||||
msgstr ""
|
||||
|
||||
#: /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
|
||||
msgid "Get device information..."
|
||||
msgstr ""
|
||||
@ -1644,12 +1644,16 @@ msgstr ""
|
||||
msgid "All books removed"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/unix/driver.py:194
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:291
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/unix/driver.py:195
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/mtp/windows/driver.py:304
|
||||
msgid "Unknown MTP device"
|
||||
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"
|
||||
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)."
|
||||
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
|
||||
msgid "Too many connection attempts from %s"
|
||||
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
|
||||
msgid "Invalid port in options: %s"
|
||||
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
|
||||
msgid "Failed to connect to port %d. Try a different value."
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
@ -2491,47 +2495,47 @@ msgstr ""
|
||||
msgid "Use the new PDF conversion engine."
|
||||
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
|
||||
msgid "The unit of measure. Default is inch. Choices are %s Note: This does not override the unit for margins!"
|
||||
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
|
||||
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 ""
|
||||
|
||||
#: /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."
|
||||
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
|
||||
msgid "The orientation of the page. Default is portrait. Choices are %s"
|
||||
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."
|
||||
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"
|
||||
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"
|
||||
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:103
|
||||
#: /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:105
|
||||
msgid "The font family used to render monospaced fonts"
|
||||
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"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
@ -3485,7 +3489,7 @@ msgid ""
|
||||
"Fetch a cover image/social metadata for the book identified by ISBN from LibraryThing.com\n"
|
||||
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/gui2/metadata/single.py:958
|
||||
#: /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?"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:62
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:89
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:63
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:90
|
||||
msgid "Start Content Server"
|
||||
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"
|
||||
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"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:107
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:126
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:113
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/actions/device.py:132
|
||||
msgid "Email to"
|
||||
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"
|
||||
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)"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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
|
||||
msgid "Stopping"
|
||||
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
|
||||
msgid "Stopping server, this could take upto a minute, please wait..."
|
||||
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"
|
||||
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?"
|
||||
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."
|
||||
msgstr ""
|
||||
|
||||
@ -7854,7 +7863,7 @@ msgid "Cannot configure the device while there are running device jobs."
|
||||
msgstr ""
|
||||
|
||||
#: /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
|
||||
msgid "Configure %s"
|
||||
msgstr ""
|
||||
@ -7964,7 +7973,7 @@ msgid "You have enabled the <b>{0}</b> formats for your {1}. The {1} may not sup
|
||||
msgstr ""
|
||||
|
||||
#: /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/preferences/plugboard.py:279
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:70
|
||||
@ -7972,7 +7981,7 @@ msgid "Invalid template"
|
||||
msgstr ""
|
||||
|
||||
#: /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/preferences/plugboard.py:280
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:71
|
||||
@ -8000,100 +8009,112 @@ msgstr ""
|
||||
msgid "Save &template:"
|
||||
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"
|
||||
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"
|
||||
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 ""
|
||||
"<b>Save &template</b> to control the filename and\n"
|
||||
" location of files sent to the device:"
|
||||
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"
|
||||
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/library/delegates.py:443
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:48
|
||||
msgid "Edit template"
|
||||
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 ""
|
||||
"A <b>list of &folders</b> on the device to\n"
|
||||
" which to send ebooks. The first one that exists will be used:"
|
||||
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:225
|
||||
#: /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:226
|
||||
msgid "Browse for a folder on the device"
|
||||
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 ""
|
||||
"Select the devices to be <b>ignored</b>. calibre <b>will not</b>\n"
|
||||
" connect to devices with a checkmark next to their names."
|
||||
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
|
||||
msgid "Send the %s format to the folder:"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
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 ""
|
||||
"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"
|
||||
" the folders specified above."
|
||||
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"
|
||||
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
|
||||
msgid "The <b>%s</b> device has no serial number, it cannot be configured"
|
||||
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."
|
||||
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."
|
||||
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
|
||||
msgid "Choose the formats to send to the %s"
|
||||
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
|
||||
msgid "&Ignore the %s in calibre"
|
||||
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
|
||||
msgid "The %s will be ignored in calibre"
|
||||
msgstr ""
|
||||
@ -8818,13 +8839,6 @@ msgstr ""
|
||||
msgid "Copied"
|
||||
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:251
|
||||
#: /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."
|
||||
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:626
|
||||
msgid "All books"
|
||||
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:625
|
||||
#: /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