mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from trunk
This commit is contained in:
commit
fa0afee166
@ -20,6 +20,57 @@
|
||||
# - title:
|
||||
|
||||
|
||||
- version: 0.8.56
|
||||
date: 2012-06-15
|
||||
|
||||
new features:
|
||||
- title: "Make the new calibre style default on Windows and OS X."
|
||||
type: major
|
||||
description: "This change gives a more 'modern' feel to the calibre user interface with focus highlighting, gradients, rounded corners, etc. In case you prefer the old look, you can restore under Preferences->Look & Feel->User interface style"
|
||||
|
||||
- title: "Get Books: Add the new SONY Reader store"
|
||||
|
||||
- title: "Read metadata from .docx (Microsoft Word) files"
|
||||
|
||||
- title: "Allow customizing the behavior of the searching for similar books by right clicking the book. You can now tell calibre to search different columns than the traditional author/series/publisher/tags/etc. in Preferences->Searching"
|
||||
|
||||
- title: "Add option to restore alternating row colors to the Tag Browser under Preferences->Look & Feel->Tag Browser"
|
||||
|
||||
- title: "Update to Qt 4.8.2 on windows compiled with link time code generation for a small performance boost"
|
||||
|
||||
bug fixes:
|
||||
- title: "Get Books: Update plugins to handle website changes at ebooks.com, project gutenberg, and virtualo"
|
||||
|
||||
- title: "AZW3 Output: Fix TOC at start option not working"
|
||||
|
||||
- title: "AZW3 Output: Close self closing script/style/title/head tags explicitly as they cause problems in webkit based renderers like the Kindle Fire and calibre's viewers."
|
||||
|
||||
- title: "Fix the current_library_name() template function not updating after a library switch"
|
||||
|
||||
- title: "AZW3 Output: Handle the case of a link pointing to the last line of text in the document."
|
||||
tickets: [1011330]
|
||||
|
||||
- title: "Fix regression in 0.8.55 that broke highlighting of items matching a search in the Tag Browser"
|
||||
tickets: [1011030]
|
||||
|
||||
- title: "News download: Handle query only relative URLs"
|
||||
|
||||
improved recipes:
|
||||
- Christian Science Monitor
|
||||
- Neue Zurcher Zeitung
|
||||
- Birmignham Post
|
||||
- Metro UK
|
||||
- New Musical Express
|
||||
- The Independent
|
||||
- The Daily Mirror
|
||||
- Vreme
|
||||
- Smithsonian Magazine
|
||||
|
||||
new recipes:
|
||||
- title: NZZ Webpaper
|
||||
author: Bernd Leinfelder
|
||||
|
||||
|
||||
- version: 0.8.55
|
||||
date: 2012-06-08
|
||||
|
||||
|
47
recipes/huffingtonpost_uk.recipe
Normal file
47
recipes/huffingtonpost_uk.recipe
Normal file
@ -0,0 +1,47 @@
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class HindustanTimes(BasicNewsRecipe):
|
||||
title = u'Huffington Post UK'
|
||||
language = 'en_GB'
|
||||
__author__ = 'Krittika Goyal'
|
||||
oldest_article = 2 #days
|
||||
max_articles_per_feed = 25
|
||||
#encoding = 'cp1252'
|
||||
use_embedded_content = False
|
||||
|
||||
no_stylesheets = True
|
||||
auto_cleanup = True
|
||||
auto_cleanup_keep = '//div[@class="articleBody"]'
|
||||
|
||||
feeds = [
|
||||
('UK Politics',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-politics/news.xml'),
|
||||
('UK Entertainment',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-entertainment/news.xml'),
|
||||
('UK Style',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-style/news.xml'),
|
||||
('UK Fashion:',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-fashion/news.xml'),
|
||||
('UK Universities:',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-universities-education/news.xml'),
|
||||
('UK World',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-world/news.xml'),
|
||||
('UK Lifestyle',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-lifestyle/news.xml'),
|
||||
('UK Comedy',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-comedy/news.xml'),
|
||||
('UK Celebrity',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-celebrity/news.xml'),
|
||||
('UK Culture',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-culture/news.xml'),
|
||||
('UK News',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk/news.xml'),
|
||||
('UK Tech',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-tech/news.xml'),
|
||||
('UK Sport',
|
||||
'http://www.huffingtonpost.com/feeds/verticals/uk-sport/news.xml'),
|
||||
]
|
||||
def get_article_url(self, entry):
|
||||
if entry.links:
|
||||
return entry.links[0]['href']
|
||||
return BasicNewsRecipe.get_article_url(self, entry)
|
@ -1,26 +1,42 @@
|
||||
import re
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
from calibre.ebooks.BeautifulSoup import BeautifulSoup
|
||||
|
||||
class SmithsonianMagazine(BasicNewsRecipe):
|
||||
title = u'Smithsonian Magazine'
|
||||
language = 'en'
|
||||
__author__ = 'Krittika Goyal'
|
||||
__author__ = 'Krittika Goyal and TerminalVeracity'
|
||||
oldest_article = 31#days
|
||||
max_articles_per_feed = 50
|
||||
use_embedded_content = False
|
||||
#encoding = 'latin1'
|
||||
recursions = 1
|
||||
cover_url = 'http://sphotos.xx.fbcdn.net/hphotos-snc7/431147_10150602715983253_764313347_n.jpg'
|
||||
match_regexps = ['&page=[2-9]$']
|
||||
preprocess_regexps = [
|
||||
(re.compile(r'for more of Smithsonian\'s coverage on history, science and nature.', re.DOTALL), lambda m: '')
|
||||
]
|
||||
extra_css = """
|
||||
h1{font-size: large; margin: .2em 0}
|
||||
h2{font-size: medium; margin: .2em 0}
|
||||
h3{font-size: medium; margin: .2em 0}
|
||||
#byLine{margin: .2em 0}
|
||||
.articleImageCaptionwide{font-style: italic}
|
||||
.wp-caption-text{font-style: italic}
|
||||
img{display: block}
|
||||
"""
|
||||
|
||||
|
||||
remove_stylesheets = True
|
||||
#remove_tags_before = dict(name='h1', attrs={'class':'heading'})
|
||||
remove_tags_after = dict(name='p', attrs={'id':'articlePaginationWrapper'})
|
||||
remove_tags_after = dict(name='div', attrs={'class':['post','articlePaginationWrapper']})
|
||||
remove_tags = [
|
||||
dict(name='iframe'),
|
||||
dict(name='div', attrs={'class':'article_sidebar_border'}),
|
||||
dict(name='div', attrs={'id':['article_sidebar_border', 'most-popular_large', 'most-popular-body_large']}),
|
||||
##dict(name='ul', attrs={'class':'article-tools'}),
|
||||
dict(name='div', attrs={'class':['article_sidebar_border','viewMorePhotos','addtoany_share_save_container','meta','social','OUTBRAIN','related-articles-inpage']}),
|
||||
dict(name='div', attrs={'id':['article_sidebar_border', 'most-popular_large', 'most-popular-body_large','comment_section','article-related']}),
|
||||
dict(name='ul', attrs={'class':'cat-breadcrumb col three last'}),
|
||||
dict(name='h4', attrs={'id':'related-topics'}),
|
||||
dict(name='table'),
|
||||
dict(name='a', attrs={'href':['/subArticleBottomWeb','/subArticleTopWeb','/subArticleTopMag','/subArticleBottomMag']}),
|
||||
dict(name='a', attrs={'name':'comments_shaded'}),
|
||||
]
|
||||
|
||||
|
||||
@ -39,15 +55,7 @@ class SmithsonianMagazine(BasicNewsRecipe):
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
story = soup.find(name='div', attrs={'id':'article-body'})
|
||||
##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)
|
||||
return soup
|
||||
|
||||
#def postprocess_html(self, soup, first):
|
||||
#for p in soup.findAll(id='articlePaginationWrapper'): p.extract()
|
||||
#if not first:
|
||||
#for div in soup.findAll(id='article-head'): div.extract()
|
||||
#return soup
|
||||
|
95
recipes/something_awful.recipe
Normal file
95
recipes/something_awful.recipe
Normal file
@ -0,0 +1,95 @@
|
||||
import re
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class SomethingAwfulRecipe(BasicNewsRecipe):
|
||||
title = 'Something Awful'
|
||||
__author__ = 'atordo'
|
||||
description = 'The Internet Makes You Stupid'
|
||||
cover_url = 'http://i.somethingawful.com/core/head-logo-bluegren.png'
|
||||
masthead_url = 'http://i.somethingawful.com/core/head-logo-bluegren.png'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 50
|
||||
auto_cleanup = False
|
||||
no_stylesheets = True
|
||||
remove_javascript = True
|
||||
language = 'en'
|
||||
use_embedded_content = False
|
||||
remove_empty_feeds = True
|
||||
publication_type = 'magazine'
|
||||
|
||||
recursions = 1
|
||||
match_regexps = [r'\?page=\d+$']
|
||||
|
||||
preprocess_regexps = [
|
||||
(re.compile(r'<!-- content end-->.*</body>', re.DOTALL), lambda match: '</body>')
|
||||
]
|
||||
|
||||
remove_attributes = [ 'align', 'alt', 'valign' ]
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='div', attrs={'class':'content_area'})
|
||||
# ,dict(name='p', attrs={'class':'pagebar'})
|
||||
]
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'class':['column_box','featurenav','social']})
|
||||
,dict(name='div', attrs={'id':'sidebar'})
|
||||
,dict(name='a', attrs={'class':'curpage'})
|
||||
]
|
||||
|
||||
extra_css = '''
|
||||
.byline{font-size:small} .font_big{font-size:large}
|
||||
.compat5{font-weight:bold} .accentbox{background-color:#E3E3E3; border:solid black}
|
||||
img{margin-bottom:0.4em; display:block; margin-left: auto; margin-right:auto}
|
||||
'''
|
||||
|
||||
#feeds = [(u'Something Awful', u'http://www.somethingawful.com/rss/index.rss.xml')]
|
||||
feeds = [
|
||||
('Photoshop Phriday', 'http://www.somethingawful.com/rss/photoshop-phriday.rss.xml')
|
||||
,('Comedy Goldmine', 'http://www.somethingawful.com/rss/comedy-goldmine.rss.xml')
|
||||
#,('The Flash Tub', 'http://www.somethingawful.com/rss/flash-tub.rss.xml')
|
||||
,('Awful Link of the Day', 'http://www.somethingawful.com/rss/awful-links.rss.xml')
|
||||
,('Fake Something Awfuls', 'http://www.somethingawful.com/rss/fake-something-awful.rss.xml')
|
||||
,('The Barbarian\'s Dojo', 'http://www.somethingawful.com/rss/steve-sumner.rss.xml')
|
||||
,('The Great Goon Database', 'http://www.somethingawful.com/rss/great-goon-database.rss.xml')
|
||||
,('Livejournal Theater', 'http://www.somethingawful.com/rss/livejournal-theater.rss.xml')
|
||||
,('Joystick Token Healthpack', 'http://www.somethingawful.com/rss/token-healthpack.rss.xml')
|
||||
#,('Webcam Ward', 'http://www.somethingawful.com/rss/webcam-ward.rss.xml')
|
||||
,('Features / Articles', 'http://www.somethingawful.com/rss/feature-articles.rss.xml')
|
||||
,('Guides', 'http://www.somethingawful.com/rss/guides.rss.xml')
|
||||
,('Legal Threats', 'http://www.somethingawful.com/rss/legal-threats.rss.xml')
|
||||
,('Pranks [ICQ]', 'http://www.somethingawful.com/rss/icq-pranks.rss.xml')
|
||||
,('State Og', 'http://www.somethingawful.com/rss/state-og.rss.xml')
|
||||
,('Everquest', 'http://www.somethingawful.com/rss/everquest.rss.xml')
|
||||
,('Pranks [Email]', 'http://www.somethingawful.com/rss/email-pranks.rss.xml')
|
||||
,('The Weekend Web', 'http://www.somethingawful.com/rss/weekend-web.rss.xml')
|
||||
,('Daily Dirt', 'http://www.somethingawful.com/rss/daily-dirt.rss.xml')
|
||||
,('The Art of Warcraft', 'http://www.somethingawful.com/rss/art-of-warcraft.rss.xml')
|
||||
,('Video Game Article', 'http://www.somethingawful.com/rss/video-game-article.rss.xml')
|
||||
,('The Awful Movie Database', 'http://www.somethingawful.com/rss/awful-movie-database.rss.xml')
|
||||
#,('Downloads', 'http://www.somethingawful.com/rss/downloads.rss.xml')
|
||||
,('Pregame Wrapup', 'http://www.somethingawful.com/rss/pregame-wrapup.rss.xml')
|
||||
,('Second Life Safari', 'http://www.somethingawful.com/rss/second-life-safari.rss.xml')
|
||||
,('The Hogosphere', 'http://www.somethingawful.com/rss/hogosphere.rss.xml')
|
||||
,('Front Page News', 'http://www.somethingawful.com/rss/news.rss.xml')
|
||||
,('Forum Friday\'s Monday', 'http://www.somethingawful.com/rss/forum-fridays.rss.xml')
|
||||
,('Cliff Yablonski Hates You', 'http://www.somethingawful.com/rss/cliff-yablonski.rss.xml')
|
||||
,('Manifestos From the Internet', 'http://www.somethingawful.com/rss/manifestos-from-internet.rss.xml')
|
||||
,('Johnston Checks In', 'http://www.somethingawful.com/rss/levi-johnston.rss.xml')
|
||||
,('Twitter Tuesday', 'http://www.somethingawful.com/rss/twitter-tuesday.rss.xml')
|
||||
,('Music Article', 'http://www.somethingawful.com/rss/music-article.rss.xml')
|
||||
,('Reviews [Games]', 'http://www.somethingawful.com/rss/game-reviews.rss.xml')
|
||||
,('Reviews [Movies]', 'http://www.somethingawful.com/rss/movie-reviews.rss.xml')
|
||||
,('Rom Pit', 'http://www.somethingawful.com/rss/rom-pit.rss.xml')
|
||||
,('Truth Media [Reviews]', 'http://www.somethingawful.com/rss/truth-media-reviews.rss.xml')
|
||||
,('Truth Media [Flames]', 'http://www.somethingawful.com/rss/truth-media-flames.rss.xml')
|
||||
,('Awful Anime', 'http://www.somethingawful.com/rss/hentai-game-reviews.rss.xml')
|
||||
,('The Horrors of Pornography', 'http://www.somethingawful.com/rss/horrors-of-porn.rss.xml')
|
||||
,('Your Band Sucks', 'http://www.somethingawful.com/rss/your-band-sucks.rss.xml')
|
||||
,('Fashion SWAT', 'http://www.somethingawful.com/rss/fashion-swat.rss.xml')
|
||||
#,('AwfulVision', 'http://www.somethingawful.com/rss/awfulvision.rss.xml')
|
||||
,('MMO Roulette', 'http://www.somethingawful.com/rss/mmo-roulette.rss.xml')
|
||||
,('The Most Awful', 'http://www.somethingawful.com/rss/most-awful.rss.xml')
|
||||
,('Garbage Day', 'http://www.somethingawful.com/rss/garbage-day.rss.xml')
|
||||
,('WTF, D&D!?', 'http://www.somethingawful.com/rss/dungeons-and-dragons.rss.xml')
|
||||
,('Current Releases', 'http://www.somethingawful.com/rss/current-movie-reviews.rss.xml')
|
||||
]
|
@ -1,5 +1,5 @@
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||
__copyright__ = '2008-2012, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
vreme.com
|
||||
'''
|
||||
@ -24,7 +24,17 @@ class Vreme(BasicNewsRecipe):
|
||||
language = 'sr'
|
||||
publication_type = 'magazine'
|
||||
masthead_url = 'http://www.vreme.com/g/vreme-logo.gif'
|
||||
extra_css = ' @font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: serif1, serif} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} .heading1{font-family: sans1, sans-serif; font-size: x-large; font-weight: bold} .heading2{font-family: sans1, sans-serif; font-size: large; font-weight: bold} .toc-heading{font-family: sans1, sans-serif; font-size: small} .column-heading2{font-family: sans1, sans-serif; font-size: large} .column-heading1{font-family: sans1, sans-serif; font-size: x-large} .column-normal{font-family: sans1, sans-serif; font-size: medium} .large{font-family: sans1, sans-serif; font-size: large} '
|
||||
extra_css = """
|
||||
@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)}
|
||||
@font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
|
||||
body{font-family: serif1, serif}
|
||||
.article_description{font-family: serif1, serif}
|
||||
.heading1{font-family: sans1, sans-serif; font-size: x-large; font-weight: bold} .heading2{font-family: sans1, sans-serif; font-size: large; font-weight: bold} .toc-heading{font-family: sans1, sans-serif; font-size: small}
|
||||
.column-heading2{font-family: sans1, sans-serif; font-size: large}
|
||||
.column-heading1{font-family: sans1, sans-serif; font-size: x-large}
|
||||
.column-normal{font-family: sans1, sans-serif; font-size: medium}
|
||||
.large{font-family: sans1, sans-serif; font-size: large}
|
||||
"""
|
||||
|
||||
conversion_options = {
|
||||
'comment' : description
|
||||
@ -58,9 +68,12 @@ class Vreme(BasicNewsRecipe):
|
||||
for item in soup.findAll(['h3','h4']):
|
||||
description = u''
|
||||
title_prefix = u''
|
||||
feed_link = item.find('a')
|
||||
if feed_link and feed_link.has_key('href') and feed_link['href'].startswith('/cms/view.php'):
|
||||
url = self.INDEX + feed_link['href']
|
||||
feed_link = item.find('a', href=True)
|
||||
if feed_link and (feed_link['href'].startswith('cms/view.php') or feed_link['href'].startswith('/cms/view.php')):
|
||||
if feed_link['href'].startswith('cms/view.php'):
|
||||
url = self.INDEX + '/' + feed_link['href']
|
||||
else:
|
||||
url = self.INDEX + feed_link['href']
|
||||
title = title_prefix + self.tag_to_string(feed_link)
|
||||
date = strftime(self.timefmt)
|
||||
articles.append({
|
||||
|
Binary file not shown.
@ -27,6 +27,7 @@ binary_includes = [
|
||||
'/usr/lib/libwmflite-0.2.so.7',
|
||||
'/usr/lib/liblcms.so.1',
|
||||
'/usr/lib/liblzma.so.0',
|
||||
'/usr/lib/libexpat.so.1',
|
||||
'/usr/lib/libunrar.so',
|
||||
'/usr/lib/libsqlite3.so.0',
|
||||
'/usr/lib/libmng.so.1',
|
||||
|
@ -18,14 +18,14 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
|
||||
"devel@lists.alioth.debian.org>\n"
|
||||
"POT-Creation-Date: 2011-11-25 14:01+0000\n"
|
||||
"PO-Revision-Date: 2012-05-29 09:12+0000\n"
|
||||
"Last-Translator: Moritz Höwer <moritzhoewermail@gmx.de>\n"
|
||||
"PO-Revision-Date: 2012-06-10 11:16+0000\n"
|
||||
"Last-Translator: SimonFS <simonschuette@arcor.de>\n"
|
||||
"Language-Team: German <debian-l10n-german@lists.debian.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-05-30 05:20+0000\n"
|
||||
"X-Generator: Launchpad (build 15316)\n"
|
||||
"X-Launchpad-Export-Date: 2012-06-11 04:46+0000\n"
|
||||
"X-Generator: Launchpad (build 15376)\n"
|
||||
"Language: de\n"
|
||||
|
||||
#. name for aaa
|
||||
@ -139,7 +139,7 @@ msgstr ""
|
||||
|
||||
#. name for abe
|
||||
msgid "Abnaki; Western"
|
||||
msgstr ""
|
||||
msgstr "Abnaki; Westlich"
|
||||
|
||||
#. name for abf
|
||||
msgid "Abai Sungai"
|
||||
|
@ -4,7 +4,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = u'calibre'
|
||||
numeric_version = (0, 8, 55)
|
||||
numeric_version = (0, 8, 56)
|
||||
__version__ = u'.'.join(map(unicode, numeric_version))
|
||||
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
|
||||
|
@ -169,6 +169,9 @@ class ANDROID(USBMS):
|
||||
# Pantech
|
||||
0x10a9 : { 0x6050 : [0x227] },
|
||||
|
||||
# Prestigio
|
||||
0x2207 : { 0 : [0x222] },
|
||||
|
||||
}
|
||||
EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books',
|
||||
'sdcard/ebooks']
|
||||
@ -182,7 +185,8 @@ class ANDROID(USBMS):
|
||||
'TELECHIP', 'HUAWEI', 'T-MOBILE', 'SEMC', 'LGE', 'NVIDIA',
|
||||
'GENERIC-', 'ZTE', 'MID', 'QUALCOMM', 'PANDIGIT', 'HYSTON',
|
||||
'VIZIO', 'GOOGLE', 'FREESCAL', 'KOBO_INC', 'LENOVO', 'ROCKCHIP',
|
||||
'POCKET', 'ONDA_MID', 'ZENITHIN', 'INGENIC', 'PMID701C', 'PD']
|
||||
'POCKET', 'ONDA_MID', 'ZENITHIN', 'INGENIC', 'PMID701C', 'PD',
|
||||
'PMP5097C']
|
||||
WINDOWS_MAIN_MEM = ['ANDROID_PHONE', 'A855', 'A853', 'INC.NEXUS_ONE',
|
||||
'__UMS_COMPOSITE', '_MB200', 'MASS_STORAGE', '_-_CARD', 'SGH-I897',
|
||||
'GT-I9000', 'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID',
|
||||
@ -198,7 +202,7 @@ class ANDROID(USBMS):
|
||||
'GT-I9003_CARD', 'XT912', 'FILE-CD_GADGET', 'RK29_SDK', 'MB855',
|
||||
'XT910', 'BOOK_A10', 'USB_2.0_DRIVER', 'I9100T', 'P999DW',
|
||||
'KTABLET_PC', 'INGENIC', 'GT-I9001_CARD', 'USB_2.0_DRIVER',
|
||||
'GT-S5830L_CARD', 'UNIVERSE', 'XT875']
|
||||
'GT-S5830L_CARD', 'UNIVERSE', 'XT875', 'PRO']
|
||||
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
||||
'FILE-STOR_GADGET', 'SGH-T959_CARD', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
||||
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',
|
||||
@ -207,7 +211,7 @@ class ANDROID(USBMS):
|
||||
'A1-07___C0541A4F', 'XT912', 'MB855', 'XT910', 'BOOK_A10_CARD',
|
||||
'USB_2.0_DRIVER', 'I9100T', 'P999DW_SD_CARD', 'KTABLET_PC',
|
||||
'FILE-CD_GADGET', 'GT-I9001_CARD', 'USB_2.0_DRIVER', 'XT875',
|
||||
'UMS_COMPOSITE']
|
||||
'UMS_COMPOSITE', 'PRO']
|
||||
|
||||
OSX_MAIN_MEM = 'Android Device Main Memory'
|
||||
|
||||
|
@ -446,7 +446,7 @@ class HTMLPreProcessor(object):
|
||||
# Remove page links
|
||||
(re.compile(r'<a name=\d+></a>', re.IGNORECASE), lambda match: ''),
|
||||
# Remove <hr> tags
|
||||
(re.compile(r'<hr.*?>', re.IGNORECASE), lambda match: '<br>'),
|
||||
(re.compile(r'<hr.*?>', re.IGNORECASE), lambda match: ''),
|
||||
|
||||
# Remove gray background
|
||||
(re.compile(r'<BODY[^<>]+>'), lambda match : '<BODY>'),
|
||||
|
@ -108,6 +108,7 @@ gprefs.defaults['blocked_auto_formats'] = []
|
||||
gprefs.defaults['auto_add_auto_convert'] = True
|
||||
gprefs.defaults['ui_style'] = 'calibre' if iswindows or isosx else 'system'
|
||||
gprefs.defaults['tag_browser_old_look'] = False
|
||||
gprefs.defaults['book_list_tooltips'] = True
|
||||
# }}}
|
||||
|
||||
NONE = QVariant() #: Null value to return from the data function of item models
|
||||
|
@ -12,8 +12,8 @@ from PyQt4.Qt import QPixmap, SIGNAL
|
||||
|
||||
from calibre.gui2 import choose_images, error_dialog
|
||||
from calibre.gui2.convert.metadata_ui import Ui_Form
|
||||
from calibre.ebooks.metadata import authors_to_string, string_to_authors, \
|
||||
MetaInformation
|
||||
from calibre.ebooks.metadata import (authors_to_string, string_to_authors,
|
||||
MetaInformation, title_sort)
|
||||
from calibre.ebooks.metadata.opf2 import metadata_to_opf
|
||||
from calibre.ptempfile import PersistentTemporaryFile
|
||||
from calibre.gui2.convert import Widget
|
||||
@ -230,9 +230,19 @@ class MetadataWidget(Widget, Ui_Form):
|
||||
Both may be None. Also returns a recommendation dictionary.
|
||||
'''
|
||||
recs = self.commit_options(save_defaults)
|
||||
self.user_mi = self.get_metadata()
|
||||
self.user_mi = mi = self.get_metadata()
|
||||
self.cover_file = self.opf_file = None
|
||||
if self.db is not None:
|
||||
if mi.title == self.db.title(self.book_id, index_is_id=True):
|
||||
mi.title_sort = self.db.title_sort(self.book_id, index_is_id=True)
|
||||
else:
|
||||
# Regenerate title sort taking into account book language
|
||||
languages = self.db.languages(self.book_id, index_is_id=True)
|
||||
if languages:
|
||||
lang = languages.split(',')[0]
|
||||
else:
|
||||
lang = None
|
||||
mi.title_sort = title_sort(mi.title, lang=lang)
|
||||
self.db.set_metadata(self.book_id, self.user_mi)
|
||||
self.mi, self.opf_file = create_opf_file(self.db, self.book_id)
|
||||
if self.cover_changed and self.cover_data is not None:
|
||||
|
@ -68,6 +68,7 @@ class DeleteMatchingFromDeviceDialog(QDialog, Ui_DeleteMatchingFromDeviceDialog)
|
||||
'<b>permanently deleted</b> from your '
|
||||
'device. Please verify the list.')+'</p>')
|
||||
self.buttonBox.accepted.connect(self.accepted)
|
||||
self.buttonBox.rejected.connect(self.rejected)
|
||||
self.table.cellClicked.connect(self.cell_clicked)
|
||||
self.table.setSelectionMode(QAbstractItemView.NoSelection)
|
||||
self.table.setColumnCount(7)
|
||||
|
@ -312,7 +312,7 @@ class %(classname)s(%(base_class)s):
|
||||
item = items[-1]
|
||||
id_ = unicode(item.data(Qt.UserRole).toString())
|
||||
title = unicode(item.data(Qt.DisplayRole).toString()).rpartition(' [')[0]
|
||||
profile = get_builtin_recipe_by_id(id_)
|
||||
profile = get_builtin_recipe_by_id(id_, download_recipe=True)
|
||||
if profile is None:
|
||||
raise Exception('Something weird happened')
|
||||
|
||||
|
@ -82,6 +82,11 @@ class BooksView(QTableView): # {{{
|
||||
files_dropped = pyqtSignal(object)
|
||||
add_column_signal = pyqtSignal()
|
||||
|
||||
def viewportEvent(self, event):
|
||||
if (event.type() == event.ToolTip and not gprefs['book_list_tooltips']):
|
||||
return False
|
||||
return QTableView.viewportEvent(self, event)
|
||||
|
||||
def __init__(self, parent, modelcls=BooksModel, use_edit_metadata_dialog=True):
|
||||
QTableView.__init__(self, parent)
|
||||
|
||||
|
@ -104,6 +104,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
r('ui_style', gprefs, restart_required=True, choices=
|
||||
[(_('System default'), 'system'), (_('Calibre style'),
|
||||
'calibre')])
|
||||
r('book_list_tooltips', gprefs)
|
||||
r('tag_browser_old_look', gprefs, restart_required=True)
|
||||
|
||||
r('cover_flow_queue_length', config, restart_required=True)
|
||||
|
@ -105,7 +105,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>&Toolbar</string>
|
||||
@ -140,7 +140,7 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@ -153,7 +153,7 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
@ -174,7 +174,7 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QPushButton" name="change_font_button">
|
||||
<property name="text">
|
||||
<string>Change &font (needs restart)</string>
|
||||
@ -194,6 +194,13 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="opt_ui_style"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="opt_book_list_tooltips">
|
||||
<property name="text">
|
||||
<string>Show &tooltips in the book list</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
|
@ -5,6 +5,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import textwrap
|
||||
|
||||
from calibre.gui2.preferences import ConfigWidgetBase, test_widget, Setting
|
||||
from calibre.gui2.preferences.misc_ui import Ui_Form
|
||||
@ -31,6 +32,11 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||
r('worker_limit', config, restart_required=True, setting=WorkersSetting)
|
||||
r('enforce_cpu_limit', config, restart_required=True)
|
||||
r('worker_max_time', gprefs)
|
||||
self.opt_worker_limit.setToolTip(textwrap.fill(
|
||||
_('The maximum number of jobs that will run simultaneously in '
|
||||
'the background. This refers to CPU intensive tasks like '
|
||||
' conversion. Lower this number'
|
||||
' if you want calibre to use less CPU.')))
|
||||
self.device_detection_button.clicked.connect(self.debug_device_detection)
|
||||
self.button_open_config_dir.clicked.connect(self.open_config_dir)
|
||||
self.user_defined_device_button.clicked.connect(self.user_defined_device)
|
||||
|
@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
import random
|
||||
import re
|
||||
import urllib2
|
||||
import urllib
|
||||
from contextlib import closing
|
||||
|
||||
from lxml import html
|
||||
@ -47,7 +47,7 @@ class EbookscomStore(BasicStoreConfig, StorePlugin):
|
||||
d.exec_()
|
||||
|
||||
def search(self, query, max_results=10, timeout=60):
|
||||
url = 'http://www.ebooks.com/SearchApp/SearchResults.net?term=' + urllib2.quote(query)
|
||||
url = 'http://www.ebooks.com/SearchApp/SearchResults.net?term=' + urllib.quote_plus(query)
|
||||
|
||||
br = browser()
|
||||
|
||||
@ -66,15 +66,12 @@ class EbookscomStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
cover_url = ''.join(data.xpath('.//div[@class="img"]//img/@src'))
|
||||
|
||||
title = ''
|
||||
author = ''
|
||||
header_parts = data.xpath('.//div[@class="descr"]/h4//a//text()')
|
||||
if header_parts:
|
||||
title = header_parts[0]
|
||||
header_parts = header_parts[1:]
|
||||
if header_parts:
|
||||
author = ', '.join(header_parts)
|
||||
|
||||
title = ''.join(data.xpath(
|
||||
'descendant::span[@class="book-title"]/a/text()')).strip()
|
||||
author = ''.join(data.xpath(
|
||||
'descendant::span[@class="author"]/a/text()')).strip()
|
||||
if not title or not author:
|
||||
continue
|
||||
|
||||
counter -= 1
|
||||
|
||||
|
@ -48,13 +48,9 @@ class SonyStore(BasicStoreConfig, StorePlugin):
|
||||
break
|
||||
|
||||
curr = ''.join(item.xpath('descendant::div[@class="pricing"]/descendant::*[@class="currency"]/@title')).strip()
|
||||
if not curr:
|
||||
curr = 'USD'
|
||||
amt = ''.join(item.xpath('descendant::div[@class="pricing"]/descendant::*[@class="amount"]/text()')).strip()
|
||||
if not amt:
|
||||
amt = '0'
|
||||
s = SearchResult()
|
||||
s.price = curr+' '+amt
|
||||
s.price = (curr+' '+amt) if (curr and amt) else _('Not Available')
|
||||
title = item.xpath('descendant::h3[@class="item"]')
|
||||
if not title: continue
|
||||
title = etree.tostring(title[0], method='text',
|
||||
|
@ -574,6 +574,9 @@ def command_set_metadata(args, dbpath):
|
||||
|
||||
if len(args) > 2:
|
||||
opf = args[2]
|
||||
if not os.path.exists(opf):
|
||||
prints(_('The OPF file %s does not exist')%opf, file=sys.stderr)
|
||||
return 1
|
||||
do_set_metadata(db, book_id, opf)
|
||||
|
||||
if opts.field:
|
||||
|
@ -102,7 +102,12 @@ class AuthController(object):
|
||||
@wraps(func)
|
||||
def authenticate(*args, **kwargs):
|
||||
cookie = cherrypy.request.cookie.get(self.cookie_name, None)
|
||||
if not (allow_cookie_auth and self.is_valid(cookie)):
|
||||
ua = cherrypy.request.headers.get('User-Agent', '').strip()
|
||||
|
||||
if ('iPad;' in ua or 'iPhone;' in ua or (
|
||||
not (allow_cookie_auth and self.is_valid(cookie)))):
|
||||
# Apparently the iPad cant handle this
|
||||
# see https://bugs.launchpad.net/bugs/1013976
|
||||
digest_auth(self.realm, get_ha1_dict_plain(self.users_dict),
|
||||
self.secret)
|
||||
|
||||
|
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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user