Merge from trunk

This commit is contained in:
Charles Haley 2011-06-03 17:39:45 +01:00
commit 0c5cdd6a8c
75 changed files with 98956 additions and 50559 deletions

View File

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from calibre.web.feeds.recipes import BasicNewsRecipe from calibre.web.feeds.recipes import BasicNewsRecipe
class AdvancedUserRecipe1303841067(BasicNewsRecipe): class AdvancedUserRecipe1303841067(BasicNewsRecipe):
title = u'Bild.de' title = u'Bild.de'
__author__ = 'schuster' __author__ = 'schuster'
oldest_article = 1 oldest_article = 1
max_articles_per_feed = 50 max_articles_per_feed = 100
no_stylesheets = True no_stylesheets = True
use_embedded_content = False use_embedded_content = False
language = 'de' language = 'de'
@ -12,11 +13,25 @@ class AdvancedUserRecipe1303841067(BasicNewsRecipe):
# get cover from myspace # get cover from myspace
cover_url = 'http://a3.l3-images.myspacecdn.com/images02/56/0232f842170b4d349779f8379c27e073/l.jpg' cover_url = 'http://a3.l3-images.myspacecdn.com/images02/56/0232f842170b4d349779f8379c27e073/l.jpg'
masthead_url = 'http://a3.l3-images.myspacecdn.com/images02/56/0232f842170b4d349779f8379c27e073/l.jpg'
# set what to fetch on the site # set what to fetch on the site
remove_tags_before = dict(name = 'h2', attrs={'id':'cover'}) remove_tags_before = dict(name = 'h2', attrs={'id':'cover'})
remove_tags_after = dict(name ='div', attrs={'class':'back'}) remove_tags_after = dict(name ='div', attrs={'class':'back'})
# remove things on the site that we don't want
remove_tags = [dict(name='div', attrs={'class':'credit'}),
dict(name='div', attrs={'class':'index'}),
dict(name='div', attrs={'id':'zstart31'}),
dict(name='div', attrs={'class':'hentry'}),
dict(name='div', attrs={'class':'back'}),
dict(name='div', attrs={'class':'pagination'}),
dict(name='div', attrs={'class':'header'}),
dict(name='div', attrs={'class':'element floatL'}),
dict(name='div', attrs={'class':'stWrap'})
]
# thanx to kiklop74 for code (see sticky thread -> Recipes - Re-usable code) # thanx to kiklop74 for code (see sticky thread -> Recipes - Re-usable code)
# this one removes a lot of direct-link's # this one removes a lot of direct-link's
def preprocess_html(self, soup): def preprocess_html(self, soup):
@ -42,5 +57,18 @@ class AdvancedUserRecipe1303841067(BasicNewsRecipe):
(u'Unterhaltung', u'http://rss.bild.de/bild-unterhaltung.xml'), (u'Unterhaltung', u'http://rss.bild.de/bild-unterhaltung.xml'),
(u'Sport', u'http://rss.bild.de/bild-sport.xml'), (u'Sport', u'http://rss.bild.de/bild-sport.xml'),
(u'Lifestyle', u'http://rss.bild.de/bild-lifestyle.xml'), (u'Lifestyle', u'http://rss.bild.de/bild-lifestyle.xml'),
(u'Ratgeber', u'http://rss.bild.de/bild-ratgeber.xml') (u'Ratgeber', u'http://rss.bild.de/bild-ratgeber.xml'),
(u'Reg. - Berlin', u'http://rss.bild.de/bild-berlin.xml'),
(u'Reg. - Bremen', u'http://rss.bild.de/bild-bremen.xml'),
(u'Reg. - Dresden', u'http://rss.bild.de/bild-dresden.xml'),
(u'Reg. - Düsseldorf', u'http://rss.bild.de/bild-duesseldorf.xml'),
(u'Reg. - Frankfurt-Main', u'http://rss.bild.de/bild-frankfurt-main.xml'),
(u'Reg. - Hamburg', u'http://rss.bild.de/bild-hamburg.xml'),
(u'Reg. - Hannover', u'http://rss.bild.de/bild-hannover.xml'),
(u'Reg. - Köln', u'http://rss.bild.de/bild-koeln.xml'),
(u'Reg. - Leipzig', u'http://rss.bild.de/bild-leipzig.xml'),
(u'Reg. - München', u'http://rss.bild.de/bild-muenchen.xml'),
(u'Reg. - Ruhrgebiet', u'http://rss.bild.de/bild-ruhrgebiet.xml'),
(u'Reg. - Stuttgart', u'http://rss.bild.de/bild-stuttgart.xml')
] ]

