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
ffbc7931f2
@ -69,7 +69,24 @@ nmake -f ms\ntdll.mak install
|
||||
Qt
|
||||
--------
|
||||
|
||||
Extract Qt sourcecode to C:\Qt\4.x.x. Run configure and make::
|
||||
Extract Qt sourcecode to C:\Qt\4.x.x.
|
||||
|
||||
Qt uses its own routine to locate and load "system libraries" including the openssl libraries needed for "Get Books". This means that we have to apply the following patch to have Qt load the openssl libraries bundled with calibre:
|
||||
|
||||
|
||||
--- src/corelib/plugin/qsystemlibrary.cpp 2011-02-22 05:04:00.000000000 -0700
|
||||
+++ src/corelib/plugin/qsystemlibrary.cpp 2011-04-25 20:53:13.635247466 -0600
|
||||
@@ -110,7 +110,7 @@ HINSTANCE QSystemLibrary::load(const wch
|
||||
|
||||
#if !defined(QT_BOOTSTRAPPED)
|
||||
if (!onlySystemDirectory)
|
||||
- searchOrder << QFileInfo(qAppFileName()).path();
|
||||
+ searchOrder << (QFileInfo(qAppFileName()).path().replace(QLatin1Char('/'), QLatin1Char('\\')) + QString::fromLatin1("\\DLLs\\"));
|
||||
#endif
|
||||
searchOrder << qSystemDirectory();
|
||||
|
||||
|
||||
Now, run configure and make::
|
||||
|
||||
configure -opensource -release -qt-zlib -qt-gif -qt-libmng -qt-libpng -qt-libtiff -qt-libjpeg -release -platform win32-msvc2008 -no-qt3support -webkit -xmlpatterns -no-phonon -no-style-plastique -no-style-cleanlooks -no-style-motif -no-style-cde -no-declarative -no-scripttools -no-audio-backend -no-multimedia -no-dbus -no-openvg -no-opengl -no-qt3support -confirm-license -nomake examples -nomake demos -nomake docs -openssl -I Q:\openssl\include -L Q:\openssl\lib && nmake
|
||||
|
||||
|
@ -11,6 +11,9 @@
|
||||
SummaryCodepage='1252' />
|
||||
|
||||
<Media Id="1" Cabinet="{app}.cab" CompressionLevel="{compression}" EmbedCab="yes" />
|
||||
<!-- The following line is needed because of the patch to QtCore4.dll. You can remove this line
|
||||
after you update Qt beyond 4.7.2. 'emus' means re-install even if version is the same not just if it is older. -->
|
||||
<Property Id='REINSTALLMODE' Value='emus'/>
|
||||
|
||||
<Upgrade Id="{upgrade_code}">
|
||||
<UpgradeVersion Maximum="{version}"
|
||||
|
@ -347,9 +347,10 @@ class UploadUserManual(Command): # {{{
|
||||
with NamedTemporaryFile(suffix='.zip') as f:
|
||||
os.fchmod(f.fileno(),
|
||||
stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWRITE)
|
||||
with CurrentDir(self.d(path)):
|
||||
with CurrentDir(path):
|
||||
with ZipFile(f, 'w') as zf:
|
||||
for x in os.listdir('.'):
|
||||
if x.endswith('.swp'): continue
|
||||
zf.write(x)
|
||||
if os.path.isdir(x):
|
||||
for y in os.listdir(x):
|
||||
|
@ -388,7 +388,11 @@ class CurrentDir(object):
|
||||
return self.cwd
|
||||
|
||||
def __exit__(self, *args):
|
||||
try:
|
||||
os.chdir(self.cwd)
|
||||
except:
|
||||
# The previous CWD no longer exists
|
||||
pass
|
||||
|
||||
|
||||
class StreamReadWrapper(object):
|
||||
|
@ -402,7 +402,7 @@ class HTMLPreProcessor(object):
|
||||
(re.compile(r'((?<=</a>)\s*file:/{2,4}[A-Z].*<br>|file:////?[A-Z].*<br>(?=\s*<hr>))', re.IGNORECASE), lambda match: ''),
|
||||
|
||||
# Center separator lines
|
||||
(re.compile(u'<br>\s*(?P<break>([*#•✦=]+\s*)+)\s*<br>'), lambda match: '<p>\n<p style="text-align:center">' + match.group(1) + '</p>'),
|
||||
(re.compile(u'<br>\s*(?P<break>([*#•✦=] *){3,})\s*<br>'), lambda match: '<p>\n<p style="text-align:center">' + match.group('break') + '</p>'),
|
||||
|
||||
# Remove page links
|
||||
(re.compile(r'<a name=\d+></a>', re.IGNORECASE), lambda match: ''),
|
||||
|
@ -174,11 +174,6 @@ class Metadata(object):
|
||||
try:
|
||||
return self.__getattribute__(field)
|
||||
except AttributeError:
|
||||
if field.startswith('#') and field.endswith('_index'):
|
||||
try:
|
||||
return self.get_extra(field[:-6])
|
||||
except:
|
||||
pass
|
||||
return default
|
||||
|
||||
def get_extra(self, field, default=None):
|
||||
|
@ -301,7 +301,7 @@ class Amazon(Source):
|
||||
if asin is None:
|
||||
asin = identifiers.get('asin', None)
|
||||
if asin:
|
||||
return 'http://amzn.com/%s'%asin
|
||||
return ('amazon', asin, 'http://amzn.com/%s'%asin)
|
||||
# }}}
|
||||
|
||||
def create_query(self, log, title=None, authors=None, identifiers={}): # {{{
|
||||
|
@ -56,7 +56,8 @@ class InternalMetadataCompareKeyGen(object):
|
||||
|
||||
'''
|
||||
Generate a sort key for comparison of the relevance of Metadata objects,
|
||||
given a search query.
|
||||
given a search query. This is used only to compare results from the same
|
||||
metadata source, not across different sources.
|
||||
|
||||
The sort key ensures that an ascending order sort is a sort by order of
|
||||
decreasing relevance.
|
||||
@ -374,7 +375,11 @@ class Source(Plugin):
|
||||
|
||||
def get_book_url(self, identifiers):
|
||||
'''
|
||||
Return the URL for the book identified by identifiers at this source.
|
||||
Return a 3-tuple or None. The 3-tuple is of the form:
|
||||
(identifier_type, identifier_value, URL).
|
||||
The URL is the URL for the book identified by identifiers at this
|
||||
source. identifier_type, identifier_value specify the identifier
|
||||
corresponding to the URL.
|
||||
This URL must be browseable to by a human using a browser. It is meant
|
||||
to provide a clickable link for the user to easily visit the books page
|
||||
at this source.
|
||||
|
@ -173,7 +173,7 @@ class GoogleBooks(Source):
|
||||
def get_book_url(self, identifiers): # {{{
|
||||
goog = identifiers.get('google', None)
|
||||
if goog is not None:
|
||||
return 'http://books.google.com/books?id=%s'%goog
|
||||
return ('google', goog, 'http://books.google.com/books?id=%s'%goog)
|
||||
# }}}
|
||||
|
||||
def create_query(self, log, title=None, authors=None, identifiers={}): # {{{
|
||||
|
@ -435,18 +435,30 @@ def identify(log, abort, # {{{
|
||||
# }}}
|
||||
|
||||
def urls_from_identifiers(identifiers): # {{{
|
||||
identifiers = dict([(k.lower(), v) for k, v in identifiers.iteritems()])
|
||||
ans = []
|
||||
for plugin in all_metadata_plugins():
|
||||
try:
|
||||
url = plugin.get_book_url(identifiers)
|
||||
if url is not None:
|
||||
ans.append((plugin.name, url))
|
||||
id_type, id_val, url = plugin.get_book_url(identifiers)
|
||||
ans.append((plugin.name, id_type, id_val, url))
|
||||
except:
|
||||
pass
|
||||
isbn = identifiers.get('isbn', None)
|
||||
if isbn:
|
||||
ans.append((isbn,
|
||||
'http://www.worldcat.org/search?q=bn%%3A%s&qt=advanced'%isbn))
|
||||
ans.append((isbn, 'isbn', isbn,
|
||||
'http://www.worldcat.org/isbn/'+isbn))
|
||||
doi = identifiers.get('doi', None)
|
||||
if doi:
|
||||
ans.append(('DOI', 'doi', doi,
|
||||
'http://dx.doi.org/'+doi))
|
||||
arxiv = identifiers.get('arxiv', None)
|
||||
if arxiv:
|
||||
ans.append(('arXiv', 'arxiv', arxiv,
|
||||
'http://arxiv.org/abs/'+arxiv))
|
||||
oclc = identifiers.get('oclc', None)
|
||||
if oclc:
|
||||
ans.append(('OCLC', 'oclc', oclc,
|
||||
'http://www.worldcat.org/oclc/'+oclc))
|
||||
return ans
|
||||
# }}}
|
||||
|
||||
|
@ -265,7 +265,7 @@ class OverDrive(Source):
|
||||
if creators:
|
||||
creators = creators.split(', ')
|
||||
# if an exact match in a preferred format occurs
|
||||
if ((author and creators[0] == author[0]) or (not author and not creators)) and od_title.lower() == title.lower() and int(formatid) in [1, 50, 410, 900] and thumbimage:
|
||||
if ((author and creators and creators[0] == author[0]) or (not author and not creators)) and od_title.lower() == title.lower() and int(formatid) in [1, 50, 410, 900] and thumbimage:
|
||||
return self.format_results(reserveid, od_title, subtitle, series, publisher,
|
||||
creators, thumbimage, worldcatlink, formatid)
|
||||
else:
|
||||
|
@ -17,13 +17,13 @@ from calibre.gui2.dnd import (dnd_has_image, dnd_get_image, dnd_get_files,
|
||||
from calibre.ebooks import BOOK_EXTENSIONS
|
||||
from calibre.ebooks.metadata.book.base import (field_metadata, Metadata)
|
||||
from calibre.ebooks.metadata import fmt_sidx
|
||||
from calibre.ebooks.metadata.sources.identify import urls_from_identifiers
|
||||
from calibre.constants import filesystem_encoding
|
||||
from calibre.library.comments import comments_to_html
|
||||
from calibre.gui2 import (config, open_local_file, open_url, pixmap_to_data,
|
||||
gprefs)
|
||||
from calibre.utils.icu import sort_key
|
||||
|
||||
|
||||
def render_html(mi, css, vertical, widget, all_fields=False): # {{{
|
||||
table = render_data(mi, all_fields=all_fields,
|
||||
use_roman_numbers=config['use_roman_numerals_for_series_number'])
|
||||
@ -114,14 +114,19 @@ def render_data(mi, use_roman_numbers=True, all_fields=False):
|
||||
ans.append((field, u'<td class="title">%s</td><td>%s</td>'%(name,
|
||||
u', '.join(fmts))))
|
||||
elif field == 'identifiers':
|
||||
pass # TODO
|
||||
urls = urls_from_identifiers(mi.identifiers)
|
||||
links = [u'<a href="%s" title="%s:%s">%s</a>' % (url, id_typ, id_val, name)
|
||||
for name, id_typ, id_val, url in urls]
|
||||
links = u', '.join(links)
|
||||
ans.append((field, u'<td class="title">%s</td><td>%s</td>'%(
|
||||
_('Ids')+':', links)))
|
||||
else:
|
||||
val = mi.format_field(field)[-1]
|
||||
if val is None:
|
||||
continue
|
||||
val = prepare_string_for_xml(val)
|
||||
if metadata['datatype'] == 'series':
|
||||
sidx = getattr(mi, field+'_index')
|
||||
sidx = mi.get(field+'_index')
|
||||
if sidx is None:
|
||||
sidx = 1.0
|
||||
val = _('Book %s of <span class="series_name">%s</span>')%(fmt_sidx(sidx,
|
||||
@ -289,6 +294,8 @@ class BookInfo(QWebView):
|
||||
|
||||
def link_activated(self, link):
|
||||
self._link_clicked = True
|
||||
if unicode(link.scheme()) in ('http', 'https'):
|
||||
return open_url(link)
|
||||
link = unicode(link.toString())
|
||||
self.link_clicked.emit(link)
|
||||
|
||||
|
@ -22,6 +22,12 @@
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../../../resources/images.qrc">:/images/dialog_warning.png</pixmap>
|
||||
</property>
|
||||
@ -46,6 +52,10 @@
|
||||
<property name="text">
|
||||
<string>Library</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../resources/images.qrc">
|
||||
<normaloff>:/images/library.png</normaloff>:/images/library.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@ -53,6 +63,10 @@
|
||||
<property name="text">
|
||||
<string>Device</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../resources/images.qrc">
|
||||
<normaloff>:/images/reader.png</normaloff>:/images/reader.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@ -60,6 +74,10 @@
|
||||
<property name="text">
|
||||
<string>Library and Device</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../resources/images.qrc">
|
||||
<normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -253,7 +253,7 @@ class ResultsView(QTableView): # {{{
|
||||
parts.append('</center>')
|
||||
if book.identifiers:
|
||||
urls = urls_from_identifiers(book.identifiers)
|
||||
ids = ['<a href="%s">%s</a>'%(url, name) for name, url in urls]
|
||||
ids = ['<a href="%s">%s</a>'%(url, name) for name, ign, ign, url in urls]
|
||||
if ids:
|
||||
parts.append('<div><b>%s:</b> %s</div><br>'%(_('See at'), ', '.join(ids)))
|
||||
if book.tags:
|
||||
|
@ -20,13 +20,14 @@ What formats does |app| support conversion to/from?
|
||||
|app| supports the conversion of many input formats to many output formats.
|
||||
It can convert every input format in the following list, to every output format.
|
||||
|
||||
*Input Formats:* CBZ, CBR, CBC, CHM, EPUB, FB2, HTML, HTMLZ, LIT, LRF, MOBI, ODT, PDF, PRC**, PDB***, PML, RB, RTF, SNB, TCR, TXT, TXTZ
|
||||
*Input Formats:* CBZ, CBR, CBC, CHM, EPUB, FB2, HTML, HTMLZ, LIT, LRF, MOBI, ODT, PDF, PRC, PDB, PML, RB, RTF, SNB, TCR, TXT, TXTZ
|
||||
|
||||
*Output Formats:* EPUB, FB2, OEB, LIT, LRF, MOBI, HTMLZ, PDB, PML, RB, PDF, SNB, TCR, TXT, TXTZ
|
||||
|
||||
** PRC is a generic format, |app| supports PRC files with TextRead and MOBIBook headers
|
||||
.. note ::
|
||||
|
||||
*** PDB is also a generic format. |app| supports eReder, Plucker, PML and zTxt PDB files.
|
||||
PRC is a generic format, |app| supports PRC files with TextRead and MOBIBook headers.
|
||||
PDB is also a generic format. |app| supports eReder, Plucker, PML and zTxt PDB files.
|
||||
|
||||
.. _best-source-formats:
|
||||
|
||||
|
@ -65,17 +65,14 @@ Catalog plugins
|
||||
Metadata download plugins
|
||||
--------------------------
|
||||
|
||||
.. module:: calibre.ebooks.metadata.fetch
|
||||
.. module:: calibre.ebooks.metadata.sources.base
|
||||
|
||||
.. autoclass:: MetadataSource
|
||||
.. autoclass:: Source
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:member-order: bysource
|
||||
|
||||
.. autoclass:: calibre.ebooks.metadata.covers.CoverDownload
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:member-order: bysource
|
||||
.. autoclass:: InternalMetadataCompareKeyGen
|
||||
|
||||
Conversion plugins
|
||||
--------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user