mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Sync to trunk
This commit is contained in:
commit
37317ee345
@ -8,16 +8,18 @@ __docformat__ = 'restructuredtext en'
|
|||||||
import sys, time, subprocess, os, re
|
import sys, time, subprocess, os, re
|
||||||
from calibre import __appname__, __version__
|
from calibre import __appname__, __version__
|
||||||
|
|
||||||
|
INSTALLJAMMER = '/home/kovid/installjammer/installjammer'
|
||||||
|
|
||||||
sv = re.sub(r'[a-z]\d+', '', __version__)
|
sv = re.sub(r'[a-z]\d+', '', __version__)
|
||||||
|
|
||||||
cmdline = [
|
cmdline = [
|
||||||
'/usr/local/installjammer/installjammer',
|
INSTALLJAMMER,
|
||||||
'--build-dir', '/tmp/calibre-installjammer',
|
'--build-dir', '/tmp/calibre-installjammer',
|
||||||
'-DAppName', __appname__,
|
'-DAppName', __appname__,
|
||||||
'-DShortAppName', __appname__,
|
'-DShortAppName', __appname__,
|
||||||
'-DApplicationURL', 'http://%s.kovidgoyal.net'%__appname__,
|
'-DApplicationURL', 'http://%s.kovidgoyal.net'%__appname__,
|
||||||
'-DCopyright', time.strftime('%Y Kovid Goyal'),
|
'-DCopyright', time.strftime('%Y Kovid Goyal'),
|
||||||
'-DPackageDescription', '%s is an e-book library manager. It can view, convert and catalog e-books in most of the major e-book formats. It can also talk to a few e-book reader devices. It can go out to the internet and fetch metadata for your books. It can download newspapers and convert them into e-books for convenient reading.'%__appname__,
|
'-DPackageDescription', '%s is an e-book library manager. It can view, convert and catalog e-books in most of the major e-book formats. It can also talk to e-book reader devices. It can go out to the internet and fetch metadata for your books. It can download newspapers and convert them into e-books for convenient reading.'%__appname__,
|
||||||
'-DPackageSummary', '%s: E-book library management'%__appname__,
|
'-DPackageSummary', '%s: E-book library management'%__appname__,
|
||||||
'-DVersion', __version__,
|
'-DVersion', __version__,
|
||||||
'-DInstallVersion', sv + '.0',
|
'-DInstallVersion', sv + '.0',
|
||||||
|
@ -138,7 +138,7 @@ ProjectID
|
|||||||
DA98A0C6-9102-73EC-2516-B147E972D3F7
|
DA98A0C6-9102-73EC-2516-B147E972D3F7
|
||||||
|
|
||||||
ProjectVersion
|
ProjectVersion
|
||||||
1.2.7.0
|
1.2.12.0
|
||||||
|
|
||||||
SaveOnlyToplevelDirs
|
SaveOnlyToplevelDirs
|
||||||
No
|
No
|
||||||
@ -211,7 +211,8 @@ File ::8E5D85A4-7608-47A1-CF7C-309060D5FF40 -filemethod {Always overwrite files}
|
|||||||
Component ::F6829AB7-9F66-4CEE-CA0E-21F54C6D3609 -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows} -name Main -parent Components
|
Component ::F6829AB7-9F66-4CEE-CA0E-21F54C6D3609 -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows} -name Main -parent Components
|
||||||
SetupType ::D9ADE41C-B744-690C-2CED-CF826BF03D2E -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows} -name Typical -parent SetupTypes
|
SetupType ::D9ADE41C-B744-690C-2CED-CF826BF03D2E -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows} -name Typical -parent SetupTypes
|
||||||
|
|
||||||
InstallComponent 3EA07B17-04D8-6508-B535-96CC7173B49A -setup Install -type pane -title {Welcome Screen} -component Welcome -active Yes -parent StandardInstall
|
InstallComponent 3EA07B17-04D8-6508-B535-96CC7173B49A -setup Install -type pane -conditions D7F585DB-0DEC-A94E-DAB0-94D558D82764 -title {Welcome Screen} -component Welcome -command reorder -active Yes -parent StandardInstall
|
||||||
|
Condition D7F585DB-0DEC-A94E-DAB0-94D558D82764 -active Yes -parent 3EA07B17-04D8-6508-B535-96CC7173B49A -title {Execute Script Condition} -component ExecuteScriptCondition -TreeObject::id D7F585DB-0DEC-A94E-DAB0-94D558D82764
|
||||||
InstallComponent 7CCDA4BB-861C-C21E-3011-E93DB58F07D6 -setup Install -type action -title {Check for Previous Install} -component CheckForPreviousInstall -active Yes -parent 3EA07B17-04D8-6508-B535-96CC7173B49A
|
InstallComponent 7CCDA4BB-861C-C21E-3011-E93DB58F07D6 -setup Install -type action -title {Check for Previous Install} -component CheckForPreviousInstall -active Yes -parent 3EA07B17-04D8-6508-B535-96CC7173B49A
|
||||||
InstallComponent 580ACF2C-517F-5E48-9DEF-7DAEFBA59FDD -setup Install -type action -conditions 6DE3B369-9D6B-6BC1-4EA0-2C54ECE159EB -title {Set Virtual Text} -component SetVirtualText -command insert -active Yes -parent 3EA07B17-04D8-6508-B535-96CC7173B49A
|
InstallComponent 580ACF2C-517F-5E48-9DEF-7DAEFBA59FDD -setup Install -type action -conditions 6DE3B369-9D6B-6BC1-4EA0-2C54ECE159EB -title {Set Virtual Text} -component SetVirtualText -command insert -active Yes -parent 3EA07B17-04D8-6508-B535-96CC7173B49A
|
||||||
Condition 6DE3B369-9D6B-6BC1-4EA0-2C54ECE159EB -active Yes -parent 580ACF2C-517F-5E48-9DEF-7DAEFBA59FDD -title {String Is Condition} -component StringIsCondition -TreeObject::id 6DE3B369-9D6B-6BC1-4EA0-2C54ECE159EB
|
Condition 6DE3B369-9D6B-6BC1-4EA0-2C54ECE159EB -active Yes -parent 580ACF2C-517F-5E48-9DEF-7DAEFBA59FDD -title {String Is Condition} -component StringIsCondition -TreeObject::id 6DE3B369-9D6B-6BC1-4EA0-2C54ECE159EB
|
||||||
@ -513,7 +514,7 @@ false
|
|||||||
1
|
1
|
||||||
|
|
||||||
3EA07B17-04D8-6508-B535-96CC7173B49A,Conditions
|
3EA07B17-04D8-6508-B535-96CC7173B49A,Conditions
|
||||||
{0 conditions}
|
{1 condition}
|
||||||
|
|
||||||
3EA07B17-04D8-6508-B535-96CC7173B49A,Message,subst
|
3EA07B17-04D8-6508-B535-96CC7173B49A,Message,subst
|
||||||
1
|
1
|
||||||
@ -1100,6 +1101,9 @@ AAFE58A0-2DFB-CA20-1F6E-D3815F885996,Alias
|
|||||||
AIX-ppc,Active
|
AIX-ppc,Active
|
||||||
No
|
No
|
||||||
|
|
||||||
|
AIX-ppc,BuildSeparateArchives
|
||||||
|
No
|
||||||
|
|
||||||
AIX-ppc,DefaultDirectoryPermission
|
AIX-ppc,DefaultDirectoryPermission
|
||||||
0755
|
0755
|
||||||
|
|
||||||
@ -1286,6 +1290,26 @@ CFBE4459-450B-1FAB-3422-609544334AA2,String
|
|||||||
D79DC0D2-38BC-9D9F-2DF4-3C76D89BF933,ExitType
|
D79DC0D2-38BC-9D9F-2DF4-3C76D89BF933,ExitType
|
||||||
Finish
|
Finish
|
||||||
|
|
||||||
|
D7F585DB-0DEC-A94E-DAB0-94D558D82764,CheckCondition
|
||||||
|
{Before Next Pane is Displayed}
|
||||||
|
|
||||||
|
D7F585DB-0DEC-A94E-DAB0-94D558D82764,Comment
|
||||||
|
{Check if calibre.exe is still running}
|
||||||
|
|
||||||
|
D7F585DB-0DEC-A94E-DAB0-94D558D82764,FailureMessage
|
||||||
|
{calibre is still running. Please shut it down before proceeding. You can quit calibre by right clicking on the calibre system tray icon.}
|
||||||
|
|
||||||
|
D7F585DB-0DEC-A94E-DAB0-94D558D82764,ResultVirtualText
|
||||||
|
CalibreRunning
|
||||||
|
|
||||||
|
D7F585DB-0DEC-A94E-DAB0-94D558D82764,Script
|
||||||
|
{set pid [::InstallAPI::FindProcesses -name calibre.exe]
|
||||||
|
if {$pid eq ""} {
|
||||||
|
## myapp.exe is not running
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0}
|
||||||
|
|
||||||
D86BBA5C-4903-33BA-59F8-4266A3D45896,Conditions
|
D86BBA5C-4903-33BA-59F8-4266A3D45896,Conditions
|
||||||
{2 conditions}
|
{2 conditions}
|
||||||
|
|
||||||
@ -1475,6 +1499,9 @@ FBA33088-C809-DD6B-D337-EADBF1CEE966,String
|
|||||||
FreeBSD-4-x86,Active
|
FreeBSD-4-x86,Active
|
||||||
No
|
No
|
||||||
|
|
||||||
|
FreeBSD-4-x86,BuildSeparateArchives
|
||||||
|
No
|
||||||
|
|
||||||
FreeBSD-4-x86,DefaultDirectoryPermission
|
FreeBSD-4-x86,DefaultDirectoryPermission
|
||||||
0755
|
0755
|
||||||
|
|
||||||
@ -1526,6 +1553,9 @@ FreeBSD-4-x86,RootInstallDir
|
|||||||
FreeBSD-x86,Active
|
FreeBSD-x86,Active
|
||||||
No
|
No
|
||||||
|
|
||||||
|
FreeBSD-x86,BuildSeparateArchives
|
||||||
|
No
|
||||||
|
|
||||||
FreeBSD-x86,DefaultDirectoryPermission
|
FreeBSD-x86,DefaultDirectoryPermission
|
||||||
0755
|
0755
|
||||||
|
|
||||||
@ -1577,6 +1607,9 @@ FreeBSD-x86,RootInstallDir
|
|||||||
HPUX-hppa,Active
|
HPUX-hppa,Active
|
||||||
No
|
No
|
||||||
|
|
||||||
|
HPUX-hppa,BuildSeparateArchives
|
||||||
|
No
|
||||||
|
|
||||||
HPUX-hppa,DefaultDirectoryPermission
|
HPUX-hppa,DefaultDirectoryPermission
|
||||||
0755
|
0755
|
||||||
|
|
||||||
@ -1628,6 +1661,9 @@ HPUX-hppa,RootInstallDir
|
|||||||
Linux-x86,Active
|
Linux-x86,Active
|
||||||
No
|
No
|
||||||
|
|
||||||
|
Linux-x86,BuildSeparateArchives
|
||||||
|
No
|
||||||
|
|
||||||
Linux-x86,DefaultDirectoryPermission
|
Linux-x86,DefaultDirectoryPermission
|
||||||
0755
|
0755
|
||||||
|
|
||||||
@ -1679,6 +1715,9 @@ Linux-x86,RootInstallDir
|
|||||||
Solaris-sparc,Active
|
Solaris-sparc,Active
|
||||||
No
|
No
|
||||||
|
|
||||||
|
Solaris-sparc,BuildSeparateArchives
|
||||||
|
No
|
||||||
|
|
||||||
Solaris-sparc,DefaultDirectoryPermission
|
Solaris-sparc,DefaultDirectoryPermission
|
||||||
0755
|
0755
|
||||||
|
|
||||||
@ -1730,6 +1769,9 @@ Solaris-sparc,RootInstallDir
|
|||||||
TarArchive,Active
|
TarArchive,Active
|
||||||
No
|
No
|
||||||
|
|
||||||
|
TarArchive,BuildSeparateArchives
|
||||||
|
No
|
||||||
|
|
||||||
TarArchive,CompressionLevel
|
TarArchive,CompressionLevel
|
||||||
6
|
6
|
||||||
|
|
||||||
@ -1790,9 +1832,15 @@ TarArchive,VirtualTextMap
|
|||||||
Windows,Active
|
Windows,Active
|
||||||
Yes
|
Yes
|
||||||
|
|
||||||
|
Windows,BuildSeparateArchives
|
||||||
|
No
|
||||||
|
|
||||||
Windows,Executable
|
Windows,Executable
|
||||||
<%AppName%>-<%Version%><%Ext%>
|
<%AppName%>-<%Version%><%Ext%>
|
||||||
|
|
||||||
|
Windows,FileDescription
|
||||||
|
{<%AppName%> <%Version%> Setup}
|
||||||
|
|
||||||
Windows,IncludeTWAPI
|
Windows,IncludeTWAPI
|
||||||
Yes
|
Yes
|
||||||
|
|
||||||
@ -1829,6 +1877,9 @@ Windows,WindowsIcon
|
|||||||
ZipArchive,Active
|
ZipArchive,Active
|
||||||
No
|
No
|
||||||
|
|
||||||
|
ZipArchive,BuildSeparateArchives
|
||||||
|
No
|
||||||
|
|
||||||
ZipArchive,CompressionLevel
|
ZipArchive,CompressionLevel
|
||||||
6
|
6
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ from calibre.ebooks.epub import config as common_config, process_encryption
|
|||||||
from calibre.ebooks.epub.from_html import convert as html2epub, find_html_index
|
from calibre.ebooks.epub.from_html import convert as html2epub, find_html_index
|
||||||
from calibre.ptempfile import TemporaryDirectory
|
from calibre.ptempfile import TemporaryDirectory
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
from calibre.ebooks.metadata.opf2 import OPFCreator
|
from calibre.ebooks.metadata.opf2 import OPFCreator, OPF
|
||||||
from calibre.utils.zipfile import ZipFile
|
from calibre.utils.zipfile import ZipFile
|
||||||
from calibre.customize.ui import run_plugins_on_preprocess
|
from calibre.customize.ui import run_plugins_on_preprocess
|
||||||
|
|
||||||
@ -25,9 +25,36 @@ def lit2opf(path, tdir, opts):
|
|||||||
print 'Exploding LIT file:', path
|
print 'Exploding LIT file:', path
|
||||||
reader = LitReader(path)
|
reader = LitReader(path)
|
||||||
reader.extract_content(tdir, False)
|
reader.extract_content(tdir, False)
|
||||||
for f in walk(tdir):
|
opf = None
|
||||||
if f.lower().endswith('.opf'):
|
for opf in walk(tdir):
|
||||||
return f
|
if opf.lower().endswith('.opf'):
|
||||||
|
break
|
||||||
|
if not opf.endswith('.opf'):
|
||||||
|
opf = None
|
||||||
|
if opf is not None: # Check for url-quoted filenames
|
||||||
|
_opf = OPF(opf, os.path.dirname(opf))
|
||||||
|
replacements = []
|
||||||
|
for item in _opf.itermanifest():
|
||||||
|
href = item.get('href', '')
|
||||||
|
path = os.path.join(os.path.dirname(opf), *(href.split('/')))
|
||||||
|
if not os.path.exists(path) and os.path.exists(path.replace('&', '%26')):
|
||||||
|
npath = path
|
||||||
|
path = path.replace('&', '%26')
|
||||||
|
replacements.append((path, npath))
|
||||||
|
if replacements:
|
||||||
|
print 'Fixing quoted filenames...'
|
||||||
|
for path, npath in replacements:
|
||||||
|
if os.path.exists(path):
|
||||||
|
os.rename(path, npath)
|
||||||
|
for f in walk(tdir):
|
||||||
|
with open(f, 'r+b') as f:
|
||||||
|
raw = f.read()
|
||||||
|
for path, npath in replacements:
|
||||||
|
raw = raw.replace(os.path.basename(path), os.path.basename(npath))
|
||||||
|
f.seek(0)
|
||||||
|
f.truncate()
|
||||||
|
f.write(raw)
|
||||||
|
return opf
|
||||||
|
|
||||||
def mobi2opf(path, tdir, opts):
|
def mobi2opf(path, tdir, opts):
|
||||||
from calibre.ebooks.mobi.reader import MobiReader
|
from calibre.ebooks.mobi.reader import MobiReader
|
||||||
|
@ -6,33 +6,28 @@ Support for reading the metadata from a LIT file.
|
|||||||
|
|
||||||
import sys, cStringIO, os
|
import sys, cStringIO, os
|
||||||
|
|
||||||
from calibre import relpath
|
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
from calibre.ebooks.metadata.opf import OPFReader
|
from calibre.ebooks.metadata.opf2 import OPF
|
||||||
from calibre.ebooks.lit.reader import LitReader
|
from calibre.ebooks.lit.reader import LitReader
|
||||||
|
|
||||||
def get_metadata(stream):
|
def get_metadata(stream):
|
||||||
try:
|
litfile = LitReader(stream)
|
||||||
litfile = LitReader(stream)
|
src = litfile.meta.encode('utf-8')
|
||||||
src = litfile.meta.encode('utf-8')
|
opf = OPF(cStringIO.StringIO(src), os.getcwd())
|
||||||
mi = OPFReader(cStringIO.StringIO(src), dir=os.getcwd())
|
mi = MetaInformation(opf)
|
||||||
cover_url, cover_item = mi.cover, None
|
covers = []
|
||||||
if cover_url:
|
for item in opf.iterguide():
|
||||||
cover_url = relpath(cover_url, os.getcwd())
|
if 'cover' not in item.get('type', '').lower():
|
||||||
for item in litfile.manifest.values():
|
continue
|
||||||
if item.path == cover_url:
|
href = item.get('href', '')
|
||||||
cover_item = item.internal
|
candidates = [href, href.replace('&', '%26')]
|
||||||
if cover_item is not None:
|
for item in litfile.manifest.values():
|
||||||
ext = cover_url.rpartition('.')[-1]
|
if item.path in candidates:
|
||||||
if not ext:
|
covers.append(item.internal)
|
||||||
ext = 'jpg'
|
break
|
||||||
else:
|
covers = [litfile.get_file('/data/' + i) for i in covers]
|
||||||
ext = ext.lower()
|
covers.sort(cmp=lambda x, y:cmp(len(x), len(y)))
|
||||||
cd = litfile.get_file('/data/' + cover_item)
|
mi.cover_data = ('jpg', covers[-1])
|
||||||
mi.cover_data = (ext, cd) if cd else (None, None)
|
|
||||||
except:
|
|
||||||
title = stream.name if hasattr(stream, 'name') and stream.name else 'Unknown'
|
|
||||||
mi = MetaInformation(title, ['Unknown'])
|
|
||||||
return mi
|
return mi
|
||||||
|
|
||||||
def main(args=sys.argv):
|
def main(args=sys.argv):
|
||||||
|
29
src/calibre/ebooks/metadata/mobi.py
Normal file
29
src/calibre/ebooks/metadata/mobi.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2009, Kovid Goyal kovid@kovidgoyal.net'
|
||||||
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
|
||||||
|
from calibre.ebooks.mobi.reader import get_metadata
|
||||||
|
|
||||||
|
def main(args=sys.argv):
|
||||||
|
if len(args) != 2:
|
||||||
|
print >>sys.stderr, 'Usage: %s file.mobi' % args[0]
|
||||||
|
return 1
|
||||||
|
fname = args[1]
|
||||||
|
mi = get_metadata(open(fname, 'rb'))
|
||||||
|
print unicode(mi)
|
||||||
|
if mi.cover_data[1]:
|
||||||
|
cover = os.path.abspath(
|
||||||
|
'.'.join((os.path.splitext(os.path.basename(fname))[0],
|
||||||
|
mi.cover_data[0].lower())))
|
||||||
|
open(cover, 'wb').write(mi.cover_data[1])
|
||||||
|
print _('Cover saved to'), cover
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
@ -435,7 +435,7 @@ class OPF(object):
|
|||||||
rating = MetadataField('rating', is_dc=False, formatter=int)
|
rating = MetadataField('rating', is_dc=False, formatter=int)
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, stream, basedir=os.getcwdu()):
|
def __init__(self, stream, basedir=os.getcwdu(), unquote_urls=True):
|
||||||
if not hasattr(stream, 'read'):
|
if not hasattr(stream, 'read'):
|
||||||
stream = open(stream, 'rb')
|
stream = open(stream, 'rb')
|
||||||
self.basedir = self.base_dir = basedir
|
self.basedir = self.base_dir = basedir
|
||||||
@ -446,7 +446,8 @@ class OPF(object):
|
|||||||
if not self.metadata:
|
if not self.metadata:
|
||||||
raise ValueError('Malformed OPF file: No <metadata> element')
|
raise ValueError('Malformed OPF file: No <metadata> element')
|
||||||
self.metadata = self.metadata[0]
|
self.metadata = self.metadata[0]
|
||||||
self.unquote_urls()
|
if unquote_urls:
|
||||||
|
self.unquote_urls()
|
||||||
self.manifest = Manifest()
|
self.manifest = Manifest()
|
||||||
m = self.manifest_path(self.root)
|
m = self.manifest_path(self.root)
|
||||||
if m:
|
if m:
|
||||||
|
@ -311,7 +311,7 @@ class MobiReader(object):
|
|||||||
opf.cover = 'images/%05d.jpg'%(self.book_header.exth.cover_offset+1)
|
opf.cover = 'images/%05d.jpg'%(self.book_header.exth.cover_offset+1)
|
||||||
manifest = [(htmlfile, 'text/x-oeb1-document')]
|
manifest = [(htmlfile, 'text/x-oeb1-document')]
|
||||||
bp = os.path.dirname(htmlfile)
|
bp = os.path.dirname(htmlfile)
|
||||||
for i in self.image_names:
|
for i in getattr(self, 'image_names', []):
|
||||||
manifest.append((os.path.join(bp, 'images/', i), 'image/jpg'))
|
manifest.append((os.path.join(bp, 'images/', i), 'image/jpg'))
|
||||||
|
|
||||||
opf.create_manifest(manifest)
|
opf.create_manifest(manifest)
|
||||||
@ -451,7 +451,7 @@ class MobiReader(object):
|
|||||||
image_index += 1
|
image_index += 1
|
||||||
try:
|
try:
|
||||||
im = PILImage.open(buf)
|
im = PILImage.open(buf)
|
||||||
except IOError, e:
|
except IOError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
path = os.path.join(output_dir, '%05d.jpg'%image_index)
|
path = os.path.join(output_dir, '%05d.jpg'%image_index)
|
||||||
@ -476,31 +476,23 @@ def get_metadata(stream):
|
|||||||
if mr.book_header.exth is None:
|
if mr.book_header.exth is None:
|
||||||
mi = MetaInformation(mr.name, [_('Unknown')])
|
mi = MetaInformation(mr.name, [_('Unknown')])
|
||||||
else:
|
else:
|
||||||
tdir = tempfile.mkdtemp('_mobi_meta', __appname__+'_')
|
|
||||||
atexit.register(shutil.rmtree, tdir)
|
|
||||||
#print tdir
|
|
||||||
mr.extract_images([], tdir)
|
|
||||||
mi = mr.create_opf('dummy.html')
|
mi = mr.create_opf('dummy.html')
|
||||||
if mi.cover:
|
try:
|
||||||
cover = os.path.join(tdir, mi.cover)
|
if hasattr(mr.book_header.exth, 'cover_offset'):
|
||||||
if not os.access(cover, os.R_OK):
|
cover_index = mr.book_header.first_image_index + mr.book_header.exth.cover_offset
|
||||||
fname = os.path.basename(cover)
|
data = mr.sections[cover_index][0]
|
||||||
match = re.match(r'(\d+)(.+)', fname)
|
else:
|
||||||
if match:
|
data = mr.sections[mr.book_header.first_image_index][0]
|
||||||
num, ext = int(match.group(1), 10), match.group(2)
|
buf = cStringIO.StringIO(data)
|
||||||
while num > 0:
|
im = PILImage.open(buf)
|
||||||
num -= 1
|
obuf = cStringIO.StringIO()
|
||||||
candidate = os.path.join(os.path.dirname(cover), '%05d%s'%(num, ext))
|
im.convert('RGBA').save(obuf, format='JPEG')
|
||||||
if os.access(candidate, os.R_OK):
|
mi.cover_data = ('jpg', obuf.getvalue())
|
||||||
cover = candidate
|
except:
|
||||||
break
|
import traceback
|
||||||
if os.access(cover, os.R_OK):
|
traceback.print_exc()
|
||||||
mi.cover_data = ('JPEG', open(os.path.join(tdir, cover), 'rb').read())
|
return mi
|
||||||
else:
|
|
||||||
path = os.path.join(tdir, 'images', '00001.jpg')
|
|
||||||
if os.access(path, os.R_OK):
|
|
||||||
mi.cover_data = ('JPEG', open(path, 'rb').read())
|
|
||||||
return mi
|
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
from calibre.utils.config import OptionParser
|
from calibre.utils.config import OptionParser
|
||||||
|
BIN
src/calibre/gui2/images/news/amspec.png
Normal file
BIN
src/calibre/gui2/images/news/amspec.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 834 B |
@ -162,7 +162,8 @@ class BooksModel(QAbstractTableModel):
|
|||||||
|
|
||||||
def refresh_ids(self, ids, current_row=-1):
|
def refresh_ids(self, ids, current_row=-1):
|
||||||
rows = self.db.refresh_ids(ids)
|
rows = self.db.refresh_ids(ids)
|
||||||
self.refresh_rows(rows, current_row=current_row)
|
if rows:
|
||||||
|
self.refresh_rows(rows, current_row=current_row)
|
||||||
|
|
||||||
def refresh_rows(self, rows, current_row=-1):
|
def refresh_rows(self, rows, current_row=-1):
|
||||||
for row in rows:
|
for row in rows:
|
||||||
@ -261,7 +262,17 @@ class BooksModel(QAbstractTableModel):
|
|||||||
self.reset()
|
self.reset()
|
||||||
self.sorted_on = (self.column_map[col], order)
|
self.sorted_on = (self.column_map[col], order)
|
||||||
|
|
||||||
|
|
||||||
|
def refresh(self, reset=True):
|
||||||
|
try:
|
||||||
|
col = self.column_map.index(self.sorted_on[0])
|
||||||
|
except:
|
||||||
|
col = 0
|
||||||
|
self.db.refresh(field=self.column_map[col],
|
||||||
|
ascending=self.sorted_on[1]==Qt.AscendingOrder)
|
||||||
|
if reset:
|
||||||
|
self.reset()
|
||||||
|
|
||||||
def resort(self, reset=True):
|
def resort(self, reset=True):
|
||||||
try:
|
try:
|
||||||
col = self.column_map.index(self.sorted_on[0])
|
col = self.column_map.index(self.sorted_on[0])
|
||||||
|
@ -478,7 +478,7 @@ class Main(MainWindow, Ui_MainWindow):
|
|||||||
self.raise_()
|
self.raise_()
|
||||||
self.activateWindow()
|
self.activateWindow()
|
||||||
elif msg.startswith('refreshdb:'):
|
elif msg.startswith('refreshdb:'):
|
||||||
self.library_view.model().resort()
|
self.library_view.model().refresh()
|
||||||
self.library_view.model().research()
|
self.library_view.model().research()
|
||||||
else:
|
else:
|
||||||
print msg
|
print msg
|
||||||
|
@ -29,5 +29,5 @@ def server_config(defaults=None):
|
|||||||
c.add_opt('develop', ['--develop'], default=False,
|
c.add_opt('develop', ['--develop'], default=False,
|
||||||
help='Development mode. Server automatically restarts on file changes and serves code files (html, css, js) from the file system instead of calibre\'s resource system.')
|
help='Development mode. Server automatically restarts on file changes and serves code files (html, css, js) from the file system instead of calibre\'s resource system.')
|
||||||
c.add_opt('max_cover', ['--max-cover'], default='600x800',
|
c.add_opt('max_cover', ['--max-cover'], default='600x800',
|
||||||
help=_('The maximum size for displayed covers'))
|
help=_('The maximum size for displayed covers. Default is %default.'))
|
||||||
return c
|
return c
|
||||||
|
@ -40,7 +40,7 @@ function create_table_headers() {
|
|||||||
|
|
||||||
|
|
||||||
function format_url(format, id, title) {
|
function format_url(format, id, title) {
|
||||||
return 'get/'+format.toLowerCase() + '/'+title + '_' + id+'.'+format.toLowerCase();
|
return 'get/'+format.toLowerCase() + '/'+encodeURIComponent(title) + '_' + id+'.'+format.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
function render_book(book) {
|
function render_book(book) {
|
||||||
|
@ -26,6 +26,7 @@ entry_points = {
|
|||||||
'opf-meta = calibre.ebooks.metadata.opf2:main',
|
'opf-meta = calibre.ebooks.metadata.opf2:main',
|
||||||
'odt-meta = calibre.ebooks.metadata.odt:main',
|
'odt-meta = calibre.ebooks.metadata.odt:main',
|
||||||
'epub-meta = calibre.ebooks.metadata.epub:main',
|
'epub-meta = calibre.ebooks.metadata.epub:main',
|
||||||
|
'mobi-meta = calibre.ebooks.metadata.mobi:main',
|
||||||
'txt2lrf = calibre.ebooks.lrf.txt.convert_from:main',
|
'txt2lrf = calibre.ebooks.lrf.txt.convert_from:main',
|
||||||
'html2lrf = calibre.ebooks.lrf.html.convert_from:main',
|
'html2lrf = calibre.ebooks.lrf.html.convert_from:main',
|
||||||
'html2oeb = calibre.ebooks.html:main',
|
'html2oeb = calibre.ebooks.html:main',
|
||||||
@ -423,7 +424,7 @@ def install_man_pages(fatal_errors):
|
|||||||
if prog in ('prs500', 'pdf-meta', 'epub-meta', 'lit-meta',
|
if prog in ('prs500', 'pdf-meta', 'epub-meta', 'lit-meta',
|
||||||
'markdown-calibre', 'calibre-debug', 'fb2-meta',
|
'markdown-calibre', 'calibre-debug', 'fb2-meta',
|
||||||
'calibre-fontconfig', 'calibre-parallel', 'odt-meta',
|
'calibre-fontconfig', 'calibre-parallel', 'odt-meta',
|
||||||
'rb-meta', 'imp-meta'):
|
'rb-meta', 'imp-meta', 'mobi-meta'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
help2man = ('help2man', prog, '--name', 'part of %s'%__appname__,
|
help2man = ('help2man', prog, '--name', 'part of %s'%__appname__,
|
||||||
|
@ -5,9 +5,8 @@ Dynamic language lookup of translations for user-visible strings.
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
|
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
|
||||||
|
|
||||||
import sys
|
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
from gettext import GNUTranslations, NullTranslations
|
from gettext import GNUTranslations
|
||||||
from calibre.translations.compiled import translations
|
from calibre.translations.compiled import translations
|
||||||
|
|
||||||
__all__ = ['translate']
|
__all__ = ['translate']
|
||||||
@ -23,5 +22,5 @@ def translate(lang, text):
|
|||||||
trans = GNUTranslations(buf)
|
trans = GNUTranslations(buf)
|
||||||
_CACHE[lang] = trans
|
_CACHE[lang] = trans
|
||||||
if trans is None:
|
if trans is None:
|
||||||
return _(text)
|
return getattr(__builtins__, '_', lambda x: x)(text)
|
||||||
return trans.ugettext(text)
|
return trans.ugettext(text)
|
||||||
|
@ -23,7 +23,7 @@ recipe_modules = ['recipe_' + r for r in (
|
|||||||
'spiegel_int', 'themarketticker', 'tomshardware', 'xkcd', 'ftd', 'zdnet',
|
'spiegel_int', 'themarketticker', 'tomshardware', 'xkcd', 'ftd', 'zdnet',
|
||||||
'joelonsoftware', 'telepolis', 'common_dreams', 'nin', 'tomshardware_de',
|
'joelonsoftware', 'telepolis', 'common_dreams', 'nin', 'tomshardware_de',
|
||||||
'pagina12', 'infobae', 'ambito', 'elargentino', 'sueddeutsche', 'the_age',
|
'pagina12', 'infobae', 'ambito', 'elargentino', 'sueddeutsche', 'the_age',
|
||||||
'laprensa',
|
'laprensa', 'amspec',
|
||||||
)]
|
)]
|
||||||
|
|
||||||
import re, imp, inspect, time, os
|
import re, imp, inspect, time, os
|
||||||
|
53
src/calibre/web/feeds/recipes/recipe_amspec.py
Normal file
53
src/calibre/web/feeds/recipes/recipe_amspec.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
'''
|
||||||
|
spectator.org
|
||||||
|
'''
|
||||||
|
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class TheAmericanSpectator(BasicNewsRecipe):
|
||||||
|
title = 'The American Spectator'
|
||||||
|
__author__ = 'Darko Miletic'
|
||||||
|
description = 'news from USA'
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
no_stylesheets = True
|
||||||
|
use_embedded_content = False
|
||||||
|
INDEX = 'http://spectator.org'
|
||||||
|
|
||||||
|
html2lrf_options = [
|
||||||
|
'--comment' , description
|
||||||
|
, '--category' , 'news, politics, USA'
|
||||||
|
, '--publisher' , title
|
||||||
|
]
|
||||||
|
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'class':'post inner'})
|
||||||
|
,dict(name='div', attrs={'class':'author-bio'})
|
||||||
|
]
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(name='object')
|
||||||
|
,dict(name='div', attrs={'class':'col3' })
|
||||||
|
,dict(name='div', attrs={'class':'post-options' })
|
||||||
|
,dict(name='p' , attrs={'class':'letter-editor'})
|
||||||
|
,dict(name='div', attrs={'class':'social' })
|
||||||
|
]
|
||||||
|
|
||||||
|
feeds = [ (u'Articles', u'http://feedproxy.google.com/amspecarticles')]
|
||||||
|
|
||||||
|
def get_cover_url(self):
|
||||||
|
cover_url = None
|
||||||
|
soup = self.index_to_soup(self.INDEX)
|
||||||
|
link_item = soup.find('a',attrs={'class':'cover'})
|
||||||
|
if link_item:
|
||||||
|
soup2 = self.index_to_soup(link_item['href'])
|
||||||
|
link_item2 = soup2.find('div',attrs={'class':'post inner issues'})
|
||||||
|
cover_url = self.INDEX + link_item2.img['src']
|
||||||
|
return cover_url
|
||||||
|
|
||||||
|
def print_version(self, url):
|
||||||
|
return url + '/print'
|
Loading…
x
Reference in New Issue
Block a user