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
|
||||
from calibre import __appname__, __version__
|
||||
|
||||
INSTALLJAMMER = '/home/kovid/installjammer/installjammer'
|
||||
|
||||
sv = re.sub(r'[a-z]\d+', '', __version__)
|
||||
|
||||
cmdline = [
|
||||
'/usr/local/installjammer/installjammer',
|
||||
INSTALLJAMMER,
|
||||
'--build-dir', '/tmp/calibre-installjammer',
|
||||
'-DAppName', __appname__,
|
||||
'-DShortAppName', __appname__,
|
||||
'-DApplicationURL', 'http://%s.kovidgoyal.net'%__appname__,
|
||||
'-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__,
|
||||
'-DVersion', __version__,
|
||||
'-DInstallVersion', sv + '.0',
|
||||
|
@ -138,7 +138,7 @@ ProjectID
|
||||
DA98A0C6-9102-73EC-2516-B147E972D3F7
|
||||
|
||||
ProjectVersion
|
||||
1.2.7.0
|
||||
1.2.12.0
|
||||
|
||||
SaveOnlyToplevelDirs
|
||||
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
|
||||
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 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
|
||||
@ -513,7 +514,7 @@ false
|
||||
1
|
||||
|
||||
3EA07B17-04D8-6508-B535-96CC7173B49A,Conditions
|
||||
{0 conditions}
|
||||
{1 condition}
|
||||
|
||||
3EA07B17-04D8-6508-B535-96CC7173B49A,Message,subst
|
||||
1
|
||||
@ -1100,6 +1101,9 @@ AAFE58A0-2DFB-CA20-1F6E-D3815F885996,Alias
|
||||
AIX-ppc,Active
|
||||
No
|
||||
|
||||
AIX-ppc,BuildSeparateArchives
|
||||
No
|
||||
|
||||
AIX-ppc,DefaultDirectoryPermission
|
||||
0755
|
||||
|
||||
@ -1286,6 +1290,26 @@ CFBE4459-450B-1FAB-3422-609544334AA2,String
|
||||
D79DC0D2-38BC-9D9F-2DF4-3C76D89BF933,ExitType
|
||||
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
|
||||
{2 conditions}
|
||||
|
||||
@ -1475,6 +1499,9 @@ FBA33088-C809-DD6B-D337-EADBF1CEE966,String
|
||||
FreeBSD-4-x86,Active
|
||||
No
|
||||
|
||||
FreeBSD-4-x86,BuildSeparateArchives
|
||||
No
|
||||
|
||||
FreeBSD-4-x86,DefaultDirectoryPermission
|
||||
0755
|
||||
|
||||
@ -1526,6 +1553,9 @@ FreeBSD-4-x86,RootInstallDir
|
||||
FreeBSD-x86,Active
|
||||
No
|
||||
|
||||
FreeBSD-x86,BuildSeparateArchives
|
||||
No
|
||||
|
||||
FreeBSD-x86,DefaultDirectoryPermission
|
||||
0755
|
||||
|
||||
@ -1577,6 +1607,9 @@ FreeBSD-x86,RootInstallDir
|
||||
HPUX-hppa,Active
|
||||
No
|
||||
|
||||
HPUX-hppa,BuildSeparateArchives
|
||||
No
|
||||
|
||||
HPUX-hppa,DefaultDirectoryPermission
|
||||
0755
|
||||
|
||||
@ -1628,6 +1661,9 @@ HPUX-hppa,RootInstallDir
|
||||
Linux-x86,Active
|
||||
No
|
||||
|
||||
Linux-x86,BuildSeparateArchives
|
||||
No
|
||||
|
||||
Linux-x86,DefaultDirectoryPermission
|
||||
0755
|
||||
|
||||
@ -1679,6 +1715,9 @@ Linux-x86,RootInstallDir
|
||||
Solaris-sparc,Active
|
||||
No
|
||||
|
||||
Solaris-sparc,BuildSeparateArchives
|
||||
No
|
||||
|
||||
Solaris-sparc,DefaultDirectoryPermission
|
||||
0755
|
||||
|
||||
@ -1730,6 +1769,9 @@ Solaris-sparc,RootInstallDir
|
||||
TarArchive,Active
|
||||
No
|
||||
|
||||
TarArchive,BuildSeparateArchives
|
||||
No
|
||||
|
||||
TarArchive,CompressionLevel
|
||||
6
|
||||
|
||||
@ -1790,9 +1832,15 @@ TarArchive,VirtualTextMap
|
||||
Windows,Active
|
||||
Yes
|
||||
|
||||
Windows,BuildSeparateArchives
|
||||
No
|
||||
|
||||
Windows,Executable
|
||||
<%AppName%>-<%Version%><%Ext%>
|
||||
|
||||
Windows,FileDescription
|
||||
{<%AppName%> <%Version%> Setup}
|
||||
|
||||
Windows,IncludeTWAPI
|
||||
Yes
|
||||
|
||||
@ -1829,6 +1877,9 @@ Windows,WindowsIcon
|
||||
ZipArchive,Active
|
||||
No
|
||||
|
||||
ZipArchive,BuildSeparateArchives
|
||||
No
|
||||
|
||||
ZipArchive,CompressionLevel
|
||||
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.ptempfile import TemporaryDirectory
|
||||
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.customize.ui import run_plugins_on_preprocess
|
||||
|
||||
@ -25,9 +25,36 @@ def lit2opf(path, tdir, opts):
|
||||
print 'Exploding LIT file:', path
|
||||
reader = LitReader(path)
|
||||
reader.extract_content(tdir, False)
|
||||
for f in walk(tdir):
|
||||
if f.lower().endswith('.opf'):
|
||||
return f
|
||||
opf = None
|
||||
for opf in walk(tdir):
|
||||
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):
|
||||
from calibre.ebooks.mobi.reader import MobiReader
|
||||
|
@ -6,33 +6,28 @@ Support for reading the metadata from a LIT file.
|
||||
|
||||
import sys, cStringIO, os
|
||||
|
||||
from calibre import relpath
|
||||
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
|
||||
|
||||
def get_metadata(stream):
|
||||
try:
|
||||
litfile = LitReader(stream)
|
||||
src = litfile.meta.encode('utf-8')
|
||||
mi = OPFReader(cStringIO.StringIO(src), dir=os.getcwd())
|
||||
cover_url, cover_item = mi.cover, None
|
||||
if cover_url:
|
||||
cover_url = relpath(cover_url, os.getcwd())
|
||||
for item in litfile.manifest.values():
|
||||
if item.path == cover_url:
|
||||
cover_item = item.internal
|
||||
if cover_item is not None:
|
||||
ext = cover_url.rpartition('.')[-1]
|
||||
if not ext:
|
||||
ext = 'jpg'
|
||||
else:
|
||||
ext = ext.lower()
|
||||
cd = litfile.get_file('/data/' + cover_item)
|
||||
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'])
|
||||
litfile = LitReader(stream)
|
||||
src = litfile.meta.encode('utf-8')
|
||||
opf = OPF(cStringIO.StringIO(src), os.getcwd())
|
||||
mi = MetaInformation(opf)
|
||||
covers = []
|
||||
for item in opf.iterguide():
|
||||
if 'cover' not in item.get('type', '').lower():
|
||||
continue
|
||||
href = item.get('href', '')
|
||||
candidates = [href, href.replace('&', '%26')]
|
||||
for item in litfile.manifest.values():
|
||||
if item.path in candidates:
|
||||
covers.append(item.internal)
|
||||
break
|
||||
covers = [litfile.get_file('/data/' + i) for i in covers]
|
||||
covers.sort(cmp=lambda x, y:cmp(len(x), len(y)))
|
||||
mi.cover_data = ('jpg', covers[-1])
|
||||
return mi
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def __init__(self, stream, basedir=os.getcwdu()):
|
||||
def __init__(self, stream, basedir=os.getcwdu(), unquote_urls=True):
|
||||
if not hasattr(stream, 'read'):
|
||||
stream = open(stream, 'rb')
|
||||
self.basedir = self.base_dir = basedir
|
||||
@ -446,7 +446,8 @@ class OPF(object):
|
||||
if not self.metadata:
|
||||
raise ValueError('Malformed OPF file: No <metadata> element')
|
||||
self.metadata = self.metadata[0]
|
||||
self.unquote_urls()
|
||||
if unquote_urls:
|
||||
self.unquote_urls()
|
||||
self.manifest = Manifest()
|
||||
m = self.manifest_path(self.root)
|
||||
if m:
|
||||
|
@ -311,7 +311,7 @@ class MobiReader(object):
|
||||
opf.cover = 'images/%05d.jpg'%(self.book_header.exth.cover_offset+1)
|
||||
manifest = [(htmlfile, 'text/x-oeb1-document')]
|
||||
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'))
|
||||
|
||||
opf.create_manifest(manifest)
|
||||
@ -451,7 +451,7 @@ class MobiReader(object):
|
||||
image_index += 1
|
||||
try:
|
||||
im = PILImage.open(buf)
|
||||
except IOError, e:
|
||||
except IOError:
|
||||
continue
|
||||
|
||||
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:
|
||||
mi = MetaInformation(mr.name, [_('Unknown')])
|
||||
else:
|
||||
tdir = tempfile.mkdtemp('_mobi_meta', __appname__+'_')
|
||||
atexit.register(shutil.rmtree, tdir)
|
||||
#print tdir
|
||||
mr.extract_images([], tdir)
|
||||
mi = mr.create_opf('dummy.html')
|
||||
if mi.cover:
|
||||
cover = os.path.join(tdir, mi.cover)
|
||||
if not os.access(cover, os.R_OK):
|
||||
fname = os.path.basename(cover)
|
||||
match = re.match(r'(\d+)(.+)', fname)
|
||||
if match:
|
||||
num, ext = int(match.group(1), 10), match.group(2)
|
||||
while num > 0:
|
||||
num -= 1
|
||||
candidate = os.path.join(os.path.dirname(cover), '%05d%s'%(num, ext))
|
||||
if os.access(candidate, os.R_OK):
|
||||
cover = candidate
|
||||
break
|
||||
if os.access(cover, os.R_OK):
|
||||
mi.cover_data = ('JPEG', open(os.path.join(tdir, cover), 'rb').read())
|
||||
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
|
||||
try:
|
||||
if hasattr(mr.book_header.exth, 'cover_offset'):
|
||||
cover_index = mr.book_header.first_image_index + mr.book_header.exth.cover_offset
|
||||
data = mr.sections[cover_index][0]
|
||||
else:
|
||||
data = mr.sections[mr.book_header.first_image_index][0]
|
||||
buf = cStringIO.StringIO(data)
|
||||
im = PILImage.open(buf)
|
||||
obuf = cStringIO.StringIO()
|
||||
im.convert('RGBA').save(obuf, format='JPEG')
|
||||
mi.cover_data = ('jpg', obuf.getvalue())
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return mi
|
||||
|
||||
|
||||
def option_parser():
|
||||
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):
|
||||
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):
|
||||
for row in rows:
|
||||
@ -262,6 +263,16 @@ class BooksModel(QAbstractTableModel):
|
||||
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):
|
||||
try:
|
||||
col = self.column_map.index(self.sorted_on[0])
|
||||
|
@ -478,7 +478,7 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
self.raise_()
|
||||
self.activateWindow()
|
||||
elif msg.startswith('refreshdb:'):
|
||||
self.library_view.model().resort()
|
||||
self.library_view.model().refresh()
|
||||
self.library_view.model().research()
|
||||
else:
|
||||
print msg
|
||||
|
@ -29,5 +29,5 @@ def server_config(defaults=None):
|
||||
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.')
|
||||
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
|
||||
|
@ -40,7 +40,7 @@ function create_table_headers() {
|
||||
|
||||
|
||||
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) {
|
||||
|
@ -26,6 +26,7 @@ entry_points = {
|
||||
'opf-meta = calibre.ebooks.metadata.opf2:main',
|
||||
'odt-meta = calibre.ebooks.metadata.odt:main',
|
||||
'epub-meta = calibre.ebooks.metadata.epub:main',
|
||||
'mobi-meta = calibre.ebooks.metadata.mobi:main',
|
||||
'txt2lrf = calibre.ebooks.lrf.txt.convert_from:main',
|
||||
'html2lrf = calibre.ebooks.lrf.html.convert_from: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',
|
||||
'markdown-calibre', 'calibre-debug', 'fb2-meta',
|
||||
'calibre-fontconfig', 'calibre-parallel', 'odt-meta',
|
||||
'rb-meta', 'imp-meta'):
|
||||
'rb-meta', 'imp-meta', 'mobi-meta'):
|
||||
continue
|
||||
|
||||
help2man = ('help2man', prog, '--name', 'part of %s'%__appname__,
|
||||
|
@ -5,9 +5,8 @@ Dynamic language lookup of translations for user-visible strings.
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
|
||||
|
||||
import sys
|
||||
from cStringIO import StringIO
|
||||
from gettext import GNUTranslations, NullTranslations
|
||||
from gettext import GNUTranslations
|
||||
from calibre.translations.compiled import translations
|
||||
|
||||
__all__ = ['translate']
|
||||
@ -23,5 +22,5 @@ def translate(lang, text):
|
||||
trans = GNUTranslations(buf)
|
||||
_CACHE[lang] = trans
|
||||
if trans is None:
|
||||
return _(text)
|
||||
return getattr(__builtins__, '_', lambda x: x)(text)
|
||||
return trans.ugettext(text)
|
||||
|
@ -23,7 +23,7 @@ recipe_modules = ['recipe_' + r for r in (
|
||||
'spiegel_int', 'themarketticker', 'tomshardware', 'xkcd', 'ftd', 'zdnet',
|
||||
'joelonsoftware', 'telepolis', 'common_dreams', 'nin', 'tomshardware_de',
|
||||
'pagina12', 'infobae', 'ambito', 'elargentino', 'sueddeutsche', 'the_age',
|
||||
'laprensa',
|
||||
'laprensa', 'amspec',
|
||||
)]
|
||||
|
||||
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