Pull from trunk

This commit is contained in:
Timothy Legge 2010-06-20 23:51:03 -03:00
commit d871e221e3
37 changed files with 21687 additions and 18271 deletions

View File

@ -4,6 +4,31 @@
# for important features/bug fixes.
# 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
date: 2010-06-18

View 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

View 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

View 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

View File

@ -1,39 +1,44 @@
from calibre.ptempfile import PersistentTemporaryFile
from calibre.web.feeds.news import BasicNewsRecipe
from calibre.ebooks.BeautifulSoup import BeautifulSoup
class PsychologyToday(BasicNewsRecipe):
class AdvancedUserRecipe1275708473(BasicNewsRecipe):
title = u'Psychology Today'
language = 'en'
__author__ = 'Krittika Goyal'
oldest_article = 1 #days
max_articles_per_feed = 25
#encoding = 'latin1'
remove_stylesheets = True
#remove_tags_before = dict(name='h1', attrs={'class':'heading'})
#remove_tags_after = dict(name='td', attrs={'class':'newptool1'})
_author__ = 'rty'
publisher = u'www.psychologytoday.com'
category = u'Psychology'
max_articles_per_feed = 100
remove_javascript = True
use_embedded_content = False
no_stylesheets = True
language = 'en'
temp_files = []
articles_are_obfuscated = True
remove_tags = [
dict(name='iframe'),
dict(name='div', attrs={'class':['pt-box-title', 'pt-box-content', 'blog-entry-footer', 'item-list', 'article-sub-meta']}),
dict(name='div', attrs={'id':['block-td_search_160', 'block-cam_search_160']}),
#dict(name='ul', attrs={'class':'article-tools'}),
#dict(name='ul', attrs={'class':'articleTools'}),
]
dict(name='div', attrs={'class':['print-source_url','field-items','print-footer']}),
dict(name='span', attrs={'class':'print-footnote'}),
]
remove_tags_before = dict(name='h1', attrs={'class':'print-title'})
remove_tags_after = dict(name='div', attrs={'class':['field-items','print-footer']})
feeds = [
('PSY TODAY',
'http://www.psychologytoday.com/articles/index.rss'),
]
feeds = [(u'Contents', u'http://www.psychologytoday.com/articles/index.rss')]
def preprocess_html(self, soup):
story = soup.find(name='div', attrs={'id':'contentColumn'})
#td = heading.findParent(name='td')
#td.extract()
soup = BeautifulSoup('<html><head><title>t</title></head><body></body></html>')
body = soup.find(name='body')
body.insert(0, story)
for x in soup.findAll(name='p', text=lambda x:x and '--&gt;' in x):
p = x.findParent('p')
if p is not None:
p.extract()
return soup
def get_article_url(self, article):
return article.get('link', None)
def get_obfuscated_article(self, url):
br = self.get_browser()
br.open(url)
response = br.follow_link(url_regex = r'/print/[0-9]+', nr = 0)
html = response.read()
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
self.temp_files[-1].write(html)
self.temp_files[-1].close()
return self.temp_files[-1].name
def get_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

View 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

View File

@ -4,13 +4,14 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
from calibre.web.feeds.news import BasicNewsRecipe
import copy
# http://online.wsj.com/page/us_in_todays_paper.html
class WallStreetJournal(BasicNewsRecipe):
title = 'The Wall Street Journal (US)'
__author__ = 'Kovid Goyal and Sujata Raman'
title = 'The Wall Street Journal'
__author__ = 'Kovid Goyal, Sujata Raman, and Joshua Oster-Morris'
description = 'News and current affairs'
needs_subscription = True
language = 'en'
@ -67,6 +68,16 @@ class WallStreetJournal(BasicNewsRecipe):
def wsj_get_index(self):
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):
soup = self.wsj_get_index()
@ -82,25 +93,62 @@ class WallStreetJournal(BasicNewsRecipe):
div = soup.find('div', attrs={'class':'itpHeader'})
div = div.find('ul', attrs={'class':'tab'})
for a in div.findAll('a', href=lambda x: x and '/itp/' in x):
title = self.tag_to_string(a)
url = 'http://online.wsj.com' + a['href']
self.log('Found section:', title)
articles = self.wsj_find_articles(url)
if articles:
feeds.append((title, articles))
pageone = a['href'].endswith('pageone')
if pageone:
title = 'Front Section'
url = 'http://online.wsj.com' + a['href']
feeds = self.wsj_add_feed(feeds,title,url)
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
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):
soup = self.index_to_soup(url)
whats_news = soup.find('div', attrs={'class':lambda x: x and
'whatsNews-simple' in x})
whats_news = soup.find('div', attrs={'class':lambda x: x and 'whatsNews-simple' in x})
if whats_news is not None:
whats_news.extract()
whats_news.extract()
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):
container = a.findParent(['li', 'div'])
meta = a.find(attrs={'class':'meta_sectionName'})
@ -118,26 +166,9 @@ class WallStreetJournal(BasicNewsRecipe):
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
def cleanup(self):
self.browser.open('http://online.wsj.com/logout?url=http://online.wsj.com')

