mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Pull from trunk
This commit is contained in:
commit
d871e221e3
@ -4,6 +4,31 @@
|
|||||||
# for important features/bug fixes.
|
# for important features/bug fixes.
|
||||||
# Also, each release can have new and improved recipes.
|
# Also, each release can have new and improved recipes.
|
||||||
|
|
||||||
|
- version: 0.7.4
|
||||||
|
date: 2010-06-19
|
||||||
|
|
||||||
|
bug fixes:
|
||||||
|
- title: "Fix regression in 0.7.3 that broke creating custom columns of rating or text types"
|
||||||
|
|
||||||
|
- title: "Fix cover browser breaking if you click on a book in the book list while cover browser is animated"
|
||||||
|
|
||||||
|
- title: "Fix a bug that could be triggered with the new book details pane if a book has a zero size cover"
|
||||||
|
tickets: [5889]
|
||||||
|
|
||||||
|
- title: "SONY driver: Fix bug preventing the editing of collections in the device view"
|
||||||
|
|
||||||
|
new recipes:
|
||||||
|
- title: Auto Prove
|
||||||
|
author: Gabriele Marini
|
||||||
|
|
||||||
|
- title: Forbes India, Maximum PC, Today Online
|
||||||
|
author: rty
|
||||||
|
|
||||||
|
improved recipes:
|
||||||
|
- WSJ
|
||||||
|
- Psychology Today
|
||||||
|
|
||||||
|
|
||||||
- version: 0.7.3
|
- version: 0.7.3
|
||||||
date: 2010-06-18
|
date: 2010-06-18
|
||||||
|
|
||||||
|
90
resources/recipes/auto_prove.recipe
Normal file
90
resources/recipes/auto_prove.recipe
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__author__ = 'GabrieleMarini, based on Darko Miletic'
|
||||||
|
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>, Gabriele Marini'
|
||||||
|
__version__ = 'v1.02 Marini Gabriele '
|
||||||
|
__date__ = '10, January 2010'
|
||||||
|
__description__ = 'Italian daily newspaper'
|
||||||
|
|
||||||
|
'''
|
||||||
|
http://www.corrieredellosport.it/
|
||||||
|
'''
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class AutoPR(BasicNewsRecipe):
|
||||||
|
__author__ = 'Gabriele Marini'
|
||||||
|
description = 'Auto and Formula 1'
|
||||||
|
|
||||||
|
cover_url = 'http://www.auto.it/res/imgs/logo_Auto.png'
|
||||||
|
|
||||||
|
|
||||||
|
title = u'Auto Prove'
|
||||||
|
publisher = 'CONTE Editore'
|
||||||
|
category = 'Sport'
|
||||||
|
|
||||||
|
language = 'it'
|
||||||
|
timefmt = '[%a, %d %b, %Y]'
|
||||||
|
|
||||||
|
oldest_article = 60
|
||||||
|
max_articles_per_feed = 20
|
||||||
|
use_embedded_content = False
|
||||||
|
recursion = 100
|
||||||
|
|
||||||
|
remove_javascript = True
|
||||||
|
no_stylesheets = True
|
||||||
|
|
||||||
|
#html2lrf_options = [
|
||||||
|
# '--comment', description
|
||||||
|
# , '--category', category
|
||||||
|
# , '--publisher', publisher
|
||||||
|
# , '--ignore-tables'
|
||||||
|
# ]
|
||||||
|
|
||||||
|
#html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='h2', attrs={'class':['tit_Article y_Txt']}),
|
||||||
|
dict(name='h2', attrs={'class':['tit_Article']}),
|
||||||
|
dict(name='div', attrs={'class':['box_Img newsdet_new ']}),
|
||||||
|
dict(name='div', attrs={'class':['box_Img newsdet_as ']}),
|
||||||
|
dict(name='table', attrs={'class':['table_A']}),
|
||||||
|
dict(name='div', attrs={'class':['txt_Article txtBox_cms']}),
|
||||||
|
dict(name='testoscheda')]
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
feeds = []
|
||||||
|
for title, url in [
|
||||||
|
("Prove su Strada" , "http://www.auto.it/rss/prove+6.xml")
|
||||||
|
]:
|
||||||
|
soup = self.index_to_soup(url)
|
||||||
|
soup = soup.find('channel')
|
||||||
|
print soup
|
||||||
|
|
||||||
|
for article in soup.findAllNext('item'):
|
||||||
|
title = self.tag_to_string(article.title)
|
||||||
|
date = self.tag_to_string(article.pubDate)
|
||||||
|
description = self.tag_to_string(article.description)
|
||||||
|
link = self.tag_to_string(article.guid)
|
||||||
|
# print article
|
||||||
|
articles = self.create_links_append(link, date, description)
|
||||||
|
if articles:
|
||||||
|
feeds.append((title, articles))
|
||||||
|
return feeds
|
||||||
|
|
||||||
|
def create_links_append(self, link, date, description):
|
||||||
|
current_articles = []
|
||||||
|
|
||||||
|
current_articles.append({'title': 'Generale', 'url': link,'description':description, 'date':date}),
|
||||||
|
current_articles.append({'title': 'Design', 'url': link.replace('scheda','design'),'description':'scheda', 'date':''}),
|
||||||
|
current_articles.append({'title': 'Interni', 'url': link.replace('scheda','interni'),'description':'Interni', 'date':''}),
|
||||||
|
current_articles.append({'title': 'Tecnica', 'url': link.replace('scheda','tecnica'),'description':'Tecnica', 'date':''}),
|
||||||
|
current_articles.append({'title': 'Su Strada', 'url': link.replace('scheda','su_strada'),'description':'Su Strada', 'date':''}),
|
||||||
|
current_articles.append({'title': 'Pagella', 'url': link.replace('scheda','pagella'),'description':'Pagella', 'date':''}),
|
||||||
|
current_articles.append({'title': 'Rilevamenti', 'url': link.replace('scheda','telemetria'),'description':'Rilevamenti', 'date':''})
|
||||||
|
|
||||||
|
return current_articles
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
55
resources/recipes/forbes_india.recipe
Normal file
55
resources/recipes/forbes_india.recipe
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class AdvancedUserRecipe1276934715(BasicNewsRecipe):
|
||||||
|
title = u'Forbes India'
|
||||||
|
__author__ = 'rty'
|
||||||
|
description = 'India Edition Forbes'
|
||||||
|
publisher = 'Forbes India'
|
||||||
|
category = 'Business News, Economy, India'
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
remove_javascript = True
|
||||||
|
use_embedded_content = False
|
||||||
|
no_stylesheets = True
|
||||||
|
language = 'en_IN'
|
||||||
|
temp_files = []
|
||||||
|
articles_are_obfuscated = True
|
||||||
|
conversion_options = {'linearize_tables':True}
|
||||||
|
feeds = [
|
||||||
|
(u'Contents', u'http://business.in.com/rssfeed/rss_all.xml'),
|
||||||
|
]
|
||||||
|
extra_css = '''
|
||||||
|
.t-10-gy-l{font-style: italic; font-size: small}
|
||||||
|
.t-30-b-d{font-weight: bold; font-size: xx-large}
|
||||||
|
.t-16-gy-l{font-weight: bold; font-size: x-large; font-syle: italic}
|
||||||
|
.storycontent{font-size: 4px;font-family: Times New Roman;}
|
||||||
|
'''
|
||||||
|
|
||||||
|
remove_tags_before = dict(name='div', attrs={'class':'pdl10 pdr15'})
|
||||||
|
|
||||||
|
|
||||||
|
def get_obfuscated_article(self, url):
|
||||||
|
br = self.get_browser()
|
||||||
|
br.open(url)
|
||||||
|
response = br.follow_link(url_regex = r'/printcontent/[0-9]+', nr = 0)
|
||||||
|
html = response.read()
|
||||||
|
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
||||||
|
self.temp_files[-1].write(html)
|
||||||
|
self.temp_files[-1].close()
|
||||||
|
return self.temp_files[-1].name
|
||||||
|
|
||||||
|
def get_cover_url(self):
|
||||||
|
index = 'http://business.in.com/magazine/'
|
||||||
|
soup = self.index_to_soup(index)
|
||||||
|
for image in soup.findAll('a',{ "class" : "lbOn a-9-b-d" }):
|
||||||
|
return image['href']
|
||||||
|
#return image['href'] + '.jpg'
|
||||||
|
return None
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
for item in soup.findAll(style=True):
|
||||||
|
del item['style']
|
||||||
|
for item in soup.findAll(width=True):
|
||||||
|
del item['width']
|
||||||
|
return soup
|
43
resources/recipes/maximum_pc.recipe
Normal file
43
resources/recipes/maximum_pc.recipe
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class AdvancedUserRecipe1276930924(BasicNewsRecipe):
|
||||||
|
title = u'Maximum PC'
|
||||||
|
__author__ = 'rty'
|
||||||
|
description = 'Maximum PC'
|
||||||
|
publisher = 'http://www.maximumpc.com'
|
||||||
|
category = 'news, computer, technology'
|
||||||
|
language = 'en'
|
||||||
|
oldest_article = 30
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
remove_javascript = True
|
||||||
|
use_embedded_content = False
|
||||||
|
no_stylesheets = True
|
||||||
|
language = 'en'
|
||||||
|
temp_files = []
|
||||||
|
articles_are_obfuscated = True
|
||||||
|
feeds = [(u'News', u'http://www.maximumpc.com/articles/4/feed'),
|
||||||
|
(u'Reviews', u'http://www.maximumpc.com/articles/40/feed'),
|
||||||
|
(u'Editors Blog', u'http://www.maximumpc.com/articles/6/feed'),
|
||||||
|
(u'How-to', u'http://www.maximumpc.com/articles/32/feed'),
|
||||||
|
(u'Features', u'http://www.maximumpc.com/articles/31/feed'),
|
||||||
|
(u'From the Magazine', u'http://www.maximumpc.com/articles/72/feed')
|
||||||
|
]
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'class':['print-title','article_body']}),
|
||||||
|
]
|
||||||
|
remove_tags = [
|
||||||
|
dict(name='div', attrs={'class':'comments-tags-actions'}),
|
||||||
|
]
|
||||||
|
remove_tags_before = dict(name='div', attrs={'class':'print-title'})
|
||||||
|
remove_tags_after = dict(name='div', attrs={'class':'meta-content'})
|
||||||
|
|
||||||
|
def get_obfuscated_article(self, url):
|
||||||
|
br = self.get_browser()
|
||||||
|
br.open(url)
|
||||||
|
response = br.follow_link(url_regex = r'/print/[0-9]+', nr = 0)
|
||||||
|
html = response.read()
|
||||||
|
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
||||||
|
self.temp_files[-1].write(html)
|
||||||
|
self.temp_files[-1].close()
|
||||||
|
return self.temp_files[-1].name
|
@ -1,39 +1,44 @@
|
|||||||
|
|
||||||
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
from calibre.ebooks.BeautifulSoup import BeautifulSoup
|
|
||||||
|
|
||||||
class PsychologyToday(BasicNewsRecipe):
|
class AdvancedUserRecipe1275708473(BasicNewsRecipe):
|
||||||
title = u'Psychology Today'
|
title = u'Psychology Today'
|
||||||
language = 'en'
|
_author__ = 'rty'
|
||||||
__author__ = 'Krittika Goyal'
|
publisher = u'www.psychologytoday.com'
|
||||||
oldest_article = 1 #days
|
category = u'Psychology'
|
||||||
max_articles_per_feed = 25
|
max_articles_per_feed = 100
|
||||||
#encoding = 'latin1'
|
remove_javascript = True
|
||||||
|
use_embedded_content = False
|
||||||
remove_stylesheets = True
|
no_stylesheets = True
|
||||||
#remove_tags_before = dict(name='h1', attrs={'class':'heading'})
|
language = 'en'
|
||||||
#remove_tags_after = dict(name='td', attrs={'class':'newptool1'})
|
temp_files = []
|
||||||
|
articles_are_obfuscated = True
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
dict(name='iframe'),
|
dict(name='div', attrs={'class':['print-source_url','field-items','print-footer']}),
|
||||||
dict(name='div', attrs={'class':['pt-box-title', 'pt-box-content', 'blog-entry-footer', 'item-list', 'article-sub-meta']}),
|
dict(name='span', attrs={'class':'print-footnote'}),
|
||||||
dict(name='div', attrs={'id':['block-td_search_160', 'block-cam_search_160']}),
|
]
|
||||||
#dict(name='ul', attrs={'class':'article-tools'}),
|
remove_tags_before = dict(name='h1', attrs={'class':'print-title'})
|
||||||
#dict(name='ul', attrs={'class':'articleTools'}),
|
remove_tags_after = dict(name='div', attrs={'class':['field-items','print-footer']})
|
||||||
]
|
|
||||||
|
|
||||||
feeds = [
|
feeds = [(u'Contents', u'http://www.psychologytoday.com/articles/index.rss')]
|
||||||
('PSY TODAY',
|
|
||||||
'http://www.psychologytoday.com/articles/index.rss'),
|
|
||||||
]
|
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def get_article_url(self, article):
|
||||||
story = soup.find(name='div', attrs={'id':'contentColumn'})
|
return article.get('link', None)
|
||||||
#td = heading.findParent(name='td')
|
|
||||||
#td.extract()
|
def get_obfuscated_article(self, url):
|
||||||
soup = BeautifulSoup('<html><head><title>t</title></head><body></body></html>')
|
br = self.get_browser()
|
||||||
body = soup.find(name='body')
|
br.open(url)
|
||||||
body.insert(0, story)
|
response = br.follow_link(url_regex = r'/print/[0-9]+', nr = 0)
|
||||||
for x in soup.findAll(name='p', text=lambda x:x and '-->' in x):
|
html = response.read()
|
||||||
p = x.findParent('p')
|
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
||||||
if p is not None:
|
self.temp_files[-1].write(html)
|
||||||
p.extract()
|
self.temp_files[-1].close()
|
||||||
return soup
|
return self.temp_files[-1].name
|
||||||
|
|
||||||
|
def get_cover_url(self):
|
||||||
|
index = 'http://www.psychologytoday.com/magazine/'
|
||||||
|
soup = self.index_to_soup(index)
|
||||||
|
for image in soup.findAll('img',{ "class" : "imagefield imagefield-field_magazine_cover" }):
|
||||||
|
return image['src'] + '.jpg'
|
||||||
|
return None
|
||||||
|
59
resources/recipes/today_online.recipe
Normal file
59
resources/recipes/today_online.recipe
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class AdvancedUserRecipe1276486274(BasicNewsRecipe):
|
||||||
|
title = u'Today Online - Singapore'
|
||||||
|
publisher = 'MediaCorp Press Ltd - Singapore'
|
||||||
|
__author__ = 'rty'
|
||||||
|
category = 'news, Singapore'
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
remove_javascript = True
|
||||||
|
use_embedded_content = False
|
||||||
|
no_stylesheets = True
|
||||||
|
language = 'en_SG'
|
||||||
|
temp_files = []
|
||||||
|
articles_are_obfuscated = True
|
||||||
|
masthead_url = 'http://www.todayonline.com/App_Themes/Default/images/icons/TodayOnlineLogo.gif'
|
||||||
|
conversion_options = {'linearize_tables':True}
|
||||||
|
extra_css = '''
|
||||||
|
.author{font-style: italic; font-size: small}
|
||||||
|
.date{font-style: italic; font-size: small}
|
||||||
|
.Headline{font-weight: bold; font-size: xx-large}
|
||||||
|
.headerStrap{font-weight: bold; font-size: x-large; font-syle: italic}
|
||||||
|
.bodyText{font-size: 4px;font-family: Times New Roman;}
|
||||||
|
'''
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'id':['fullPrintBodyHolder']})
|
||||||
|
]
|
||||||
|
remove_tags_after = [ dict(name='div', attrs={'class':'button'})]
|
||||||
|
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(name='div', attrs={'class':['url','button']})
|
||||||
|
]
|
||||||
|
feeds = [
|
||||||
|
(u'Singapore', u'http://www.todayonline.com/RSS/Singapore'),
|
||||||
|
(u'Hot News', u'http://www.todayonline.com/RSS/Hotnews'),
|
||||||
|
(u'Today Online', u'http://www.todayonline.com/RSS/Todayonline'),
|
||||||
|
(u'Voices', u'http://www.todayonline.com/RSS/Voices'),
|
||||||
|
(u'Commentary', u'http://www.todayonline.com/RSS/Commentary'),
|
||||||
|
(u'World', u'http://www.todayonline.com/RSS/World'),
|
||||||
|
(u'Business', u'http://www.todayonline.com/RSS/Business'),
|
||||||
|
(u'Column', u'http://www.todayonline.com/RSS/Columns'),
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_obfuscated_article(self, url):
|
||||||
|
br = self.get_browser()
|
||||||
|
br.open(url)
|
||||||
|
response = br.follow_link(url_regex = r'/Print/', nr = 0)
|
||||||
|
html = response.read()
|
||||||
|
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
||||||
|
self.temp_files[-1].write(html)
|
||||||
|
self.temp_files[-1].close()
|
||||||
|
return self.temp_files[-1].name
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
for item in soup.findAll(style=True):
|
||||||
|
del item['style']
|
||||||
|
return soup
|
@ -4,13 +4,14 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
import copy
|
||||||
|
|
||||||
# http://online.wsj.com/page/us_in_todays_paper.html
|
# http://online.wsj.com/page/us_in_todays_paper.html
|
||||||
|
|
||||||
class WallStreetJournal(BasicNewsRecipe):
|
class WallStreetJournal(BasicNewsRecipe):
|
||||||
|
|
||||||
title = 'The Wall Street Journal (US)'
|
title = 'The Wall Street Journal'
|
||||||
__author__ = 'Kovid Goyal and Sujata Raman'
|
__author__ = 'Kovid Goyal, Sujata Raman, and Joshua Oster-Morris'
|
||||||
description = 'News and current affairs'
|
description = 'News and current affairs'
|
||||||
needs_subscription = True
|
needs_subscription = True
|
||||||
language = 'en'
|
language = 'en'
|
||||||
@ -67,6 +68,16 @@ class WallStreetJournal(BasicNewsRecipe):
|
|||||||
def wsj_get_index(self):
|
def wsj_get_index(self):
|
||||||
return self.index_to_soup('http://online.wsj.com/itp')
|
return self.index_to_soup('http://online.wsj.com/itp')
|
||||||
|
|
||||||
|
def wsj_add_feed(self,feeds,title,url):
|
||||||
|
self.log('Found section:', title)
|
||||||
|
if url.endswith('whatsnews'):
|
||||||
|
articles = self.wsj_find_wn_articles(url)
|
||||||
|
else:
|
||||||
|
articles = self.wsj_find_articles(url)
|
||||||
|
if articles:
|
||||||
|
feeds.append((title, articles))
|
||||||
|
return feeds
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
soup = self.wsj_get_index()
|
soup = self.wsj_get_index()
|
||||||
|
|
||||||
@ -82,25 +93,62 @@ class WallStreetJournal(BasicNewsRecipe):
|
|||||||
div = soup.find('div', attrs={'class':'itpHeader'})
|
div = soup.find('div', attrs={'class':'itpHeader'})
|
||||||
div = div.find('ul', attrs={'class':'tab'})
|
div = div.find('ul', attrs={'class':'tab'})
|
||||||
for a in div.findAll('a', href=lambda x: x and '/itp/' in x):
|
for a in div.findAll('a', href=lambda x: x and '/itp/' in x):
|
||||||
title = self.tag_to_string(a)
|
pageone = a['href'].endswith('pageone')
|
||||||
url = 'http://online.wsj.com' + a['href']
|
if pageone:
|
||||||
self.log('Found section:', title)
|
title = 'Front Section'
|
||||||
articles = self.wsj_find_articles(url)
|
url = 'http://online.wsj.com' + a['href']
|
||||||
if articles:
|
feeds = self.wsj_add_feed(feeds,title,url)
|
||||||
feeds.append((title, articles))
|
title = 'What''s News'
|
||||||
|
url = url.replace('pageone','whatsnews')
|
||||||
|
feeds = self.wsj_add_feed(feeds,title,url)
|
||||||
|
else:
|
||||||
|
title = self.tag_to_string(a)
|
||||||
|
url = 'http://online.wsj.com' + a['href']
|
||||||
|
feeds = self.wsj_add_feed(feeds,title,url)
|
||||||
return feeds
|
return feeds
|
||||||
|
|
||||||
|
def wsj_find_wn_articles(self, url):
|
||||||
|
soup = self.index_to_soup(url)
|
||||||
|
articles = []
|
||||||
|
|
||||||
|
whats_news = soup.find('div', attrs={'class':lambda x: x and 'whatsNews-simple' in x})
|
||||||
|
if whats_news is not None:
|
||||||
|
for a in whats_news.findAll('a', href=lambda x: x and '/article/' in x):
|
||||||
|
container = a.findParent(['p'])
|
||||||
|
meta = a.find(attrs={'class':'meta_sectionName'})
|
||||||
|
if meta is not None:
|
||||||
|
meta.extract()
|
||||||
|
title = self.tag_to_string(a).strip()
|
||||||
|
url = a['href']
|
||||||
|
desc = ''
|
||||||
|
if container is not None:
|
||||||
|
desc = self.tag_to_string(container)
|
||||||
|
|
||||||
|
articles.append({'title':title, 'url':url,
|
||||||
|
'description':desc, 'date':''})
|
||||||
|
|
||||||
|
self.log('\tFound WN article:', title)
|
||||||
|
|
||||||
|
return articles
|
||||||
|
|
||||||
def wsj_find_articles(self, url):
|
def wsj_find_articles(self, url):
|
||||||
soup = self.index_to_soup(url)
|
soup = self.index_to_soup(url)
|
||||||
|
|
||||||
whats_news = soup.find('div', attrs={'class':lambda x: x and
|
whats_news = soup.find('div', attrs={'class':lambda x: x and 'whatsNews-simple' in x})
|
||||||
'whatsNews-simple' in x})
|
|
||||||
if whats_news is not None:
|
if whats_news is not None:
|
||||||
whats_news.extract()
|
whats_news.extract()
|
||||||
|
|
||||||
articles = []
|
articles = []
|
||||||
|
|
||||||
|
flavorarea = soup.find('div', attrs={'class':lambda x: x and 'ahed' in x})
|
||||||
|
if flavorarea is not None:
|
||||||
|
flavorstory = flavorarea.find('a', href=lambda x: x and x.startswith('/article'))
|
||||||
|
if flavorstory is not None:
|
||||||
|
flavorstory['class'] = 'mjLinkItem'
|
||||||
|
metapage = soup.find('span', attrs={'class':lambda x: x and 'meta_sectionName' in x})
|
||||||
|
if metapage is not None:
|
||||||
|
flavorstory.append( copy.copy(metapage) ) #metapage should always be A1 because that should be first on the page
|
||||||
|
|
||||||
for a in soup.findAll('a', attrs={'class':'mjLinkItem'}, href=True):
|
for a in soup.findAll('a', attrs={'class':'mjLinkItem'}, href=True):
|
||||||
container = a.findParent(['li', 'div'])
|
container = a.findParent(['li', 'div'])
|
||||||
meta = a.find(attrs={'class':'meta_sectionName'})
|
meta = a.find(attrs={'class':'meta_sectionName'})
|
||||||
@ -118,26 +166,9 @@ class WallStreetJournal(BasicNewsRecipe):
|
|||||||
|
|
||||||
self.log('\tFound article:', title)
|
self.log('\tFound article:', title)
|
||||||
|
|
||||||
'''
|
|
||||||
# Find related articles
|
|
||||||
a.extract()
|
|
||||||
for a in container.findAll('a', href=lambda x: x and '/article/'
|
|
||||||
in x and 'articleTabs' not in x):
|
|
||||||
url = a['href']
|
|
||||||
if not url.startswith('http:'):
|
|
||||||
url = 'http://online.wsj.com'+url
|
|
||||||
title = self.tag_to_string(a).strip()
|
|
||||||
if not title or title.startswith('['): continue
|
|
||||||
if title:
|
|
||||||
articles.append({'title':self.tag_to_string(a),
|
|
||||||
'url':url, 'description':'', 'date':''})
|
|
||||||
self.log('\t\tFound related:', title)
|
|
||||||
'''
|
|
||||||
|
|
||||||
return articles
|
return articles
|
||||||
|
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
self.browser.open('http://online.wsj.com/logout?url=http://online.wsj.com')
|
self.browser.open('http://online.wsj.com/logout?url=http://online.wsj.com')
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,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__ = 'calibre'
|
__appname__ = 'calibre'
|
||||||
__version__ = '0.7.3'
|
__version__ = '0.7.4'
|
||||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
@ -6,8 +6,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
|
|
||||||
import cStringIO, ctypes, datetime, os, re, shutil, subprocess, sys, tempfile, time
|
import cStringIO, ctypes, datetime, os, re, shutil, subprocess, sys, tempfile, time
|
||||||
|
from calibre.constants import __appname__, __version__, DEBUG
|
||||||
from calibre.constants import DEBUG
|
|
||||||
from calibre import fit_image
|
from calibre import fit_image
|
||||||
from calibre.constants import isosx, iswindows
|
from calibre.constants import isosx, iswindows
|
||||||
from calibre.devices.errors import UserFeedback
|
from calibre.devices.errors import UserFeedback
|
||||||
@ -79,7 +78,7 @@ class ITUNES(DevicePlugin):
|
|||||||
supported_platforms = ['osx','windows']
|
supported_platforms = ['osx','windows']
|
||||||
author = 'GRiker'
|
author = 'GRiker'
|
||||||
#: The version of this plugin as a 3-tuple (major, minor, revision)
|
#: The version of this plugin as a 3-tuple (major, minor, revision)
|
||||||
version = (0,6,0)
|
version = (0,7,0)
|
||||||
|
|
||||||
OPEN_FEEDBACK_MESSAGE = _(
|
OPEN_FEEDBACK_MESSAGE = _(
|
||||||
'Apple device detected, launching iTunes, please wait ...')
|
'Apple device detected, launching iTunes, please wait ...')
|
||||||
@ -294,7 +293,7 @@ class ITUNES(DevicePlugin):
|
|||||||
'author':[book.artist()],
|
'author':[book.artist()],
|
||||||
'lib_book':library_books[this_book.path] if this_book.path in library_books else None,
|
'lib_book':library_books[this_book.path] if this_book.path in library_books else None,
|
||||||
'dev_book':book,
|
'dev_book':book,
|
||||||
'uuid': book.album()
|
'uuid': book.composer()
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.report_progress is not None:
|
if self.report_progress is not None:
|
||||||
@ -330,7 +329,7 @@ class ITUNES(DevicePlugin):
|
|||||||
'title':book.Name,
|
'title':book.Name,
|
||||||
'author':book.Artist,
|
'author':book.Artist,
|
||||||
'lib_book':library_books[this_book.path] if this_book.path in library_books else None,
|
'lib_book':library_books[this_book.path] if this_book.path in library_books else None,
|
||||||
'uuid': book.Album
|
'uuid': book.Composer
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.report_progress is not None:
|
if self.report_progress is not None:
|
||||||
@ -1426,10 +1425,10 @@ class ITUNES(DevicePlugin):
|
|||||||
attempts = 9
|
attempts = 9
|
||||||
while attempts:
|
while attempts:
|
||||||
# Try by uuid - only one hit
|
# Try by uuid - only one hit
|
||||||
hits = dev_books.Search(search['uuid'],self.SearchField.index('Albums'))
|
hits = dev_books.Search(search['uuid'],self.SearchField.index('All'))
|
||||||
if hits:
|
if hits:
|
||||||
hit = hits[0]
|
hit = hits[0]
|
||||||
self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Album))
|
self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer))
|
||||||
return hit
|
return hit
|
||||||
|
|
||||||
# Try by author - there could be multiple hits
|
# Try by author - there could be multiple hits
|
||||||
@ -1438,7 +1437,7 @@ class ITUNES(DevicePlugin):
|
|||||||
for hit in hits:
|
for hit in hits:
|
||||||
if hit.Name == search['title']:
|
if hit.Name == search['title']:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Album))
|
self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer))
|
||||||
return hit
|
return hit
|
||||||
|
|
||||||
attempts -= 1
|
attempts -= 1
|
||||||
@ -1493,11 +1492,11 @@ class ITUNES(DevicePlugin):
|
|||||||
if 'uuid' in search:
|
if 'uuid' in search:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" searching by uuid '%s' ..." % search['uuid'])
|
self.log.info(" searching by uuid '%s' ..." % search['uuid'])
|
||||||
hits = lib_books.Search(search['uuid'],self.SearchField.index('Albums'))
|
hits = lib_books.Search(search['uuid'],self.SearchField.index('All'))
|
||||||
if hits:
|
if hits:
|
||||||
hit = hits[0]
|
hit = hits[0]
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Album))
|
self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer))
|
||||||
return hit
|
return hit
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
@ -1507,7 +1506,7 @@ class ITUNES(DevicePlugin):
|
|||||||
for hit in hits:
|
for hit in hits:
|
||||||
if hit.Name == search['title']:
|
if hit.Name == search['title']:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Album))
|
self.log.info(" found '%s' by %s (%s)" % (hit.Name, hit.Artist, hit.Composer))
|
||||||
return hit
|
return hit
|
||||||
|
|
||||||
attempts -= 1
|
attempts -= 1
|
||||||
@ -1558,6 +1557,10 @@ class ITUNES(DevicePlugin):
|
|||||||
return thumb.getvalue()
|
return thumb.getvalue()
|
||||||
except:
|
except:
|
||||||
self.log.error(" error generating thumb for '%s'" % book.name())
|
self.log.error(" error generating thumb for '%s'" % book.name())
|
||||||
|
try:
|
||||||
|
zfw.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
elif iswindows:
|
elif iswindows:
|
||||||
@ -1587,6 +1590,10 @@ class ITUNES(DevicePlugin):
|
|||||||
return thumb.getvalue()
|
return thumb.getvalue()
|
||||||
except:
|
except:
|
||||||
self.log.error(" error generating thumb for '%s'" % book.Name)
|
self.log.error(" error generating thumb for '%s'" % book.Name)
|
||||||
|
try:
|
||||||
|
zfw.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_device_book_size(self, file, compressed_size):
|
def _get_device_book_size(self, file, compressed_size):
|
||||||
@ -1925,6 +1932,7 @@ class ITUNES(DevicePlugin):
|
|||||||
self.log.error(" could not confirm valid iTunes.media_dir from %s" % 'com.apple.itunes')
|
self.log.error(" could not confirm valid iTunes.media_dir from %s" % 'com.apple.itunes')
|
||||||
self.log.error(" media_dir: %s" % media_dir)
|
self.log.error(" media_dir: %s" % media_dir)
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
|
self.log.info(" %s %s" % (__appname__, __version__))
|
||||||
self.log.info(" [OSX %s - %s (%s), driver version %d.%d.%d]" %
|
self.log.info(" [OSX %s - %s (%s), driver version %d.%d.%d]" %
|
||||||
(self.iTunes.name(), self.iTunes.version(), self.initial_status,
|
(self.iTunes.name(), self.iTunes.version(), self.initial_status,
|
||||||
self.version[0],self.version[1],self.version[2]))
|
self.version[0],self.version[1],self.version[2]))
|
||||||
@ -1954,6 +1962,7 @@ class ITUNES(DevicePlugin):
|
|||||||
self.log.error(" '%s' not found" % media_dir)
|
self.log.error(" '%s' not found" % media_dir)
|
||||||
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
|
self.log.info(" %s %s" % (__appname__, __version__))
|
||||||
self.log.info(" [Windows %s - %s (%s), driver version %d.%d.%d]" %
|
self.log.info(" [Windows %s - %s (%s), driver version %d.%d.%d]" %
|
||||||
(self.iTunes.Windows[0].name, self.iTunes.Version, self.initial_status,
|
(self.iTunes.Windows[0].name, self.iTunes.Version, self.initial_status,
|
||||||
self.version[0],self.version[1],self.version[2]))
|
self.version[0],self.version[1],self.version[2]))
|
||||||
@ -2041,7 +2050,7 @@ class ITUNES(DevicePlugin):
|
|||||||
|
|
||||||
elif iswindows:
|
elif iswindows:
|
||||||
dev_pl = self._get_device_books_playlist()
|
dev_pl = self._get_device_books_playlist()
|
||||||
hits = dev_pl.Search(cached_book['uuid'],self.SearchField.index('Albums'))
|
hits = dev_pl.Search(cached_book['uuid'],self.SearchField.index('All'))
|
||||||
if hits:
|
if hits:
|
||||||
hit = hits[0]
|
hit = hits[0]
|
||||||
if False:
|
if False:
|
||||||
@ -2095,7 +2104,7 @@ class ITUNES(DevicePlugin):
|
|||||||
self.iTunes.delete(cached_book['lib_book'])
|
self.iTunes.delete(cached_book['lib_book'])
|
||||||
except:
|
except:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" '%s' not found in iTunes" % cached_book['title'])
|
self.log.info(" unable to remove '%s' from iTunes" % cached_book['title'])
|
||||||
|
|
||||||
elif iswindows:
|
elif iswindows:
|
||||||
'''
|
'''
|
||||||
@ -2107,13 +2116,14 @@ class ITUNES(DevicePlugin):
|
|||||||
path = book.Location
|
path = book.Location
|
||||||
except:
|
except:
|
||||||
book = self._find_library_book(cached_book)
|
book = self._find_library_book(cached_book)
|
||||||
|
path = book.Location
|
||||||
|
|
||||||
if book:
|
if book:
|
||||||
storage_path = os.path.split(book.Location)
|
storage_path = os.path.split(path)
|
||||||
if book.Location.startswith(self.iTunes_media):
|
if path.startswith(self.iTunes_media):
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" removing '%s' at %s" %
|
self.log.info(" removing '%s' at %s" %
|
||||||
(cached_book['title'], book.Location))
|
(cached_book['title'], path))
|
||||||
try:
|
try:
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
except:
|
except:
|
||||||
@ -2134,7 +2144,7 @@ class ITUNES(DevicePlugin):
|
|||||||
book.Delete()
|
book.Delete()
|
||||||
except:
|
except:
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
self.log.info(" '%s' not found in iTunes" % cached_book['title'])
|
self.log.info(" unable to remove '%s' from iTunes" % cached_book['title'])
|
||||||
|
|
||||||
def _update_epub_metadata(self, fpath, metadata):
|
def _update_epub_metadata(self, fpath, metadata):
|
||||||
'''
|
'''
|
||||||
@ -2241,14 +2251,16 @@ class ITUNES(DevicePlugin):
|
|||||||
|
|
||||||
if isosx:
|
if isosx:
|
||||||
if lb_added:
|
if lb_added:
|
||||||
lb_added.album.set(metadata.uuid)
|
lb_added.album.set(metadata.title)
|
||||||
|
lb_added.composer.set(metadata.uuid)
|
||||||
lb_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
lb_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
lb_added.enabled.set(True)
|
lb_added.enabled.set(True)
|
||||||
lb_added.sort_artist.set(metadata.author_sort.title())
|
lb_added.sort_artist.set(metadata.author_sort.title())
|
||||||
lb_added.sort_name.set(this_book.title_sorter)
|
lb_added.sort_name.set(this_book.title_sorter)
|
||||||
|
|
||||||
if db_added:
|
if db_added:
|
||||||
db_added.album.set(metadata.uuid)
|
db_added.album.set(metadata.title)
|
||||||
|
db_added.composer.set(metadata.uuid)
|
||||||
db_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
db_added.description.set("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
db_added.enabled.set(True)
|
db_added.enabled.set(True)
|
||||||
db_added.sort_artist.set(metadata.author_sort.title())
|
db_added.sort_artist.set(metadata.author_sort.title())
|
||||||
@ -2296,14 +2308,16 @@ class ITUNES(DevicePlugin):
|
|||||||
|
|
||||||
elif iswindows:
|
elif iswindows:
|
||||||
if lb_added:
|
if lb_added:
|
||||||
lb_added.Album = metadata.uuid
|
lb_added.Album = metadata.title
|
||||||
|
lb_added.Composer = metadata.uuid
|
||||||
lb_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
lb_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
lb_added.Enabled = True
|
lb_added.Enabled = True
|
||||||
lb_added.SortArtist = (metadata.author_sort.title())
|
lb_added.SortArtist = (metadata.author_sort.title())
|
||||||
lb_added.SortName = (this_book.title_sorter)
|
lb_added.SortName = (this_book.title_sorter)
|
||||||
|
|
||||||
if db_added:
|
if db_added:
|
||||||
db_added.Album = metadata.uuid
|
db_added.Album = metadata.title
|
||||||
|
db_added.Composer = metadata.uuid
|
||||||
db_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
db_added.Description = ("%s %s" % (self.description_prefix,strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
db_added.Enabled = True
|
db_added.Enabled = True
|
||||||
db_added.SortArtist = (metadata.author_sort.title())
|
db_added.SortArtist = (metadata.author_sort.title())
|
||||||
|
@ -84,7 +84,7 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
|
|
||||||
OptionRecommendation(name='no_svg_cover', recommended_value=False,
|
OptionRecommendation(name='no_svg_cover', recommended_value=False,
|
||||||
help=_('Do not use SVG for the book cover. Use this option if '
|
help=_('Do not use SVG for the book cover. Use this option if '
|
||||||
'your EPUB is going to be used ona device that does not '
|
'your EPUB is going to be used on a device that does not '
|
||||||
'support SVG, like the iPhone or the JetBook Lite. '
|
'support SVG, like the iPhone or the JetBook Lite. '
|
||||||
'Without this option, such devices will display the cover '
|
'Without this option, such devices will display the cover '
|
||||||
'as a blank page.')
|
'as a blank page.')
|
||||||
|
@ -93,10 +93,16 @@ class CoverView(QWidget): # {{{
|
|||||||
self._current_pixmap_size = val
|
self._current_pixmap_size = val
|
||||||
|
|
||||||
def do_layout(self):
|
def do_layout(self):
|
||||||
|
if self.rect().width() == 0 or self.rect().height() == 0:
|
||||||
|
return
|
||||||
pixmap = self.pixmap
|
pixmap = self.pixmap
|
||||||
pwidth, pheight = pixmap.width(), pixmap.height()
|
pwidth, pheight = pixmap.width(), pixmap.height()
|
||||||
self.pwidth, self.pheight = fit_image(pwidth, pheight,
|
try:
|
||||||
|
self.pwidth, self.pheight = fit_image(pwidth, pheight,
|
||||||
self.rect().width(), self.rect().height())[1:]
|
self.rect().width(), self.rect().height())[1:]
|
||||||
|
except:
|
||||||
|
self.pwidth, self.pheight = self.rect().width()-1, \
|
||||||
|
self.rect().height()-1
|
||||||
self.current_pixmap_size = QSize(self.pwidth, self.pheight)
|
self.current_pixmap_size = QSize(self.pwidth, self.pheight)
|
||||||
self.animation.setEndValue(self.current_pixmap_size)
|
self.animation.setEndValue(self.current_pixmap_size)
|
||||||
|
|
||||||
@ -120,7 +126,8 @@ class CoverView(QWidget): # {{{
|
|||||||
self.data = {'id':data.get('id', None)}
|
self.data = {'id':data.get('id', None)}
|
||||||
if data.has_key('cover'):
|
if data.has_key('cover'):
|
||||||
self.pixmap = QPixmap.fromImage(data.pop('cover'))
|
self.pixmap = QPixmap.fromImage(data.pop('cover'))
|
||||||
if self.pixmap.isNull():
|
if self.pixmap.isNull() or self.pixmap.width() < 5 or \
|
||||||
|
self.pixmap.height() < 5:
|
||||||
self.pixmap = self.default_pixmap
|
self.pixmap = self.default_pixmap
|
||||||
else:
|
else:
|
||||||
self.pixmap = self.default_pixmap
|
self.pixmap = self.default_pixmap
|
||||||
|
@ -205,8 +205,8 @@ class CoverFlowMixin(object):
|
|||||||
sm.select(index, sm.ClearAndSelect|sm.Rows)
|
sm.select(index, sm.ClearAndSelect|sm.Rows)
|
||||||
self.library_view.setCurrentIndex(index)
|
self.library_view.setCurrentIndex(index)
|
||||||
except:
|
except:
|
||||||
pass
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
def sync_listview_to_cf(self, row):
|
def sync_listview_to_cf(self, row):
|
||||||
self.cf_last_updated_at = time.time()
|
self.cf_last_updated_at = time.time()
|
||||||
|
@ -919,8 +919,8 @@ class DeviceBooksModel(BooksModel): # {{{
|
|||||||
flags = QAbstractTableModel.flags(self, index)
|
flags = QAbstractTableModel.flags(self, index)
|
||||||
if index.isValid() and self.editable:
|
if index.isValid() and self.editable:
|
||||||
cname = self.column_map[index.column()]
|
cname = self.column_map[index.column()]
|
||||||
if cname in ('title', 'authors') or (cname == 'collection' and \
|
if cname in ('title', 'authors') or \
|
||||||
self.db.supports_collections()):
|
(cname == 'collections' and self.db.supports_collections()):
|
||||||
flags |= Qt.ItemIsEditable
|
flags |= Qt.ItemIsEditable
|
||||||
return flags
|
return flags
|
||||||
|
|
||||||
|
@ -496,6 +496,7 @@ int PictureFlowPrivate::currentSlide() const
|
|||||||
|
|
||||||
void PictureFlowPrivate::setCurrentSlide(int index)
|
void PictureFlowPrivate::setCurrentSlide(int index)
|
||||||
{
|
{
|
||||||
|
animateTimer.stop();
|
||||||
step = 0;
|
step = 0;
|
||||||
centerIndex = qBound(index, 0, slideImages->count()-1);
|
centerIndex = qBound(index, 0, slideImages->count()-1);
|
||||||
target = centerIndex;
|
target = centerIndex;
|
||||||
|
@ -467,7 +467,8 @@ class CustomColumns(object):
|
|||||||
books_ratings_link as bl,
|
books_ratings_link as bl,
|
||||||
ratings as r
|
ratings as r
|
||||||
WHERE {lt}.value={table}.id and bl.book={lt}.book and
|
WHERE {lt}.value={table}.id and bl.book={lt}.book and
|
||||||
r.id = bl.rating and r.rating <> 0) avg_rating
|
r.id = bl.rating and r.rating <> 0) avg_rating,
|
||||||
|
value AS sort
|
||||||
FROM {table};
|
FROM {table};
|
||||||
|
|
||||||
CREATE VIEW tag_browser_filtered_{table} AS SELECT
|
CREATE VIEW tag_browser_filtered_{table} AS SELECT
|
||||||
@ -481,7 +482,8 @@ class CustomColumns(object):
|
|||||||
ratings as r
|
ratings as r
|
||||||
WHERE {lt}.value={table}.id AND bl.book={lt}.book AND
|
WHERE {lt}.value={table}.id AND bl.book={lt}.book AND
|
||||||
r.id = bl.rating AND r.rating <> 0 AND
|
r.id = bl.rating AND r.rating <> 0 AND
|
||||||
books_list_filter(bl.book)) avg_rating
|
books_list_filter(bl.book)) avg_rating,
|
||||||
|
value AS sort
|
||||||
FROM {table};
|
FROM {table};
|
||||||
|
|
||||||
'''.format(lt=lt, table=table),
|
'''.format(lt=lt, table=table),
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -4,9 +4,9 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: calibre 0.7.3\n"
|
"Project-Id-Version: calibre 0.7.4\n"
|
||||||
"POT-Creation-Date: 2010-06-18 11:10+MDT\n"
|
"POT-Creation-Date: 2010-06-19 18:08+MDT\n"
|
||||||
"PO-Revision-Date: 2010-06-18 11:10+MDT\n"
|
"PO-Revision-Date: 2010-06-19 18:08+MDT\n"
|
||||||
"Last-Translator: Automatically generated\n"
|
"Last-Translator: Automatically generated\n"
|
||||||
"Language-Team: LANGUAGE\n"
|
"Language-Team: LANGUAGE\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -422,55 +422,55 @@ msgstr ""
|
|||||||
msgid "Communicate with S60 phones."
|
msgid "Communicate with S60 phones."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:78
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:77
|
||||||
msgid "Communicate with iBooks through iTunes."
|
msgid "Communicate with iBooks through iTunes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:84
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:83
|
||||||
msgid "Apple device detected, launching iTunes, please wait ..."
|
msgid "Apple device detected, launching iTunes, please wait ..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:227
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:226
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:230
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:229
|
||||||
msgid "Updating device metadata listing..."
|
msgid "Updating device metadata listing..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:301
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:300
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:338
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:337
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:842
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:841
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:876
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:875
|
||||||
msgid "%d of %d"
|
msgid "%d of %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:345
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:344
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:881
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:880
|
||||||
msgid "finished"
|
msgid "finished"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:519
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:518
|
||||||
msgid ""
|
msgid ""
|
||||||
"Some books not found in iTunes database.\n"
|
"Some books not found in iTunes database.\n"
|
||||||
"Delete using the iBooks app.\n"
|
"Delete using the iBooks app.\n"
|
||||||
"Click 'Show Details' for a list."
|
"Click 'Show Details' for a list."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:742
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:741
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/deviceconfig.py:28
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/deviceconfig.py:28
|
||||||
msgid "settings for device drivers"
|
msgid "settings for device drivers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:744
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:743
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/deviceconfig.py:30
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/deviceconfig.py:30
|
||||||
msgid "Ordered list of formats the device will accept"
|
msgid "Ordered list of formats the device will accept"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:813
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:812
|
||||||
msgid ""
|
msgid ""
|
||||||
"Some cover art could not be converted.\n"
|
"Some cover art could not be converted.\n"
|
||||||
"Click 'Show Details' for a list."
|
"Click 'Show Details' for a list."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2168
|
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2178
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:810
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:810
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:816
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:816
|
||||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:844
|
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:844
|
||||||
@ -1269,7 +1269,7 @@ msgid "Normally, if the input file has no cover and you don't specify one, a def
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:86
|
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:86
|
||||||
msgid "Do not use SVG for the book cover. Use this option if your EPUB is going to be used ona device that does not support SVG, like the iPhone or the JetBook Lite. Without this option, such devices will display the cover as a blank page."
|
msgid "Do not use SVG for the book cover. Use this option if your EPUB is going to be used on a device that does not support SVG, like the iPhone or the JetBook Lite. Without this option, such devices will display the cover as a blank page."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:94
|
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/output.py:94
|
||||||
@ -1547,10 +1547,10 @@ msgstr ""
|
|||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:385
|
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/__init__.py:385
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:34
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:34
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:201
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:202
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:207
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:208
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:208
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:209
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:214
|
||||||
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:215
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:184
|
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata_ui.py:184
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:99
|
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:99
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:67
|
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:67
|
||||||
@ -2886,7 +2886,7 @@ msgstr ""
|
|||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:22
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:22
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:44
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:44
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:53
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:53
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:302
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:309
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:114
|
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:114
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:115
|
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:115
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:116
|
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:116
|
||||||
@ -2931,7 +2931,7 @@ msgstr ""
|
|||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:301
|
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:308
|
||||||
msgid "Click to open Book Details window"
|
msgid "Click to open Book Details window"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
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
Loading…
x
Reference in New Issue
Block a user