View File

@ -28,7 +28,7 @@ class Guardian(BasicNewsRecipe):
# List of section titles to ignore # List of section titles to ignore
# For example: ['Sport'] # For example: ['Sport']
ignore_sections = [] ignore_sections = []
timefmt = ' [%a, %d %b %Y]' timefmt = ' [%a, %d %b %Y]'
keep_only_tags = [ keep_only_tags = [
dict(name='div', attrs={'id':["content","article_header","main-article-info",]}), dict(name='div', attrs={'id':["content","article_header","main-article-info",]}),
@ -87,8 +87,14 @@ class Guardian(BasicNewsRecipe):
idx = soup.find('div', id='book-index') idx = soup.find('div', id='book-index')
for s in idx.findAll('strong', attrs={'class':'book'}): for s in idx.findAll('strong', attrs={'class':'book'}):
a = s.find('a', href=True) a = s.find('a', href=True)
yield (self.tag_to_string(a), a['href']) section_title = self.tag_to_string(a)
if not section_title in self.ignore_sections:
prefix = ''
if section_title != 'Main section':
prefix = section_title + ': '
for subsection in s.parent.findAll('a', attrs={'class':'book-section'}):
yield (prefix + self.tag_to_string(subsection), subsection['href'])
def find_articles(self, url): def find_articles(self, url):
soup = self.index_to_soup(url) soup = self.index_to_soup(url)
div = soup.find('div', attrs={'class':'book-index'}) div = soup.find('div', attrs={'class':'book-index'})
@ -109,15 +115,12 @@ class Guardian(BasicNewsRecipe):
'title': title, 'url':url, 'description':desc, 'title': title, 'url':url, 'description':desc,
'date' : strftime('%a, %d %b'), 'date' : strftime('%a, %d %b'),
} }
def parse_index(self): def parse_index(self):
try: try:
feeds = [] feeds = []
for title, href in self.find_sections(): for title, href in self.find_sections():
if not title in self.ignore_sections: feeds.append((title, list(self.find_articles(href))))
feeds.append((title, list(self.find_articles(href))))
return feeds return feeds
except: except:
raise NotImplementedError raise NotImplementedError

View File

@ -49,6 +49,7 @@ class TelegraphUK(BasicNewsRecipe):
(u'UK News' , u'http://www.telegraph.co.uk/news/uknews/rss' ) (u'UK News' , u'http://www.telegraph.co.uk/news/uknews/rss' )
,(u'World News' , u'http://www.telegraph.co.uk/news/worldnews/rss' ) ,(u'World News' , u'http://www.telegraph.co.uk/news/worldnews/rss' )
,(u'Politics' , u'http://www.telegraph.co.uk/news/newstopics/politics/rss' ) ,(u'Politics' , u'http://www.telegraph.co.uk/news/newstopics/politics/rss' )
,(u'Finance' , u'http://www.telegraph.co.uk/finance/rss' )
,(u'Technology News', u'http://www.telegraph.co.uk/scienceandtechnology/technology/technologynews/rss' ) ,(u'Technology News', u'http://www.telegraph.co.uk/scienceandtechnology/technology/technologynews/rss' )
,(u'UK News' , u'http://www.telegraph.co.uk/scienceandtechnology/technology/technologyreviews/rss') ,(u'UK News' , u'http://www.telegraph.co.uk/scienceandtechnology/technology/technologyreviews/rss')
,(u'Science News' , u'http://www.telegraph.co.uk/scienceandtechnology/science/sciencenews/rss' ) ,(u'Science News' , u'http://www.telegraph.co.uk/scienceandtechnology/science/sciencenews/rss' )