View File

@ -2,7 +2,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
__appname__ = 'calibre'
__version__ = '0.7.3'
__version__ = '0.7.4'
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
import re

View File

@ -6,8 +6,7 @@ __docformat__ = 'restructuredtext en'
import cStringIO, ctypes, datetime, os, re, shutil, subprocess, sys, tempfile, time
from calibre.constants import DEBUG
from calibre.constants import __appname__, __version__, DEBUG
from calibre import fit_image
from calibre.constants import isosx, iswindows
from calibre.devices.errors import UserFeedback
@ -79,7 +78,7 @@ class ITUNES(DevicePlugin):
supported_platforms = ['osx','windows']
author = 'GRiker'
#: The version of this plugin as a 3-tuple (major, minor, revision)
version = (0,6,0)
version = (0,7,0)
OPEN_FEEDBACK_MESSAGE = _(
'Apple device detected, launching iTunes, please wait ...')
@ -294,7 +293,7 @@ class ITUNES(DevicePlugin):
'author':[book.artist()],
'lib_book':library_books[this_book.path] if this_book.path in library_books else None,
'dev_book':book,
'uuid': book.album()
'uuid': book.composer()
}
if self.report_progress is not None:
@ -330,7 +329,7 @@ class ITUNES(DevicePlugin):
'title':book.Name,
'author':book.Artist,
'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:
@ -1426,10 +1425,10 @@ class ITUNES(DevicePlugin):
attempts = 9
while attempts:
# 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:
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
# Try by author - there could be multiple hits
@ -1438,7 +1437,7 @@ class ITUNES(DevicePlugin):
for hit in hits:
if hit.Name == search['title']:
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
attempts -= 1
@ -1493,11 +1492,11 @@ class ITUNES(DevicePlugin):
if 'uuid' in search:
if DEBUG:
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:
hit = hits[0]
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
if DEBUG:
@ -1507,7 +1506,7 @@ class ITUNES(DevicePlugin):
for hit in hits:
if hit.Name == search['title']:
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
attempts -= 1
@ -1558,6 +1557,10 @@ class ITUNES(DevicePlugin):
return thumb.getvalue()
except:
self.log.error(" error generating thumb for '%s'" % book.name())
try:
zfw.close()
except:
pass
return None
elif iswindows:
@ -1587,6 +1590,10 @@ class ITUNES(DevicePlugin):
return thumb.getvalue()
except:
self.log.error(" error generating thumb for '%s'" % book.Name)
try:
zfw.close()
except:
pass
return None
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(" media_dir: %s" % media_dir)
if DEBUG:
self.log.info(" %s %s" % (__appname__, __version__))
self.log.info(" [OSX %s - %s (%s), driver version %d.%d.%d]" %
(self.iTunes.name(), self.iTunes.version(), self.initial_status,
self.version[0],self.version[1],self.version[2]))
@ -1954,6 +1962,7 @@ class ITUNES(DevicePlugin):
self.log.error(" '%s' not found" % media_dir)
if DEBUG:
self.log.info(" %s %s" % (__appname__, __version__))
self.log.info(" [Windows %s - %s (%s), driver version %d.%d.%d]" %
(self.iTunes.Windows[0].name, self.iTunes.Version, self.initial_status,
self.version[0],self.version[1],self.version[2]))
@ -2041,7 +2050,7 @@ class ITUNES(DevicePlugin):
elif iswindows:
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:
hit = hits[0]
if False:
@ -2095,7 +2104,7 @@ class ITUNES(DevicePlugin):
self.iTunes.delete(cached_book['lib_book'])
except:
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:
'''
@ -2107,13 +2116,14 @@ class ITUNES(DevicePlugin):
path = book.Location
except:
book = self._find_library_book(cached_book)
path = book.Location
if book:
storage_path = os.path.split(book.Location)
if book.Location.startswith(self.iTunes_media):
storage_path = os.path.split(path)
if path.startswith(self.iTunes_media):
if DEBUG:
self.log.info(" removing '%s' at %s" %
(cached_book['title'], book.Location))
(cached_book['title'], path))
try:
os.remove(path)
except:
@ -2134,7 +2144,7 @@ class ITUNES(DevicePlugin):
book.Delete()
except:
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):
'''
@ -2241,14 +2251,16 @@ class ITUNES(DevicePlugin):
if isosx:
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.enabled.set(True)
lb_added.sort_artist.set(metadata.author_sort.title())
lb_added.sort_name.set(this_book.title_sorter)
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.enabled.set(True)
db_added.sort_artist.set(metadata.author_sort.title())
@ -2296,14 +2308,16 @@ class ITUNES(DevicePlugin):
elif iswindows:
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.Enabled = True
lb_added.SortArtist = (metadata.author_sort.title())
lb_added.SortName = (this_book.title_sorter)
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.Enabled = True
db_added.SortArtist = (metadata.author_sort.title())

