mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge
This commit is contained in:
commit
533e75ed65
120
Changelog.yaml
120
Changelog.yaml
@ -19,6 +19,126 @@
|
|||||||
# new recipes:
|
# new recipes:
|
||||||
# - title:
|
# - title:
|
||||||
|
|
||||||
|
- version: 0.8.26
|
||||||
|
date: 2011-11-12
|
||||||
|
|
||||||
|
new features:
|
||||||
|
- title: "Tweak to control sorting of date type columns. You can choose to have them sorted only by displayed fields"
|
||||||
|
|
||||||
|
- title: "Driver for the Trekstor 3.0"
|
||||||
|
|
||||||
|
- title: "Performance improvements when evaluating templates, and in particular general program mode templates"
|
||||||
|
|
||||||
|
bug fixes:
|
||||||
|
- title: "ODT Input: When converting to EPUB improve handling of large images placed inside small frames, to prevent them from obscuring text."
|
||||||
|
tickets: [860272,884759]
|
||||||
|
|
||||||
|
- title: "EPUB Input: Automatically strip entries of type application/text from the spine. Apparently there are EPUB production tools out there that create them."
|
||||||
|
tickets: [884792]
|
||||||
|
|
||||||
|
- title: "Keep the startup splash screen visible until the GUI has fully completed initializing."
|
||||||
|
tickets: [885827]
|
||||||
|
|
||||||
|
- title: "ODT Input: Fix handling of span tags containing only whitespace."
|
||||||
|
tickets: [887311]
|
||||||
|
|
||||||
|
- title: "On windows when changing title or author via the main book list, handle the case of one of the books files being open in another program more gracefully."
|
||||||
|
tickets: [880585]
|
||||||
|
|
||||||
|
- title: "When adding a format to an existing book record, ensure that no changes are made to the database until after the file operations have succeeded."
|
||||||
|
|
||||||
|
- title: "Fix bug that prevented configuring which fields to download metadata for when adding books by ISBN"
|
||||||
|
tickets: [856076]
|
||||||
|
|
||||||
|
- title: "Fix Japanese characters not being crrectly displayed on index pages in news downloads for the SONY T1"
|
||||||
|
tickets: [888029]
|
||||||
|
|
||||||
|
- title: "Get Books: Fix booleans in search expressions not working in non-English calibre versions"
|
||||||
|
tickets: [887554]
|
||||||
|
|
||||||
|
- title: "Fix a bug in the support for hours/minutes/seconds in datetime format strings"
|
||||||
|
tickets: [887412]
|
||||||
|
|
||||||
|
- title: "Treat an author_sort value of 'Unknown' the same way as unknown authors are treated in template processing"
|
||||||
|
|
||||||
|
- title: "Detect SD card in Kobo Vox"
|
||||||
|
|
||||||
|
- title: "Amazon metadata download: Workaround for change in Amazon website causing some books to have incorrect ratings downloaded"
|
||||||
|
|
||||||
|
improved recipes:
|
||||||
|
- Metro NL
|
||||||
|
- The Independent
|
||||||
|
- Frankfurter Rundschau
|
||||||
|
- L'Espresso
|
||||||
|
- Il Giornale
|
||||||
|
- Berlingske.dk
|
||||||
|
- Suedeutsche Zeitung
|
||||||
|
|
||||||
|
new recipes:
|
||||||
|
- title: Techtarget
|
||||||
|
author: Julio Map
|
||||||
|
|
||||||
|
- version: 0.8.25
|
||||||
|
date: 2011-11-06
|
||||||
|
|
||||||
|
new features:
|
||||||
|
- title: "Drivers for the LG Optimus 2X, HTC Incredible S, Samsung Stratosphere and the Kobo Vox"
|
||||||
|
tickets: [886558, 885058, 884762, 884039]
|
||||||
|
|
||||||
|
- title: "Get books: Add ebookpoint.pl store"
|
||||||
|
|
||||||
|
- title: "Support hour/minute/seconds in datetime format strings in the template language and in tweaks"
|
||||||
|
|
||||||
|
bug fixes:
|
||||||
|
- title: "Fix Book detils preferences showing custom columns even after they have been deleted"
|
||||||
|
tickets: [884799]
|
||||||
|
|
||||||
|
- title: "Replace use of insecure tempfile in the bundled rtf2xml library."
|
||||||
|
tickets: [885245]
|
||||||
|
|
||||||
|
- title: "Remove the suid mount helper used on linux and bsd, as it proved impossible to make it secure."
|
||||||
|
description: "This means that if you are on BSD or an older linux distribution, without support for udisks, device detection will no longer work in calibre. You will have to either mount the devices by hand before starting calibre, or stick with version 0.8.24 (the vulnerability in the mount helper is a privilege escalation, which is relatively harmless on the vast majority of single user systems)."
|
||||||
|
tickets: [885027]
|
||||||
|
|
||||||
|
- title: "Do not error out if there is an invalid regex for title sort set in tweaks"
|
||||||
|
|
||||||
|
- title: "Content server: Fix another place where --url-prefix was forgotten"
|
||||||
|
tickets: [885332]
|
||||||
|
|
||||||
|
- title: "HTML Input: Limit memory consumption when converting HTML files that link to large binary files."
|
||||||
|
tickets: [884821]
|
||||||
|
|
||||||
|
- title: "T1 driver: Workaround for T1 showing error messages when opening some news downloads on the device"
|
||||||
|
|
||||||
|
- title: "Kobo driver: Fix longstanding bug that would prevent re-adding a epub that has been previously deleted from the Kobo using calibre"
|
||||||
|
|
||||||
|
- title: "Fix partial cover search not resuming after pressing back in the metadata download dialog"
|
||||||
|
tickets: [875196]
|
||||||
|
|
||||||
|
- title: "T1 driver: Fix auto refresh covers option"
|
||||||
|
|
||||||
|
- title: "Content server: Do not show tracebacks in HTML output when not running in develop mode"
|
||||||
|
|
||||||
|
- title: "Textile output; Fix out of memory issue when dealing with large margins."
|
||||||
|
|
||||||
|
improved recipes:
|
||||||
|
- The Independent
|
||||||
|
- Die Zeit subscription version
|
||||||
|
- NIN online
|
||||||
|
- Science News
|
||||||
|
- Updated Daily Mirror
|
||||||
|
- Science AAAS
|
||||||
|
|
||||||
|
new recipes:
|
||||||
|
- title: b365 Realitatea and Catavencii
|
||||||
|
author: Silviu Cotoara
|
||||||
|
|
||||||
|
- title: Various Greek news sources
|
||||||
|
author: Stelios
|
||||||
|
|
||||||
|
- title: Real world economics blog
|
||||||
|
author: Julio Map
|
||||||
|
|
||||||
- version: 0.8.24
|
- version: 0.8.24
|
||||||
date: 2011-10-27
|
date: 2011-10-27
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
@ -18,11 +17,17 @@ class Berlingske_dk(BasicNewsRecipe):
|
|||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
remove_empty_feeds = True
|
remove_empty_feeds = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
|
remove_javascript = True
|
||||||
publication_type = 'newspaper'
|
publication_type = 'newspaper'
|
||||||
encoding = 'utf8'
|
encoding = 'utf8'
|
||||||
language = 'da'
|
language = 'da'
|
||||||
masthead_url = 'http://www.berlingske.dk/sites/all/themes/bm/img/layout/masthead_bg.gif'
|
auto_cleanup = True
|
||||||
extra_css = ' body{font-family: Arial,Helvetica,sans-serif } h1,.manchet,.byline{font-family: Cambria,Georgia,Times,"Times New Roman",serif } '
|
extra_css = '''
|
||||||
|
.manchet {color:#888888;}
|
||||||
|
.dateline {font-size: x-small; color:#444444;}
|
||||||
|
.manchet,.dateline { font-family: Cambria,Georgia,Times,"Times New Roman",serif }
|
||||||
|
.body {font-family: Arial,Helvetica,sans-serif }
|
||||||
|
'''
|
||||||
|
|
||||||
conversion_options = {
|
conversion_options = {
|
||||||
'comment' : description
|
'comment' : description
|
||||||
@ -32,18 +37,14 @@ class Berlingske_dk(BasicNewsRecipe):
|
|||||||
}
|
}
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
(u'Breaking news' , u'http://www.berlingske.dk/breaking/rss' )
|
(u'Breaking news' , u'http://www.b.dk/breaking/rss' )
|
||||||
,(u'Seneste nyt' , u'http://www.berlingske.dk/seneste/rss' )
|
,(u'Seneste nyt' , u'http://www.b.dk/seneste/rss' )
|
||||||
,(u'Topnyheder' , u'http://www.berlingske.dk/top/rss' )
|
,(u'Topnyheder' , u'http://www.b.dk/top/rss' )
|
||||||
,(u'Danmark' , u'http://www.berlingske.dk/danmark/seneste/rss' )
|
,(u'Danmark' , u'http://www.b.dk/danmark/seneste/rss' )
|
||||||
,(u'Verden' , u'http://www.berlingske.dk/verden/seneste/rss' )
|
,(u'Verden' , u'http://www.b.dk/verden/seneste/rss' )
|
||||||
,(u'Klima' , u'http://www.berlingske.dk/klima/seneste/rss' )
|
,(u'Klima' , u'http://www.b.dk/klima/seneste/rss' )
|
||||||
,(u'Debat' , u'http://www.berlingske.dk/debat/seneste/rss' )
|
,(u'Debat' , u'http://www.b.dk/debat/seneste/rss' )
|
||||||
,(u'Koebenhavn' , u'http://www.berlingske.dk/koebenhavn/seneste/rss')
|
,(u'Koebenhavn' , u'http://www.b.dk/koebenhavn/seneste/rss')
|
||||||
,(u'Politik' , u'http://www.berlingske.dk/politik/seneste/rss' )
|
,(u'Politik' , u'http://www.b.dk/politik/seneste/rss' )
|
||||||
,(u'Kultur' , u'http://www.berlingske.dk/kultur/seneste/rss' )
|
,(u'Kultur' , u'http://www.b.dk/kultur/seneste/rss' )
|
||||||
]
|
]
|
||||||
|
|
||||||
keep_only_tags = [dict(attrs={'class':['first','pt-article']})]
|
|
||||||
remove_tags = [dict(name=['object','link','base','iframe','embed'])]
|
|
||||||
|
|
||||||
|
@ -55,12 +55,17 @@ class Economist(BasicNewsRecipe):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def get_cover_url(self):
|
def get_cover_url(self):
|
||||||
br = self.browser
|
soup = self.index_to_soup('http://www.economist.com/printedition/covers')
|
||||||
br.open(self.INDEX)
|
div = soup.find('div', attrs={'class':lambda x: x and
|
||||||
issue = br.geturl().split('/')[4]
|
'print-cover-links' in x})
|
||||||
self.log('Fetching cover for issue: %s'%issue)
|
a = div.find('a', href=True)
|
||||||
cover_url = "http://media.economist.com/sites/default/files/imagecache/print-cover-full/print-covers/%s_CNA400.jpg" %(issue.translate(None,'-'))
|
url = a.get('href')
|
||||||
return cover_url
|
if url.startswith('/'):
|
||||||
|
url = 'http://www.economist.com' + url
|
||||||
|
soup = self.index_to_soup(url)
|
||||||
|
div = soup.find('div', attrs={'class':'cover-content'})
|
||||||
|
img = div.find('img', src=True)
|
||||||
|
return img.get('src')
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
return self.economist_parse_index()
|
return self.economist_parse_index()
|
||||||
|
@ -39,13 +39,17 @@ class Economist(BasicNewsRecipe):
|
|||||||
delay = 1
|
delay = 1
|
||||||
|
|
||||||
def get_cover_url(self):
|
def get_cover_url(self):
|
||||||
br = self.browser
|
soup = self.index_to_soup('http://www.economist.com/printedition/covers')
|
||||||
br.open(self.INDEX)
|
div = soup.find('div', attrs={'class':lambda x: x and
|
||||||
issue = br.geturl().split('/')[4]
|
'print-cover-links' in x})
|
||||||
self.log('Fetching cover for issue: %s'%issue)
|
a = div.find('a', href=True)
|
||||||
cover_url = "http://media.economist.com/sites/default/files/imagecache/print-cover-full/print-covers/%s_CNA400.jpg" %(issue.translate(None,'-'))
|
url = a.get('href')
|
||||||
return cover_url
|
if url.startswith('/'):
|
||||||
|
url = 'http://www.economist.com' + url
|
||||||
|
soup = self.index_to_soup(url)
|
||||||
|
div = soup.find('div', attrs={'class':'cover-content'})
|
||||||
|
img = div.find('img', src=True)
|
||||||
|
return img.get('src')
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
try:
|
try:
|
||||||
|
@ -1,35 +1,61 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010-2011, Christian Schmitt'
|
||||||
|
|
||||||
|
'''
|
||||||
|
fr-online.de
|
||||||
|
'''
|
||||||
|
|
||||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
class AdvancedUserRecipe(BasicNewsRecipe):
|
|
||||||
|
|
||||||
title = u'Frankfurter Rundschau'
|
class FROnlineRecipe(BasicNewsRecipe):
|
||||||
__author__ = 'schuster'
|
title = 'Frankfurter Rundschau'
|
||||||
oldest_article = 1
|
__author__ = 'maccs'
|
||||||
max_articles_per_feed = 100
|
description = 'Nachrichten aus D und aller Welt'
|
||||||
no_stylesheets = True
|
encoding = 'utf-8'
|
||||||
use_embedded_content = False
|
masthead_url = 'http://www.fr-online.de/image/view/-/1474018/data/823552/-/logo.png'
|
||||||
language = 'de'
|
publisher = 'Druck- und Verlagshaus Frankfurt am Main GmbH'
|
||||||
remove_javascript = True
|
category = 'news, germany, world'
|
||||||
cover_url = 'http://www.fr-online.de/image/view/-/1474018/data/823538/-/logo.png'
|
language = 'de'
|
||||||
extra_css = '''
|
publication_type = 'newspaper'
|
||||||
h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;}
|
use_embedded_content = False
|
||||||
h4{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;}
|
remove_javascript = True
|
||||||
img {min-width:300px; max-width:600px; min-height:300px; max-height:800px}
|
no_stylesheets = True
|
||||||
p{font-family:Arial,Helvetica,sans-serif;font-size:small;}
|
oldest_article = 1 # Increase this number if you're interested in older articles
|
||||||
body{font-family:Helvetica,Arial,sans-serif;font-size:small;}
|
max_articles_per_feed = 50 # Seems a reasonable number to me
|
||||||
'''
|
extra_css = '''
|
||||||
|
body { font-family: "arial", "verdana", "geneva", sans-serif; font-size: 12px; margin: 0px; background-color: #ffffff;}
|
||||||
feeds = [(u'Startseite', u'http://www.fr-online.de/home/-/1472778/1472778/-/view/asFeed/-/index.xml'),
|
.imgSubline{background-color: #f4f4f4; font-size: 0.8em;}
|
||||||
(u'Politik', u'http://www.fr-online.de/politik/-/1472596/1472596/-/view/asFeed/-/index.xml'),
|
.p--heading-1 {font-weight: bold;}
|
||||||
(u'Meinungen', u'http://www.fr-online.de/politik/meinung/-/1472602/1472602/-/view/asFeed/-/index.xml'),
|
.calibre_navbar {font-size: 0.8em; font-family: "arial", "verdana", "geneva", sans-serif;}
|
||||||
(u'Wirtschaft', u'http://www.fr-online.de/wirtschaft/-/1472780/1472780/-/view/asFeed/-/index.xml'),
|
'''
|
||||||
(u'Sport', u'http://www.fr-online.de/sport/-/1472784/1472784/-/view/asFeed/-/index.xml'),
|
keep_only_tags = [{'class':'ArticleHeadlineH1'}, {'class':'article_text'}]
|
||||||
(u'Kultur', u'http://www.fr-online.de/kultur/-/1472786/1472786/-/view/asFeed/-/index.xml'),
|
cover_url = 'http://www.fr-online.de/image/view/-/1474018/data/823552/-/logo.png'
|
||||||
(u'Panorama', u'http://www.fr-online.de/panorama/-/1472782/1472782/-/view/asFeed/-/index.xml'),
|
cover_margins = (100, 150, '#ffffff')
|
||||||
(u'Digital', u'http://www.fr-online.de/digital/-/1472406/1472406/-/view/asFeed/-/index.xml'),
|
|
||||||
(u'Wissenschaft', u'http://www.fr-online.de/wissenschaft/-/1472788/1472788/-/view/asFeed/-/index.xml')
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def print_version(self, url):
|
feeds = []
|
||||||
return url.replace('index.html', 'view/printVersion/-/index.html')
|
feeds.append(('Startseite', u'http://www.fr-online.de/home/-/1472778/1472778/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Politik', u'http://www.fr-online.de/politik/-/1472596/1472596/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Meinung', u'http://www.fr-online.de/politik/meinung/-/1472602/1472602/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Wirtschaft', u'http://www.fr-online.de/wirtschaft/-/1472780/1472780/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Sport', u'http://www.fr-online.de/sport/-/1472784/1472784/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Eintracht Frankfurt', u'http://www.fr-online.de/sport/eintracht-frankfurt/-/1473446/1473446/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Kultur und Medien', u'http://www.fr-online.de/kultur/-/1472786/1472786/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Panorama', u'http://www.fr-online.de/panorama/-/1472782/1472782/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Frankfurt', u'http://www.fr-online.de/frankfurt/-/1472798/1472798/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Rhein-Main', u'http://www.fr-online.de/rhein-main/-/1472796/1472796/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Hanau', u'http://www.fr-online.de/rhein-main/hanau/-/1472866/1472866/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Darmstadt', u'http://www.fr-online.de/rhein-main/darmstadt/-/1472858/1472858/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Wiesbaden', u'http://www.fr-online.de/rhein-main/wiesbaden/-/1472860/1472860/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Offenbach', u'http://www.fr-online.de/rhein-main/offenbach/-/1472856/1472856/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Bad Homburg', u'http://www.fr-online.de/rhein-main/bad-homburg/-/1472864/1472864/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Digital', u'http://www.fr-online.de/digital/-/1472406/1472406/-/view/asFeed/-/index.xml'))
|
||||||
|
feeds.append(('Wissenschaft', u'http://www.fr-online.de/wissenschaft/-/1472788/1472788/-/view/asFeed/-/index.xml'))
|
||||||
|
|
||||||
|
|
||||||
|
def print_version(self, url):
|
||||||
|
return url.replace('index.html', 'view/printVersion/-/index.html')
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__author__ = 'Gabriele Marini, based on Darko Miletic'
|
__author__ = 'Gambarini, based on Darko Miletic'
|
||||||
__copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009-2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
description = 'Italian daily newspaper - 19-04-2010'
|
description = 'Italian daily newspaper - 09-11-2011'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
http://www.ilgiornale.it/
|
http://www.ilgiornale.it/
|
||||||
@ -11,7 +11,7 @@ from calibre.ebooks.BeautifulSoup import BeautifulSoup
|
|||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class IlGiornale(BasicNewsRecipe):
|
class IlGiornale(BasicNewsRecipe):
|
||||||
__author__ = 'Marini Gabriele'
|
__author__ = 'GAMBARINI'
|
||||||
description = 'Italian daily newspaper'
|
description = 'Italian daily newspaper'
|
||||||
|
|
||||||
cover_url = 'http://www.ilgiornale.it/img_v1/logo.gif'
|
cover_url = 'http://www.ilgiornale.it/img_v1/logo.gif'
|
||||||
@ -23,9 +23,8 @@ class IlGiornale(BasicNewsRecipe):
|
|||||||
timefmt = '[%a, %d %b, %Y]'
|
timefmt = '[%a, %d %b, %Y]'
|
||||||
|
|
||||||
oldest_article = 7
|
oldest_article = 7
|
||||||
max_articles_per_feed = 50
|
max_articles_per_feed = 100
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
recursion = 100
|
|
||||||
|
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
conversion_options = {'linearize_tables':True}
|
conversion_options = {'linearize_tables':True}
|
||||||
@ -38,11 +37,11 @@ class IlGiornale(BasicNewsRecipe):
|
|||||||
def print_version(self, url):
|
def print_version(self, url):
|
||||||
raw = self.browser.open(url).read()
|
raw = self.browser.open(url).read()
|
||||||
soup = BeautifulSoup(raw.decode('utf8', 'replace'))
|
soup = BeautifulSoup(raw.decode('utf8', 'replace'))
|
||||||
all_print_tags = soup.find('div', {'style':'float:left; width:35%;'})
|
all_print_tags = soup.find('div', {'id':'print_article'})
|
||||||
print_link = all_print_tags.contents[1]
|
print_link = all_print_tags.a
|
||||||
if all_print_tags is None:
|
if print_link is None:
|
||||||
return url
|
return url
|
||||||
return print_link['href']
|
return 'http://www.ilgiornale.it' + print_link['href']
|
||||||
|
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
|
@ -1,13 +1,379 @@
|
|||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
# adapted from old recipe by Darko Miletic <darko.miletic at gmail.com>
|
||||||
|
|
||||||
class AdvancedUserRecipe1320474488(BasicNewsRecipe):
|
import re
|
||||||
|
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||||
|
from calibre.ebooks.BeautifulSoup import Tag, NavigableString
|
||||||
|
|
||||||
|
|
||||||
|
class TheIndependentNew(BasicNewsRecipe):
|
||||||
|
|
||||||
|
# flag to enable/disable article graphics on business pages/some others
|
||||||
|
# eg http://www.independent.co.uk/news/world/europe/berlusconi-departure-fails-to-calm-the-markets-6259682.html
|
||||||
|
# -max dimensions can be altered using the .pictureContainer img selector in the css
|
||||||
|
_FETCH_ARTICLE_GRAPHICS = True
|
||||||
|
|
||||||
|
#Flag to enable/disable image fetching (not business)
|
||||||
|
_FETCH_IMAGES = True
|
||||||
|
|
||||||
|
|
||||||
|
#used for converting rating to stars
|
||||||
|
_STAR_URL = 'http://www.independent.co.uk/skins/ind/images/rating_star.png'
|
||||||
|
_NO_STAR_URL = 'http://www.independent.co.uk/skins/ind/images/rating_star_grey.png'
|
||||||
|
|
||||||
|
|
||||||
|
title = u'The Independent'
|
||||||
|
__author__ = 'Will'
|
||||||
|
description = 'The latest in UK News and World News from The \
|
||||||
|
Independent. Wide range of international and local news, sports \
|
||||||
|
news, commentary and opinion pieces.Independent News - Breaking news \
|
||||||
|
that matters. Your daily comprehensive news source - The \
|
||||||
|
Independent Newspaper'
|
||||||
|
publisher = 'The Independent'
|
||||||
|
category = 'news, UK'
|
||||||
|
no_stylesheets = True
|
||||||
|
use_embedded_content = False
|
||||||
|
remove_empty_feeds = True
|
||||||
|
language = 'en_GB'
|
||||||
|
publication_type = 'newspaper'
|
||||||
|
masthead_url = 'http://www.independent.co.uk/independent.co.uk/editorial/logo/independent_Masthead.png'
|
||||||
|
encoding = 'utf-8'
|
||||||
|
remove_tags =[
|
||||||
|
dict(attrs={'id' : ['RelatedArtTag','renderBiography']}),
|
||||||
|
dict(attrs={'class' : ['autoplay','openBiogPopup']})
|
||||||
|
]
|
||||||
|
|
||||||
|
keep_only_tags =[dict(attrs={'id':'main'})]
|
||||||
|
recursions = 0
|
||||||
|
|
||||||
|
# fixes non compliant html nesting and 'marks' article graphics links
|
||||||
|
preprocess_regexps = [
|
||||||
|
(re.compile('<span class="storyTop ">(?P<nested>.*?)</span>', re.DOTALL),
|
||||||
|
lambda match: '<div class="storyTop">' + match.group('nested') + '</div>'),
|
||||||
|
(re.compile('<strong>.*?Click.*?to view graphic.*?</strong>', re.DOTALL),
|
||||||
|
lambda match: '<div class="article-graphic">' + match.group(0) + '</div>'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : category
|
||||||
|
, 'publisher' : publisher
|
||||||
|
, 'language' : language
|
||||||
|
}
|
||||||
|
|
||||||
|
extra_css = """
|
||||||
|
h1{font-family: Georgia,serif }
|
||||||
|
body{font-family: Verdana,Arial,Helvetica,sans-serif}
|
||||||
|
img{margin-bottom: 0.4em; display:block}
|
||||||
|
.starRating img {float: left}
|
||||||
|
.starRating {margin-top:0.4em; display: block}
|
||||||
|
.image {clear:left; font-size: x-small; color:#888888;}
|
||||||
|
.articleByTimeLocation {font-size: x-small; color:#888888;
|
||||||
|
margin-bottom:0.2em ; margin-top:0.2em ; display:block}
|
||||||
|
.subtitle {clear:left}
|
||||||
|
.column-1 h1 { color: #191919}
|
||||||
|
.column-1 h2 { color: #333333}
|
||||||
|
.column-1 h3 { color: #444444}
|
||||||
|
.column-1 p { color: #777777}
|
||||||
|
.column-1 p,a,h1,h2,h3 { margin: 0; }
|
||||||
|
.column-1 div{color:#888888; margin: 0;}
|
||||||
|
.articleContent {display: block; clear:left;}
|
||||||
|
.storyTop{}
|
||||||
|
.pictureContainer img { max-width: 400px; max-height: 400px;}
|
||||||
|
"""
|
||||||
|
|
||||||
title = u'The Independent'
|
|
||||||
oldest_article = 1
|
oldest_article = 1
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
auto_cleanup = True
|
|
||||||
language = 'en_GB'
|
_processed_urls = []
|
||||||
__author__ = 'NotTaken'
|
|
||||||
|
|
||||||
|
def get_article_url(self, article):
|
||||||
|
url = super(self.__class__,self).get_article_url(article)
|
||||||
|
|
||||||
|
title = article.get('title', None)
|
||||||
|
if title and re.search("^Video:",title):
|
||||||
|
return None
|
||||||
|
|
||||||
|
#remove duplicates
|
||||||
|
if not (url in self._processed_urls):
|
||||||
|
self._processed_urls.append(url)
|
||||||
|
else:
|
||||||
|
url = None
|
||||||
|
return url
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
|
||||||
|
items_to_extract = []
|
||||||
|
|
||||||
|
for item in soup.findAll(attrs={'class' : re.compile("widget.*")}):
|
||||||
|
remove = True
|
||||||
|
pattern = re.compile('((articleContent)|(title))$')
|
||||||
|
if (pattern.search(item['class'])) is not None:
|
||||||
|
remove = False
|
||||||
|
|
||||||
|
# corrections
|
||||||
|
# story content always good
|
||||||
|
pattern = re.compile('storyContent')
|
||||||
|
if (pattern.search(item['class'])) is not None:
|
||||||
|
remove = False
|
||||||
|
|
||||||
|
#images
|
||||||
|
pattern = re.compile('slideshow')
|
||||||
|
if (pattern.search(item['class'])) is not None:
|
||||||
|
if self._FETCH_IMAGES:
|
||||||
|
remove = False
|
||||||
|
else:
|
||||||
|
remove = True
|
||||||
|
|
||||||
|
#social widgets always bad
|
||||||
|
pattern = re.compile('socialwidget')
|
||||||
|
if (pattern.search(item['class'])) is not None:
|
||||||
|
remove = True
|
||||||
|
|
||||||
|
if remove:
|
||||||
|
items_to_extract.append(item)
|
||||||
|
|
||||||
|
for item in items_to_extract:
|
||||||
|
item.extract()
|
||||||
|
|
||||||
|
items_to_extract = []
|
||||||
|
|
||||||
|
if self._FETCH_IMAGES:
|
||||||
|
for item in soup.findAll('a',attrs={'href' : re.compile('.*')}):
|
||||||
|
if item.img is not None:
|
||||||
|
#use full size image
|
||||||
|
img = item.findNext('img')
|
||||||
|
|
||||||
|
img['src'] = item['href']
|
||||||
|
|
||||||
|
#insert caption if available
|
||||||
|
if img['title'] is not None and (len(img['title']) > 1):
|
||||||
|
tag = Tag(soup,'h3')
|
||||||
|
text = NavigableString(img['title'])
|
||||||
|
tag.insert(0,text)
|
||||||
|
|
||||||
|
#picture before text
|
||||||
|
img.extract()
|
||||||
|
item.insert(0,img)
|
||||||
|
item.insert(1,tag)
|
||||||
|
|
||||||
|
# remove link
|
||||||
|
item.name = "div"
|
||||||
|
item["class"]='image'
|
||||||
|
del item["href"]
|
||||||
|
|
||||||
|
|
||||||
|
#remove empty subtitles
|
||||||
|
"""
|
||||||
|
currently the subtitle is located in first paragraph after
|
||||||
|
sibling <h3 class="subtitle"> tag. This may be 'fixed' at
|
||||||
|
some point.
|
||||||
|
"""
|
||||||
|
subtitle = soup.find('h3',attrs={'class' : 'subtitle'})
|
||||||
|
if subtitle is not None:
|
||||||
|
subtitleText = subtitle.findNext('p')
|
||||||
|
if subtitleText is not None:
|
||||||
|
if len(subtitleText.contents[0]) <= 1 :
|
||||||
|
subtitleText.extract()
|
||||||
|
subtitle.extract()
|
||||||
|
|
||||||
|
|
||||||
|
#replace rating numbers with stars
|
||||||
|
for item in soup.findAll('div',attrs={ 'class' : 'starRating'}):
|
||||||
|
if item is not None:
|
||||||
|
soup2 = self._insertRatingStars(soup,item)
|
||||||
|
if soup2 is not None:
|
||||||
|
soup = soup2
|
||||||
|
|
||||||
|
|
||||||
|
#remove empty paragraph tags in storyTop which can leave a space
|
||||||
|
#between first paragraph and rest of story
|
||||||
|
storyTop = soup.find('div',attrs={ 'class' : ['storyTop']})
|
||||||
|
for item in storyTop.findAll('p'):
|
||||||
|
if item.contents is not None and len(item.contents[0]) <= 1 :
|
||||||
|
items_to_extract.append(item)
|
||||||
|
|
||||||
|
for item in items_to_extract:
|
||||||
|
item.extract()
|
||||||
|
|
||||||
|
items_to_extract = []
|
||||||
|
|
||||||
|
|
||||||
|
#remove line breaks immediately next to tags with default margins
|
||||||
|
#to prevent double line spacing and narrow columns of text
|
||||||
|
storyTop = soup.find('div',attrs={ 'class' : ['storyTop']})
|
||||||
|
self._remove_undesired_line_breaks_from_tag(storyTop,soup)
|
||||||
|
|
||||||
|
|
||||||
|
#replace article graphics link with the graphics themselves
|
||||||
|
if self._FETCH_ARTICLE_GRAPHICS:
|
||||||
|
items_to_insert = []
|
||||||
|
for item in soup.findAll('div', attrs={'class' : ['article-graphic']}):
|
||||||
|
strong = item.find('strong')
|
||||||
|
for child in strong:
|
||||||
|
if isinstance(child,Tag):
|
||||||
|
if str(child.name) == 'a':
|
||||||
|
items_to_insert.extend(self._get_article_graphic(strong,child['href'],soup))
|
||||||
|
|
||||||
|
for item in items_to_insert:
|
||||||
|
item[0].replaceWith(item[1])
|
||||||
|
|
||||||
|
for item in items_to_extract:
|
||||||
|
item.extract()
|
||||||
|
|
||||||
|
return soup
|
||||||
|
|
||||||
|
|
||||||
|
def _get_article_graphic(self,old_item,url,soup):
|
||||||
|
|
||||||
|
items_to_insert = []
|
||||||
|
|
||||||
|
if re.search('\.jpg$',str(url)):
|
||||||
|
div = Tag(soup,'div')
|
||||||
|
div['class'] = 'pictureContainer'
|
||||||
|
img = Tag(soup,'img')
|
||||||
|
img['src'] = url
|
||||||
|
img['alt'] = 'article graphic'
|
||||||
|
div.insert(0,img)
|
||||||
|
items_to_insert.append((old_item,div,))
|
||||||
|
return items_to_insert
|
||||||
|
|
||||||
|
soup2 = self.index_to_soup(url)
|
||||||
|
for item in soup2.findAll('div',attrs={'class' : re.compile("widget picture article.*")}):
|
||||||
|
items_to_insert.append((old_item,item),)
|
||||||
|
return items_to_insert
|
||||||
|
|
||||||
|
|
||||||
|
def _insertRatingStars(self,soup,item):
|
||||||
|
if item.contents is None:
|
||||||
|
return
|
||||||
|
rating = item.contents[0]
|
||||||
|
if not rating.isdigit():
|
||||||
|
return None
|
||||||
|
rating = int(item.contents[0])
|
||||||
|
for i in range(1,6):
|
||||||
|
star = Tag(soup,'img')
|
||||||
|
if i <= rating:
|
||||||
|
star['src'] = self._STAR_URL
|
||||||
|
else:
|
||||||
|
star['src'] = self._NO_STAR_URL
|
||||||
|
star['alt'] = 'star number ' + str(i)
|
||||||
|
item.insert(i,star)
|
||||||
|
#item.contents[0] = NavigableString('(' + str(rating) + ')')
|
||||||
|
item.contents[0] = ''
|
||||||
|
|
||||||
|
def postprocess_html(self,soup, first_fetch):
|
||||||
|
#find broken images and remove captions
|
||||||
|
items_to_extract = []
|
||||||
|
for item in soup.findAll('div', attrs={'class' : 'image'}):
|
||||||
|
img = item.findNext('img')
|
||||||
|
if img is not None and img['src'] is not None:
|
||||||
|
# broken images still point to remote url
|
||||||
|
pattern = re.compile('http://www.independent.co.uk.*')
|
||||||
|
if pattern.match(img["src"]) is not None:
|
||||||
|
caption = img.findNextSibling('h3')
|
||||||
|
if caption is not None:
|
||||||
|
items_to_extract.append(caption)
|
||||||
|
items_to_extract.append(img)
|
||||||
|
|
||||||
|
for item in items_to_extract:
|
||||||
|
item.extract()
|
||||||
|
return soup
|
||||||
|
|
||||||
|
def _recurisvely_linearise_tag_tree(
|
||||||
|
self,
|
||||||
|
item,
|
||||||
|
linearised= None,
|
||||||
|
count=0,
|
||||||
|
limit = 100
|
||||||
|
):
|
||||||
|
linearised = linearised or []
|
||||||
|
count = count + 1
|
||||||
|
if count > limit:
|
||||||
|
return linearised
|
||||||
|
if not (isinstance(item,Tag)):
|
||||||
|
return linearised
|
||||||
|
for nested in item:
|
||||||
|
linearised.append(nested)
|
||||||
|
linearised = self._recurisvely_linearise_tag_tree(nested,linearised, count)
|
||||||
|
return linearised
|
||||||
|
|
||||||
|
|
||||||
|
def _get_previous_tag(self,current_index, tag_tree):
|
||||||
|
if current_index == 0:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return tag_tree[current_index - 1]
|
||||||
|
|
||||||
|
|
||||||
|
def _get_next_tag(self,current_index, tag_tree):
|
||||||
|
if current_index < len(tag_tree) - 1:
|
||||||
|
return tag_tree[current_index + 1]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _list_match(self,test_str, list_regex):
|
||||||
|
for regex in list_regex:
|
||||||
|
match = re.match(regex, test_str)
|
||||||
|
if match is not None:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _remove_undesired_line_breaks_from_tag(self,parent,soup):
|
||||||
|
|
||||||
|
if parent is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
tag_tree = self._recurisvely_linearise_tag_tree(parent)
|
||||||
|
items_to_remove = []
|
||||||
|
|
||||||
|
|
||||||
|
for item in tag_tree:
|
||||||
|
if item == u'\n':
|
||||||
|
items_to_remove.append(item)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for item in items_to_remove:
|
||||||
|
tag_tree.remove(item)
|
||||||
|
|
||||||
|
|
||||||
|
spaced_tags = [r'p', r'h\d', r'blockquote']
|
||||||
|
tags_to_extract = []
|
||||||
|
tags_to_replace = []
|
||||||
|
for (i, tag) in enumerate(tag_tree):
|
||||||
|
if isinstance(tag, Tag):
|
||||||
|
if str(tag) == '<br />':
|
||||||
|
previous_tag = self._get_previous_tag(i, tag_tree)
|
||||||
|
|
||||||
|
if isinstance(previous_tag, Tag):
|
||||||
|
previous_tag_is_spaced = previous_tag is not None\
|
||||||
|
and self._list_match(str(previous_tag.name),
|
||||||
|
spaced_tags)
|
||||||
|
else:
|
||||||
|
previous_tag_is_spaced = False
|
||||||
|
|
||||||
|
next_tag = self._get_next_tag(i, tag_tree)
|
||||||
|
|
||||||
|
if isinstance(next_tag, Tag):
|
||||||
|
next_tag_is_spaced = next_tag is not None\
|
||||||
|
and self._list_match(str(next_tag.name), spaced_tags)
|
||||||
|
else:
|
||||||
|
next_tag_is_spaced = False
|
||||||
|
|
||||||
|
if previous_tag_is_spaced or next_tag_is_spaced or i == 0\
|
||||||
|
or i == len(tag_tree) - 1:
|
||||||
|
tags_to_extract.append(tag)
|
||||||
|
else:
|
||||||
|
tags_to_replace.append((tag,NavigableString(' '),))
|
||||||
|
|
||||||
|
|
||||||
|
for pair in tags_to_replace:
|
||||||
|
pair[0].replaceWith(pair[1])
|
||||||
|
for tag in tags_to_extract:
|
||||||
|
tag.extract()
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
(u'News - UK',
|
(u'News - UK',
|
||||||
@ -25,7 +391,7 @@ class AdvancedUserRecipe1320474488(BasicNewsRecipe):
|
|||||||
(u'News - Education',
|
(u'News - Education',
|
||||||
u'http://www.independent.co.uk/news/education/?service=rss'),
|
u'http://www.independent.co.uk/news/education/?service=rss'),
|
||||||
(u'News - Obituaries',
|
(u'News - Obituaries',
|
||||||
u'http://rss.feedsportal.com/c/266/f/3531/index.rss'),
|
u'http://www.independent.co.uk/news/obituaries/?service=rss'),
|
||||||
(u'News - Corrections',
|
(u'News - Corrections',
|
||||||
u'http://www.independent.co.uk/news/corrections/?service=rss'
|
u'http://www.independent.co.uk/news/corrections/?service=rss'
|
||||||
),
|
),
|
||||||
@ -46,11 +412,11 @@ class AdvancedUserRecipe1320474488(BasicNewsRecipe):
|
|||||||
u'http://www.independent.co.uk/sport/motor-racing/?service=rss'
|
u'http://www.independent.co.uk/sport/motor-racing/?service=rss'
|
||||||
),
|
),
|
||||||
(u'Sport - Olympics',
|
(u'Sport - Olympics',
|
||||||
u'http://rss.feedsportal.com/c/266/f/3800/index.rss'),
|
u'http://www.independent.co.uk/sport/olympics/?service=rss'),
|
||||||
(u'Sport - Racing',
|
(u'Sport - Racing',
|
||||||
u'http://www.independent.co.uk/sport/racing/?service=rss'),
|
u'http://www.independent.co.uk/sport/racing/?service=rss'),
|
||||||
(u'Sport - Rugby League',
|
(u'Sport - Rugby League',
|
||||||
u'http://rss.feedsportal.com/c/266/f/3795/index.rss'),
|
u'http://www.independent.co.uk/sport/general/rugby-league/?service=rss'),
|
||||||
(u'Sport - Rugby Union',
|
(u'Sport - Rugby Union',
|
||||||
u'http://www.independent.co.uk/sport/rugby/rugby-union/?service=rss'
|
u'http://www.independent.co.uk/sport/rugby/rugby-union/?service=rss'
|
||||||
),
|
),
|
||||||
@ -114,6 +480,5 @@ class AdvancedUserRecipe1320474488(BasicNewsRecipe):
|
|||||||
(u'Money', u'http://www.independent.co.uk/money/?service=rss'),
|
(u'Money', u'http://www.independent.co.uk/money/?service=rss'),
|
||||||
(u'IndyBest',
|
(u'IndyBest',
|
||||||
u'http://www.independent.co.uk/extras/indybest/?service=rss'),
|
u'http://www.independent.co.uk/extras/indybest/?service=rss'),
|
||||||
(u'Blogs', u'http://blogs.independent.co.uk/feed/rss/'),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ __description__ = 'Italian weekly magazine'
|
|||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Espresso(BasicNewsRecipe):
|
class Espresso(BasicNewsRecipe):
|
||||||
__author__ = 'Lorenzo Vigentini, Gabriele Marini'
|
__author__ = 'Lorenzo Vigentini, Gabriele Marini, Krittika Goyal'
|
||||||
description = 'Italian weekly magazine'
|
description = 'Italian weekly magazine'
|
||||||
|
|
||||||
cover_url = 'http://espresso.repubblica.it/images/logo_espresso.gif'
|
cover_url = 'http://espresso.repubblica.it/images/logo_espresso.gif'
|
||||||
@ -26,10 +26,9 @@ class Espresso(BasicNewsRecipe):
|
|||||||
oldest_article = 16
|
oldest_article = 16
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
recursion = 10
|
|
||||||
|
|
||||||
remove_javascript = True
|
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
|
auto_cleanup = True
|
||||||
|
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
@ -42,36 +41,3 @@ class Espresso(BasicNewsRecipe):
|
|||||||
(u'Chiesa: HomePage', u'http://data.kataweb.it/rss/chiesa/homepage/it'),
|
(u'Chiesa: HomePage', u'http://data.kataweb.it/rss/chiesa/homepage/it'),
|
||||||
(u'Chiesa: Speciali e Focus', u'http://data.kataweb.it/rss/chiesa/speciali_e_focus/it')
|
(u'Chiesa: Speciali e Focus', u'http://data.kataweb.it/rss/chiesa/speciali_e_focus/it')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def print_version(self,url):
|
|
||||||
print url[7:25]
|
|
||||||
if url[7:25] == 'temi.repubblica.it':
|
|
||||||
return url + '/?printpage=undefined'
|
|
||||||
elif url[7:25] == 'www.chiesa.espress':
|
|
||||||
return url
|
|
||||||
return url + '/&print=true'
|
|
||||||
|
|
||||||
|
|
||||||
keep_only_tags = [
|
|
||||||
dict(name='div', attrs={'class':['testo','copertina','occhiello','firma','didascalia','content-second-right','detail-articles','titolo-local','generic-articles']}),
|
|
||||||
dict(name='div', attrs={'class':['generic-articles','summary','detail-articles']}),
|
|
||||||
dict(name='div', attrs={'id':['content-second-right','content2']})
|
|
||||||
]
|
|
||||||
|
|
||||||
remove_tags = [
|
|
||||||
dict(name='div',attrs={'class':['servizi','aggiungi','label-web','bottom-mobile','box-abbonamenti','box-cerca','big','little','stampaweb']}),
|
|
||||||
dict(name='div',attrs={'id':['topheader','header','navigation-new','navigation','content-second-left','menutext']}),
|
|
||||||
dict(name='ul',attrs={'id':'user-utility'}),
|
|
||||||
dict(name=['script','noscript','iframe'])
|
|
||||||
]
|
|
||||||
# extra_css = '''
|
|
||||||
# h1 {font-family:Times New Roman,"Trebuchet MS",Arial,Helvetica,sans-serif; font-size:24px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:18px;}
|
|
||||||
# h2 {font-family:Times New Roman, "Trebuchet MS",Arial,Helvetica,sans-serif; font-size:18px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:16px; }
|
|
||||||
# h3 {color:#333333;font-family:Times New Roman, "Trebuchet MS",Arial,Helvetica,sans-serif; font-size:16px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:14px;}
|
|
||||||
# h4 {color:#333333; font-family:Times New Roman, "Trebuchet MS",Arial,Helvetica,sans-serif;font-size:16px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:14px; }
|
|
||||||
# h5 {color:#333333; font-family:Times New Roman, "Trebuchet MS",Arial,Helvetica,sans-serif; font-size:12px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:bold; line-height:14px; text-transform:uppercase;}
|
|
||||||
# .firma {color:#333333;font-family:Times New Roman, "Trebuchet MS",Arial,Helvetica,sans-serif;font-size:12px; font-size-adjust:none; font-stretch:normal; font-style:italic; font-variant:normal; font-weight:bold; line-height:15px; text-decoration:none;}
|
|
||||||
# .testo {font-family:Times New Roman, "Trebuchet MS",Arial,Helvetica,sans-serif; font-size:10px;}
|
|
||||||
# '''
|
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
import re
|
import re
|
||||||
from calibre.utils.magick import Image
|
from calibre.utils.magick import Image
|
||||||
@ -8,21 +9,27 @@ from calibre.utils.magick import Image
|
|||||||
version 1.4 Updated tags, delay and added autoclean 22-09-2011
|
version 1.4 Updated tags, delay and added autoclean 22-09-2011
|
||||||
version 1.5 Changes due to changes in site
|
version 1.5 Changes due to changes in site
|
||||||
version 1.6 Added css, removed auto cleanup, added buitenland section, added use_embedded_content, added remove_attributes
|
version 1.6 Added css, removed auto cleanup, added buitenland section, added use_embedded_content, added remove_attributes
|
||||||
Added som processing on pictures
|
Added some processing on pictures
|
||||||
Removed links in html
|
Removed links in html
|
||||||
Removed extre white characters
|
Removed extre white characters
|
||||||
changed handling of self closing span
|
changed handling of self closing span
|
||||||
'''
|
Version 1.7 11-11-2011 Changed oldest_article back to 1.5
|
||||||
|
changed è into è
|
||||||
|
updated remove tags
|
||||||
|
removed keep_only tags
|
||||||
|
'''
|
||||||
|
|
||||||
class AdvancedUserRecipe1306097511(BasicNewsRecipe):
|
class AdvancedUserRecipe1306097511(BasicNewsRecipe):
|
||||||
title = u'Metro Nieuws NL'
|
title = u'Metro Nieuws NL'
|
||||||
oldest_article = 2
|
oldest_article = 1.5
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
__author__ = u'DrMerry'
|
__author__ = u'DrMerry'
|
||||||
description = u'Metro Nederland'
|
description = u'Metro Nederland'
|
||||||
language = u'nl'
|
language = u'nl'
|
||||||
simultaneous_downloads = 5
|
simultaneous_downloads = 5
|
||||||
|
timeout = 2
|
||||||
#delay = 1
|
#delay = 1
|
||||||
|
center_navbar = True
|
||||||
#auto_cleanup = True
|
#auto_cleanup = True
|
||||||
#auto_cleanup_keep = '//div[@class="article-image-caption-2column"]/*|//div[@id="date"]/*|//div[@class="article-image-caption-3column"]/*'
|
#auto_cleanup_keep = '//div[@class="article-image-caption-2column"]/*|//div[@id="date"]/*|//div[@class="article-image-caption-3column"]/*'
|
||||||
timefmt = ' [%A, %d %b %Y]'
|
timefmt = ' [%A, %d %b %Y]'
|
||||||
@ -31,31 +38,32 @@ class AdvancedUserRecipe1306097511(BasicNewsRecipe):
|
|||||||
remove_empty_feeds = True
|
remove_empty_feeds = True
|
||||||
cover_url = 'http://www.oldreadmetro.com/img/en/metroholland/last/1/small.jpg'
|
cover_url = 'http://www.oldreadmetro.com/img/en/metroholland/last/1/small.jpg'
|
||||||
publication_type = 'newspaper'
|
publication_type = 'newspaper'
|
||||||
remove_tags_before = dict(name='div', attrs={'id':'date'})
|
remove_tags_before = dict(id='date')
|
||||||
remove_tags_after = dict(name='div', attrs={'class':'article-body'})
|
remove_tags_after = dict(name='div', attrs={'class':'article-body'})
|
||||||
encoding = 'utf-8'
|
encoding = 'utf-8'
|
||||||
remove_attributes = ['style', 'font', 'width', 'height']
|
remove_attributes = ['style', 'font', 'width', 'height']
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
|
conversion_options = {
|
||||||
|
'authors' : 'Metro Nederland',
|
||||||
|
'author_sort' : 'Metro Nederland',
|
||||||
|
'publisher' : 'DrMerry/Metro Nederland'
|
||||||
|
}
|
||||||
extra_css = 'body {padding:5px 0px; background:#fff;font-size: 13px;}\
|
extra_css = 'body {padding:5px 0px; background:#fff;font-size: 13px;}\
|
||||||
#date {clear: both;margin-left: 19px;font-size: 11px;font-weight: 300;color: #616262;height: 15px;}\
|
#date {clear: both;margin-left: 19px;font-size: 11px;font-weight: 300;color: #616262;height: 15px;}\
|
||||||
.article-box-fact.module-title {clear:both;border-top:1px solid black;border-bottom:4px solid black;padding: 8px 0;color: #24763b;font-family: arial, sans-serif;font-size: 14px;font-weight: bold;}\
|
.article-box-fact.module-title {clear:both;padding: 8px 0;color: #24763b;font-family: arial, sans-serif;font-size: 14px;font-weight: bold;}\
|
||||||
h1.title {color: #000000;font-size: 44px;padding-bottom: 10px;line-height: 1.15;font-weight: 300;} h2.subtitle {font-size: 13px;font-weight: 700;padding-bottom: 10px;}\
|
h1.title {color: #000000;font-size: 44px;padding-bottom: 10px;font-weight: 300;} h2.subtitle {font-size: 13px;font-weight: 700;padding-bottom: 10px;}\
|
||||||
.article-body p{padding-bottom:10px;}div.column-1-3{float: left;display: inline;width: 567px;margin-left: 19px;border-right: 1px solid #CACACA;padding-right: 9px;}\
|
.article-body p{padding-bottom:10px;}div.column-1-3{margin-left: 19px;padding-right: 9px;}\
|
||||||
div.column-1-2 {float: left;display: inline;width: 373px;padding-right: 7px;border-right: 1px solid #CACACA;}\
|
div.column-1-2 {display: inline;padding-right: 7px;}\
|
||||||
p.article-image-caption {font-size: 12px;font-weight: 300;line-height: 1.4;color: #616262;margin-top: 5px;} \
|
p.article-image-caption {font-size: 12px;font-weight: 300;color: #616262;margin-top: 5px;} \
|
||||||
p.article-image-caption .credits {font-style: italic;font-size: 10px;}\
|
p.article-image-caption .credits {font-style: italic;font-size: 10px;}\
|
||||||
div.article-image-caption {width: 246px;margin-bottom: 5px;margin-left: 10px;}\
|
div.article-image-caption {width: 246px;margin-bottom: 5px;margin-left: 10px;}\
|
||||||
div.article-image-caption-2column {margin-bottom: 10px;width: 373px;} div.article-image-caption-3column {}\
|
div.article-image-caption-2column {margin-bottom: 10px;width: 373px;} div.article-image-caption-3column {}\
|
||||||
img {border:0px;} .img-mask {position:absolute;top:0px;left:0px;}'
|
img {border:0px;} .img-mask {position:absolute;top:0px;left:0px;}'
|
||||||
|
|
||||||
keep_only_tags = [dict(name='div', attrs={'class':[ 'article-image-caption-2column', 'article-image-caption-3column', 'article-body', 'article-box-fact']}),
|
remove_tags = [dict(name='div', attrs={'class':[ 'metroCommentFormWrap', 'related-links'
|
||||||
dict(name='div', attrs={'id':['date']}),
|
|
||||||
dict(name='h1', attrs={'class':['title']}),
|
|
||||||
dict(name='h2', attrs={'class':['subtitle']})]
|
|
||||||
|
|
||||||
remove_tags = [dict(name='div', attrs={'class':[ 'metroCommentFormWrap',
|
|
||||||
'commentForm', 'metroCommentInnerWrap', 'article-slideshow-counter-container', 'article-slideshow-control', 'ad', 'header-links',
|
'commentForm', 'metroCommentInnerWrap', 'article-slideshow-counter-container', 'article-slideshow-control', 'ad', 'header-links',
|
||||||
'art-rgt','pluck-app pluck-comm', 'share-and-byline', 'article-tools-below-title', 'col-179 ', 'related-links', 'clear padding-top-15', 'share-tools', 'article-page-auto-pushes', 'footer-edit']}),
|
'art-rgt','pluck-app pluck-comm', 'share-and-byline', 'article-tools-below-title', 'col-179 ', 'related-links', 'clear padding-top-15', 'share-tools',
|
||||||
|
'article1','article-page-auto-pushes', 'footer-edit','clear']}),
|
||||||
dict(name='div', attrs={'id':['article-2', 'article-4', 'article-1', 'navigation', 'footer', 'header', 'comments', 'sidebar', 'share-and-byline']}),
|
dict(name='div', attrs={'id':['article-2', 'article-4', 'article-1', 'navigation', 'footer', 'header', 'comments', 'sidebar', 'share-and-byline']}),
|
||||||
dict(name='iframe')]
|
dict(name='iframe')]
|
||||||
|
|
||||||
@ -70,26 +78,8 @@ class AdvancedUserRecipe1306097511(BasicNewsRecipe):
|
|||||||
iurl = tag['src']
|
iurl = tag['src']
|
||||||
img = Image()
|
img = Image()
|
||||||
img.open(iurl)
|
img.open(iurl)
|
||||||
#width, height = img.size
|
|
||||||
#print '***img is: ', iurl, '\n****width is: ', width, 'height is: ', height
|
|
||||||
img.trim(0)
|
img.trim(0)
|
||||||
img.save(iurl)
|
img.save(iurl)
|
||||||
'''
|
|
||||||
#width, height = img.size
|
|
||||||
#print '***TRIMMED img width is: ', width, 'height is: ', height
|
|
||||||
left=0
|
|
||||||
top=0
|
|
||||||
border_color='#ffffff'
|
|
||||||
width, height = img.size
|
|
||||||
#print '***retrieved img width is: ', width, 'height is: ', height
|
|
||||||
height_correction = 1.17
|
|
||||||
canvas = create_canvas(width, height*height_correction,border_color)
|
|
||||||
canvas.compose(img, left, top)
|
|
||||||
#img = canvas
|
|
||||||
canvas.save(iurl)
|
|
||||||
#width, height = canvas.size
|
|
||||||
#print '***NEW img width is: ', width, 'height is: ', height
|
|
||||||
'''
|
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
@ -8,17 +9,18 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
from calibre import strftime
|
from calibre import strftime
|
||||||
|
|
||||||
class SueddeutcheZeitung(BasicNewsRecipe):
|
class SueddeutcheZeitung(BasicNewsRecipe):
|
||||||
title = 'Sueddeutche Zeitung'
|
title = 'Süddeutsche Zeitung'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
description = 'News from Germany. Access to paid content.'
|
description = 'News from Germany. Access to paid content.'
|
||||||
publisher = 'Sueddeutche Zeitung'
|
publisher = 'Süddeutsche Zeitung'
|
||||||
category = 'news, politics, Germany'
|
category = 'news, politics, Germany'
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
oldest_article = 2
|
oldest_article = 2
|
||||||
encoding = 'cp1252'
|
encoding = 'iso-8859-1'
|
||||||
needs_subscription = True
|
needs_subscription = True
|
||||||
remove_empty_feeds = True
|
remove_empty_feeds = True
|
||||||
delay = 1
|
delay = 1
|
||||||
|
cover_source = 'http://www.sueddeutsche.de/verlag'
|
||||||
PREFIX = 'http://www.sueddeutsche.de'
|
PREFIX = 'http://www.sueddeutsche.de'
|
||||||
INDEX = PREFIX + '/app/epaper/textversion/'
|
INDEX = PREFIX + '/app/epaper/textversion/'
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
@ -58,6 +60,7 @@ class SueddeutcheZeitung(BasicNewsRecipe):
|
|||||||
feeds = [
|
feeds = [
|
||||||
(u'Politik' , INDEX + 'Politik/' )
|
(u'Politik' , INDEX + 'Politik/' )
|
||||||
,(u'Seite drei' , INDEX + 'Seite+drei/' )
|
,(u'Seite drei' , INDEX + 'Seite+drei/' )
|
||||||
|
,(u'Thema des Tages' , INDEX + 'Thema+des+Tages/' )
|
||||||
,(u'Meinungsseite' , INDEX + 'Meinungsseite/')
|
,(u'Meinungsseite' , INDEX + 'Meinungsseite/')
|
||||||
,(u'Wissen' , INDEX + 'Wissen/' )
|
,(u'Wissen' , INDEX + 'Wissen/' )
|
||||||
,(u'Panorama' , INDEX + 'Panorama/' )
|
,(u'Panorama' , INDEX + 'Panorama/' )
|
||||||
@ -82,6 +85,11 @@ class SueddeutcheZeitung(BasicNewsRecipe):
|
|||||||
,(u'Beilage' , INDEX + 'Beilage/' )
|
,(u'Beilage' , INDEX + 'Beilage/' )
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_cover_url(self):
|
||||||
|
cover_source_soup = self.index_to_soup(self.cover_source)
|
||||||
|
preview_image_div = cover_source_soup.find(attrs={'class':'preview-image'})
|
||||||
|
return preview_image_div.div.img['src']
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
src = self.index_to_soup(self.INDEX)
|
src = self.index_to_soup(self.INDEX)
|
||||||
id = ''
|
id = ''
|
||||||
@ -92,7 +100,7 @@ class SueddeutcheZeitung(BasicNewsRecipe):
|
|||||||
lfeeds = self.get_feeds()
|
lfeeds = self.get_feeds()
|
||||||
for feedobj in lfeeds:
|
for feedobj in lfeeds:
|
||||||
feedtitle, feedurl = feedobj
|
feedtitle, feedurl = feedobj
|
||||||
self.report_progress(0, _('Fetching feed')+' %s...'%(feedtitle if feedtitle else feedurl))
|
self.report_progress(0, ('Fetching feed')+' %s...'%(feedtitle if feedtitle else feedurl))
|
||||||
articles = []
|
articles = []
|
||||||
soup = self.index_to_soup(feedurl + id)
|
soup = self.index_to_soup(feedurl + id)
|
||||||
tbl = soup.find(attrs={'class':'szprintd'})
|
tbl = soup.find(attrs={'class':'szprintd'})
|
||||||
|
50
recipes/techtarget.recipe
Normal file
50
recipes/techtarget.recipe
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class TechTarget(BasicNewsRecipe):
|
||||||
|
title = u'Techtarget'
|
||||||
|
__author__ = 'Julio:map'
|
||||||
|
description = '''IT Infrastructure related blogs
|
||||||
|
from Techtarget'''
|
||||||
|
publisher = 'Techtarget'
|
||||||
|
category = 'IT, Infrastructure'
|
||||||
|
oldest_article = 7
|
||||||
|
language = 'en'
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
no_stylesheets = True
|
||||||
|
use_embedded_content = False
|
||||||
|
needs_subscription = True
|
||||||
|
auto_cleanup = False
|
||||||
|
LOGIN = u'http://searchservervirtualization.techtarget.com/login'
|
||||||
|
|
||||||
|
def get_browser(self):
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
if self.username is not None:
|
||||||
|
br.open(self.LOGIN)
|
||||||
|
br.select_form(nr=1)
|
||||||
|
br['email'] = self.username
|
||||||
|
if self.password is not None:
|
||||||
|
br['password'] = self.password
|
||||||
|
br.submit()
|
||||||
|
return br
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':'article'}),dict(name='div', attrs={'class':'entry'})]
|
||||||
|
remove_tags= [dict(name='div', attrs={'id':['articleToolbar','relatedContent']})]
|
||||||
|
remove_tags_after = [dict(name='div', attrs={'id':'relatedContent'})]
|
||||||
|
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'IT news and analysis for CIOs', u'http://feeds.pheedo.com/SearchCIOITNewsAndAnalysisForCIOs'),
|
||||||
|
(u'TotalCIO', u'http://feeds.pheedo.com/1532.xml'),
|
||||||
|
(u'SearchCIO-Midmarket: Technology news and tips for midmarket CIOs', u'http://feeds.pheedo.com/techtarget/Searchsmb/Smbs'),
|
||||||
|
(u'Compliance news and advice for senior IT and business managers', u'http://feeds.pheedo.com/tt/1200'),
|
||||||
|
(u'Server virtualization news and opinions', u'http://feeds.pheedo.com/SearchservervirtualizationServerVirtualizationNewsAndOpinions'),
|
||||||
|
(u'The Virtualization Room', u'http://feeds.pheedo.com/techtarget/nzLe'),
|
||||||
|
(u'Server virtualization technical tips and expert advice', u'http://feeds.pheedo.com/SearchservervirtualizationServerVirtualizationTechnicalTipsAndExpertAdvice'),
|
||||||
|
(u'Cloud Computing news and Technical Advice', u'http://feeds.pheedo.com/1260'),
|
||||||
|
(u'IT infrastructure news', u'http://feeds.pheedo.com/techtarget/Searchdatacenter/ItInfrastructure'),
|
||||||
|
(u'Storage Channel Update', u'http://feeds.pheedo.com/ChannelMarker-TheItChannelWeblog'),
|
||||||
|
(u'VMware Tips and News', u'http://feeds.pheedo.com/SearchvmwarecomVmwareTipsAndTricks'),
|
||||||
|
(u'Enterprise IT news roundup', u'http://feeds.pheedo.com/WhatisEnterpriseItNewsRoundup'),
|
||||||
|
(u'WhatIs: Enterprise IT tips and expert advice', u'http://feeds.pheedo.com/WhatisEnterpriseItTipsAndExpertAdvice'),
|
||||||
|
(u'WhatIs: Enterprise IT news roundup', u'http://feeds.pheedo.com/WhatisEnterpriseItNewsRoundup'),
|
||||||
|
]
|
@ -315,6 +315,12 @@ content_server_wont_display = []
|
|||||||
# level sorts, and if you are seeing a slowdown, reduce the value of this tweak.
|
# level sorts, and if you are seeing a slowdown, reduce the value of this tweak.
|
||||||
maximum_resort_levels = 5
|
maximum_resort_levels = 5
|
||||||
|
|
||||||
|
#: Choose whether dates are sorted using visible fields
|
||||||
|
# Date values contain both a date and a time. When sorted, all the fields are
|
||||||
|
# used, regardless of what is displayed. Set this tweak to True to use only
|
||||||
|
# the fields that are being displayed.
|
||||||
|
sort_dates_using_visible_fields = False
|
||||||
|
|
||||||
#: Specify which font to use when generating a default cover
|
#: Specify which font to use when generating a default cover
|
||||||
# Absolute path to .ttf font files to use as the fonts for the title, author
|
# Absolute path to .ttf font files to use as the fonts for the title, author
|
||||||
# and footer when generating a default cover. Useful if the default font (Liberation
|
# and footer when generating a default cover. Useful if the default font (Liberation
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,14 +8,14 @@ msgstr ""
|
|||||||
"Project-Id-Version: calibre\n"
|
"Project-Id-Version: calibre\n"
|
||||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"POT-Creation-Date: 2011-09-27 14:31+0000\n"
|
"POT-Creation-Date: 2011-09-27 14:31+0000\n"
|
||||||
"PO-Revision-Date: 2011-10-22 22:04+0000\n"
|
"PO-Revision-Date: 2011-10-28 15:37+0000\n"
|
||||||
"Last-Translator: Fitoschido <fitoschido@gmail.com>\n"
|
"Last-Translator: Jellby <Unknown>\n"
|
||||||
"Language-Team: Spanish <es@li.org>\n"
|
"Language-Team: Spanish <es@li.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Launchpad-Export-Date: 2011-10-23 05:13+0000\n"
|
"X-Launchpad-Export-Date: 2011-10-29 05:16+0000\n"
|
||||||
"X-Generator: Launchpad (build 14170)\n"
|
"X-Generator: Launchpad (build 14197)\n"
|
||||||
|
|
||||||
#. name for aaa
|
#. name for aaa
|
||||||
msgid "Ghotuo"
|
msgid "Ghotuo"
|
||||||
@ -5911,11 +5911,11 @@ msgstr "Gwahatike"
|
|||||||
|
|
||||||
#. name for dai
|
#. name for dai
|
||||||
msgid "Day"
|
msgid "Day"
|
||||||
msgstr "Día"
|
msgstr "Day"
|
||||||
|
|
||||||
#. name for daj
|
#. name for daj
|
||||||
msgid "Daju; Dar Fur"
|
msgid "Daju; Dar Fur"
|
||||||
msgstr ""
|
msgstr "Daju de Darfur"
|
||||||
|
|
||||||
#. name for dak
|
#. name for dak
|
||||||
msgid "Dakota"
|
msgid "Dakota"
|
||||||
@ -5955,7 +5955,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for dau
|
#. name for dau
|
||||||
msgid "Daju; Dar Sila"
|
msgid "Daju; Dar Sila"
|
||||||
msgstr ""
|
msgstr "Daju de Dar Sila"
|
||||||
|
|
||||||
#. name for dav
|
#. name for dav
|
||||||
msgid "Taita"
|
msgid "Taita"
|
||||||
@ -6379,7 +6379,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for djc
|
#. name for djc
|
||||||
msgid "Daju; Dar Daju"
|
msgid "Daju; Dar Daju"
|
||||||
msgstr ""
|
msgstr "Daju de Dar Daju"
|
||||||
|
|
||||||
#. name for djd
|
#. name for djd
|
||||||
msgid "Djamindjung"
|
msgid "Djamindjung"
|
||||||
|
@ -9,101 +9,101 @@ msgstr ""
|
|||||||
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
||||||
"devel@lists.alioth.debian.org>\n"
|
"devel@lists.alioth.debian.org>\n"
|
||||||
"POT-Creation-Date: 2011-09-27 14:31+0000\n"
|
"POT-Creation-Date: 2011-09-27 14:31+0000\n"
|
||||||
"PO-Revision-Date: 2011-10-15 17:29+0000\n"
|
"PO-Revision-Date: 2011-11-10 07:13+0000\n"
|
||||||
"Last-Translator: Devilinside <Unknown>\n"
|
"Last-Translator: Devilinside <Unknown>\n"
|
||||||
"Language-Team: Hungarian <debian-l10n-hungarian@lists.d.o>\n"
|
"Language-Team: Hungarian <debian-l10n-hungarian@lists.d.o>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Launchpad-Export-Date: 2011-10-16 05:14+0000\n"
|
"X-Launchpad-Export-Date: 2011-11-11 04:52+0000\n"
|
||||||
"X-Generator: Launchpad (build 14124)\n"
|
"X-Generator: Launchpad (build 14277)\n"
|
||||||
"X-Poedit-Country: HUNGARY\n"
|
"X-Poedit-Country: HUNGARY\n"
|
||||||
"Language: hu\n"
|
"Language: hu\n"
|
||||||
"X-Poedit-Language: Hungarian\n"
|
"X-Poedit-Language: Hungarian\n"
|
||||||
|
|
||||||
#. name for aaa
|
#. name for aaa
|
||||||
msgid "Ghotuo"
|
msgid "Ghotuo"
|
||||||
msgstr "Ghotuo"
|
msgstr "ghotuo"
|
||||||
|
|
||||||
#. name for aab
|
#. name for aab
|
||||||
msgid "Alumu-Tesu"
|
msgid "Alumu-Tesu"
|
||||||
msgstr "Alumu-Tesu"
|
msgstr "alumu-tesu"
|
||||||
|
|
||||||
#. name for aac
|
#. name for aac
|
||||||
msgid "Ari"
|
msgid "Ari"
|
||||||
msgstr "Ari"
|
msgstr "ari"
|
||||||
|
|
||||||
#. name for aad
|
#. name for aad
|
||||||
msgid "Amal"
|
msgid "Amal"
|
||||||
msgstr "Amal"
|
msgstr "amal"
|
||||||
|
|
||||||
#. name for aae
|
#. name for aae
|
||||||
msgid "Albanian; Arbëreshë"
|
msgid "Albanian; Arbëreshë"
|
||||||
msgstr "Albán; Arbëreshë"
|
msgstr "albán; Arbëreshë"
|
||||||
|
|
||||||
#. name for aaf
|
#. name for aaf
|
||||||
msgid "Aranadan"
|
msgid "Aranadan"
|
||||||
msgstr "Aranadan"
|
msgstr "aranadan"
|
||||||
|
|
||||||
#. name for aag
|
#. name for aag
|
||||||
msgid "Ambrak"
|
msgid "Ambrak"
|
||||||
msgstr "Ambrak"
|
msgstr "ambrak"
|
||||||
|
|
||||||
#. name for aah
|
#. name for aah
|
||||||
msgid "Arapesh; Abu'"
|
msgid "Arapesh; Abu'"
|
||||||
msgstr "Arapesh; Abu'"
|
msgstr "arapesh; Abu'"
|
||||||
|
|
||||||
#. name for aai
|
#. name for aai
|
||||||
msgid "Arifama-Miniafia"
|
msgid "Arifama-Miniafia"
|
||||||
msgstr ""
|
msgstr "arifama-miniafia"
|
||||||
|
|
||||||
#. name for aak
|
#. name for aak
|
||||||
msgid "Ankave"
|
msgid "Ankave"
|
||||||
msgstr ""
|
msgstr "ankave"
|
||||||
|
|
||||||
#. name for aal
|
#. name for aal
|
||||||
msgid "Afade"
|
msgid "Afade"
|
||||||
msgstr ""
|
msgstr "afade"
|
||||||
|
|
||||||
#. name for aam
|
#. name for aam
|
||||||
msgid "Aramanik"
|
msgid "Aramanik"
|
||||||
msgstr ""
|
msgstr "aramanik"
|
||||||
|
|
||||||
#. name for aan
|
#. name for aan
|
||||||
msgid "Anambé"
|
msgid "Anambé"
|
||||||
msgstr ""
|
msgstr "anambé"
|
||||||
|
|
||||||
#. name for aao
|
#. name for aao
|
||||||
msgid "Arabic; Algerian Saharan"
|
msgid "Arabic; Algerian Saharan"
|
||||||
msgstr "Arab; Algériai Szaharai"
|
msgstr "arab; algériai-szaharai"
|
||||||
|
|
||||||
#. name for aap
|
#. name for aap
|
||||||
msgid "Arára; Pará"
|
msgid "Arára; Pará"
|
||||||
msgstr ""
|
msgstr "arára; Pará"
|
||||||
|
|
||||||
#. name for aaq
|
#. name for aaq
|
||||||
msgid "Abnaki; Eastern"
|
msgid "Abnaki; Eastern"
|
||||||
msgstr ""
|
msgstr "abnaki; keleti"
|
||||||
|
|
||||||
#. name for aar
|
#. name for aar
|
||||||
msgid "Afar"
|
msgid "Afar"
|
||||||
msgstr "Afar"
|
msgstr "afar"
|
||||||
|
|
||||||
#. name for aas
|
#. name for aas
|
||||||
msgid "Aasáx"
|
msgid "Aasáx"
|
||||||
msgstr ""
|
msgstr "aasáx"
|
||||||
|
|
||||||
#. name for aat
|
#. name for aat
|
||||||
msgid "Albanian; Arvanitika"
|
msgid "Albanian; Arvanitika"
|
||||||
msgstr ""
|
msgstr "albán; Arvanitika"
|
||||||
|
|
||||||
#. name for aau
|
#. name for aau
|
||||||
msgid "Abau"
|
msgid "Abau"
|
||||||
msgstr ""
|
msgstr "abau"
|
||||||
|
|
||||||
#. name for aaw
|
#. name for aaw
|
||||||
msgid "Solong"
|
msgid "Solong"
|
||||||
msgstr ""
|
msgstr "szolong"
|
||||||
|
|
||||||
#. name for aax
|
#. name for aax
|
||||||
msgid "Mandobo Atas"
|
msgid "Mandobo Atas"
|
||||||
@ -115,7 +115,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for aba
|
#. name for aba
|
||||||
msgid "Abé"
|
msgid "Abé"
|
||||||
msgstr ""
|
msgstr "abé"
|
||||||
|
|
||||||
#. name for abb
|
#. name for abb
|
||||||
msgid "Bankon"
|
msgid "Bankon"
|
||||||
@ -131,7 +131,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for abe
|
#. name for abe
|
||||||
msgid "Abnaki; Western"
|
msgid "Abnaki; Western"
|
||||||
msgstr ""
|
msgstr "abnaki; nyugati"
|
||||||
|
|
||||||
#. name for abf
|
#. name for abf
|
||||||
msgid "Abai Sungai"
|
msgid "Abai Sungai"
|
||||||
@ -143,7 +143,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for abh
|
#. name for abh
|
||||||
msgid "Arabic; Tajiki"
|
msgid "Arabic; Tajiki"
|
||||||
msgstr ""
|
msgstr "arab; tadzsik"
|
||||||
|
|
||||||
#. name for abi
|
#. name for abi
|
||||||
msgid "Abidji"
|
msgid "Abidji"
|
||||||
@ -151,7 +151,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for abj
|
#. name for abj
|
||||||
msgid "Aka-Bea"
|
msgid "Aka-Bea"
|
||||||
msgstr ""
|
msgstr "aka-bea"
|
||||||
|
|
||||||
#. name for abk
|
#. name for abk
|
||||||
msgid "Abkhazian"
|
msgid "Abkhazian"
|
||||||
@ -187,7 +187,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for abs
|
#. name for abs
|
||||||
msgid "Malay; Ambonese"
|
msgid "Malay; Ambonese"
|
||||||
msgstr ""
|
msgstr "maláj; amboni"
|
||||||
|
|
||||||
#. name for abt
|
#. name for abt
|
||||||
msgid "Ambulas"
|
msgid "Ambulas"
|
||||||
@ -199,7 +199,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for abv
|
#. name for abv
|
||||||
msgid "Arabic; Baharna"
|
msgid "Arabic; Baharna"
|
||||||
msgstr ""
|
msgstr "arab; Baharna"
|
||||||
|
|
||||||
#. name for abw
|
#. name for abw
|
||||||
msgid "Pal"
|
msgid "Pal"
|
||||||
@ -236,7 +236,7 @@ msgstr "akinéz"
|
|||||||
|
|
||||||
#. name for acf
|
#. name for acf
|
||||||
msgid "Creole French; Saint Lucian"
|
msgid "Creole French; Saint Lucian"
|
||||||
msgstr ""
|
msgstr "francia (kreol); Sainte-Lucie"
|
||||||
|
|
||||||
#. name for ach
|
#. name for ach
|
||||||
msgid "Acoli"
|
msgid "Acoli"
|
||||||
@ -256,7 +256,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for acm
|
#. name for acm
|
||||||
msgid "Arabic; Mesopotamian"
|
msgid "Arabic; Mesopotamian"
|
||||||
msgstr ""
|
msgstr "arab; mezopotámiai"
|
||||||
|
|
||||||
#. name for acn
|
#. name for acn
|
||||||
msgid "Achang"
|
msgid "Achang"
|
||||||
@ -268,7 +268,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for acq
|
#. name for acq
|
||||||
msgid "Arabic; Ta'izzi-Adeni"
|
msgid "Arabic; Ta'izzi-Adeni"
|
||||||
msgstr ""
|
msgstr "arabic; ta'izzi-adeni"
|
||||||
|
|
||||||
#. name for acr
|
#. name for acr
|
||||||
msgid "Achi"
|
msgid "Achi"
|
||||||
@ -296,11 +296,11 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for acx
|
#. name for acx
|
||||||
msgid "Arabic; Omani"
|
msgid "Arabic; Omani"
|
||||||
msgstr ""
|
msgstr "arab; ománi"
|
||||||
|
|
||||||
#. name for acy
|
#. name for acy
|
||||||
msgid "Arabic; Cypriot"
|
msgid "Arabic; Cypriot"
|
||||||
msgstr ""
|
msgstr "arab; ciprusi"
|
||||||
|
|
||||||
#. name for acz
|
#. name for acz
|
||||||
msgid "Acheron"
|
msgid "Acheron"
|
||||||
@ -384,11 +384,11 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for adx
|
#. name for adx
|
||||||
msgid "Tibetan; Amdo"
|
msgid "Tibetan; Amdo"
|
||||||
msgstr ""
|
msgstr "tibeti; Amdo"
|
||||||
|
|
||||||
#. name for ady
|
#. name for ady
|
||||||
msgid "Adyghe"
|
msgid "Adyghe"
|
||||||
msgstr ""
|
msgstr "adyghe"
|
||||||
|
|
||||||
#. name for adz
|
#. name for adz
|
||||||
msgid "Adzera"
|
msgid "Adzera"
|
||||||
@ -408,7 +408,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for aed
|
#. name for aed
|
||||||
msgid "Argentine Sign Language"
|
msgid "Argentine Sign Language"
|
||||||
msgstr ""
|
msgstr "argentín jelnyelv"
|
||||||
|
|
||||||
#. name for aee
|
#. name for aee
|
||||||
msgid "Pashayi; Northeast"
|
msgid "Pashayi; Northeast"
|
||||||
@ -500,7 +500,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for afr
|
#. name for afr
|
||||||
msgid "Afrikaans"
|
msgid "Afrikaans"
|
||||||
msgstr "Afrikaans"
|
msgstr "afrikaansz"
|
||||||
|
|
||||||
#. name for afs
|
#. name for afs
|
||||||
msgid "Creole; Afro-Seminole"
|
msgid "Creole; Afro-Seminole"
|
||||||
@ -680,7 +680,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for aib
|
#. name for aib
|
||||||
msgid "Ainu (China)"
|
msgid "Ainu (China)"
|
||||||
msgstr ""
|
msgstr "ainu (Kína)"
|
||||||
|
|
||||||
#. name for aic
|
#. name for aic
|
||||||
msgid "Ainbai"
|
msgid "Ainbai"
|
||||||
@ -700,7 +700,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for aig
|
#. name for aig
|
||||||
msgid "Creole English; Antigua and Barbuda"
|
msgid "Creole English; Antigua and Barbuda"
|
||||||
msgstr ""
|
msgstr "angol (kreol); Antigua és Barbuda"
|
||||||
|
|
||||||
#. name for aih
|
#. name for aih
|
||||||
msgid "Ai-Cham"
|
msgid "Ai-Cham"
|
||||||
@ -708,7 +708,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for aii
|
#. name for aii
|
||||||
msgid "Neo-Aramaic; Assyrian"
|
msgid "Neo-Aramaic; Assyrian"
|
||||||
msgstr ""
|
msgstr "arámi; új-arámi; asszír"
|
||||||
|
|
||||||
#. name for aij
|
#. name for aij
|
||||||
msgid "Lishanid Noshan"
|
msgid "Lishanid Noshan"
|
||||||
@ -728,7 +728,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for ain
|
#. name for ain
|
||||||
msgid "Ainu (Japan)"
|
msgid "Ainu (Japan)"
|
||||||
msgstr ""
|
msgstr "ainu (Japán)"
|
||||||
|
|
||||||
#. name for aio
|
#. name for aio
|
||||||
msgid "Aiton"
|
msgid "Aiton"
|
||||||
@ -800,7 +800,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for aka
|
#. name for aka
|
||||||
msgid "Akan"
|
msgid "Akan"
|
||||||
msgstr "Akan"
|
msgstr "akan"
|
||||||
|
|
||||||
#. name for akb
|
#. name for akb
|
||||||
msgid "Batak Angkola"
|
msgid "Batak Angkola"
|
||||||
@ -968,7 +968,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for alt
|
#. name for alt
|
||||||
msgid "Altai; Southern"
|
msgid "Altai; Southern"
|
||||||
msgstr ""
|
msgstr "altáji; déli"
|
||||||
|
|
||||||
#. name for alu
|
#. name for alu
|
||||||
msgid "'Are'are"
|
msgid "'Are'are"
|
||||||
@ -1014,9 +1014,10 @@ msgstr ""
|
|||||||
msgid "Amarag"
|
msgid "Amarag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# src/trans.h:283
|
||||||
#. name for amh
|
#. name for amh
|
||||||
msgid "Amharic"
|
msgid "Amharic"
|
||||||
msgstr "Amhara"
|
msgstr "amhara"
|
||||||
|
|
||||||
#. name for ami
|
#. name for ami
|
||||||
msgid "Amis"
|
msgid "Amis"
|
||||||
@ -1076,7 +1077,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for amw
|
#. name for amw
|
||||||
msgid "Neo-Aramaic; Western"
|
msgid "Neo-Aramaic; Western"
|
||||||
msgstr ""
|
msgstr "arámi; új-arámi; nyugati"
|
||||||
|
|
||||||
#. name for amx
|
#. name for amx
|
||||||
msgid "Anmatyerre"
|
msgid "Anmatyerre"
|
||||||
@ -1116,7 +1117,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for ang
|
#. name for ang
|
||||||
msgid "English; Old (ca. 450-1100)"
|
msgid "English; Old (ca. 450-1100)"
|
||||||
msgstr ""
|
msgstr "angol; óangol (kb. 450-1100)"
|
||||||
|
|
||||||
#. name for anh
|
#. name for anh
|
||||||
msgid "Nend"
|
msgid "Nend"
|
||||||
@ -1413,7 +1414,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for arc
|
#. name for arc
|
||||||
msgid "Aramaic; Official (700-300 BCE)"
|
msgid "Aramaic; Official (700-300 BCE)"
|
||||||
msgstr ""
|
msgstr "arámi; hivatalos (i.e. 700- i.e. 300)"
|
||||||
|
|
||||||
#. name for ard
|
#. name for ard
|
||||||
msgid "Arabana"
|
msgid "Arabana"
|
||||||
@ -1423,9 +1424,10 @@ msgstr ""
|
|||||||
msgid "Arrarnta; Western"
|
msgid "Arrarnta; Western"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# src/trans.h:294
|
||||||
#. name for arg
|
#. name for arg
|
||||||
msgid "Aragonese"
|
msgid "Aragonese"
|
||||||
msgstr "Aragóniai"
|
msgstr "aragóniai"
|
||||||
|
|
||||||
#. name for arh
|
#. name for arh
|
||||||
msgid "Arhuaco"
|
msgid "Arhuaco"
|
||||||
@ -1545,7 +1547,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for asm
|
#. name for asm
|
||||||
msgid "Assamese"
|
msgid "Assamese"
|
||||||
msgstr "Asszámi"
|
msgstr "asszámi"
|
||||||
|
|
||||||
#. name for asn
|
#. name for asn
|
||||||
msgid "Asuriní; Xingú"
|
msgid "Asuriní; Xingú"
|
||||||
@ -1677,7 +1679,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for atv
|
#. name for atv
|
||||||
msgid "Altai; Northern"
|
msgid "Altai; Northern"
|
||||||
msgstr ""
|
msgstr "altáji; északi"
|
||||||
|
|
||||||
#. name for atw
|
#. name for atw
|
||||||
msgid "Atsugewi"
|
msgid "Atsugewi"
|
||||||
@ -1787,9 +1789,10 @@ msgstr ""
|
|||||||
msgid "Arabic; Uzbeki"
|
msgid "Arabic; Uzbeki"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# src/trans.h:283
|
||||||
#. name for ava
|
#. name for ava
|
||||||
msgid "Avaric"
|
msgid "Avaric"
|
||||||
msgstr "Avar"
|
msgstr "avar"
|
||||||
|
|
||||||
#. name for avb
|
#. name for avb
|
||||||
msgid "Avau"
|
msgid "Avau"
|
||||||
@ -1801,7 +1804,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for ave
|
#. name for ave
|
||||||
msgid "Avestan"
|
msgid "Avestan"
|
||||||
msgstr "Avesztai"
|
msgstr "avesztai"
|
||||||
|
|
||||||
#. name for avi
|
#. name for avi
|
||||||
msgid "Avikam"
|
msgid "Avikam"
|
||||||
@ -1941,7 +1944,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for ayc
|
#. name for ayc
|
||||||
msgid "Aymara; Southern"
|
msgid "Aymara; Southern"
|
||||||
msgstr "Ajmara; Déli"
|
msgstr "ajmara; Déli"
|
||||||
|
|
||||||
#. name for ayd
|
#. name for ayd
|
||||||
msgid "Ayabadhu"
|
msgid "Ayabadhu"
|
||||||
@ -1973,7 +1976,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for aym
|
#. name for aym
|
||||||
msgid "Aymara"
|
msgid "Aymara"
|
||||||
msgstr "Ajmara"
|
msgstr "ajmara"
|
||||||
|
|
||||||
#. name for ayn
|
#. name for ayn
|
||||||
msgid "Arabic; Sanaani"
|
msgid "Arabic; Sanaani"
|
||||||
@ -1993,7 +1996,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for ayr
|
#. name for ayr
|
||||||
msgid "Aymara; Central"
|
msgid "Aymara; Central"
|
||||||
msgstr "Ajmara; Közép"
|
msgstr "ajmara; Közép"
|
||||||
|
|
||||||
#. name for ays
|
#. name for ays
|
||||||
msgid "Ayta; Sorsogon"
|
msgid "Ayta; Sorsogon"
|
||||||
@ -2021,11 +2024,12 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for azb
|
#. name for azb
|
||||||
msgid "Azerbaijani; South"
|
msgid "Azerbaijani; South"
|
||||||
msgstr "Azeri; Déli"
|
msgstr "azeri; Déli"
|
||||||
|
|
||||||
|
# src/trans.h:311
|
||||||
#. name for aze
|
#. name for aze
|
||||||
msgid "Azerbaijani"
|
msgid "Azerbaijani"
|
||||||
msgstr "Azeri"
|
msgstr "azeri"
|
||||||
|
|
||||||
#. name for azg
|
#. name for azg
|
||||||
msgid "Amuzgo; San Pedro Amuzgos"
|
msgid "Amuzgo; San Pedro Amuzgos"
|
||||||
@ -2033,7 +2037,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for azj
|
#. name for azj
|
||||||
msgid "Azerbaijani; North"
|
msgid "Azerbaijani; North"
|
||||||
msgstr "Azeri; Északi"
|
msgstr "azeri; Északi"
|
||||||
|
|
||||||
#. name for azm
|
#. name for azm
|
||||||
msgid "Amuzgo; Ipalapa"
|
msgid "Amuzgo; Ipalapa"
|
||||||
@ -2077,7 +2081,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for bah
|
#. name for bah
|
||||||
msgid "Creole English; Bahamas"
|
msgid "Creole English; Bahamas"
|
||||||
msgstr ""
|
msgstr "angol (kreol); Bahamák"
|
||||||
|
|
||||||
#. name for baj
|
#. name for baj
|
||||||
msgid "Barakai"
|
msgid "Barakai"
|
||||||
@ -2085,7 +2089,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for bak
|
#. name for bak
|
||||||
msgid "Bashkir"
|
msgid "Bashkir"
|
||||||
msgstr "Baskír"
|
msgstr "baskír"
|
||||||
|
|
||||||
#. name for bal
|
#. name for bal
|
||||||
msgid "Baluchi"
|
msgid "Baluchi"
|
||||||
@ -2110,7 +2114,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for bar
|
#. name for bar
|
||||||
msgid "Bavarian"
|
msgid "Bavarian"
|
||||||
msgstr "Bajor"
|
msgstr "bajor"
|
||||||
|
|
||||||
#. name for bas
|
#. name for bas
|
||||||
msgid "Basa (Cameroon)"
|
msgid "Basa (Cameroon)"
|
||||||
@ -2494,7 +2498,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for bel
|
#. name for bel
|
||||||
msgid "Belarusian"
|
msgid "Belarusian"
|
||||||
msgstr "Belarusz"
|
msgstr "belarusz"
|
||||||
|
|
||||||
#. name for bem
|
#. name for bem
|
||||||
msgid "Bemba (Zambia)"
|
msgid "Bemba (Zambia)"
|
||||||
@ -2502,7 +2506,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for ben
|
#. name for ben
|
||||||
msgid "Bengali"
|
msgid "Bengali"
|
||||||
msgstr "Bengáli"
|
msgstr "bengáli"
|
||||||
|
|
||||||
#. name for beo
|
#. name for beo
|
||||||
msgid "Beami"
|
msgid "Beami"
|
||||||
@ -2798,7 +2802,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for bhn
|
#. name for bhn
|
||||||
msgid "Neo-Aramaic; Bohtan"
|
msgid "Neo-Aramaic; Bohtan"
|
||||||
msgstr ""
|
msgstr "arámi; új-arámi; bohtan"
|
||||||
|
|
||||||
#. name for bho
|
#. name for bho
|
||||||
msgid "Bhojpuri"
|
msgid "Bhojpuri"
|
||||||
@ -2966,7 +2970,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for bjf
|
#. name for bjf
|
||||||
msgid "Neo-Aramaic; Barzani Jewish"
|
msgid "Neo-Aramaic; Barzani Jewish"
|
||||||
msgstr ""
|
msgstr "arámi; új-arámi; barzani zsidó"
|
||||||
|
|
||||||
#. name for bjg
|
#. name for bjg
|
||||||
msgid "Bidyogo"
|
msgid "Bidyogo"
|
||||||
@ -3366,7 +3370,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for bng
|
#. name for bng
|
||||||
msgid "Benga"
|
msgid "Benga"
|
||||||
msgstr ""
|
msgstr "benga"
|
||||||
|
|
||||||
#. name for bni
|
#. name for bni
|
||||||
msgid "Bangi"
|
msgid "Bangi"
|
||||||
@ -3504,9 +3508,10 @@ msgstr ""
|
|||||||
msgid "Borôro"
|
msgid "Borôro"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# src/trans.h:309
|
||||||
#. name for bos
|
#. name for bos
|
||||||
msgid "Bosnian"
|
msgid "Bosnian"
|
||||||
msgstr "Bosnyák"
|
msgstr "bosnyák"
|
||||||
|
|
||||||
#. name for bot
|
#. name for bot
|
||||||
msgid "Bongo"
|
msgid "Bongo"
|
||||||
@ -3678,7 +3683,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for bqn
|
#. name for bqn
|
||||||
msgid "Bulgarian Sign Language"
|
msgid "Bulgarian Sign Language"
|
||||||
msgstr "Bolgár jelnyelv"
|
msgstr "bolgár jelnyelv"
|
||||||
|
|
||||||
#. name for bqo
|
#. name for bqo
|
||||||
msgid "Balo"
|
msgid "Balo"
|
||||||
@ -4071,9 +4076,10 @@ msgstr ""
|
|||||||
msgid "Bugawac"
|
msgid "Bugawac"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# src/trans.h:285
|
||||||
#. name for bul
|
#. name for bul
|
||||||
msgid "Bulgarian"
|
msgid "Bulgarian"
|
||||||
msgstr "Bolgár"
|
msgstr "bolgár"
|
||||||
|
|
||||||
#. name for bum
|
#. name for bum
|
||||||
msgid "Bulu (Cameroon)"
|
msgid "Bulu (Cameroon)"
|
||||||
@ -4557,11 +4563,11 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for bzj
|
#. name for bzj
|
||||||
msgid "Kriol English; Belize"
|
msgid "Kriol English; Belize"
|
||||||
msgstr ""
|
msgstr "angol (kreol); Belize"
|
||||||
|
|
||||||
#. name for bzk
|
#. name for bzk
|
||||||
msgid "Creole English; Nicaragua"
|
msgid "Creole English; Nicaragua"
|
||||||
msgstr ""
|
msgstr "angol (kreol); Nicaragua"
|
||||||
|
|
||||||
#. name for bzl
|
#. name for bzl
|
||||||
msgid "Boano (Sulawesi)"
|
msgid "Boano (Sulawesi)"
|
||||||
@ -5036,7 +5042,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for chu
|
#. name for chu
|
||||||
msgid "Slavonic; Old"
|
msgid "Slavonic; Old"
|
||||||
msgstr ""
|
msgstr "szláv; ószláv"
|
||||||
|
|
||||||
#. name for chv
|
#. name for chv
|
||||||
msgid "Chuvash"
|
msgid "Chuvash"
|
||||||
@ -5224,7 +5230,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for cld
|
#. name for cld
|
||||||
msgid "Neo-Aramaic; Chaldean"
|
msgid "Neo-Aramaic; Chaldean"
|
||||||
msgstr ""
|
msgstr "arámi; új-arámi; új-babilóniai"
|
||||||
|
|
||||||
#. name for cle
|
#. name for cle
|
||||||
msgid "Chinantec; Lealao"
|
msgid "Chinantec; Lealao"
|
||||||
@ -5622,7 +5628,7 @@ msgstr "kasubi"
|
|||||||
|
|
||||||
#. name for csc
|
#. name for csc
|
||||||
msgid "Catalan Sign Language"
|
msgid "Catalan Sign Language"
|
||||||
msgstr ""
|
msgstr "katalán jelnyelv"
|
||||||
|
|
||||||
#. name for csd
|
#. name for csd
|
||||||
msgid "Chiangmai Sign Language"
|
msgid "Chiangmai Sign Language"
|
||||||
@ -5630,7 +5636,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for cse
|
#. name for cse
|
||||||
msgid "Czech Sign Language"
|
msgid "Czech Sign Language"
|
||||||
msgstr ""
|
msgstr "cseh jelnyelv"
|
||||||
|
|
||||||
#. name for csf
|
#. name for csf
|
||||||
msgid "Cuba Sign Language"
|
msgid "Cuba Sign Language"
|
||||||
@ -7261,7 +7267,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for enm
|
#. name for enm
|
||||||
msgid "English; Middle (1100-1500)"
|
msgid "English; Middle (1100-1500)"
|
||||||
msgstr "közép-angol (1100-1500)"
|
msgstr "angol; középkori (1100-1500)"
|
||||||
|
|
||||||
#. name for enn
|
#. name for enn
|
||||||
msgid "Engenni"
|
msgid "Engenni"
|
||||||
@ -7697,7 +7703,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for fpe
|
#. name for fpe
|
||||||
msgid "Creole English; Fernando Po"
|
msgid "Creole English; Fernando Po"
|
||||||
msgstr ""
|
msgstr "angol (kreol); Fernando Po"
|
||||||
|
|
||||||
#. name for fqs
|
#. name for fqs
|
||||||
msgid "Fas"
|
msgid "Fas"
|
||||||
@ -7726,7 +7732,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for fro
|
#. name for fro
|
||||||
msgid "French; Old (842-ca. 1400)"
|
msgid "French; Old (842-ca. 1400)"
|
||||||
msgstr ""
|
msgstr "francia; ófrancia (842- kb. 1400)"
|
||||||
|
|
||||||
#. name for frp
|
#. name for frp
|
||||||
msgid "Arpitan"
|
msgid "Arpitan"
|
||||||
@ -8059,7 +8065,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for gcl
|
#. name for gcl
|
||||||
msgid "Creole English; Grenadian"
|
msgid "Creole English; Grenadian"
|
||||||
msgstr ""
|
msgstr "angol (kreol); Grenada"
|
||||||
|
|
||||||
#. name for gcn
|
#. name for gcn
|
||||||
msgid "Gaina"
|
msgid "Gaina"
|
||||||
@ -8442,7 +8448,7 @@ msgstr "ír"
|
|||||||
|
|
||||||
#. name for glg
|
#. name for glg
|
||||||
msgid "Galician"
|
msgid "Galician"
|
||||||
msgstr ""
|
msgstr "galíciai"
|
||||||
|
|
||||||
#. name for glh
|
#. name for glh
|
||||||
msgid "Pashayi; Northwest"
|
msgid "Pashayi; Northwest"
|
||||||
@ -8634,7 +8640,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for goh
|
#. name for goh
|
||||||
msgid "German; Old High (ca. 750-1050)"
|
msgid "German; Old High (ca. 750-1050)"
|
||||||
msgstr ""
|
msgstr "német; ónémet (kb. 750-1050)"
|
||||||
|
|
||||||
#. name for goi
|
#. name for goi
|
||||||
msgid "Gobasi"
|
msgid "Gobasi"
|
||||||
@ -9716,7 +9722,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for hsh
|
#. name for hsh
|
||||||
msgid "Hungarian Sign Language"
|
msgid "Hungarian Sign Language"
|
||||||
msgstr ""
|
msgstr "magyar jelnyelv"
|
||||||
|
|
||||||
#. name for hsl
|
#. name for hsl
|
||||||
msgid "Hausa Sign Language"
|
msgid "Hausa Sign Language"
|
||||||
@ -10931,7 +10937,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for jpa
|
#. name for jpa
|
||||||
msgid "Aramaic; Jewish Palestinian"
|
msgid "Aramaic; Jewish Palestinian"
|
||||||
msgstr ""
|
msgstr "arámi; zsidó palesztin"
|
||||||
|
|
||||||
# src/trans.h:222
|
# src/trans.h:222
|
||||||
#. name for jpn
|
#. name for jpn
|
||||||
@ -11799,7 +11805,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for khg
|
#. name for khg
|
||||||
msgid "Tibetan; Khams"
|
msgid "Tibetan; Khams"
|
||||||
msgstr ""
|
msgstr "tibeti; Khams"
|
||||||
|
|
||||||
#. name for khh
|
#. name for khh
|
||||||
msgid "Kehu"
|
msgid "Kehu"
|
||||||
@ -12076,7 +12082,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for kka
|
#. name for kka
|
||||||
msgid "Kakanda"
|
msgid "Kakanda"
|
||||||
msgstr ""
|
msgstr "kakanda"
|
||||||
|
|
||||||
#. name for kkb
|
#. name for kkb
|
||||||
msgid "Kwerisa"
|
msgid "Kwerisa"
|
||||||
@ -18256,7 +18262,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for nhb
|
#. name for nhb
|
||||||
msgid "Beng"
|
msgid "Beng"
|
||||||
msgstr ""
|
msgstr "beng"
|
||||||
|
|
||||||
#. name for nhc
|
#. name for nhc
|
||||||
msgid "Nahuatl; Tabasco"
|
msgid "Nahuatl; Tabasco"
|
||||||
@ -18926,7 +18932,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for non
|
#. name for non
|
||||||
msgid "Norse; Old"
|
msgid "Norse; Old"
|
||||||
msgstr "ónorvég"
|
msgstr "norvég; ónorvég"
|
||||||
|
|
||||||
#. name for nop
|
#. name for nop
|
||||||
msgid "Numanggang"
|
msgid "Numanggang"
|
||||||
@ -19347,7 +19353,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for nwc
|
#. name for nwc
|
||||||
msgid "Newari; Old"
|
msgid "Newari; Old"
|
||||||
msgstr ""
|
msgstr "newari; ónewari"
|
||||||
|
|
||||||
#. name for nwe
|
#. name for nwe
|
||||||
msgid "Ngwe"
|
msgid "Ngwe"
|
||||||
@ -19567,11 +19573,11 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for oar
|
#. name for oar
|
||||||
msgid "Aramaic; Old (up to 700 BCE)"
|
msgid "Aramaic; Old (up to 700 BCE)"
|
||||||
msgstr ""
|
msgstr "arámi; óarámi (i.e. 700-ig)"
|
||||||
|
|
||||||
#. name for oav
|
#. name for oav
|
||||||
msgid "Avar; Old"
|
msgid "Avar; Old"
|
||||||
msgstr ""
|
msgstr "avar; óavar"
|
||||||
|
|
||||||
#. name for obi
|
#. name for obi
|
||||||
msgid "Obispeño"
|
msgid "Obispeño"
|
||||||
@ -19595,11 +19601,11 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for obr
|
#. name for obr
|
||||||
msgid "Burmese; Old"
|
msgid "Burmese; Old"
|
||||||
msgstr ""
|
msgstr "burmai; óburmai"
|
||||||
|
|
||||||
#. name for obt
|
#. name for obt
|
||||||
msgid "Breton; Old"
|
msgid "Breton; Old"
|
||||||
msgstr ""
|
msgstr "breton; óbreton"
|
||||||
|
|
||||||
#. name for obu
|
#. name for obu
|
||||||
msgid "Obulom"
|
msgid "Obulom"
|
||||||
@ -19611,7 +19617,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for och
|
#. name for och
|
||||||
msgid "Chinese; Old"
|
msgid "Chinese; Old"
|
||||||
msgstr ""
|
msgstr "kínai; ókínai"
|
||||||
|
|
||||||
#. name for oci
|
#. name for oci
|
||||||
msgid "Occitan (post 1500)"
|
msgid "Occitan (post 1500)"
|
||||||
@ -19635,7 +19641,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for odt
|
#. name for odt
|
||||||
msgid "Dutch; Old"
|
msgid "Dutch; Old"
|
||||||
msgstr ""
|
msgstr "holland; óholland"
|
||||||
|
|
||||||
#. name for odu
|
#. name for odu
|
||||||
msgid "Odual"
|
msgid "Odual"
|
||||||
@ -19647,7 +19653,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for ofs
|
#. name for ofs
|
||||||
msgid "Frisian; Old"
|
msgid "Frisian; Old"
|
||||||
msgstr ""
|
msgstr "fríz; ófríz"
|
||||||
|
|
||||||
#. name for ofu
|
#. name for ofu
|
||||||
msgid "Efutop"
|
msgid "Efutop"
|
||||||
@ -19663,7 +19669,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for oge
|
#. name for oge
|
||||||
msgid "Georgian; Old"
|
msgid "Georgian; Old"
|
||||||
msgstr ""
|
msgstr "grúz; ógrúz"
|
||||||
|
|
||||||
#. name for ogg
|
#. name for ogg
|
||||||
msgid "Ogbogolo"
|
msgid "Ogbogolo"
|
||||||
@ -19679,11 +19685,11 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for oht
|
#. name for oht
|
||||||
msgid "Hittite; Old"
|
msgid "Hittite; Old"
|
||||||
msgstr ""
|
msgstr "hettita; óhettita"
|
||||||
|
|
||||||
#. name for ohu
|
#. name for ohu
|
||||||
msgid "Hungarian; Old"
|
msgid "Hungarian; Old"
|
||||||
msgstr ""
|
msgstr "magyar; ómagyar"
|
||||||
|
|
||||||
#. name for oia
|
#. name for oia
|
||||||
msgid "Oirata"
|
msgid "Oirata"
|
||||||
@ -19711,7 +19717,7 @@ msgstr "odzsibwa"
|
|||||||
|
|
||||||
#. name for ojp
|
#. name for ojp
|
||||||
msgid "Japanese; Old"
|
msgid "Japanese; Old"
|
||||||
msgstr ""
|
msgstr "japán; ójapán"
|
||||||
|
|
||||||
#. name for ojs
|
#. name for ojs
|
||||||
msgid "Ojibwa; Severn"
|
msgid "Ojibwa; Severn"
|
||||||
@ -19771,7 +19777,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for oko
|
#. name for oko
|
||||||
msgid "Korean; Old (3rd-9th cent.)"
|
msgid "Korean; Old (3rd-9th cent.)"
|
||||||
msgstr ""
|
msgstr "koreai; ókoreai (III--IX. sz.)"
|
||||||
|
|
||||||
#. name for okr
|
#. name for okr
|
||||||
msgid "Kirike"
|
msgid "Kirike"
|
||||||
@ -19939,7 +19945,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for onw
|
#. name for onw
|
||||||
msgid "Nubian; Old"
|
msgid "Nubian; Old"
|
||||||
msgstr ""
|
msgstr "núbiai; ónúbiai"
|
||||||
|
|
||||||
#. name for onx
|
#. name for onx
|
||||||
msgid "Onin Based Pidgin"
|
msgid "Onin Based Pidgin"
|
||||||
@ -20043,7 +20049,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for orv
|
#. name for orv
|
||||||
msgid "Russian; Old"
|
msgid "Russian; Old"
|
||||||
msgstr ""
|
msgstr "orosz; óorosz"
|
||||||
|
|
||||||
#. name for orw
|
#. name for orw
|
||||||
msgid "Oro Win"
|
msgid "Oro Win"
|
||||||
@ -20075,7 +20081,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for osp
|
#. name for osp
|
||||||
msgid "Spanish; Old"
|
msgid "Spanish; Old"
|
||||||
msgstr ""
|
msgstr "spanyol; óspanyol"
|
||||||
|
|
||||||
#. name for oss
|
#. name for oss
|
||||||
msgid "Ossetian"
|
msgid "Ossetian"
|
||||||
@ -20091,7 +20097,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for osx
|
#. name for osx
|
||||||
msgid "Saxon; Old"
|
msgid "Saxon; Old"
|
||||||
msgstr ""
|
msgstr "szász; ószász"
|
||||||
|
|
||||||
#. name for ota
|
#. name for ota
|
||||||
msgid "Turkish; Ottoman (1500-1928)"
|
msgid "Turkish; Ottoman (1500-1928)"
|
||||||
@ -20099,7 +20105,7 @@ msgstr "török (ottomán) (1500-1928)"
|
|||||||
|
|
||||||
#. name for otb
|
#. name for otb
|
||||||
msgid "Tibetan; Old"
|
msgid "Tibetan; Old"
|
||||||
msgstr ""
|
msgstr "tibeti; ótibeti"
|
||||||
|
|
||||||
#. name for otd
|
#. name for otd
|
||||||
msgid "Ot Danum"
|
msgid "Ot Danum"
|
||||||
@ -20115,7 +20121,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for otk
|
#. name for otk
|
||||||
msgid "Turkish; Old"
|
msgid "Turkish; Old"
|
||||||
msgstr ""
|
msgstr "török; ótörök"
|
||||||
|
|
||||||
#. name for otl
|
#. name for otl
|
||||||
msgid "Otomi; Tilapa"
|
msgid "Otomi; Tilapa"
|
||||||
@ -20159,7 +20165,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for oty
|
#. name for oty
|
||||||
msgid "Tamil; Old"
|
msgid "Tamil; Old"
|
||||||
msgstr ""
|
msgstr "tamil; ótamil"
|
||||||
|
|
||||||
#. name for otz
|
#. name for otz
|
||||||
msgid "Otomi; Ixtenco"
|
msgid "Otomi; Ixtenco"
|
||||||
@ -20179,7 +20185,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for oui
|
#. name for oui
|
||||||
msgid "Uighur; Old"
|
msgid "Uighur; Old"
|
||||||
msgstr ""
|
msgstr "ujgur; óujgur"
|
||||||
|
|
||||||
#. name for oum
|
#. name for oum
|
||||||
msgid "Ouma"
|
msgid "Ouma"
|
||||||
@ -20195,7 +20201,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for owl
|
#. name for owl
|
||||||
msgid "Welsh; Old"
|
msgid "Welsh; Old"
|
||||||
msgstr ""
|
msgstr "walesi; ówalesi"
|
||||||
|
|
||||||
#. name for oyb
|
#. name for oyb
|
||||||
msgid "Oy"
|
msgid "Oy"
|
||||||
@ -20532,7 +20538,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for peo
|
#. name for peo
|
||||||
msgid "Persian; Old (ca. 600-400 B.C.)"
|
msgid "Persian; Old (ca. 600-400 B.C.)"
|
||||||
msgstr ""
|
msgstr "perzsa"
|
||||||
|
|
||||||
#. name for pep
|
#. name for pep
|
||||||
msgid "Kunja"
|
msgid "Kunja"
|
||||||
@ -22487,7 +22493,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for sam
|
#. name for sam
|
||||||
msgid "Aramaic; Samaritan"
|
msgid "Aramaic; Samaritan"
|
||||||
msgstr ""
|
msgstr "arámi; szamaritánus"
|
||||||
|
|
||||||
# src/trans.h:193
|
# src/trans.h:193
|
||||||
#. name for san
|
#. name for san
|
||||||
@ -22914,7 +22920,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for sga
|
#. name for sga
|
||||||
msgid "Irish; Old (to 900)"
|
msgid "Irish; Old (to 900)"
|
||||||
msgstr "óír (900-ig)"
|
msgstr "ír; óír (900-ig)"
|
||||||
|
|
||||||
#. name for sgb
|
#. name for sgb
|
||||||
msgid "Ayta; Mag-antsi"
|
msgid "Ayta; Mag-antsi"
|
||||||
@ -25571,7 +25577,7 @@ msgstr "tumleo"
|
|||||||
|
|
||||||
#. name for tmr
|
#. name for tmr
|
||||||
msgid "Aramaic; Jewish Babylonian (ca. 200-1200 CE)"
|
msgid "Aramaic; Jewish Babylonian (ca. 200-1200 CE)"
|
||||||
msgstr ""
|
msgstr "arámi; zsidó babilóniai (kb. 200-1200)"
|
||||||
|
|
||||||
#. name for tms
|
#. name for tms
|
||||||
msgid "Tima"
|
msgid "Tima"
|
||||||
@ -28446,10 +28452,9 @@ msgstr ""
|
|||||||
msgid "Kombio"
|
msgid "Kombio"
|
||||||
msgstr "kombio"
|
msgstr "kombio"
|
||||||
|
|
||||||
# src/trans.h:285
|
|
||||||
#. name for xbm
|
#. name for xbm
|
||||||
msgid "Breton; Middle"
|
msgid "Breton; Middle"
|
||||||
msgstr "breton; közép"
|
msgstr "breton; Középkori"
|
||||||
|
|
||||||
#. name for xbn
|
#. name for xbn
|
||||||
msgid "Kenaboi"
|
msgid "Kenaboi"
|
||||||
@ -28514,7 +28519,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for xct
|
#. name for xct
|
||||||
msgid "Tibetan; Classical"
|
msgid "Tibetan; Classical"
|
||||||
msgstr ""
|
msgstr "tibeti; klasszikus"
|
||||||
|
|
||||||
#. name for xcu
|
#. name for xcu
|
||||||
msgid "Curonian"
|
msgid "Curonian"
|
||||||
@ -30792,7 +30797,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for zpg
|
#. name for zpg
|
||||||
msgid "Zapotec; Guevea De Humboldt"
|
msgid "Zapotec; Guevea De Humboldt"
|
||||||
msgstr ""
|
msgstr "zapoték; Guevea De Humboldt"
|
||||||
|
|
||||||
#. name for zph
|
#. name for zph
|
||||||
msgid "Zapotec; Totomachapan"
|
msgid "Zapotec; Totomachapan"
|
||||||
|
@ -12,14 +12,14 @@ msgstr ""
|
|||||||
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
||||||
"devel@lists.alioth.debian.org>\n"
|
"devel@lists.alioth.debian.org>\n"
|
||||||
"POT-Creation-Date: 2011-09-27 14:31+0000\n"
|
"POT-Creation-Date: 2011-09-27 14:31+0000\n"
|
||||||
"PO-Revision-Date: 2011-09-27 16:17+0000\n"
|
"PO-Revision-Date: 2011-11-03 23:08+0000\n"
|
||||||
"Last-Translator: Kovid Goyal <Unknown>\n"
|
"Last-Translator: drMerry <Unknown>\n"
|
||||||
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
|
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Launchpad-Export-Date: 2011-09-28 04:42+0000\n"
|
"X-Launchpad-Export-Date: 2011-11-05 04:47+0000\n"
|
||||||
"X-Generator: Launchpad (build 14049)\n"
|
"X-Generator: Launchpad (build 14231)\n"
|
||||||
"Language: nl\n"
|
"Language: nl\n"
|
||||||
|
|
||||||
#. name for aaa
|
#. name for aaa
|
||||||
@ -23624,7 +23624,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for som
|
#. name for som
|
||||||
msgid "Somali"
|
msgid "Somali"
|
||||||
msgstr "Somali"
|
msgstr "Somalisch"
|
||||||
|
|
||||||
#. name for soo
|
#. name for soo
|
||||||
msgid "Songo"
|
msgid "Songo"
|
||||||
@ -24504,7 +24504,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for tat
|
#. name for tat
|
||||||
msgid "Tatar"
|
msgid "Tatar"
|
||||||
msgstr "Tatar"
|
msgstr "Tataars"
|
||||||
|
|
||||||
#. name for tau
|
#. name for tau
|
||||||
msgid "Tanana; Upper"
|
msgid "Tanana; Upper"
|
||||||
|
@ -10,14 +10,14 @@ msgstr ""
|
|||||||
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
||||||
"devel@lists.alioth.debian.org>\n"
|
"devel@lists.alioth.debian.org>\n"
|
||||||
"POT-Creation-Date: 2011-09-27 14:31+0000\n"
|
"POT-Creation-Date: 2011-09-27 14:31+0000\n"
|
||||||
"PO-Revision-Date: 2011-10-25 19:06+0000\n"
|
"PO-Revision-Date: 2011-11-11 00:16+0000\n"
|
||||||
"Last-Translator: zeugma <Unknown>\n"
|
"Last-Translator: kulkke <Unknown>\n"
|
||||||
"Language-Team: Turkish <gnome-turk@gnome.org>\n"
|
"Language-Team: Turkish <gnome-turk@gnome.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Launchpad-Export-Date: 2011-10-26 05:13+0000\n"
|
"X-Launchpad-Export-Date: 2011-11-11 04:53+0000\n"
|
||||||
"X-Generator: Launchpad (build 14189)\n"
|
"X-Generator: Launchpad (build 14277)\n"
|
||||||
"Language: tr\n"
|
"Language: tr\n"
|
||||||
|
|
||||||
#. name for aaa
|
#. name for aaa
|
||||||
@ -18891,7 +18891,7 @@ msgstr ""
|
|||||||
|
|
||||||
#. name for nor
|
#. name for nor
|
||||||
msgid "Norwegian"
|
msgid "Norwegian"
|
||||||
msgstr "Norveççe"
|
msgstr "Norveçce"
|
||||||
|
|
||||||
#. name for nos
|
#. name for nos
|
||||||
msgid "Nisu; Eastern"
|
msgid "Nisu; Eastern"
|
||||||
|
@ -116,8 +116,14 @@ class UploadToGoogleCode(Command): # {{{
|
|||||||
return self.re_upload()
|
return self.re_upload()
|
||||||
|
|
||||||
for fname in installers():
|
for fname in installers():
|
||||||
path = self.upload_one(fname)
|
bname = os.path.basename(fname)
|
||||||
self.paths[os.path.basename(fname)] = path
|
if bname in self.old_files:
|
||||||
|
path = 'http://calibre-ebook.googlecode.com/files/'+bname
|
||||||
|
self.info('%s already uploaded, skipping. Assuming URL is: %s',
|
||||||
|
bname, path)
|
||||||
|
else:
|
||||||
|
path = self.upload_one(fname)
|
||||||
|
self.paths[bname] = path
|
||||||
self.info('Updating path map')
|
self.info('Updating path map')
|
||||||
self.info(repr(self.paths))
|
self.info(repr(self.paths))
|
||||||
raw = subprocess.Popen(['ssh', 'divok', 'cat', self.GPATHS],
|
raw = subprocess.Popen(['ssh', 'divok', 'cat', self.GPATHS],
|
||||||
|
@ -4,7 +4,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
__appname__ = u'calibre'
|
__appname__ = u'calibre'
|
||||||
numeric_version = (0, 8, 24)
|
numeric_version = (0, 8, 26)
|
||||||
__version__ = u'.'.join(map(unicode, numeric_version))
|
__version__ = u'.'.join(map(unicode, numeric_version))
|
||||||
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
|
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
|
||||||
|
|
||||||
|
@ -66,4 +66,6 @@ Various things that require other things before they can be migrated:
|
|||||||
functionality.
|
functionality.
|
||||||
2. Catching DatabaseException and sqlite.Error when creating new
|
2. Catching DatabaseException and sqlite.Error when creating new
|
||||||
libraries/switching/on calibre startup.
|
libraries/switching/on calibre startup.
|
||||||
|
3. From refresh in the legacy interface: Rember to flush the composite
|
||||||
|
column template cache.
|
||||||
'''
|
'''
|
||||||
|
@ -48,6 +48,7 @@ class Cache(object):
|
|||||||
self.read_lock, self.write_lock = create_locks()
|
self.read_lock, self.write_lock = create_locks()
|
||||||
self.record_lock = RecordLock(self.read_lock)
|
self.record_lock = RecordLock(self.read_lock)
|
||||||
self.format_metadata_cache = defaultdict(dict)
|
self.format_metadata_cache = defaultdict(dict)
|
||||||
|
self.formatter_template_cache = {}
|
||||||
|
|
||||||
# Implement locking for all simple read/write API methods
|
# Implement locking for all simple read/write API methods
|
||||||
# An unlocked version of the method is stored with the name starting
|
# An unlocked version of the method is stored with the name starting
|
||||||
@ -89,7 +90,7 @@ class Cache(object):
|
|||||||
return self.backend.format_abspath(book_id, fmt, name, path)
|
return self.backend.format_abspath(book_id, fmt, name, path)
|
||||||
|
|
||||||
def _get_metadata(self, book_id, get_user_categories=True): # {{{
|
def _get_metadata(self, book_id, get_user_categories=True): # {{{
|
||||||
mi = Metadata(None)
|
mi = Metadata(None, template_cache=self.formatter_template_cache)
|
||||||
author_ids = self._field_ids_for('authors', book_id)
|
author_ids = self._field_ids_for('authors', book_id)
|
||||||
aut_list = [self._author_data(i) for i in author_ids]
|
aut_list = [self._author_data(i) for i in author_ids]
|
||||||
aum = []
|
aum = []
|
||||||
|
@ -166,11 +166,12 @@ class ANDROID(USBMS):
|
|||||||
'MB525', 'ANDROID2.3', 'SGH-I997', 'GT-I5800_CARD', 'MB612',
|
'MB525', 'ANDROID2.3', 'SGH-I997', 'GT-I5800_CARD', 'MB612',
|
||||||
'GT-S5830_CARD', 'GT-S5570_CARD', 'MB870', 'MID7015A',
|
'GT-S5830_CARD', 'GT-S5570_CARD', 'MB870', 'MID7015A',
|
||||||
'ALPANDIGITAL', 'ANDROID_MID', 'VTAB1008', 'EMX51_BBG_ANDROI',
|
'ALPANDIGITAL', 'ANDROID_MID', 'VTAB1008', 'EMX51_BBG_ANDROI',
|
||||||
'UMS', '.K080']
|
'UMS', '.K080', 'P990']
|
||||||
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
||||||
'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
||||||
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',
|
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',
|
||||||
'__UMS_COMPOSITE', 'SGH-I997_CARD', 'MB870', 'ALPANDIGITAL', 'ANDROID_MID']
|
'__UMS_COMPOSITE', 'SGH-I997_CARD', 'MB870', 'ALPANDIGITAL',
|
||||||
|
'ANDROID_MID', 'P990_SD_CARD', '.K080']
|
||||||
|
|
||||||
OSX_MAIN_MEM = 'Android Device Main Memory'
|
OSX_MAIN_MEM = 'Android Device Main Memory'
|
||||||
|
|
||||||
|
@ -256,6 +256,8 @@ class DevicePlugin(Plugin):
|
|||||||
|
|
||||||
def set_progress_reporter(self, report_progress):
|
def set_progress_reporter(self, report_progress):
|
||||||
'''
|
'''
|
||||||
|
Set a function to report progress information.
|
||||||
|
|
||||||
:param report_progress: Function that is called with a % progress
|
:param report_progress: Function that is called with a % progress
|
||||||
(number between 0 and 100) for various tasks
|
(number between 0 and 100) for various tasks
|
||||||
If it is called with -1 that means that the
|
If it is called with -1 that means that the
|
||||||
|
@ -40,7 +40,7 @@ class KOBO(USBMS):
|
|||||||
CAN_SET_METADATA = ['collections']
|
CAN_SET_METADATA = ['collections']
|
||||||
|
|
||||||
VENDOR_ID = [0x2237]
|
VENDOR_ID = [0x2237]
|
||||||
PRODUCT_ID = [0x4161, 0x4163]
|
PRODUCT_ID = [0x4161, 0x4163, 0x4165]
|
||||||
BCD = [0x0110, 0x0323, 0x0326]
|
BCD = [0x0110, 0x0323, 0x0326]
|
||||||
|
|
||||||
VENDOR_NAME = ['KOBO_INC', 'KOBO']
|
VENDOR_NAME = ['KOBO_INC', 'KOBO']
|
||||||
|
@ -233,7 +233,7 @@ class TREKSTOR(USBMS):
|
|||||||
|
|
||||||
VENDOR_NAME = 'TREKSTOR'
|
VENDOR_NAME = 'TREKSTOR'
|
||||||
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['EBOOK_PLAYER_7',
|
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['EBOOK_PLAYER_7',
|
||||||
'EBOOK_PLAYER_5M']
|
'EBOOK_PLAYER_5M', 'EBOOK-READER_3.0']
|
||||||
|
|
||||||
class EEEREADER(USBMS):
|
class EEEREADER(USBMS):
|
||||||
|
|
||||||
|
@ -503,7 +503,10 @@ class PRST1(USBMS):
|
|||||||
|
|
||||||
def upload_book_cover(self, connection, book, source_id):
|
def upload_book_cover(self, connection, book, source_id):
|
||||||
debug_print('PRST1: Uploading/Refreshing Cover for ' + book.title)
|
debug_print('PRST1: Uploading/Refreshing Cover for ' + book.title)
|
||||||
if not book.thumbnail or not book.thumbnail[-1]:
|
if (not book.thumbnail or isinstance(book.thumbnail, ImageWrapper) or
|
||||||
|
not book.thumbnail[-1]):
|
||||||
|
# If the thumbnail is an ImageWrapper instance, it refers to a book
|
||||||
|
# not in the calibre library
|
||||||
return
|
return
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ class EPUBInput(InputFormatPlugin):
|
|||||||
for y in opf.itermanifest():
|
for y in opf.itermanifest():
|
||||||
id_ = y.get('id', None)
|
id_ = y.get('id', None)
|
||||||
if id_ and y.get('media-type', None) in \
|
if id_ and y.get('media-type', None) in \
|
||||||
('application/vnd.adobe-page-template+xml',):
|
('application/vnd.adobe-page-template+xml','application/text'):
|
||||||
not_for_spine.add(id_)
|
not_for_spine.add(id_)
|
||||||
|
|
||||||
for x in list(opf.iterspine()):
|
for x in list(opf.iterspine()):
|
||||||
@ -189,6 +189,9 @@ class EPUBInput(InputFormatPlugin):
|
|||||||
x.getparent().remove(x)
|
x.getparent().remove(x)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if len(list(opf.iterspine())) == 0:
|
||||||
|
raise ValueError('No valid entries in the spine of this EPUB')
|
||||||
|
|
||||||
with open('content.opf', 'wb') as nopf:
|
with open('content.opf', 'wb') as nopf:
|
||||||
nopf.write(opf.render())
|
nopf.write(opf.render())
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ Input plugin for HTML or OPF ebooks.
|
|||||||
|
|
||||||
import os, re, sys, uuid, tempfile, errno as gerrno
|
import os, re, sys, uuid, tempfile, errno as gerrno
|
||||||
from urlparse import urlparse, urlunparse
|
from urlparse import urlparse, urlunparse
|
||||||
from urllib import unquote
|
from urllib import unquote, quote
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from itertools import izip
|
from itertools import izip
|
||||||
|
|
||||||
@ -468,7 +468,10 @@ class HTMLInput(InputFormatPlugin):
|
|||||||
self.oeb.log, ignore_opf=True)
|
self.oeb.log, ignore_opf=True)
|
||||||
# Load into memory
|
# Load into memory
|
||||||
item = self.oeb.manifest.add(id, href, media_type)
|
item = self.oeb.manifest.add(id, href, media_type)
|
||||||
item.html_input_href = bhref
|
# bhref refers to an already existing file. The read() method of
|
||||||
|
# DirContainer will call unquote on it before trying to read the
|
||||||
|
# file, therefore we quote it here.
|
||||||
|
item.html_input_href = quote(bhref)
|
||||||
if guessed in self.OEB_STYLES:
|
if guessed in self.OEB_STYLES:
|
||||||
item.override_css_fetch = partial(
|
item.override_css_fetch = partial(
|
||||||
self.css_import_handler, os.path.dirname(link))
|
self.css_import_handler, os.path.dirname(link))
|
||||||
|
@ -32,6 +32,7 @@ NULL_VALUES = {
|
|||||||
'device_collections': [],
|
'device_collections': [],
|
||||||
'author_sort_map': {},
|
'author_sort_map': {},
|
||||||
'authors' : [_('Unknown')],
|
'authors' : [_('Unknown')],
|
||||||
|
'author_sort' : _('Unknown'),
|
||||||
'title' : _('Unknown'),
|
'title' : _('Unknown'),
|
||||||
'user_categories' : {},
|
'user_categories' : {},
|
||||||
'author_link_map' : {},
|
'author_link_map' : {},
|
||||||
@ -45,9 +46,9 @@ class SafeFormat(TemplateFormatter):
|
|||||||
def get_value(self, orig_key, args, kwargs):
|
def get_value(self, orig_key, args, kwargs):
|
||||||
if not orig_key:
|
if not orig_key:
|
||||||
return ''
|
return ''
|
||||||
orig_key = orig_key.lower()
|
key = orig_key = orig_key.lower()
|
||||||
key = orig_key
|
if key != 'title_sort' and key not in TOP_LEVEL_IDENTIFIERS and \
|
||||||
if key != 'title_sort' and key not in TOP_LEVEL_IDENTIFIERS:
|
key not in ALL_METADATA_FIELDS:
|
||||||
key = field_metadata.search_term_to_field_key(key)
|
key = field_metadata.search_term_to_field_key(key)
|
||||||
if key is None or (self.book and
|
if key is None or (self.book and
|
||||||
key not in self.book.all_field_keys()):
|
key not in self.book.all_field_keys()):
|
||||||
@ -59,9 +60,8 @@ class SafeFormat(TemplateFormatter):
|
|||||||
b = self.book.get_user_metadata(key, False)
|
b = self.book.get_user_metadata(key, False)
|
||||||
except:
|
except:
|
||||||
b = None
|
b = None
|
||||||
if b and b['datatype'] == 'int' and self.book.get(key, 0) == 0:
|
if b and ((b['datatype'] == 'int' and self.book.get(key, 0) == 0) or
|
||||||
v = ''
|
(b['datatype'] == 'float' and self.book.get(key, 0.0) == 0.0)):
|
||||||
elif b and b['datatype'] == 'float' and self.book.get(key, 0.0) == 0.0:
|
|
||||||
v = ''
|
v = ''
|
||||||
else:
|
else:
|
||||||
v = self.book.format_field(key, series_with_index=False)[1]
|
v = self.book.format_field(key, series_with_index=False)[1]
|
||||||
@ -95,7 +95,7 @@ class Metadata(object):
|
|||||||
becomes a reserved field name.
|
becomes a reserved field name.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, title, authors=(_('Unknown'),), other=None):
|
def __init__(self, title, authors=(_('Unknown'),), other=None, template_cache=None):
|
||||||
'''
|
'''
|
||||||
@param title: title or ``_('Unknown')``
|
@param title: title or ``_('Unknown')``
|
||||||
@param authors: List of strings or []
|
@param authors: List of strings or []
|
||||||
@ -114,6 +114,7 @@ class Metadata(object):
|
|||||||
self.author = list(authors) if authors else []# Needed for backward compatibility
|
self.author = list(authors) if authors else []# Needed for backward compatibility
|
||||||
self.authors = list(authors) if authors else []
|
self.authors = list(authors) if authors else []
|
||||||
self.formatter = SafeFormat()
|
self.formatter = SafeFormat()
|
||||||
|
self.template_cache = template_cache
|
||||||
|
|
||||||
def is_null(self, field):
|
def is_null(self, field):
|
||||||
'''
|
'''
|
||||||
@ -159,7 +160,8 @@ class Metadata(object):
|
|||||||
d['display']['composite_template'],
|
d['display']['composite_template'],
|
||||||
self,
|
self,
|
||||||
_('TEMPLATE ERROR'),
|
_('TEMPLATE ERROR'),
|
||||||
self).strip()
|
self, column_name=field,
|
||||||
|
template_cache=self.template_cache).strip()
|
||||||
return val
|
return val
|
||||||
if field.startswith('#') and field.endswith('_index'):
|
if field.startswith('#') and field.endswith('_index'):
|
||||||
try:
|
try:
|
||||||
|
@ -341,11 +341,11 @@ class Worker(Thread): # Get details {{{
|
|||||||
return authors
|
return authors
|
||||||
|
|
||||||
def parse_rating(self, root):
|
def parse_rating(self, root):
|
||||||
ratings = root.xpath('//div[@class="jumpBar"]/descendant::span[@class="asinReviewsSummary"]')
|
ratings = root.xpath('//div[@class="jumpBar"]/descendant::span[contains(@class,"asinReviewsSummary")]')
|
||||||
if not ratings:
|
if not ratings:
|
||||||
ratings = root.xpath('//div[@class="buying"]/descendant::span[@class="asinReviewsSummary"]')
|
ratings = root.xpath('//div[@class="buying"]/descendant::span[contains(@class,"asinReviewsSummary")]')
|
||||||
if not ratings:
|
if not ratings:
|
||||||
ratings = root.xpath('//span[@class="crAvgStars"]/descendant::span[@class="asinReviewsSummary"]')
|
ratings = root.xpath('//span[@class="crAvgStars"]/descendant::span[contains(@class,"asinReviewsSummary")]')
|
||||||
if ratings:
|
if ratings:
|
||||||
for elem in ratings[0].xpath('descendant::*[@title]'):
|
for elem in ratings[0].xpath('descendant::*[@title]'):
|
||||||
t = elem.get('title').strip()
|
t = elem.get('title').strip()
|
||||||
|
@ -44,15 +44,19 @@ class Extract(ODF2XHTML):
|
|||||||
# Remove the position:relative as it causes problems with some epub
|
# Remove the position:relative as it causes problems with some epub
|
||||||
# renderers. Remove display: block on an image inside a div as it is
|
# renderers. Remove display: block on an image inside a div as it is
|
||||||
# redundant and prevents text-align:center from working in ADE
|
# redundant and prevents text-align:center from working in ADE
|
||||||
|
# Also ensure that the img is contained in its containing div
|
||||||
imgpath = XPath('//h:div/h:img[@style]')
|
imgpath = XPath('//h:div/h:img[@style]')
|
||||||
for img in imgpath(root):
|
for img in imgpath(root):
|
||||||
div = img.getparent()
|
div = img.getparent()
|
||||||
if len(div) == 1:
|
if len(div) == 1:
|
||||||
style = div.attrib['style'].replace('position:relative', '')
|
style = div.attrib.get('style', '')
|
||||||
if style.startswith(';'): style = style[1:]
|
if style and not style.endswith(';'):
|
||||||
|
style = style + ';'
|
||||||
|
style += 'position:static' # Ensures position of containing
|
||||||
|
# div is static
|
||||||
|
# Ensure that the img is always contained in its frame
|
||||||
div.attrib['style'] = style
|
div.attrib['style'] = style
|
||||||
if img.attrib.get('style', '') == 'display: block;':
|
img.attrib['style'] = 'max-width: 100%; max-height: 100%'
|
||||||
del img.attrib['style']
|
|
||||||
|
|
||||||
# A div/div/img construct causes text-align:center to not work in ADE
|
# A div/div/img construct causes text-align:center to not work in ADE
|
||||||
# so set the display of the second div to inline. This should have no
|
# so set the display of the second div to inline. This should have no
|
||||||
|
@ -6,7 +6,7 @@ from threading import RLock
|
|||||||
from urllib import unquote
|
from urllib import unquote
|
||||||
from PyQt4.Qt import (QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt,
|
from PyQt4.Qt import (QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt,
|
||||||
QByteArray, QTranslator, QCoreApplication, QThread,
|
QByteArray, QTranslator, QCoreApplication, QThread,
|
||||||
QEvent, QTimer, pyqtSignal, QDate, QDesktopServices,
|
QEvent, QTimer, pyqtSignal, QDateTime, QDesktopServices,
|
||||||
QFileDialog, QFileIconProvider, QSettings,
|
QFileDialog, QFileIconProvider, QSettings,
|
||||||
QIcon, QApplication, QDialog, QUrl, QFont)
|
QIcon, QApplication, QDialog, QUrl, QFont)
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ gprefs.defaults['show_files_after_save'] = True
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
NONE = QVariant() #: Null value to return from the data function of item models
|
NONE = QVariant() #: Null value to return from the data function of item models
|
||||||
UNDEFINED_QDATE = QDate(UNDEFINED_DATE)
|
UNDEFINED_QDATETIME = QDateTime(UNDEFINED_DATE)
|
||||||
|
|
||||||
ALL_COLUMNS = ['title', 'ondevice', 'authors', 'size', 'timestamp', 'rating', 'publisher',
|
ALL_COLUMNS = ['title', 'ondevice', 'authors', 'size', 'timestamp', 'rating', 'publisher',
|
||||||
'tags', 'series', 'pubdate']
|
'tags', 'series', 'pubdate']
|
||||||
|
@ -22,7 +22,6 @@ from calibre.constants import preferred_encoding, filesystem_encoding
|
|||||||
from calibre.gui2.actions import InterfaceAction
|
from calibre.gui2.actions import InterfaceAction
|
||||||
from calibre.gui2 import question_dialog
|
from calibre.gui2 import question_dialog
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
from calibre.ebooks.metadata.sources.base import msprefs
|
|
||||||
|
|
||||||
def get_filters():
|
def get_filters():
|
||||||
return [
|
return [
|
||||||
@ -181,17 +180,9 @@ class AddAction(InterfaceAction):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
self.gui.library_view.model().books_added(self.isbn_add_dialog.value)
|
self.gui.library_view.model().books_added(self.isbn_add_dialog.value)
|
||||||
self.isbn_add_dialog.accept()
|
self.isbn_add_dialog.accept()
|
||||||
orig = msprefs['ignore_fields']
|
self.gui.iactions['Edit Metadata'].download_metadata(
|
||||||
new = list(orig)
|
ids=self.add_by_isbn_ids, ensure_fields=frozenset(['title',
|
||||||
for x in ('title', 'authors'):
|
'authors']))
|
||||||
if x in new:
|
|
||||||
new.remove(x)
|
|
||||||
msprefs['ignore_fields'] = new
|
|
||||||
try:
|
|
||||||
self.gui.iactions['Edit Metadata'].download_metadata(
|
|
||||||
ids=self.add_by_isbn_ids)
|
|
||||||
finally:
|
|
||||||
msprefs['ignore_fields'] = orig
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class EditMetadataAction(InterfaceAction):
|
|||||||
self.action_merge.setEnabled(enabled)
|
self.action_merge.setEnabled(enabled)
|
||||||
|
|
||||||
# Download metadata {{{
|
# Download metadata {{{
|
||||||
def download_metadata(self, ids=None):
|
def download_metadata(self, ids=None, ensure_fields=None):
|
||||||
if ids is None:
|
if ids is None:
|
||||||
rows = self.gui.library_view.selectionModel().selectedRows()
|
rows = self.gui.library_view.selectionModel().selectedRows()
|
||||||
if not rows or len(rows) == 0:
|
if not rows or len(rows) == 0:
|
||||||
@ -76,7 +76,8 @@ class EditMetadataAction(InterfaceAction):
|
|||||||
ids = [db.id(row.row()) for row in rows]
|
ids = [db.id(row.row()) for row in rows]
|
||||||
from calibre.gui2.metadata.bulk_download import start_download
|
from calibre.gui2.metadata.bulk_download import start_download
|
||||||
start_download(self.gui, ids,
|
start_download(self.gui, ids,
|
||||||
Dispatcher(self.metadata_downloaded))
|
Dispatcher(self.metadata_downloaded),
|
||||||
|
ensure_fields=ensure_fields)
|
||||||
|
|
||||||
def metadata_downloaded(self, job):
|
def metadata_downloaded(self, job):
|
||||||
if job.failed:
|
if job.failed:
|
||||||
|
@ -7,15 +7,15 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from PyQt4.Qt import QComboBox, QLabel, QSpinBox, QDoubleSpinBox, QDateEdit, \
|
from PyQt4.Qt import QComboBox, QLabel, QSpinBox, QDoubleSpinBox, QDateTimeEdit, \
|
||||||
QDate, QGroupBox, QVBoxLayout, QSizePolicy, \
|
QDateTime, QGroupBox, QVBoxLayout, QSizePolicy, \
|
||||||
QSpacerItem, QIcon, QCheckBox, QWidget, QHBoxLayout, SIGNAL, \
|
QSpacerItem, QIcon, QCheckBox, QWidget, QHBoxLayout, SIGNAL, \
|
||||||
QPushButton
|
QPushButton
|
||||||
|
|
||||||
from calibre.utils.date import qt_to_dt, now
|
from calibre.utils.date import qt_to_dt, now
|
||||||
from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox
|
from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox
|
||||||
from calibre.gui2.comments_editor import Editor as CommentsEditor
|
from calibre.gui2.comments_editor import Editor as CommentsEditor
|
||||||
from calibre.gui2 import UNDEFINED_QDATE, error_dialog
|
from calibre.gui2 import UNDEFINED_QDATETIME, error_dialog
|
||||||
from calibre.utils.config import tweaks
|
from calibre.utils.config import tweaks
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
from calibre.library.comments import comments_to_html
|
from calibre.library.comments import comments_to_html
|
||||||
@ -142,27 +142,27 @@ class Rating(Int):
|
|||||||
val *= 2
|
val *= 2
|
||||||
return val
|
return val
|
||||||
|
|
||||||
class DateEdit(QDateEdit):
|
class DateTimeEdit(QDateTimeEdit):
|
||||||
|
|
||||||
def focusInEvent(self, x):
|
def focusInEvent(self, x):
|
||||||
self.setSpecialValueText('')
|
self.setSpecialValueText('')
|
||||||
QDateEdit.focusInEvent(self, x)
|
QDateTimeEdit.focusInEvent(self, x)
|
||||||
|
|
||||||
def focusOutEvent(self, x):
|
def focusOutEvent(self, x):
|
||||||
self.setSpecialValueText(_('Undefined'))
|
self.setSpecialValueText(_('Undefined'))
|
||||||
QDateEdit.focusOutEvent(self, x)
|
QDateTimeEdit.focusOutEvent(self, x)
|
||||||
|
|
||||||
def set_to_today(self):
|
def set_to_today(self):
|
||||||
self.setDate(now())
|
self.setDateTime(now())
|
||||||
|
|
||||||
def set_to_clear(self):
|
def set_to_clear(self):
|
||||||
self.setDate(UNDEFINED_QDATE)
|
self.setDateTime(UNDEFINED_QDATETIME)
|
||||||
|
|
||||||
class DateTime(Base):
|
class DateTime(Base):
|
||||||
|
|
||||||
def setup_ui(self, parent):
|
def setup_ui(self, parent):
|
||||||
cm = self.col_metadata
|
cm = self.col_metadata
|
||||||
self.widgets = [QLabel('&'+cm['name']+':', parent), DateEdit(parent)]
|
self.widgets = [QLabel('&'+cm['name']+':', parent), DateTimeEdit(parent)]
|
||||||
self.widgets.append(QLabel(''))
|
self.widgets.append(QLabel(''))
|
||||||
w = QWidget(parent)
|
w = QWidget(parent)
|
||||||
self.widgets.append(w)
|
self.widgets.append(w)
|
||||||
@ -179,24 +179,24 @@ class DateTime(Base):
|
|||||||
w = self.widgets[1]
|
w = self.widgets[1]
|
||||||
format = cm['display'].get('date_format','')
|
format = cm['display'].get('date_format','')
|
||||||
if not format:
|
if not format:
|
||||||
format = 'dd MMM yyyy'
|
format = 'dd MMM yyyy hh:mm'
|
||||||
w.setDisplayFormat(format)
|
w.setDisplayFormat(format)
|
||||||
w.setCalendarPopup(True)
|
w.setCalendarPopup(True)
|
||||||
w.setMinimumDate(UNDEFINED_QDATE)
|
w.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
w.setSpecialValueText(_('Undefined'))
|
w.setSpecialValueText(_('Undefined'))
|
||||||
self.today_button.clicked.connect(w.set_to_today)
|
self.today_button.clicked.connect(w.set_to_today)
|
||||||
self.clear_button.clicked.connect(w.set_to_clear)
|
self.clear_button.clicked.connect(w.set_to_clear)
|
||||||
|
|
||||||
def setter(self, val):
|
def setter(self, val):
|
||||||
if val is None:
|
if val is None:
|
||||||
val = self.widgets[1].minimumDate()
|
val = self.widgets[1].minimumDateTime()
|
||||||
else:
|
else:
|
||||||
val = QDate(val.year, val.month, val.day)
|
val = QDateTime(val)
|
||||||
self.widgets[1].setDate(val)
|
self.widgets[1].setDateTime(val)
|
||||||
|
|
||||||
def getter(self):
|
def getter(self):
|
||||||
val = self.widgets[1].date()
|
val = self.widgets[1].dateTime()
|
||||||
if val == UNDEFINED_QDATE:
|
if val <= UNDEFINED_QDATETIME:
|
||||||
val = None
|
val = None
|
||||||
else:
|
else:
|
||||||
val = qt_to_dt(val)
|
val = qt_to_dt(val)
|
||||||
@ -537,9 +537,9 @@ class BulkBase(Base):
|
|||||||
if hasattr(self.main_widget, 'valueChanged'):
|
if hasattr(self.main_widget, 'valueChanged'):
|
||||||
# spinbox widgets
|
# spinbox widgets
|
||||||
self.main_widget.valueChanged.connect(self.a_c_checkbox_changed)
|
self.main_widget.valueChanged.connect(self.a_c_checkbox_changed)
|
||||||
if hasattr(self.main_widget, 'dateChanged'):
|
if hasattr(self.main_widget, 'dateTimeChanged'):
|
||||||
# dateEdit widgets
|
# dateEdit widgets
|
||||||
self.main_widget.dateChanged.connect(self.a_c_checkbox_changed)
|
self.main_widget.dateTimeChanged.connect(self.a_c_checkbox_changed)
|
||||||
|
|
||||||
def a_c_checkbox_changed(self):
|
def a_c_checkbox_changed(self):
|
||||||
if not self.ignore_change_signals:
|
if not self.ignore_change_signals:
|
||||||
@ -658,7 +658,7 @@ class BulkDateTime(BulkBase):
|
|||||||
|
|
||||||
def setup_ui(self, parent):
|
def setup_ui(self, parent):
|
||||||
cm = self.col_metadata
|
cm = self.col_metadata
|
||||||
self.make_widgets(parent, DateEdit)
|
self.make_widgets(parent, DateTimeEdit)
|
||||||
self.widgets.append(QLabel(''))
|
self.widgets.append(QLabel(''))
|
||||||
w = QWidget(parent)
|
w = QWidget(parent)
|
||||||
self.widgets.append(w)
|
self.widgets.append(w)
|
||||||
@ -678,22 +678,22 @@ class BulkDateTime(BulkBase):
|
|||||||
format = 'dd MMM yyyy'
|
format = 'dd MMM yyyy'
|
||||||
w.setDisplayFormat(format)
|
w.setDisplayFormat(format)
|
||||||
w.setCalendarPopup(True)
|
w.setCalendarPopup(True)
|
||||||
w.setMinimumDate(UNDEFINED_QDATE)
|
w.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
w.setSpecialValueText(_('Undefined'))
|
w.setSpecialValueText(_('Undefined'))
|
||||||
self.today_button.clicked.connect(w.set_to_today)
|
self.today_button.clicked.connect(w.set_to_today)
|
||||||
self.clear_button.clicked.connect(w.set_to_clear)
|
self.clear_button.clicked.connect(w.set_to_clear)
|
||||||
|
|
||||||
def setter(self, val):
|
def setter(self, val):
|
||||||
if val is None:
|
if val is None:
|
||||||
val = self.main_widget.minimumDate()
|
val = self.main_widget.minimumDateTime()
|
||||||
else:
|
else:
|
||||||
val = QDate(val.year, val.month, val.day)
|
val = QDateTime(val)
|
||||||
self.main_widget.setDate(val)
|
self.main_widget.setDateTime(val)
|
||||||
self.ignore_change_signals = False
|
self.ignore_change_signals = False
|
||||||
|
|
||||||
def getter(self):
|
def getter(self):
|
||||||
val = self.main_widget.date()
|
val = self.main_widget.dateTime()
|
||||||
if val == UNDEFINED_QDATE:
|
if val <= UNDEFINED_QDATETIME:
|
||||||
val = None
|
val = None
|
||||||
else:
|
else:
|
||||||
val = qt_to_dt(val)
|
val = qt_to_dt(val)
|
||||||
|
@ -7,14 +7,14 @@ import re, os, inspect
|
|||||||
|
|
||||||
from PyQt4.Qt import Qt, QDialog, QGridLayout, QVBoxLayout, QFont, QLabel, \
|
from PyQt4.Qt import Qt, QDialog, QGridLayout, QVBoxLayout, QFont, QLabel, \
|
||||||
pyqtSignal, QDialogButtonBox, QInputDialog, QLineEdit, \
|
pyqtSignal, QDialogButtonBox, QInputDialog, QLineEdit, \
|
||||||
QDate, QCompleter
|
QDateTime, QCompleter
|
||||||
|
|
||||||
from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog
|
from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog
|
||||||
from calibre.gui2.dialogs.tag_editor import TagEditor
|
from calibre.gui2.dialogs.tag_editor import TagEditor
|
||||||
from calibre.ebooks.metadata import string_to_authors, authors_to_string, title_sort
|
from calibre.ebooks.metadata import string_to_authors, authors_to_string, title_sort
|
||||||
from calibre.ebooks.metadata.book.base import SafeFormat
|
from calibre.ebooks.metadata.book.base import SafeFormat
|
||||||
from calibre.gui2.custom_column_widgets import populate_metadata_page
|
from calibre.gui2.custom_column_widgets import populate_metadata_page
|
||||||
from calibre.gui2 import error_dialog, ResizableDialog, UNDEFINED_QDATE, \
|
from calibre.gui2 import error_dialog, ResizableDialog, UNDEFINED_QDATETIME, \
|
||||||
gprefs, question_dialog
|
gprefs, question_dialog
|
||||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||||
from calibre.utils.config import dynamic, JSONConfig
|
from calibre.utils.config import dynamic, JSONConfig
|
||||||
@ -306,18 +306,21 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
|
|||||||
self.series.editTextChanged.connect(self.series_changed)
|
self.series.editTextChanged.connect(self.series_changed)
|
||||||
self.tag_editor_button.clicked.connect(self.tag_editor)
|
self.tag_editor_button.clicked.connect(self.tag_editor)
|
||||||
self.autonumber_series.stateChanged[int].connect(self.auto_number_changed)
|
self.autonumber_series.stateChanged[int].connect(self.auto_number_changed)
|
||||||
self.pubdate.setMinimumDate(UNDEFINED_QDATE)
|
self.pubdate.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
pubdate_format = tweaks['gui_pubdate_display_format']
|
pubdate_format = tweaks['gui_pubdate_display_format']
|
||||||
if pubdate_format is not None:
|
if pubdate_format is not None:
|
||||||
self.pubdate.setDisplayFormat(pubdate_format)
|
self.pubdate.setDisplayFormat(pubdate_format)
|
||||||
self.pubdate.setSpecialValueText(_('Undefined'))
|
self.pubdate.setSpecialValueText(_('Undefined'))
|
||||||
self.clear_pubdate_button.clicked.connect(self.clear_pubdate)
|
self.clear_pubdate_button.clicked.connect(self.clear_pubdate)
|
||||||
self.pubdate.dateChanged.connect(self.do_apply_pubdate)
|
self.pubdate.dateTimeChanged.connect(self.do_apply_pubdate)
|
||||||
self.adddate.setDate(QDate.currentDate())
|
self.adddate.setDateTime(QDateTime.currentDateTime())
|
||||||
self.adddate.setMinimumDate(UNDEFINED_QDATE)
|
self.adddate.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
|
adddate_format = tweaks['gui_timestamp_display_format']
|
||||||
|
if adddate_format is not None:
|
||||||
|
self.adddate.setDisplayFormat(adddate_format)
|
||||||
self.adddate.setSpecialValueText(_('Undefined'))
|
self.adddate.setSpecialValueText(_('Undefined'))
|
||||||
self.clear_adddate_button.clicked.connect(self.clear_adddate)
|
self.clear_adddate_button.clicked.connect(self.clear_adddate)
|
||||||
self.adddate.dateChanged.connect(self.do_apply_adddate)
|
self.adddate.dateTimeChanged.connect(self.do_apply_adddate)
|
||||||
|
|
||||||
if len(self.db.custom_field_keys(include_composites=False)) == 0:
|
if len(self.db.custom_field_keys(include_composites=False)) == 0:
|
||||||
self.central_widget.removeTab(1)
|
self.central_widget.removeTab(1)
|
||||||
@ -347,13 +350,13 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
|
|||||||
self.apply_pubdate.setChecked(True)
|
self.apply_pubdate.setChecked(True)
|
||||||
|
|
||||||
def clear_pubdate(self, *args):
|
def clear_pubdate(self, *args):
|
||||||
self.pubdate.setDate(UNDEFINED_QDATE)
|
self.pubdate.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
|
|
||||||
def do_apply_adddate(self, *args):
|
def do_apply_adddate(self, *args):
|
||||||
self.apply_adddate.setChecked(True)
|
self.apply_adddate.setChecked(True)
|
||||||
|
|
||||||
def clear_adddate(self, *args):
|
def clear_adddate(self, *args):
|
||||||
self.adddate.setDate(UNDEFINED_QDATE)
|
self.adddate.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
|
|
||||||
def button_clicked(self, which):
|
def button_clicked(self, which):
|
||||||
if which == self.button_box.button(QDialogButtonBox.Apply):
|
if which == self.button_box.button(QDialogButtonBox.Apply):
|
||||||
@ -935,9 +938,9 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
|
|||||||
languages = self.languages.lang_codes
|
languages = self.languages.lang_codes
|
||||||
pubdate = adddate = None
|
pubdate = adddate = None
|
||||||
if self.apply_pubdate.isChecked():
|
if self.apply_pubdate.isChecked():
|
||||||
pubdate = qt_to_dt(self.pubdate.date())
|
pubdate = qt_to_dt(self.pubdate.dateTime())
|
||||||
if self.apply_adddate.isChecked():
|
if self.apply_adddate.isChecked():
|
||||||
adddate = qt_to_dt(self.adddate.date())
|
adddate = qt_to_dt(self.adddate.dateTime())
|
||||||
|
|
||||||
cover_action = None
|
cover_action = None
|
||||||
if self.cover_remove.isChecked():
|
if self.cover_remove.isChecked():
|
||||||
|
@ -366,7 +366,7 @@ from the value in the box</string>
|
|||||||
<item row="9" column="1">
|
<item row="9" column="1">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDateEdit" name="adddate">
|
<widget class="QDateTimeEdit" name="adddate">
|
||||||
<property name="displayFormat">
|
<property name="displayFormat">
|
||||||
<string>d MMM yyyy</string>
|
<string>d MMM yyyy</string>
|
||||||
</property>
|
</property>
|
||||||
@ -411,7 +411,7 @@ from the value in the box</string>
|
|||||||
<item row="10" column="1">
|
<item row="10" column="1">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDateEdit" name="pubdate">
|
<widget class="QDateTimeEdit" name="pubdate">
|
||||||
<property name="displayFormat">
|
<property name="displayFormat">
|
||||||
<string>MMM yyyy</string>
|
<string>MMM yyyy</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -14,10 +14,10 @@ from PyQt4.Qt import (QColor, Qt, QModelIndex, QSize, QApplication,
|
|||||||
QStyledItemDelegate, QComboBox, QTextDocument,
|
QStyledItemDelegate, QComboBox, QTextDocument,
|
||||||
QAbstractTextDocumentLayout)
|
QAbstractTextDocumentLayout)
|
||||||
|
|
||||||
from calibre.gui2 import UNDEFINED_QDATE, error_dialog
|
from calibre.gui2 import UNDEFINED_QDATETIME, error_dialog
|
||||||
from calibre.gui2.widgets import EnLineEdit
|
from calibre.gui2.widgets import EnLineEdit
|
||||||
from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox
|
from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox
|
||||||
from calibre.utils.date import now, format_date
|
from calibre.utils.date import now, format_date, qt_to_dt
|
||||||
from calibre.utils.config import tweaks
|
from calibre.utils.config import tweaks
|
||||||
from calibre.utils.formatter import validation_formatter
|
from calibre.utils.formatter import validation_formatter
|
||||||
from calibre.utils.icu import sort_key
|
from calibre.utils.icu import sort_key
|
||||||
@ -107,25 +107,23 @@ class RatingDelegate(QStyledItemDelegate): # {{{
|
|||||||
class DateDelegate(QStyledItemDelegate): # {{{
|
class DateDelegate(QStyledItemDelegate): # {{{
|
||||||
|
|
||||||
def __init__(self, parent, tweak_name='gui_timestamp_display_format',
|
def __init__(self, parent, tweak_name='gui_timestamp_display_format',
|
||||||
default_format='dd MMM yyyy', editor_format='dd MMM yyyy'):
|
default_format='dd MMM yyyy'):
|
||||||
QStyledItemDelegate.__init__(self, parent)
|
QStyledItemDelegate.__init__(self, parent)
|
||||||
self.tweak_name = tweak_name
|
self.tweak_name = tweak_name
|
||||||
self.default_format = default_format
|
self.format = tweaks[self.tweak_name]
|
||||||
self.editor_format = editor_format
|
if self.format is None:
|
||||||
|
self.format = default_format
|
||||||
|
|
||||||
def displayText(self, val, locale):
|
def displayText(self, val, locale):
|
||||||
d = val.toDate()
|
d = val.toDateTime()
|
||||||
if d <= UNDEFINED_QDATE:
|
if d <= UNDEFINED_QDATETIME:
|
||||||
return ''
|
return ''
|
||||||
format = tweaks[self.tweak_name]
|
return format_date(qt_to_dt(d, as_utc=False), self.format)
|
||||||
if format is None:
|
|
||||||
format = self.default_format
|
|
||||||
return format_date(d.toPyDate(), format)
|
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
def createEditor(self, parent, option, index):
|
||||||
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
|
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
|
||||||
qde.setDisplayFormat(self.editor_format)
|
qde.setDisplayFormat(self.format)
|
||||||
qde.setMinimumDate(UNDEFINED_QDATE)
|
qde.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
qde.setSpecialValueText(_('Undefined'))
|
qde.setSpecialValueText(_('Undefined'))
|
||||||
qde.setCalendarPopup(True)
|
qde.setCalendarPopup(True)
|
||||||
return qde
|
return qde
|
||||||
@ -134,18 +132,18 @@ class DateDelegate(QStyledItemDelegate): # {{{
|
|||||||
class PubDateDelegate(QStyledItemDelegate): # {{{
|
class PubDateDelegate(QStyledItemDelegate): # {{{
|
||||||
|
|
||||||
def displayText(self, val, locale):
|
def displayText(self, val, locale):
|
||||||
d = val.toDate()
|
d = val.toDateTime()
|
||||||
if d <= UNDEFINED_QDATE:
|
if d <= UNDEFINED_QDATETIME:
|
||||||
return ''
|
return ''
|
||||||
format = tweaks['gui_pubdate_display_format']
|
self.format = tweaks['gui_pubdate_display_format']
|
||||||
if format is None:
|
if self.format is None:
|
||||||
format = 'MMM yyyy'
|
self.format = 'MMM yyyy'
|
||||||
return format_date(d.toPyDate(), format)
|
return format_date(qt_to_dt(d, as_utc=False), self.format)
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
def createEditor(self, parent, option, index):
|
||||||
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
|
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
|
||||||
qde.setDisplayFormat('MM yyyy')
|
qde.setDisplayFormat(self.format)
|
||||||
qde.setMinimumDate(UNDEFINED_QDATE)
|
qde.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
qde.setSpecialValueText(_('Undefined'))
|
qde.setSpecialValueText(_('Undefined'))
|
||||||
qde.setCalendarPopup(True)
|
qde.setCalendarPopup(True)
|
||||||
return qde
|
return qde
|
||||||
@ -259,15 +257,15 @@ class CcDateDelegate(QStyledItemDelegate): # {{{
|
|||||||
self.format = format
|
self.format = format
|
||||||
|
|
||||||
def displayText(self, val, locale):
|
def displayText(self, val, locale):
|
||||||
d = val.toDate()
|
d = val.toDateTime()
|
||||||
if d <= UNDEFINED_QDATE:
|
if d <= UNDEFINED_QDATETIME:
|
||||||
return ''
|
return ''
|
||||||
return format_date(d.toPyDate(), self.format)
|
return format_date(qt_to_dt(d, as_utc=False), self.format)
|
||||||
|
|
||||||
def createEditor(self, parent, option, index):
|
def createEditor(self, parent, option, index):
|
||||||
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
|
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
|
||||||
qde.setDisplayFormat(self.format)
|
qde.setDisplayFormat(self.format)
|
||||||
qde.setMinimumDate(UNDEFINED_QDATE)
|
qde.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
qde.setSpecialValueText(_('Undefined'))
|
qde.setSpecialValueText(_('Undefined'))
|
||||||
qde.setCalendarPopup(True)
|
qde.setCalendarPopup(True)
|
||||||
return qde
|
return qde
|
||||||
@ -279,11 +277,11 @@ class CcDateDelegate(QStyledItemDelegate): # {{{
|
|||||||
val = m.db.data[index.row()][m.custom_columns[m.column_map[index.column()]]['rec_index']]
|
val = m.db.data[index.row()][m.custom_columns[m.column_map[index.column()]]['rec_index']]
|
||||||
if val is None:
|
if val is None:
|
||||||
val = now()
|
val = now()
|
||||||
editor.setDate(val)
|
editor.setDateTime(val)
|
||||||
|
|
||||||
def setModelData(self, editor, model, index):
|
def setModelData(self, editor, model, index):
|
||||||
val = editor.date()
|
val = editor.dateTime()
|
||||||
if val <= UNDEFINED_QDATE:
|
if val <= UNDEFINED_QDATETIME:
|
||||||
val = None
|
val = None
|
||||||
model.setData(index, QVariant(val), Qt.EditRole)
|
model.setData(index, QVariant(val), Qt.EditRole)
|
||||||
|
|
||||||
|
@ -5,13 +5,13 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import functools, re, os, traceback
|
import functools, re, os, traceback, errno
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from PyQt4.Qt import (QAbstractTableModel, Qt, pyqtSignal, QIcon, QImage,
|
from PyQt4.Qt import (QAbstractTableModel, Qt, pyqtSignal, QIcon, QImage,
|
||||||
QModelIndex, QVariant, QDate, QColor)
|
QModelIndex, QVariant, QDateTime, QColor)
|
||||||
|
|
||||||
from calibre.gui2 import NONE, UNDEFINED_QDATE
|
from calibre.gui2 import NONE, UNDEFINED_QDATETIME, error_dialog
|
||||||
from calibre.utils.pyparsing import ParseException
|
from calibre.utils.pyparsing import ParseException
|
||||||
from calibre.ebooks.metadata import fmt_sidx, authors_to_string, string_to_authors
|
from calibre.ebooks.metadata import fmt_sidx, authors_to_string, string_to_authors
|
||||||
from calibre.ebooks.metadata.book.base import SafeFormat
|
from calibre.ebooks.metadata.book.base import SafeFormat
|
||||||
@ -580,9 +580,9 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
def datetime_type(r, idx=-1):
|
def datetime_type(r, idx=-1):
|
||||||
val = self.db.data[r][idx]
|
val = self.db.data[r][idx]
|
||||||
if val is not None:
|
if val is not None:
|
||||||
return QVariant(QDate(val))
|
return QVariant(QDateTime(val))
|
||||||
else:
|
else:
|
||||||
return QVariant(UNDEFINED_QDATE)
|
return QVariant(UNDEFINED_QDATETIME)
|
||||||
|
|
||||||
def bool_type(r, idx=-1):
|
def bool_type(r, idx=-1):
|
||||||
return None # displayed using a decorator
|
return None # displayed using a decorator
|
||||||
@ -815,7 +815,7 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
if not val:
|
if not val:
|
||||||
val = None
|
val = None
|
||||||
elif typ == 'datetime':
|
elif typ == 'datetime':
|
||||||
val = value.toDate()
|
val = value.toDateTime()
|
||||||
if val.isNull():
|
if val.isNull():
|
||||||
val = None
|
val = None
|
||||||
else:
|
else:
|
||||||
@ -851,59 +851,78 @@ class BooksModel(QAbstractTableModel): # {{{
|
|||||||
|
|
||||||
def setData(self, index, value, role):
|
def setData(self, index, value, role):
|
||||||
if role == Qt.EditRole:
|
if role == Qt.EditRole:
|
||||||
row, col = index.row(), index.column()
|
from calibre.gui2.ui import get_gui
|
||||||
column = self.column_map[col]
|
try:
|
||||||
if self.is_custom_column(column):
|
return self._set_data(index, value)
|
||||||
if not self.set_custom_column_data(row, column, value):
|
except (IOError, OSError) as err:
|
||||||
return False
|
if getattr(err, 'errno', None) == errno.EACCES: # Permission denied
|
||||||
else:
|
import traceback
|
||||||
if column not in self.editable_cols:
|
error_dialog(get_gui(), _('Permission denied'),
|
||||||
return False
|
_('Could not change the on disk location of this'
|
||||||
val = int(value.toInt()[0]) if column == 'rating' else \
|
' book. Is it open in another program?'),
|
||||||
value.toDate() if column in ('timestamp', 'pubdate') else \
|
det_msg=traceback.format_exc(), show=True)
|
||||||
unicode(value.toString()).strip()
|
except:
|
||||||
id = self.db.id(row)
|
import traceback
|
||||||
books_to_refresh = set([id])
|
traceback.print_exc()
|
||||||
if column == 'rating':
|
error_dialog(get_gui(), _('Failed to set data'),
|
||||||
val = 0 if val < 0 else 5 if val > 5 else val
|
_('Could not set data, click Show Details to see why.'),
|
||||||
val *= 2
|
det_msg=traceback.format_exc(), show=True)
|
||||||
self.db.set_rating(id, val)
|
return False
|
||||||
elif column == 'series':
|
|
||||||
val = val.strip()
|
def _set_data(self, index, value):
|
||||||
if not val:
|
row, col = index.row(), index.column()
|
||||||
books_to_refresh |= self.db.set_series(id, val,
|
column = self.column_map[col]
|
||||||
allow_case_change=True)
|
if self.is_custom_column(column):
|
||||||
self.db.set_series_index(id, 1.0)
|
if not self.set_custom_column_data(row, column, value):
|
||||||
else:
|
return False
|
||||||
pat = re.compile(r'\[([.0-9]+)\]')
|
else:
|
||||||
match = pat.search(val)
|
if column not in self.editable_cols:
|
||||||
if match is not None:
|
return False
|
||||||
self.db.set_series_index(id, float(match.group(1)))
|
val = (int(value.toInt()[0]) if column == 'rating' else
|
||||||
val = pat.sub('', val).strip()
|
value.toDateTime() if column in ('timestamp', 'pubdate')
|
||||||
elif val:
|
else unicode(value.toString()).strip())
|
||||||
if tweaks['series_index_auto_increment'] != 'const':
|
id = self.db.id(row)
|
||||||
ni = self.db.get_next_series_num_for(val)
|
books_to_refresh = set([id])
|
||||||
if ni != 1:
|
if column == 'rating':
|
||||||
self.db.set_series_index(id, ni)
|
val = 0 if val < 0 else 5 if val > 5 else val
|
||||||
if val:
|
val *= 2
|
||||||
books_to_refresh |= self.db.set_series(id, val,
|
self.db.set_rating(id, val)
|
||||||
allow_case_change=True)
|
elif column == 'series':
|
||||||
elif column == 'timestamp':
|
val = val.strip()
|
||||||
if val.isNull() or not val.isValid():
|
if not val:
|
||||||
return False
|
books_to_refresh |= self.db.set_series(id, val,
|
||||||
self.db.set_timestamp(id, qt_to_dt(val, as_utc=False))
|
|
||||||
elif column == 'pubdate':
|
|
||||||
if val.isNull() or not val.isValid():
|
|
||||||
return False
|
|
||||||
self.db.set_pubdate(id, qt_to_dt(val, as_utc=False))
|
|
||||||
elif column == 'languages':
|
|
||||||
val = val.split(',')
|
|
||||||
self.db.set_languages(id, val)
|
|
||||||
else:
|
|
||||||
books_to_refresh |= self.db.set(row, column, val,
|
|
||||||
allow_case_change=True)
|
allow_case_change=True)
|
||||||
self.refresh_ids(list(books_to_refresh), row)
|
self.db.set_series_index(id, 1.0)
|
||||||
self.dataChanged.emit(index, index)
|
else:
|
||||||
|
pat = re.compile(r'\[([.0-9]+)\]')
|
||||||
|
match = pat.search(val)
|
||||||
|
if match is not None:
|
||||||
|
self.db.set_series_index(id, float(match.group(1)))
|
||||||
|
val = pat.sub('', val).strip()
|
||||||
|
elif val:
|
||||||
|
if tweaks['series_index_auto_increment'] != 'const':
|
||||||
|
ni = self.db.get_next_series_num_for(val)
|
||||||
|
if ni != 1:
|
||||||
|
self.db.set_series_index(id, ni)
|
||||||
|
if val:
|
||||||
|
books_to_refresh |= self.db.set_series(id, val,
|
||||||
|
allow_case_change=True)
|
||||||
|
elif column == 'timestamp':
|
||||||
|
if val.isNull() or not val.isValid():
|
||||||
|
return False
|
||||||
|
self.db.set_timestamp(id, qt_to_dt(val, as_utc=False))
|
||||||
|
elif column == 'pubdate':
|
||||||
|
if val.isNull() or not val.isValid():
|
||||||
|
return False
|
||||||
|
self.db.set_pubdate(id, qt_to_dt(val, as_utc=False))
|
||||||
|
elif column == 'languages':
|
||||||
|
val = val.split(',')
|
||||||
|
self.db.set_languages(id, val)
|
||||||
|
else:
|
||||||
|
books_to_refresh |= self.db.set(row, column, val,
|
||||||
|
allow_case_change=True)
|
||||||
|
self.refresh_ids(list(books_to_refresh), row)
|
||||||
|
self.dataChanged.emit(index, index)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -134,10 +134,12 @@ class GuiRunner(QObject):
|
|||||||
main = Main(self.opts, gui_debug=self.gui_debug)
|
main = Main(self.opts, gui_debug=self.gui_debug)
|
||||||
if self.splash_screen is not None:
|
if self.splash_screen is not None:
|
||||||
self.splash_screen.showMessage(_('Initializing user interface...'))
|
self.splash_screen.showMessage(_('Initializing user interface...'))
|
||||||
self.splash_screen.finish(main)
|
|
||||||
main.initialize(self.library_path, db, self.listener, self.actions)
|
main.initialize(self.library_path, db, self.listener, self.actions)
|
||||||
|
if self.splash_screen is not None:
|
||||||
|
self.splash_screen.finish(main)
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
prints('Started up in', time.time() - self.startup_time)
|
prints('Started up in', time.time() - self.startup_time, 'with',
|
||||||
|
len(db.data), 'books')
|
||||||
add_filesystem_book = partial(main.iactions['Add Books'].add_filesystem_book, allow_device=False)
|
add_filesystem_book = partial(main.iactions['Add Books'].add_filesystem_book, allow_device=False)
|
||||||
sys.excepthook = main.unhandled_exception
|
sys.excepthook = main.unhandled_exception
|
||||||
if len(self.args) > 1:
|
if len(self.args) > 1:
|
||||||
@ -347,7 +349,8 @@ def main(args=sys.argv):
|
|||||||
except socket.error:
|
except socket.error:
|
||||||
if iswindows:
|
if iswindows:
|
||||||
cant_start()
|
cant_start()
|
||||||
os.remove(ADDRESS)
|
if os.path.exists(ADDRESS):
|
||||||
|
os.remove(ADDRESS)
|
||||||
try:
|
try:
|
||||||
listener = Listener(address=ADDRESS)
|
listener = Listener(address=ADDRESS)
|
||||||
except socket.error:
|
except socket.error:
|
||||||
|
@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
import textwrap, re, os, errno, shutil
|
import textwrap, re, os, errno, shutil
|
||||||
|
|
||||||
from PyQt4.Qt import (Qt, QDateEdit, QDate, pyqtSignal, QMessageBox,
|
from PyQt4.Qt import (Qt, QDateTimeEdit, pyqtSignal, QMessageBox,
|
||||||
QIcon, QToolButton, QWidget, QLabel, QGridLayout, QApplication,
|
QIcon, QToolButton, QWidget, QLabel, QGridLayout, QApplication,
|
||||||
QDoubleSpinBox, QListWidgetItem, QSize, QPixmap, QDialog, QMenu,
|
QDoubleSpinBox, QListWidgetItem, QSize, QPixmap, QDialog, QMenu,
|
||||||
QPushButton, QSpinBox, QLineEdit, QSizePolicy, QDialogButtonBox, QAction)
|
QPushButton, QSpinBox, QLineEdit, QSizePolicy, QDialogButtonBox, QAction)
|
||||||
@ -21,7 +21,7 @@ from calibre.utils.config import tweaks, prefs
|
|||||||
from calibre.ebooks.metadata import (title_sort, authors_to_string,
|
from calibre.ebooks.metadata import (title_sort, authors_to_string,
|
||||||
string_to_authors, check_isbn, authors_to_sort_string)
|
string_to_authors, check_isbn, authors_to_sort_string)
|
||||||
from calibre.ebooks.metadata.meta import get_metadata
|
from calibre.ebooks.metadata.meta import get_metadata
|
||||||
from calibre.gui2 import (file_icon_provider, UNDEFINED_QDATE,
|
from calibre.gui2 import (file_icon_provider, UNDEFINED_QDATETIME,
|
||||||
choose_files, error_dialog, choose_images)
|
choose_files, error_dialog, choose_images)
|
||||||
from calibre.utils.date import (local_tz, qt_to_dt, as_local_time,
|
from calibre.utils.date import (local_tz, qt_to_dt, as_local_time,
|
||||||
UNDEFINED_DATE)
|
UNDEFINED_DATE)
|
||||||
@ -1377,25 +1377,24 @@ class PublisherEdit(MultiCompleteComboBox): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class DateEdit(QDateEdit): # {{{
|
class DateEdit(QDateTimeEdit): # {{{
|
||||||
|
|
||||||
TOOLTIP = ''
|
TOOLTIP = ''
|
||||||
LABEL = _('&Date:')
|
LABEL = _('&Date:')
|
||||||
FMT = 'd MMM yyyy'
|
FMT = 'dd MMM yyyy hh:mm:ss'
|
||||||
ATTR = 'timestamp'
|
ATTR = 'timestamp'
|
||||||
|
TWEAK = 'gui_timestamp_display_format'
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
QDateEdit.__init__(self, parent)
|
QDateTimeEdit.__init__(self, parent)
|
||||||
self.setToolTip(self.TOOLTIP)
|
self.setToolTip(self.TOOLTIP)
|
||||||
self.setWhatsThis(self.TOOLTIP)
|
self.setWhatsThis(self.TOOLTIP)
|
||||||
fmt = self.FMT
|
fmt = tweaks[self.TWEAK]
|
||||||
if fmt is None:
|
if fmt is None:
|
||||||
fmt = tweaks['gui_pubdate_display_format']
|
fmt = self.FMT
|
||||||
if fmt is None:
|
|
||||||
fmt = 'MMM yyyy'
|
|
||||||
self.setDisplayFormat(fmt)
|
self.setDisplayFormat(fmt)
|
||||||
self.setCalendarPopup(True)
|
self.setCalendarPopup(True)
|
||||||
self.setMinimumDate(UNDEFINED_QDATE)
|
self.setMinimumDateTime(UNDEFINED_QDATETIME)
|
||||||
self.setSpecialValueText(_('Undefined'))
|
self.setSpecialValueText(_('Undefined'))
|
||||||
self.clear_button = QToolButton(parent)
|
self.clear_button = QToolButton(parent)
|
||||||
self.clear_button.setIcon(QIcon(I('trash.png')))
|
self.clear_button.setIcon(QIcon(I('trash.png')))
|
||||||
@ -1408,12 +1407,13 @@ class DateEdit(QDateEdit): # {{{
|
|||||||
@dynamic_property
|
@dynamic_property
|
||||||
def current_val(self):
|
def current_val(self):
|
||||||
def fget(self):
|
def fget(self):
|
||||||
return qt_to_dt(self.date(), as_utc=False)
|
return qt_to_dt(self.dateTime(), as_utc=False)
|
||||||
def fset(self, val):
|
def fset(self, val):
|
||||||
if val is None:
|
if val is None:
|
||||||
val = UNDEFINED_DATE
|
val = UNDEFINED_DATE
|
||||||
val = as_local_time(val)
|
else:
|
||||||
self.setDate(QDate(val.year, val.month, val.day))
|
val = as_local_time(val)
|
||||||
|
self.setDateTime(val)
|
||||||
return property(fget=fget, fset=fset)
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
def initialize(self, db, id_):
|
def initialize(self, db, id_):
|
||||||
@ -1429,11 +1429,12 @@ class DateEdit(QDateEdit): # {{{
|
|||||||
@property
|
@property
|
||||||
def changed(self):
|
def changed(self):
|
||||||
o, c = self.original_val, self.current_val
|
o, c = self.original_val, self.current_val
|
||||||
return o.year != c.year or o.month != c.month or o.day != c.day
|
return o != c
|
||||||
|
|
||||||
class PubdateEdit(DateEdit):
|
class PubdateEdit(DateEdit):
|
||||||
LABEL = _('Publishe&d:')
|
LABEL = _('Publishe&d:')
|
||||||
FMT = None
|
FMT = 'MMM yyyy'
|
||||||
ATTR = 'pubdate'
|
ATTR = 'pubdate'
|
||||||
|
TWEAK = 'gui_pubdate_display_format'
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -98,7 +98,7 @@ def split_jobs(ids, batch_size=100):
|
|||||||
ids = ids[batch_size:]
|
ids = ids[batch_size:]
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def start_download(gui, ids, callback):
|
def start_download(gui, ids, callback, ensure_fields=None):
|
||||||
d = ConfirmDialog(ids, gui)
|
d = ConfirmDialog(ids, gui)
|
||||||
ret = d.exec_()
|
ret = d.exec_()
|
||||||
d.b.clicked.disconnect()
|
d.b.clicked.disconnect()
|
||||||
@ -108,7 +108,8 @@ def start_download(gui, ids, callback):
|
|||||||
for batch in split_jobs(ids):
|
for batch in split_jobs(ids):
|
||||||
job = ThreadedJob('metadata bulk download',
|
job = ThreadedJob('metadata bulk download',
|
||||||
_('Download metadata for %d books')%len(batch),
|
_('Download metadata for %d books')%len(batch),
|
||||||
download, (batch, gui.current_db, d.identify, d.covers), {}, callback)
|
download, (batch, gui.current_db, d.identify, d.covers,
|
||||||
|
ensure_fields), {}, callback)
|
||||||
gui.job_manager.run_threaded_job(job)
|
gui.job_manager.run_threaded_job(job)
|
||||||
gui.status_bar.show_message(_('Metadata download started'), 3000)
|
gui.status_bar.show_message(_('Metadata download started'), 3000)
|
||||||
|
|
||||||
@ -127,10 +128,10 @@ def get_job_details(job):
|
|||||||
det_msg = '\n'.join(det_msg)
|
det_msg = '\n'.join(det_msg)
|
||||||
return id_map, failed_ids, failed_covers, all_failed, det_msg
|
return id_map, failed_ids, failed_covers, all_failed, det_msg
|
||||||
|
|
||||||
def merge_result(oldmi, newmi):
|
def merge_result(oldmi, newmi, ensure_fields=None):
|
||||||
dummy = Metadata(_('Unknown'))
|
dummy = Metadata(_('Unknown'))
|
||||||
for f in msprefs['ignore_fields']:
|
for f in msprefs['ignore_fields']:
|
||||||
if ':' not in f:
|
if ':' not in f and (ensure_fields and f not in ensure_fields):
|
||||||
setattr(newmi, f, getattr(dummy, f))
|
setattr(newmi, f, getattr(dummy, f))
|
||||||
fields = set()
|
fields = set()
|
||||||
for plugin in metadata_plugins(['identify']):
|
for plugin in metadata_plugins(['identify']):
|
||||||
@ -154,7 +155,7 @@ def merge_result(oldmi, newmi):
|
|||||||
|
|
||||||
return newmi
|
return newmi
|
||||||
|
|
||||||
def download(ids, db, do_identify, covers,
|
def download(ids, db, do_identify, covers, ensure_fields,
|
||||||
log=None, abort=None, notifications=None):
|
log=None, abort=None, notifications=None):
|
||||||
ids = list(ids)
|
ids = list(ids)
|
||||||
metadata = [db.get_metadata(i, index_is_id=True, get_user_categories=False)
|
metadata = [db.get_metadata(i, index_is_id=True, get_user_categories=False)
|
||||||
@ -184,7 +185,7 @@ def download(ids, db, do_identify, covers,
|
|||||||
pass
|
pass
|
||||||
if results:
|
if results:
|
||||||
all_failed = False
|
all_failed = False
|
||||||
mi = merge_result(mi, results[0])
|
mi = merge_result(mi, results[0], ensure_fields=ensure_fields)
|
||||||
identifiers = mi.identifiers
|
identifiers = mi.identifiers
|
||||||
if not mi.is_null('rating'):
|
if not mi.is_null('rating'):
|
||||||
# set_metadata expects a rating out of 10
|
# set_metadata expects a rating out of 10
|
||||||
@ -193,7 +194,7 @@ def download(ids, db, do_identify, covers,
|
|||||||
log.error('Failed to download metadata for', title)
|
log.error('Failed to download metadata for', title)
|
||||||
failed_ids.add(i)
|
failed_ids.add(i)
|
||||||
# We don't want set_metadata operating on anything but covers
|
# We don't want set_metadata operating on anything but covers
|
||||||
mi = merge_result(mi, mi)
|
mi = merge_result(mi, mi, ensure_fields=ensure_fields)
|
||||||
if covers:
|
if covers:
|
||||||
cdata = download_cover(log, title=title, authors=authors,
|
cdata = download_cover(log, title=title, authors=authors,
|
||||||
identifiers=identifiers)
|
identifiers=identifiers)
|
||||||
|
@ -440,8 +440,8 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
return False
|
return False
|
||||||
self.books_to_refresh |= getattr(widget, 'books_to_refresh',
|
self.books_to_refresh |= getattr(widget, 'books_to_refresh',
|
||||||
set([]))
|
set([]))
|
||||||
except IOError as err:
|
except (IOError, OSError) as err:
|
||||||
if err.errno == errno.EACCES: # Permission denied
|
if getattr(err, 'errno', None) == errno.EACCES: # Permission denied
|
||||||
import traceback
|
import traceback
|
||||||
fname = err.filename if err.filename else 'file'
|
fname = err.filename if err.filename else 'file'
|
||||||
error_dialog(self, _('Permission denied'),
|
error_dialog(self, _('Permission denied'),
|
||||||
|
@ -121,13 +121,13 @@ class AdvSearchBuilderDialog(QDialog, Ui_Dialog):
|
|||||||
format = unicode(self.format_box.text()).strip()
|
format = unicode(self.format_box.text()).strip()
|
||||||
if format:
|
if format:
|
||||||
ans.append('format:"' + self.mc + format + '"')
|
ans.append('format:"' + self.mc + format + '"')
|
||||||
drm = unicode(self.drm_combo.currentText()).strip()
|
drm = '' if self.drm_combo.currentIndex() == 0 else 'true' if self.drm_combo.currentIndex() == 1 else 'false'
|
||||||
if drm:
|
if drm:
|
||||||
ans.append('drm:' + drm)
|
ans.append('drm:' + drm)
|
||||||
download = unicode(self.download_combo.currentText()).strip()
|
download = '' if self.download_combo.currentIndex() == 0 else 'true' if self.download_combo.currentIndex() == 1 else 'false'
|
||||||
if download:
|
if download:
|
||||||
ans.append('download:' + download)
|
ans.append('download:' + download)
|
||||||
affiliate = unicode(self.affiliate_combo.currentText()).strip()
|
affiliate = '' if self.affiliate_combo.currentIndex() == 0 else 'true' if self.affiliate_combo.currentIndex() == 1 else 'false'
|
||||||
if affiliate:
|
if affiliate:
|
||||||
ans.append('affiliate:' + affiliate)
|
ans.append('affiliate:' + affiliate)
|
||||||
if ans:
|
if ans:
|
||||||
|
@ -122,6 +122,11 @@ class Kobo(Device):
|
|||||||
output_format = 'EPUB'
|
output_format = 'EPUB'
|
||||||
id = 'kobo'
|
id = 'kobo'
|
||||||
|
|
||||||
|
class KoboVox(Kobo):
|
||||||
|
name = 'Kobo Vox'
|
||||||
|
output_profile = 'tablet'
|
||||||
|
id = 'kobo_vox'
|
||||||
|
|
||||||
class Booq(Device):
|
class Booq(Device):
|
||||||
name = 'bq Classic'
|
name = 'bq Classic'
|
||||||
manufacturer = 'Booq'
|
manufacturer = 'Booq'
|
||||||
|
@ -12,7 +12,7 @@ from datetime import timedelta
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
from calibre.utils.config import tweaks, prefs
|
from calibre.utils.config import tweaks, prefs
|
||||||
from calibre.utils.date import parse_date, now, UNDEFINED_DATE
|
from calibre.utils.date import parse_date, now, UNDEFINED_DATE, clean_date_for_sort
|
||||||
from calibre.utils.search_query_parser import SearchQueryParser
|
from calibre.utils.search_query_parser import SearchQueryParser
|
||||||
from calibre.utils.pyparsing import ParseException
|
from calibre.utils.pyparsing import ParseException
|
||||||
from calibre.utils.localization import canonicalize_lang, lang_map
|
from calibre.utils.localization import canonicalize_lang, lang_map
|
||||||
@ -936,6 +936,9 @@ class ResultCache(SearchQueryParser): # {{{
|
|||||||
item.refresh_composites()
|
item.refresh_composites()
|
||||||
|
|
||||||
def refresh(self, db, field=None, ascending=True):
|
def refresh(self, db, field=None, ascending=True):
|
||||||
|
# reinitialize the template cache in case a composite column has changed
|
||||||
|
db.initialize_template_cache()
|
||||||
|
|
||||||
temp = db.conn.get('SELECT * FROM meta2')
|
temp = db.conn.get('SELECT * FROM meta2')
|
||||||
self._data = list(itertools.repeat(None, temp[-1][0]+2)) if temp else []
|
self._data = list(itertools.repeat(None, temp[-1][0]+2)) if temp else []
|
||||||
for r in temp:
|
for r in temp:
|
||||||
@ -1059,7 +1062,17 @@ class SortKeyGenerator(object):
|
|||||||
if dt == 'datetime':
|
if dt == 'datetime':
|
||||||
if val is None:
|
if val is None:
|
||||||
val = UNDEFINED_DATE
|
val = UNDEFINED_DATE
|
||||||
|
if tweaks['sort_dates_using_visible_fields']:
|
||||||
|
format = None
|
||||||
|
if name == 'timestamp':
|
||||||
|
format = tweaks['gui_timestamp_display_format']
|
||||||
|
elif name == 'pubdate':
|
||||||
|
format = tweaks['gui_pubdate_display_format']
|
||||||
|
elif name == 'last_modified':
|
||||||
|
format = tweaks['gui_last_modified_display_format']
|
||||||
|
elif fm['is_custom']:
|
||||||
|
format = fm['display'].get('date_format', None)
|
||||||
|
val = clean_date_for_sort(val, format)
|
||||||
elif dt == 'series':
|
elif dt == 'series':
|
||||||
if val is None:
|
if val is None:
|
||||||
val = ('', 1)
|
val = ('', 1)
|
||||||
|
@ -216,8 +216,12 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.create_custom_column(f['label'], f['name'], f['datatype'],
|
self.create_custom_column(f['label'], f['name'], f['datatype'],
|
||||||
f['is_multiple'] is not None and len(f['is_multiple']) > 0,
|
f['is_multiple'] is not None and len(f['is_multiple']) > 0,
|
||||||
f['is_editable'], f['display'])
|
f['is_editable'], f['display'])
|
||||||
|
self.initialize_template_cache()
|
||||||
self.initialize_dynamic()
|
self.initialize_dynamic()
|
||||||
|
|
||||||
|
def initialize_template_cache(self):
|
||||||
|
self.formatter_template_cache = {}
|
||||||
|
|
||||||
def get_property(self, idx, index_is_id=False, loc=-1):
|
def get_property(self, idx, index_is_id=False, loc=-1):
|
||||||
row = self.data._data[idx] if index_is_id else self.data[idx]
|
row = self.data._data[idx] if index_is_id else self.data[idx]
|
||||||
if row is not None:
|
if row is not None:
|
||||||
@ -897,7 +901,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
'''
|
'''
|
||||||
row = self.data._data[idx] if index_is_id else self.data[idx]
|
row = self.data._data[idx] if index_is_id else self.data[idx]
|
||||||
fm = self.FIELD_MAP
|
fm = self.FIELD_MAP
|
||||||
mi = Metadata(None)
|
mi = Metadata(None, template_cache=self.formatter_template_cache)
|
||||||
|
|
||||||
aut_list = row[fm['au_map']]
|
aut_list = row[fm['au_map']]
|
||||||
if aut_list:
|
if aut_list:
|
||||||
@ -955,6 +959,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
mi.set_identifiers(self.get_identifiers(id, index_is_id=True))
|
mi.set_identifiers(self.get_identifiers(id, index_is_id=True))
|
||||||
mi.application_id = id
|
mi.application_id = id
|
||||||
mi.id = id
|
mi.id = id
|
||||||
|
|
||||||
for key, meta in self.field_metadata.custom_iteritems():
|
for key, meta in self.field_metadata.custom_iteritems():
|
||||||
mi.set_user_metadata(key, meta)
|
mi.set_user_metadata(key, meta)
|
||||||
if meta['datatype'] == 'composite':
|
if meta['datatype'] == 'composite':
|
||||||
@ -1312,10 +1317,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
if path is None:
|
if path is None:
|
||||||
path = os.path.join(self.library_path, self.path(id, index_is_id=True))
|
path = os.path.join(self.library_path, self.path(id, index_is_id=True))
|
||||||
name = self.conn.get('SELECT name FROM data WHERE book=? AND format=?', (id, format), all=False)
|
name = self.conn.get('SELECT name FROM data WHERE book=? AND format=?', (id, format), all=False)
|
||||||
if name:
|
if name and not replace:
|
||||||
if not replace:
|
return False
|
||||||
return False
|
|
||||||
self.conn.execute('DELETE FROM data WHERE book=? AND format=?', (id, format))
|
|
||||||
name = self.construct_file_name(id)
|
name = self.construct_file_name(id)
|
||||||
ext = ('.' + format.lower()) if format else ''
|
ext = ('.' + format.lower()) if format else ''
|
||||||
dest = os.path.join(path, name+ext)
|
dest = os.path.join(path, name+ext)
|
||||||
@ -1328,7 +1331,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
shutil.copyfileobj(stream, f)
|
shutil.copyfileobj(stream, f)
|
||||||
stream.seek(0, 2)
|
stream.seek(0, 2)
|
||||||
size=stream.tell()
|
size=stream.tell()
|
||||||
self.conn.execute('INSERT INTO data (book,format,uncompressed_size,name) VALUES (?,?,?,?)',
|
self.conn.execute('INSERT OR REPLACE INTO data (book,format,uncompressed_size,name) VALUES (?,?,?,?)',
|
||||||
(id, format.upper(), size, name))
|
(id, format.upper(), size, name))
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
self.refresh_ids([id])
|
self.refresh_ids([id])
|
||||||
|
@ -635,9 +635,7 @@ class FieldMetadata(dict):
|
|||||||
self._search_term_map[t] = key
|
self._search_term_map[t] = key
|
||||||
|
|
||||||
def search_term_to_field_key(self, term):
|
def search_term_to_field_key(self, term):
|
||||||
if term in self._search_term_map:
|
return self._search_term_map.get(term, term)
|
||||||
return self._search_term_map[term]
|
|
||||||
return term
|
|
||||||
|
|
||||||
def searchable_fields(self):
|
def searchable_fields(self):
|
||||||
return [k for k in self._tb_cats.keys()
|
return [k for k in self._tb_cats.keys()
|
||||||
|
@ -114,7 +114,7 @@ html_short_title = 'Start'
|
|||||||
html_logo = 'resources/logo.png'
|
html_logo = 'resources/logo.png'
|
||||||
|
|
||||||
epub_author = 'Kovid Goyal'
|
epub_author = 'Kovid Goyal'
|
||||||
epub_cover = 'epub_cover.jpg'
|
kovid_epub_cover = 'epub_cover.jpg'
|
||||||
epub_publisher = 'Kovid Goyal'
|
epub_publisher = 'Kovid Goyal'
|
||||||
epub_identifier = 'http://manual.calibre-ebook.com'
|
epub_identifier = 'http://manual.calibre-ebook.com'
|
||||||
epub_scheme = 'url'
|
epub_scheme = 'url'
|
||||||
|
@ -251,7 +251,7 @@ def template_docs(app):
|
|||||||
update_cli_doc('template_ref.rst', raw, info)
|
update_cli_doc('template_ref.rst', raw, info)
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
app.add_config_value('epub_cover', None, False)
|
app.add_config_value('kovid_epub_cover', None, False)
|
||||||
app.add_builder(EPUBHelpBuilder)
|
app.add_builder(EPUBHelpBuilder)
|
||||||
app.connect('doctree-read', substitute)
|
app.connect('doctree-read', substitute)
|
||||||
app.connect('builder-inited', generate_docs)
|
app.connect('builder-inited', generate_docs)
|
||||||
|
@ -136,7 +136,7 @@ the previously checked out |app| code directory, for example::
|
|||||||
|
|
||||||
cd /Users/kovid/work/calibre
|
cd /Users/kovid/work/calibre
|
||||||
|
|
||||||
calibre is the directory that contains the src and resources sub-directories. Ensure you have installed the |app| commandline tools via :guilabel:Preferences->Advanced->Miscellaneous in the |app| GUI.
|
calibre is the directory that contains the src and resources sub-directories. Ensure you have installed the |app| commandline tools via :guilabel:`Preferences->Advanced->Miscellaneous` in the |app| GUI.
|
||||||
|
|
||||||
The next step is to set the environment variable ``CALIBRE_DEVELOP_FROM`` to the absolute path of the src directory.
|
The next step is to set the environment variable ``CALIBRE_DEVELOP_FROM`` to the absolute path of the src directory.
|
||||||
So, following the example above, it would be ``/Users/kovid/work/calibre/src``. Apple
|
So, following the example above, it would be ``/Users/kovid/work/calibre/src``. Apple
|
||||||
|
@ -55,8 +55,8 @@ class EPUBHelpBuilder(EpubBuilder):
|
|||||||
open(opf, 'wb').write(raw)
|
open(opf, 'wb').write(raw)
|
||||||
|
|
||||||
def build_epub(self, outdir, *args, **kwargs):
|
def build_epub(self, outdir, *args, **kwargs):
|
||||||
if self.config.epub_cover:
|
if self.config.kovid_epub_cover:
|
||||||
self.add_cover(outdir, self.config.epub_cover)
|
self.add_cover(outdir, self.config.kovid_epub_cover)
|
||||||
self.fix_duplication_bugs(outdir)
|
self.fix_duplication_bugs(outdir)
|
||||||
EpubBuilder.build_epub(self, outdir, *args, **kwargs)
|
EpubBuilder.build_epub(self, outdir, *args, **kwargs)
|
||||||
|
|
||||||
|
@ -242,10 +242,6 @@ Replace ``192.168.1.2`` with the local IP address of the computer running |app|.
|
|||||||
|
|
||||||
If you get timeout errors while browsing the calibre catalog in Stanza, try increasing the connection timeout value in the stanza settings. Go to Info->Settings and increase the value of Download Timeout.
|
If you get timeout errors while browsing the calibre catalog in Stanza, try increasing the connection timeout value in the stanza settings. Go to Info->Settings and increase the value of Download Timeout.
|
||||||
|
|
||||||
.. note::
|
|
||||||
As of iOS version 5 Stanza no longer works on Apple devices. Alternatives to Stanza are discussed `in this forum <http://www.mobileread.com/forums/showthread.php?t=152789>`_.
|
|
||||||
|
|
||||||
|
|
||||||
Using iBooks
|
Using iBooks
|
||||||
**************
|
**************
|
||||||
|
|
||||||
|
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