mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
Sync to trunk.
This commit is contained in:
commit
ad5d8fc4f2
@ -11,7 +11,7 @@
|
||||
- title: "Page turn animations in the e-book viewer"
|
||||
type: major
|
||||
description: >
|
||||
"Now when you use the Page Down/Page Up keys or the next/previous page buttons in the viewer, page turning will be animated. The duration of the animation can be controlled in the viewer preferences. Setting it to o disables the animation completely."
|
||||
"Now when you use the Page Down/Page Up keys or the next/previous page buttons in the viewer, page turning will be animated. The duration of the animation can be controlled in the viewer preferences. Setting it to 0 disables the animation completely."
|
||||
|
||||
- title: "Conversion pipeline: Add an option to set the minimum line height of all elemnts as a percentage of the computed font size. By default, calibre now sets the line height to 120% of the computed font size."
|
||||
|
||||
|
@ -41,6 +41,20 @@ series_index_auto_increment = 'next'
|
||||
# selecting 'manage authors', and pressing 'Recalculate all author sort values'.
|
||||
author_sort_copy_method = 'invert'
|
||||
|
||||
# Set which author field to display in the tags pane (the list of authors,
|
||||
# series, publishers etc on the left hand side). The choices are author and
|
||||
# author_sort. This tweak affects only the tags pane, and only what is displayed
|
||||
# under the authors category. Please note that if you set this to author_sort,
|
||||
# it is very possible to see duplicate names in the list becasue although it is
|
||||
# guaranteed that author names are unique, there is no such guarantee for
|
||||
# author_sort values. Showing duplicates won't break anything, but it could
|
||||
# lead to some confusion. When using 'author_sort', the tooltip will show the
|
||||
# author's name.
|
||||
# Examples:
|
||||
# tags_pane_use_field_for_author_name = 'author'
|
||||
# tags_pane_use_field_for_author_name = 'author_sort'
|
||||
tags_pane_use_field_for_author_name = 'author'
|
||||
|
||||
|
||||
# Set whether boolean custom columns are two- or three-valued.
|
||||
# Two-values for true booleans
|
||||
|
@ -1,78 +1,72 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
class JournalofHospitalMedicine(BasicNewsRecipe):
|
||||
|
||||
title = 'Journal of Hospital Medicine'
|
||||
__author__ = 'Krittika Goyal'
|
||||
__author__ = 'Kovid Goyal'
|
||||
description = 'Medical news'
|
||||
timefmt = ' [%d %b, %Y]'
|
||||
needs_subscription = True
|
||||
language = 'en'
|
||||
|
||||
no_stylesheets = True
|
||||
keep_only_tags = [dict(id=['articleTitle', 'articleMeta', 'fulltext'])]
|
||||
remove_tags = [dict(attrs={'class':'licensedContent'})]
|
||||
|
||||
|
||||
# TO LOGIN
|
||||
def get_browser(self):
|
||||
br = BasicNewsRecipe.get_browser()
|
||||
br.open('http://www3.interscience.wiley.com/cgi-bin/home')
|
||||
br.select_form(name='siteLogin')
|
||||
br['LoginName'] = self.username
|
||||
br['Password'] = self.password
|
||||
br.select_form(nr=0)
|
||||
br['j_username'] = self.username
|
||||
br['j_password'] = self.password
|
||||
response = br.submit()
|
||||
raw = response.read()
|
||||
if 'userName = ""' in raw:
|
||||
if '<h2>LOGGED IN</h2>' not in raw:
|
||||
raise Exception('Login failed. Check your username and password')
|
||||
return br
|
||||
|
||||
#TO GET ARTICLE TOC
|
||||
def johm_get_index(self):
|
||||
return self.index_to_soup('http://www3.interscience.wiley.com/journal/111081937/home')
|
||||
return self.index_to_soup('http://onlinelibrary.wiley.com/journal/10.1002/(ISSN)1553-5606/currentissue')
|
||||
|
||||
# To parse artice toc
|
||||
def parse_index(self):
|
||||
parse_soup = self.johm_get_index()
|
||||
|
||||
div = parse_soup.find(id='contentCell')
|
||||
|
||||
current_section = None
|
||||
current_articles = []
|
||||
soup = self.johm_get_index()
|
||||
toc = soup.find(id='issueTocGroups')
|
||||
feeds = []
|
||||
for x in div.findAll(True):
|
||||
if x.name == 'h4':
|
||||
# Section heading found
|
||||
if current_articles and current_section:
|
||||
feeds.append((current_section, current_articles))
|
||||
current_section = self.tag_to_string(x)
|
||||
current_articles = []
|
||||
self.log('\tFound section:', current_section)
|
||||
if current_section is not None and x.name == 'strong':
|
||||
title = self.tag_to_string(x)
|
||||
p = x.parent.parent.find('a', href=lambda x: x and '/HTMLSTART' in x)
|
||||
if p is None:
|
||||
for group in toc.findAll('li', id=re.compile(r'group\d+')):
|
||||
gtitle = group.find(attrs={'class':'subSectionHeading'})
|
||||
if gtitle is None:
|
||||
continue
|
||||
url = p.get('href', False)
|
||||
if not url or not title:
|
||||
gtitle = self.tag_to_string(gtitle)
|
||||
arts = group.find(attrs={'class':'articles'})
|
||||
if arts is None:
|
||||
continue
|
||||
self.log('Found section:', gtitle)
|
||||
articles = []
|
||||
for art in arts.findAll(attrs={'class':lambda x: x and 'tocArticle'
|
||||
in x}):
|
||||
a = art.find('a', href=True)
|
||||
if a is None:
|
||||
continue
|
||||
url = a.get('href')
|
||||
if url.startswith('/'):
|
||||
url = 'http://www3.interscience.wiley.com'+url
|
||||
url = url.replace('/HTMLSTART', '/main.html,ftx_abs')
|
||||
self.log('\t\tFound article:', title)
|
||||
self.log('\t\t\t', url)
|
||||
#if url.startswith('/'):
|
||||
#url = 'http://online.wsj.com'+url
|
||||
current_articles.append({'title': title, 'url':url,
|
||||
'description':'', 'date':''})
|
||||
|
||||
if current_articles and current_section:
|
||||
feeds.append((current_section, current_articles))
|
||||
url = 'http://onlinelibrary.wiley.com' + url
|
||||
url = url.replace('/abstract', '/full')
|
||||
title = self.tag_to_string(a)
|
||||
a.extract()
|
||||
pm = art.find(attrs={'class':'productMenu'})
|
||||
if pm is not None:
|
||||
pm.extract()
|
||||
desc = self.tag_to_string(art)
|
||||
self.log('\tFound article:', title, 'at', url)
|
||||
articles.append({'title':title, 'url':url, 'description':desc,
|
||||
'date':''})
|
||||
if articles:
|
||||
feeds.append((gtitle, articles))
|
||||
|
||||
return feeds
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
for img in soup.findAll('img', src=True):
|
||||
img['src'] = img['src'].replace('tfig', 'nfig')
|
||||
return soup
|
||||
|
||||
|
@ -4,7 +4,7 @@ from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
class NYTimes(BasicNewsRecipe):
|
||||
|
||||
title = 'New England Journal of Medicine'
|
||||
__author__ = 'Krittika Goyal'
|
||||
__author__ = 'Kovid Goyal'
|
||||
description = 'Medical news'
|
||||
timefmt = ' [%d %b, %Y]'
|
||||
needs_subscription = True
|
||||
|
@ -36,6 +36,16 @@ Install BeautifulSoup 3.0.x manually into site-packages (3.1.x parses broken HTM
|
||||
|
||||
Install pywin32 and edit win32com\__init__.py setting _frozen = True and
|
||||
__gen_path__ to a temp dir (otherwise it tries to set it to a dir in the install tree which leads to permission errors)
|
||||
Note that you should use::
|
||||
|
||||
import tempfile
|
||||
__gen_path__ = os.path.join(
|
||||
tempfile.gettempdir(), "gen_py",
|
||||
"%d.%d" % (sys.version_info[0], sys.version_info[1]))
|
||||
|
||||
Use gettempdir instead of the win32 api method as gettempdir returns a temp dir that is guaranteed to actually work.
|
||||
|
||||
|
||||
Also edit win32com\client\gencache.py and change the except IOError on line 57 to catch all exceptions.
|
||||
|
||||
SQLite
|
||||
|
@ -28,7 +28,7 @@ class ANDROID(USBMS):
|
||||
|
||||
# Motorola
|
||||
0x22b8 : { 0x41d9 : [0x216], 0x2d67 : [0x100], 0x41db : [0x216],
|
||||
0x4285 : [0x216]},
|
||||
0x4285 : [0x216], 0x42a3 : [0x216] },
|
||||
|
||||
# Sony Ericsson
|
||||
0xfce : { 0xd12e : [0x0100]},
|
||||
|
@ -62,9 +62,9 @@ class SWEEX(USBMS):
|
||||
# Ordered list of supported formats
|
||||
FORMATS = ['epub', 'prc', 'fb2', 'html', 'rtf', 'chm', 'pdf', 'txt']
|
||||
|
||||
VENDOR_ID = [0x0525]
|
||||
PRODUCT_ID = [0xa4a5]
|
||||
BCD = [0x0319]
|
||||
VENDOR_ID = [0x0525, 0x177f]
|
||||
PRODUCT_ID = [0xa4a5, 0x300]
|
||||
BCD = [0x0319, 0x110]
|
||||
|
||||
VENDOR_NAME = 'SWEEX'
|
||||
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOKREADER'
|
||||
|
@ -245,7 +245,7 @@ class RTFInput(InputFormatPlugin):
|
||||
from calibre.ebooks.metadata.meta import get_metadata
|
||||
from calibre.ebooks.metadata.opf2 import OPFCreator
|
||||
from calibre.ebooks.rtf2xml.ParseRtf import RtfInvalidCodeException
|
||||
self.options = options
|
||||
self.opts = options
|
||||
self.log = log
|
||||
self.log('Converting RTF to XML...')
|
||||
#Name of the preprocesssed RTF file
|
||||
@ -290,12 +290,12 @@ class RTFInput(InputFormatPlugin):
|
||||
res = transform.tostring(result)
|
||||
res = res[:100].replace('xmlns:html', 'xmlns') + res[100:]
|
||||
# Replace newlines inserted by the 'empty_paragraphs' option in rtf2xml with html blank lines
|
||||
if not getattr(self.options, 'remove_paragraph_spacing', False):
|
||||
if not getattr(self.opts, 'remove_paragraph_spacing', False):
|
||||
res = re.sub('\s*<body>', '<body>', res)
|
||||
res = re.sub('(?<=\n)\n{2}',
|
||||
u'<p>\u00a0</p>\n'.encode('utf-8'), res)
|
||||
if self.options.preprocess_html:
|
||||
preprocessor = PreProcessor(self.options, log=getattr(self, 'log', None))
|
||||
if self.opts.preprocess_html:
|
||||
preprocessor = PreProcessor(self.opts, log=getattr(self, 'log', None))
|
||||
res = preprocessor(res)
|
||||
f.write(res)
|
||||
self.write_inline_css(inline_class, border_styles)
|
||||
|
@ -18,6 +18,7 @@ from PyQt4.Qt import Qt, QTreeView, QApplication, pyqtSignal, \
|
||||
from calibre.ebooks.metadata import title_sort
|
||||
from calibre.gui2 import config, NONE
|
||||
from calibre.library.field_metadata import TagsIcons, category_icon_map
|
||||
from calibre.utils.config import tweaks
|
||||
from calibre.utils.icu import sort_key
|
||||
from calibre.utils.search_query_parser import saved_searches
|
||||
from calibre.gui2 import error_dialog
|
||||
@ -409,17 +410,31 @@ class TagTreeItem(object): # {{{
|
||||
return NONE
|
||||
|
||||
def tag_data(self, role):
|
||||
if role == Qt.DisplayRole:
|
||||
if self.tag.count == 0:
|
||||
return QVariant('%s'%(self.tag.name))
|
||||
tag = self.tag
|
||||
if tag.category == 'authors' and \
|
||||
tweaks['tags_pane_use_field_for_author_name'] == 'author_sort':
|
||||
name = tag.sort
|
||||
tt_author = True
|
||||
else:
|
||||
return QVariant('[%d] %s'%(self.tag.count, self.tag.name))
|
||||
name = tag.name
|
||||
tt_author = False
|
||||
if role == Qt.DisplayRole:
|
||||
if tag.count == 0:
|
||||
return QVariant('%s'%(name))
|
||||
else:
|
||||
return QVariant('[%d] %s'%(tag.count, name))
|
||||
if role == Qt.EditRole:
|
||||
return QVariant(self.tag.name)
|
||||
return QVariant(tag.name)
|
||||
if role == Qt.DecorationRole:
|
||||
return self.icon_state_map[self.tag.state]
|
||||
if role == Qt.ToolTipRole and self.tag.tooltip is not None:
|
||||
return QVariant(self.tag.tooltip)
|
||||
return self.icon_state_map[tag.state]
|
||||
if role == Qt.ToolTipRole:
|
||||
if tt_author:
|
||||
if tag.tooltip is not None:
|
||||
return QVariant('(%s) %s'%(tag.name, tag.tooltip))
|
||||
else:
|
||||
return QVariant(tag.name)
|
||||
if tag.tooltip is not None:
|
||||
return QVariant(tag.tooltip)
|
||||
return NONE
|
||||
|
||||
def toggle(self):
|
||||
|
@ -1128,6 +1128,10 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
for l in list:
|
||||
(id, val, sort_val) = (l[0], l[1], l[2])
|
||||
tids[category][val] = (id, sort_val)
|
||||
elif cat['datatype'] == 'rating':
|
||||
for l in list:
|
||||
(id, val) = (l[0], l[1])
|
||||
tids[category][val] = (id, '{0:05.2f}'.format(val))
|
||||
else:
|
||||
for l in list:
|
||||
(id, val) = (l[0], l[1])
|
||||
@ -1256,12 +1260,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
|
||||
# sort the list
|
||||
if sort == 'name':
|
||||
def get_sort_key(x):
|
||||
sk = x.s
|
||||
if isinstance(sk, unicode):
|
||||
sk = sort_key(sk)
|
||||
return sk
|
||||
kf = get_sort_key
|
||||
kf = lambda x :sort_key(x.s)
|
||||
reverse=False
|
||||
elif sort == 'popularity':
|
||||
kf = lambda x: x.c
|
||||
|
@ -541,7 +541,9 @@ Use the options to remove headers and footers to mitigate this issue. If the hea
|
||||
removed from the text it can throw off the paragraph unwrapping.
|
||||
|
||||
Some limitations of PDF input is complex, multi-column, and image based documents are not supported.
|
||||
Extraction of vector images and tables from within the document is also not supported.
|
||||
Extraction of vector images and tables from within the document is also not supported. Some PDFs use special glyphs to
|
||||
represent double ll or doubfle ff or fi,etc. Conversion of these may or may not work depending on jusy how they are
|
||||
represented internally in the PDF.
|
||||
|
||||
Comic Book Collections
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
Loading…
x
Reference in New Issue
Block a user