View File

@ -84,7 +84,7 @@ class EPUBOutput(OutputFormatPlugin):
OptionRecommendation(name='no_svg_cover', recommended_value=False,
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. '
'Without this option, such devices will display the cover '
'as a blank page.')

View File

@ -93,10 +93,16 @@ class CoverView(QWidget): # {{{
self._current_pixmap_size = val
def do_layout(self):
if self.rect().width() == 0 or self.rect().height() == 0:
return
pixmap = self.pixmap
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:]
except:
self.pwidth, self.pheight = self.rect().width()-1, \
self.rect().height()-1
self.current_pixmap_size = QSize(self.pwidth, self.pheight)
self.animation.setEndValue(self.current_pixmap_size)
@ -120,7 +126,8 @@ class CoverView(QWidget): # {{{
self.data = {'id':data.get('id', None)}
if data.has_key('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
else:
self.pixmap = self.default_pixmap

View File

@ -205,8 +205,8 @@ class CoverFlowMixin(object):
sm.select(index, sm.ClearAndSelect|sm.Rows)
self.library_view.setCurrentIndex(index)
except:
pass
import traceback
traceback.print_exc()
def sync_listview_to_cf(self, row):
self.cf_last_updated_at = time.time()

View File

@ -919,8 +919,8 @@ class DeviceBooksModel(BooksModel): # {{{
flags = QAbstractTableModel.flags(self, index)
if index.isValid() and self.editable:
cname = self.column_map[index.column()]
if cname in ('title', 'authors') or (cname == 'collection' and \
self.db.supports_collections()):
if cname in ('title', 'authors') or \
(cname == 'collections' and self.db.supports_collections()):
flags |= Qt.ItemIsEditable
return flags

View File

@ -496,6 +496,7 @@ int PictureFlowPrivate::currentSlide() const
void PictureFlowPrivate::setCurrentSlide(int index)
{
animateTimer.stop();
step = 0;
centerIndex = qBound(index, 0, slideImages->count()-1);
target = centerIndex;

View File

@ -467,7 +467,8 @@ class CustomColumns(object):
books_ratings_link as bl,
ratings as r
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};
CREATE VIEW tag_browser_filtered_{table} AS SELECT
@ -481,7 +482,8 @@ class CustomColumns(object):
ratings as r
WHERE {lt}.value={table}.id AND bl.book={lt}.book 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};
'''.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

View File

@ -4,9 +4,9 @@
#
msgid ""
msgstr ""
"Project-Id-Version: calibre 0.7.3\n"
"POT-Creation-Date: 2010-06-18 11:10+MDT\n"
"PO-Revision-Date: 2010-06-18 11:10+MDT\n"
"Project-Id-Version: calibre 0.7.4\n"
"POT-Creation-Date: 2010-06-19 18:08+MDT\n"
"PO-Revision-Date: 2010-06-19 18:08+MDT\n"
"Last-Translator: Automatically generated\n"
"Language-Team: LANGUAGE\n"
"MIME-Version: 1.0\n"
@ -422,55 +422,55 @@ msgstr ""
msgid "Communicate with S60 phones."
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."
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 ..."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:227
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:230
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:226
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:229
msgid "Updating device metadata listing..."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:301
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:338
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:842
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:876
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:300
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:337
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:841
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:875
msgid "%d of %d"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:345
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:881
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:344
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:880
msgid "finished"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:519
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:518
msgid ""
"Some books not found in iTunes database.\n"
"Delete using the iBooks app.\n"
"Click 'Show Details' for a list."
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
msgid "settings for device drivers"
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
msgid "Ordered list of formats the device will accept"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:813
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:812
msgid ""
"Some cover art could not be converted.\n"
"Click 'Show Details' for a list."
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:816
#: /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 ""
#: /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 ""
#: /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/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: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/dialogs/book_info.py:99
#: /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:44
#: /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:115
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:116
@ -2931,7 +2931,7 @@ msgstr ""
msgid "None"
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"
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