View File

@ -10,8 +10,8 @@ import re
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
class Time(BasicNewsRecipe): class Time(BasicNewsRecipe):
recipe_disabled = ('This recipe has been disabled as TIME no longer' #recipe_disabled = ('This recipe has been disabled as TIME no longer'
' publish complete articles on the web.') # ' publish complete articles on the web.')
title = u'Time' title = u'Time'
__author__ = 'Kovid Goyal and Sujata Raman' __author__ = 'Kovid Goyal and Sujata Raman'
description = 'Weekly magazine' description = 'Weekly magazine'

View File

@ -82,7 +82,7 @@ class ZAOBAO(BasicNewsRecipe):
return soup return soup
def parse_feeds(self): def parse_feeds(self):
self.log_debug(_('ZAOBAO overrided parse_feeds()')) self.log(_('ZAOBAO overrided parse_feeds()'))
parsed_feeds = BasicNewsRecipe.parse_feeds(self) parsed_feeds = BasicNewsRecipe.parse_feeds(self)
for id, obj in enumerate(self.INDEXES): for id, obj in enumerate(self.INDEXES):
@ -99,7 +99,7 @@ class ZAOBAO(BasicNewsRecipe):
a_title = self.tag_to_string(a) a_title = self.tag_to_string(a)
date = '' date = ''
description = '' description = ''
self.log_debug(_('adding %s at %s')%(a_title,a_url)) self.log(_('adding %s at %s')%(a_title,a_url))
articles.append({ articles.append({
'title':a_title, 'title':a_title,
'date':date, 'date':date,
@ -110,23 +110,23 @@ class ZAOBAO(BasicNewsRecipe):
pfeeds = feeds_from_index([(title, articles)], oldest_article=self.oldest_article, pfeeds = feeds_from_index([(title, articles)], oldest_article=self.oldest_article,
max_articles_per_feed=self.max_articles_per_feed) max_articles_per_feed=self.max_articles_per_feed)
self.log_debug(_('adding %s to feed')%(title)) self.log(_('adding %s to feed')%(title))
for feed in pfeeds: for feed in pfeeds:
self.log_debug(_('adding feed: %s')%(feed.title)) self.log(_('adding feed: %s')%(feed.title))
feed.description = self.DESC_SENSE feed.description = self.DESC_SENSE
parsed_feeds.append(feed) parsed_feeds.append(feed)
for a, article in enumerate(feed): for a, article in enumerate(feed):
self.log_debug(_('added article %s from %s')%(article.title, article.url)) self.log(_('added article %s from %s')%(article.title, article.url))
self.log_debug(_('added feed %s')%(feed.title)) self.log(_('added feed %s')%(feed.title))
for i, feed in enumerate(parsed_feeds): for i, feed in enumerate(parsed_feeds):
# workaorund a strange problem: Somethimes the xml encoding is not apllied correctly by parse() # workaorund a strange problem: Somethimes the xml encoding is not apllied correctly by parse()
weired_encoding_detected = False weired_encoding_detected = False
if not isinstance(feed.description, unicode) and self.encoding and feed.description: if not isinstance(feed.description, unicode) and self.encoding and feed.description:
self.log_debug(_('Feed %s is not encoded correctly, manually replace it')%(feed.title)) self.log(_('Feed %s is not encoded correctly, manually replace it')%(feed.title))
feed.description = feed.description.decode(self.encoding, 'replace') feed.description = feed.description.decode(self.encoding, 'replace')
elif feed.description.find(self.DESC_SENSE) == -1 and self.encoding and feed.description: elif feed.description.find(self.DESC_SENSE) == -1 and self.encoding and feed.description:
self.log_debug(_('Feed %s is weired encoded, manually redo all')%(feed.title)) self.log(_('Feed %s is weired encoded, manually redo all')%(feed.title))
feed.description = feed.description.encode('cp1252', 'replace').decode(self.encoding, 'replace') feed.description = feed.description.encode('cp1252', 'replace').decode(self.encoding, 'replace')
weired_encoding_detected = True weired_encoding_detected = True
@ -148,7 +148,7 @@ class ZAOBAO(BasicNewsRecipe):
article.text_summary = article.text_summary.encode('cp1252', 'replace').decode(self.encoding, 'replace') article.text_summary = article.text_summary.encode('cp1252', 'replace').decode(self.encoding, 'replace')
if article.title == "Untitled article": if article.title == "Untitled article":
self.log_debug(_('Removing empty article %s from %s')%(article.title, article.url)) self.log(_('Removing empty article %s from %s')%(article.title, article.url))
# remove the article # remove the article
feed.articles[a:a+1] = [] feed.articles[a:a+1] = []
return parsed_feeds return parsed_feeds

View File

@ -77,7 +77,7 @@ categories_use_field_for_author_name = 'author'
# ascii ordering. This tweak controls when that switch happens. Set it to zero # ascii ordering. This tweak controls when that switch happens. Set it to zero
# to always use ascii ordering. Set it to something larger than zero to switch # to always use ascii ordering. Set it to something larger than zero to switch
# to ascii ordering for performance reasons. # to ascii ordering for performance reasons.
completion_change_to_ascii_sorting = 1000 completion_change_to_ascii_sorting = 2500
#: Control partitioning of Tag Browser #: Control partitioning of Tag Browser
# When partitioning the tags browser, the format of the subcategory label is # When partitioning the tags browser, the format of the subcategory label is

View File

@ -2392,6 +2392,16 @@ class ITUNES(DriverBase):
self.iTunes.Windows[0].Minimized = True self.iTunes.Windows[0].Minimized = True
self.initial_status = 'launched' self.initial_status = 'launched'
try:
# Pre-emptive test to confirm functional iTunes automation interface
foo = self.iTunes.Version
foo
except:
self.iTunes = None
raise OpenFeedback('Unable to connect to iTunes.\n' +
' iTunes automation interface non-responsive, ' +
'recommend reinstalling iTunes')
# Read the current storage path for iTunes media from the XML file # Read the current storage path for iTunes media from the XML file
media_dir = '' media_dir = ''
string = None string = None
@ -2988,7 +2998,6 @@ class ITUNES(DriverBase):
newmi = book newmi = book
return newmi return newmi
class ITUNES_ASYNC(ITUNES): class ITUNES_ASYNC(ITUNES):
''' '''
This subclass allows the user to interact directly with iTunes via a menu option This subclass allows the user to interact directly with iTunes via a menu option

View File

@ -224,13 +224,16 @@ class TREKSTOR(USBMS):
FORMATS = ['epub', 'txt', 'pdf'] FORMATS = ['epub', 'txt', 'pdf']
VENDOR_ID = [0x1e68] VENDOR_ID = [0x1e68]
PRODUCT_ID = [0x0041, 0x0042] PRODUCT_ID = [0x0041, 0x0042,
0x003e # This is for the EBOOK_PLAYER_5M https://bugs.launchpad.net/bugs/792091
]
BCD = [0x0002] BCD = [0x0002]
EBOOK_DIR_MAIN = 'Ebooks' EBOOK_DIR_MAIN = 'Ebooks'
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']
class EEEREADER(USBMS): class EEEREADER(USBMS):

View File

@ -12,20 +12,23 @@ from PyQt4.Qt import QLineEdit, QAbstractListModel, Qt, \
from calibre.utils.icu import sort_key, lower from calibre.utils.icu import sort_key, lower
from calibre.gui2 import NONE from calibre.gui2 import NONE
from calibre.gui2.widgets import EnComboBox, LineEditECM from calibre.gui2.widgets import EnComboBox, LineEditECM
from calibre.utils.config import tweaks from calibre.utils.config_base import tweaks
class CompleteModel(QAbstractListModel): class CompleteModel(QAbstractListModel):
def __init__(self, parent=None): def __init__(self, parent=None):
QAbstractListModel.__init__(self, parent) QAbstractListModel.__init__(self, parent)
self.items = [] self.items = []
self.sorting = QCompleter.UnsortedModel
def set_items(self, items): def set_items(self, items):
items = [unicode(x.strip()) for x in items] items = [unicode(x.strip()) for x in items]
if len(items) < tweaks['completion_change_to_ascii_sorting']: if len(items) < tweaks['completion_change_to_ascii_sorting']:
self.items = list(sorted(items, key=lambda x: sort_key(x))) self.items = sorted(items, key=lambda x: sort_key(x))
self.sorting = QCompleter.UnsortedModel
else: else:
self.items = list(sorted(items, key=lambda x: x)) self.items = sorted(items, key=lambda x:x.lower())
self.sorting = QCompleter.CaseInsensitivelySortedModel
self.lowered_items = [lower(x) for x in self.items] self.lowered_items = [lower(x) for x in self.items]
self.reset() self.reset()
@ -66,6 +69,7 @@ class MultiCompleteLineEdit(QLineEdit, LineEditECM):
c.setWidget(self) c.setWidget(self)
c.setCompletionMode(QCompleter.PopupCompletion) c.setCompletionMode(QCompleter.PopupCompletion)
c.setCaseSensitivity(Qt.CaseInsensitive) c.setCaseSensitivity(Qt.CaseInsensitive)
c.setModelSorting(self._model.sorting)
c.setCompletionRole(Qt.DisplayRole) c.setCompletionRole(Qt.DisplayRole)
p = c.popup() p = c.popup()
p.setMouseTracking(True) p.setMouseTracking(True)
@ -78,10 +82,6 @@ class MultiCompleteLineEdit(QLineEdit, LineEditECM):
# Interface {{{ # Interface {{{
def update_items_cache(self, complete_items): def update_items_cache(self, complete_items):
if len(complete_items) < tweaks['completion_change_to_ascii_sorting']:
self._completer.setModelSorting(QCompleter.UnsortedModel)
else:
self._completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
self.all_items = complete_items self.all_items = complete_items
def set_separator(self, sep): def set_separator(self, sep):
@ -153,6 +153,7 @@ class MultiCompleteLineEdit(QLineEdit, LineEditECM):
return self._model.items return self._model.items
def fset(self, items): def fset(self, items):
self._model.set_items(items) self._model.set_items(items)
self._completer.setModelSorting(self._model.sorting)
return property(fget=fget, fset=fset) return property(fget=fget, fset=fset)
class MultiCompleteComboBox(EnComboBox): class MultiCompleteComboBox(EnComboBox):

View File

@ -595,7 +595,8 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if f is None: if f is None:
continue continue
with tempfile.SpooledTemporaryFile(max_size=100*(1024**2)) as stream: with tempfile.SpooledTemporaryFile(max_size=100*(1024**2)) as stream:
shutil.copyfileobj(f, stream) with f:
shutil.copyfileobj(f, stream)
stream.seek(0) stream.seek(0)
self.add_format(id, format, stream, index_is_id=True, self.add_format(id, format, stream, index_is_id=True,
path=tpath, notify=False) path=tpath, notify=False)

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

16897
src/calibre/translations/br.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff