Sync to trunk

This commit is contained in:
John Schember 2009-01-22 16:48:21 -05:00
commit 37317ee345
16 changed files with 231 additions and 70 deletions

View File

@ -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',

View File

@ -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

View File

@ -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)
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): for f in walk(tdir):
if f.lower().endswith('.opf'): with open(f, 'r+b') as f:
return 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

View File

@ -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')
mi = OPFReader(cStringIO.StringIO(src), dir=os.getcwd()) opf = OPF(cStringIO.StringIO(src), os.getcwd())
cover_url, cover_item = mi.cover, None mi = MetaInformation(opf)
if cover_url: covers = []
cover_url = relpath(cover_url, os.getcwd()) 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(): for item in litfile.manifest.values():
if item.path == cover_url: if item.path in candidates:
cover_item = item.internal covers.append(item.internal)
if cover_item is not None: break
ext = cover_url.rpartition('.')[-1] covers = [litfile.get_file('/data/' + i) for i in covers]
if not ext: covers.sort(cmp=lambda x, y:cmp(len(x), len(y)))
ext = 'jpg' mi.cover_data = ('jpg', covers[-1])
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'])
return mi return mi
def main(args=sys.argv): def main(args=sys.argv):

View 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())

View File

@ -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,6 +446,7 @@ 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]
if unquote_urls:
self.unquote_urls() self.unquote_urls()
self.manifest = Manifest() self.manifest = Manifest()
m = self.manifest_path(self.root) m = self.manifest_path(self.root)

View File

@ -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,32 +476,24 @@ 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)
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: else:
path = os.path.join(tdir, 'images', '00001.jpg') data = mr.sections[mr.book_header.first_image_index][0]
if os.access(path, os.R_OK): buf = cStringIO.StringIO(data)
mi.cover_data = ('JPEG', open(path, 'rb').read()) 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 return mi
def option_parser(): def option_parser():
from calibre.utils.config import OptionParser from calibre.utils.config import OptionParser
parser = OptionParser(usage=_('%prog [options] myebook.mobi')) parser = OptionParser(usage=_('%prog [options] myebook.mobi'))

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

View File

@ -162,6 +162,7 @@ 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)
if rows:
self.refresh_rows(rows, current_row=current_row) self.refresh_rows(rows, current_row=current_row)
def refresh_rows(self, rows, current_row=-1): def refresh_rows(self, rows, current_row=-1):
@ -262,6 +263,16 @@ class BooksModel(QAbstractTableModel):
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])

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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__,

View File

@ -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)

View File

@ -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

View 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'