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
09988d93de
@ -6,7 +6,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os, socket, struct, subprocess, glob
|
||||
import os, socket, struct, subprocess
|
||||
from distutils.spawn import find_executable
|
||||
|
||||
from PyQt4 import pyqtconfig
|
||||
@ -91,33 +91,31 @@ podofo_inc = '/usr/include/podofo'
|
||||
podofo_lib = '/usr/lib'
|
||||
|
||||
if iswindows:
|
||||
fc_inc = r'C:\cygwin\home\kovid\fontconfig\include\fontconfig'
|
||||
fc_lib = r'C:\cygwin\home\kovid\fontconfig\lib'
|
||||
poppler_inc_dirs = consolidate('POPPLER_INC_DIR',
|
||||
(r'C:\cygwin\home\kovid\poppler\poppler-source\poppler;'
|
||||
r'C:\cygwin\home\kovid\poppler\poppler-source;'
|
||||
r'C:\cygwin\home\kovid\poppler\poppler-build;'
|
||||
r'C:\cygwin\home\kovid\poppler\poppler-build\poppler'))
|
||||
popplerqt4_inc_dirs = poppler_inc_dirs + [poppler_inc_dirs[1]+r'\qt4']
|
||||
poppler_lib_dirs = consolidate('POPPLER_LIB_DIR',
|
||||
(r'C:\cygwin\home\kovid\poppler\poppler-build\qt4\src\Release;'
|
||||
r'C:\cygwin\home\kovid\poppler\poppler-build\Release'))
|
||||
popplerqt4_lib_dirs = poppler_lib_dirs
|
||||
poppler_libs = []
|
||||
poppler_objs = glob.glob(r'C:\cygwin\home\kovid\poppler\poppler-build\poppler.dir\Release\*.obj')
|
||||
popplerqt4_libs = poppler_libs + ['QtCore4', 'QtGui4']
|
||||
png_inc_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\include']
|
||||
png_lib_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\lib']
|
||||
png_libs = [r'libpng']
|
||||
jpg_lib_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\lib']
|
||||
prefix = r'C:\cygwin\home\kovid\sw'
|
||||
sw_inc_dir = os.path.join(prefix, 'include')
|
||||
sw_lib_dir = os.path.join(prefix, 'lib')
|
||||
fc_inc = os.path.join(sw_inc_dir, 'fontconfig')
|
||||
fc_lib = sw_lib_dir
|
||||
png_inc_dirs = [sw_inc_dir]
|
||||
png_lib_dirs = [sw_lib_dir]
|
||||
png_libs = ['png12']
|
||||
jpg_lib_dirs = [sw_lib_dir]
|
||||
jpg_libs = ['jpeg']
|
||||
ft_lib_dirs = [sw_lib_dir]
|
||||
ft_libs = ['freetype']
|
||||
poppler_inc_dirs = consolidate('POPPLER_INC_DIR',
|
||||
r'%s\poppler;%s'%(sw_inc_dir, sw_inc_dir))
|
||||
|
||||
popplerqt4_inc_dirs = poppler_inc_dirs + [poppler_inc_dirs[1]+r'\qt4']
|
||||
poppler_lib_dirs = consolidate('POPPLER_LIB_DIR', sw_lib_dir)
|
||||
popplerqt4_lib_dirs = poppler_lib_dirs
|
||||
poppler_libs = ['poppler']
|
||||
popplerqt4_libs = poppler_libs + ['QtCore4', 'QtGui4']
|
||||
magick_inc_dirs = [r'C:\cygwin\home\kovid\ImageMagick-6.5.6-Q16\include']
|
||||
magick_lib_dirs = [r'C:\cygwin\home\kovid\ImageMagick-6.5.6-Q16\lib']
|
||||
magick_libs = ['CORE_RL_wand_', 'CORE_RL_magick_']
|
||||
ft_lib_dirs = [r'C:\cygwin\home\\kovid\gnuwin32\lib']
|
||||
ft_libs = ['freetype']
|
||||
podofo_inc = 'C:\\podofo\\include\\podofo'
|
||||
podofo_lib = r'C:\podofo'
|
||||
podofo_inc = os.path.join(sw_inc_dir, 'podofo')
|
||||
podofo_lib = sw_lib_dir
|
||||
elif isosx:
|
||||
fc_inc = '/Users/kovid/fontconfig/include/fontconfig'
|
||||
fc_lib = '/Users/kovid/fontconfig/lib'
|
||||
@ -137,7 +135,7 @@ elif isosx:
|
||||
magick_libs = ['MagickWand', 'MagickCore']
|
||||
png_inc_dirs = consolidate('PNG_INC_DIR', '/usr/local/include')
|
||||
png_lib_dirs = consolidate('PNG_LIB_DIR', '/usr/local/lib')
|
||||
png_libs = ['png']
|
||||
png_libs = ['png12']
|
||||
else:
|
||||
# Include directories
|
||||
poppler_inc_dirs = pkgconfig_include_dirs('poppler',
|
||||
|
@ -16,7 +16,7 @@ from setup.build_environment import fc_inc, fc_lib, \
|
||||
fc_error, poppler_libs, poppler_lib_dirs, poppler_inc_dirs, podofo_inc, \
|
||||
podofo_lib, podofo_error, poppler_error, pyqt, OSX_SDK, NMAKE, \
|
||||
leopard_build, QMAKE, msvc, MT, win_inc, win_lib, png_inc_dirs, \
|
||||
magick_inc_dirs, magick_lib_dirs, png_lib_dirs, png_libs, poppler_objs, \
|
||||
magick_inc_dirs, magick_lib_dirs, png_lib_dirs, png_libs, \
|
||||
magick_error, magick_libs, ft_lib_dirs, ft_libs, jpg_libs, jpg_lib_dirs
|
||||
MT
|
||||
isunix = islinux or isosx
|
||||
@ -26,8 +26,8 @@ make = 'make' if isunix else NMAKE
|
||||
class Extension(object):
|
||||
|
||||
def absolutize(self, paths):
|
||||
return [x if os.path.isabs(x) else os.path.join(SRC, x.replace('/',
|
||||
os.sep)) for x in paths]
|
||||
return list(set([x if os.path.isabs(x) else os.path.join(SRC, x.replace('/',
|
||||
os.sep)) for x in paths]))
|
||||
|
||||
|
||||
def __init__(self, name, sources, **kwargs):
|
||||
@ -61,7 +61,6 @@ extensions = [
|
||||
libraries=poppler_libs+magick_libs+png_libs+ft_libs+jpg_libs+pdfreflow_libs,
|
||||
lib_dirs=poppler_lib_dirs+magick_lib_dirs+png_lib_dirs+ft_lib_dirs+jpg_lib_dirs,
|
||||
inc_dirs=poppler_inc_dirs+magick_inc_dirs+png_inc_dirs,
|
||||
extra_objs=poppler_objs,
|
||||
error=reflow_error,
|
||||
cflags=['-DPNG_SKIP_SETJMP_CHECK'] if islinux else []
|
||||
),
|
||||
@ -161,7 +160,7 @@ if isosx:
|
||||
if iswindows:
|
||||
cc = cxx = msvc.cc
|
||||
cflags = '/c /nologo /Ox /MD /W3 /EHsc /DNDEBUG'.split()
|
||||
ldflags = '/DLL /nologo /INCREMENTAL:NO'.split()
|
||||
ldflags = '/DLL /nologo /INCREMENTAL:NO /NODEFAULTLIB:libcmt.lib'.split()
|
||||
#cflags = '/c /nologo /Ox /MD /W3 /EHsc /Zi'.split()
|
||||
#ldflags = '/DLL /nologo /INCREMENTAL:NO /DEBUG'.split()
|
||||
|
||||
@ -372,6 +371,8 @@ class BuildPDF2XML(Command):
|
||||
|
||||
def run(self, opts):
|
||||
dest = os.path.expanduser('~/bin/pdf2xml')
|
||||
if iswindows:
|
||||
dest = r'C:\cygwin\home\kovid\sw\bin\pdf2xml.exe'
|
||||
odest = self.j(self.d(self.SRC), 'build', 'objects', 'pdf2xml')
|
||||
if not os.path.exists(odest):
|
||||
os.makedirs(odest)
|
||||
@ -380,11 +381,15 @@ class BuildPDF2XML(Command):
|
||||
for src in reflow_sources:
|
||||
if src.endswith('python.cpp'):
|
||||
continue
|
||||
obj = self.j(odest, self.b(src+'.o'))
|
||||
obj = self.j(odest, self.b(src+('.obj' if iswindows else '.o')))
|
||||
if self.newer(obj, [src]+reflow_headers):
|
||||
cmd = ['g++', '-pthread', '-pedantic', '-ggdb', '-c', '-Wall', '-I/usr/include/poppler',
|
||||
cmd = [cxx, '-pthread', '-pedantic', '-ggdb', '-c', '-Wall', '-I/usr/include/poppler',
|
||||
'-I/usr/include/ImageMagick',
|
||||
'-DPDF2XML', '-o', obj, src]
|
||||
if iswindows:
|
||||
cmd = [cxx, '/c', '/MD', '/W3', '/EHsc', '/Zi', '/DPDF2XML']
|
||||
cmd += ['-I'+x for x in poppler_inc_dirs+magick_inc_dirs]
|
||||
cmd += ['/Fo'+obj, src]
|
||||
self.info(*cmd)
|
||||
subprocess.check_call(cmd)
|
||||
objects.append(obj)
|
||||
@ -392,6 +397,12 @@ class BuildPDF2XML(Command):
|
||||
if self.newer(dest, objects):
|
||||
cmd = ['g++', '-g', '-o', dest]+objects+['-lpoppler', '-lMagickWand',
|
||||
'-lpng', '-lpthread']
|
||||
if iswindows:
|
||||
cmd = [msvc.linker] + '/INCREMENTAL:NO /DEBUG /NODEFAULTLIB:libcmt.lib'.split()
|
||||
cmd += ['/LIBPATH:'+x for x in magick_lib_dirs+poppler_lib_dirs]
|
||||
cmd += [x+'.lib' for x in
|
||||
png_libs+magick_libs+poppler_libs+ft_libs+jpg_libs+pdfreflow_libs]
|
||||
cmd += ['/OUT:'+dest] + objects
|
||||
self.info(*cmd)
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
@ -24,6 +24,7 @@ class LinuxFreeze(Command):
|
||||
|
||||
is64bit = platform.architecture()[0] == '64bit'
|
||||
arch = 'x86_64' if is64bit else 'i686'
|
||||
ffi = '/usr/lib/libffi.so.5' if is64bit else '/usr/lib/gcc/i686-pc-linux-gnu/4.4.1/libffi.so.4'
|
||||
|
||||
|
||||
QTDIR = '/usr/lib/qt4'
|
||||
@ -58,6 +59,7 @@ class LinuxFreeze(Command):
|
||||
'/usr/lib/libgthread-2.0.so.0',
|
||||
'/usr/lib/gcc/***-pc-linux-gnu/4.4.1/libstdc++.so.6'.replace('***',
|
||||
arch),
|
||||
ffi,
|
||||
'/usr/lib/libpng12.so.0',
|
||||
'/usr/lib/libexslt.so.0',
|
||||
'/usr/lib/libMagickWand.so.2',
|
||||
|
@ -232,10 +232,6 @@ test
|
||||
}
|
||||
FileGroup ::BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9 -setup Install -active Yes -platforms {AIX-ppc FreeBSD-4-x86 FreeBSD-x86 HPUX-hppa Linux-x86 Solaris-sparc Windows TarArchive ZipArchive FreeBSD-5-x86 FreeBSD-6-x86 FreeBSD-7-x86 Linux-x86_64 Solaris-x86} -name {Program Files} -parent FileGroups
|
||||
File ::8E5D85A4-7608-47A1-CF7C-309060D5FF40 -filemethod {Always overwrite files} -type dir -directory <%InstallDir%> -name /home/kovid/work/calibre/build/py2exe -parent BEF8D398-58BA-1F66-39D6-D4A63D5BEEF9
|
||||
File ::FC870EE7-667B-481F-113B-B4504DFCCFA5 -type dir -name bin -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::377C588B-B324-CA09-ED49-4DB5F82A15ED -type dir -name etc -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::55DE4B9F-0881-FF51-E2BA-EC72B5D3425C -type dir -name fonts -parent 377C588B-B324-CA09-ED49-4DB5F82A15ED
|
||||
File ::32D7DBE0-E0B1-5BDD-66C5-2A13D8BC8F90 -name fonts.conf -parent 55DE4B9F-0881-FF51-E2BA-EC72B5D3425C
|
||||
File ::B95D03D4-EA59-F00E-59E1-BA05758879DA -type dir -name imageformats -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::A624029D-AE0F-49A5-4DAC-7720CDCAB271 -name qmng4.dll -parent B95D03D4-EA59-F00E-59E1-BA05758879DA
|
||||
File ::C53E8AB9-30FC-730C-3DA3-851C9B4838A1 -name qmng4.exp -parent B95D03D4-EA59-F00E-59E1-BA05758879DA
|
||||
@ -362,7 +358,6 @@ File ::A6419A84-6C22-784E-6D84-D09972770770 -name unicodedata.pyd -parent 8E5D85
|
||||
File ::E658FBE0-5860-D041-12D3-76ADD18F804B -name servicemanager.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::C98A6FC4-E341-7FD4-005C-DA2B384E11D8 -name win32api.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::ADA36EEA-7DE1-447C-B1AB-A4908E65E2CD -name IM_MOD_RL_ipl_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::53C2EC15-850F-8F49-6425-C228FB6E6D0E -name libfontconfig-1.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::EDE6F457-C83F-C5FA-9AF4-38FDFF17D929 -name PIL._imagingtk.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::09D0906E-3611-3DB7-32CF-A140585694A7 -name win32pdh.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::4C84F0DC-7157-0C90-2062-180139B03E25 -name IM_MOD_RL_rgb_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
@ -385,7 +380,6 @@ File ::404A98F1-84FD-B6D0-B130-354EECD9253C -name IM_MOD_RL_emf_.dll -parent 8E5
|
||||
File ::17034C34-403E-B405-99C1-F80B7F00E27C -name log.xml -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::34E63A2C-65C5-0A84-ACF1-BD6A844D4579 -name pythoncom26.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::2F20484B-53B8-B08E-B691-C5B2D49A9CB4 -name QtWebKit4.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::8AF134C8-9189-3F9A-A081-9143FFD44C45 -name freetype6.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::E8A4442D-D0D3-31CD-997A-3CEB641CF5B7 -name IM_MOD_RL_mtv_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::0CA87D0B-5A04-1439-AEE8-C97072D47BA7 -name CORE_RL_tiff_.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::AC24F520-88D4-D1CF-5797-27C715CE8ACA -name pyexpat.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
@ -564,11 +558,18 @@ File ::8D7A36A6-4517-E995-E989-2E522E7A1438 -name calibre-smtp.exe.local -parent
|
||||
File ::9E4E5E8F-30C0-E631-9516-2AE01A5CA0E9 -name ebook-device.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::7BE6B538-70D5-A7EB-5F91-E14CE57B394B -name calibre-complete.exe.local -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::C4E40030-3EE0-8B05-E6B9-89E81433EE1F -name phonon4.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::C9967023-A4C2-856C-1D90-DC710105EBCD -name jpeg62.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::B1560042-C99B-9803-552E-21C15F0DFD85 -type dir -name resources -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::DEDE8BE9-D712-2770-A1EC-7E9164CC6D29 -name libpng12.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::2A8619DB-B715-CBF8-E711-C6B0C5FD9EF4 -name _elementtree.pyd -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::0924A77D-EDD2-FF33-560A-983053637A47 -name libexpat-1.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::F92DE458-3417-3474-E0E0-C2CB98CA452A -name libxml2.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::5243CC78-8F58-46D6-4CDB-98FE073F4966 -name libxml2.dll.manifest -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::6C13AD7D-4C52-05F7-21D7-6258D4ECD542 -name freetype.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::800D9AFB-00CF-043C-0096-77BB4A2CD629 -name fontconfig.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::3B4975F7-B38C-895A-F11F-04BDF303309E -name jpeg.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::BA7F0DB8-28CB-9E0C-AA32-C10A729813D5 -name libexpatw.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::54736356-200D-EE7B-5D46-62B198B8AAF5 -name libexpat.dll -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::620D5BA9-9652-2032-ED10-D3958F594AF4 -type dir -name fontconfig -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
File ::57DAE30B-1BBA-0D0B-8DB0-DCE473520E9C -name zlib1.dll.manifest -parent 8E5D85A4-7608-47A1-CF7C-309060D5FF40
|
||||
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 FreeBSD-5-x86 FreeBSD-6-x86 FreeBSD-7-x86 Linux-x86_64 Solaris-x86} -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 FreeBSD-5-x86 FreeBSD-6-x86 FreeBSD-7-x86 Linux-x86_64 Solaris-x86} -name Typical -parent SetupTypes
|
||||
|
||||
|
@ -9,13 +9,8 @@ Freeze app into executable using py2exe.
|
||||
QT_DIR = 'C:\\Qt\\4.5.2'
|
||||
LIBUSB_DIR = 'C:\\libusb'
|
||||
LIBUNRAR = 'C:\\Program Files\\UnrarDLL\\unrar.dll'
|
||||
POPPLER = 'C:\\cygwin\\home\\kovid\\poppler\\poppler-build'
|
||||
GNUWIN32 = r'C:\cygwin\home\kovid\gnuwin32'
|
||||
IMAGEMAGICK_DIR = 'C:\\ImageMagick'
|
||||
PDFTK = 'C:\\pdftk.exe'
|
||||
PODOFO = 'C:\\podofo'
|
||||
FONTCONFIG_DIR = 'C:\\fontconfig'
|
||||
VC90 = r'C:\VC90.CRT'
|
||||
SW = r'C:\cygwin\home\kovid\sw'
|
||||
|
||||
import sys
|
||||
|
||||
@ -193,36 +188,23 @@ class BuildEXE(bc):
|
||||
shutil.copyfile(f, os.path.join(tdir, os.path.basename(f)))
|
||||
print '\tAdding unrar'
|
||||
shutil.copyfile(LIBUNRAR, os.path.join(PY2EXE_DIR, os.path.basename(LIBUNRAR)))
|
||||
print '\tAdding poppler'
|
||||
for x in (r'pdftohtml.exe', 'freetype.dll'):
|
||||
shutil.copyfile(os.path.join(r'C:\cygwin\home\kovid\poppler-old\bin', x),
|
||||
os.path.join(PY2EXE_DIR, os.path.basename(x)))
|
||||
for x in ('jpeg62', 'zlib1', 'libpng12'):
|
||||
shutil.copy2(os.path.join(GNUWIN32, 'bin', x+'.dll'), PY2EXE_DIR)
|
||||
print '\tAdding podofo'
|
||||
for f in glob.glob(os.path.join(PODOFO, '*.dll')):
|
||||
shutil.copyfile(f, os.path.join(PY2EXE_DIR, os.path.basename(f)))
|
||||
|
||||
print '\tAdding ImageMagick'
|
||||
for f in os.listdir(IMAGEMAGICK_DIR):
|
||||
shutil.copyfile(os.path.join(IMAGEMAGICK_DIR, f), os.path.join(PY2EXE_DIR, f))
|
||||
print '\tCopying fontconfig'
|
||||
for f in glob.glob(os.path.join(FONTCONFIG_DIR, '*')):
|
||||
tgt = os.path.join(PY2EXE_DIR, os.path.basename(f))
|
||||
if os.path.isdir(f):
|
||||
shutil.copytree(f, tgt)
|
||||
else:
|
||||
shutil.copyfile(f, tgt)
|
||||
print '\tAdding misc binary deps'
|
||||
bindir = os.path.join(SW, 'bin')
|
||||
shutil.copy2(os.path.join(bindir, 'pdftohtml.exe'), PY2EXE_DIR)
|
||||
for pat in ('*.dll', '*.xml'):
|
||||
for f in glob.glob(os.path.join(bindir, pat)):
|
||||
shutil.copy2(f, PY2EXE_DIR)
|
||||
for x in ('Microsoft.VC90.CRT', 'zlib1.dll', 'libxml2.dll'):
|
||||
shutil.copy2(os.path.join(bindir, x+'.manifest'), PY2EXE_DIR)
|
||||
shutil.copytree(os.path.join(SW, 'etc', 'fonts'),
|
||||
os.path.join(PY2EXE_DIR, 'fontconfig'))
|
||||
|
||||
print
|
||||
print 'Doing DLL redirection' # See http://msdn.microsoft.com/en-us/library/ms682600(VS.85).aspx
|
||||
for f in glob.glob(os.path.join(PY2EXE_DIR, '*.exe')):
|
||||
open(f + '.local', 'w').write('\n')
|
||||
|
||||
print
|
||||
print 'Adding Windows runtime dependencies...'
|
||||
for f in glob.glob(os.path.join(VC90, '*')):
|
||||
shutil.copyfile(f, os.path.join(PY2EXE_DIR, os.path.basename(f)))
|
||||
|
||||
|
||||
def exe_factory(dest_base, script, icon_resources=None):
|
||||
@ -271,13 +253,12 @@ def main(args=sys.argv):
|
||||
'email.iterators',
|
||||
'email.generator',
|
||||
'win32process', 'win32api', 'msvcrt',
|
||||
'win32event', 'calibre.ebooks.lrf.any.*',
|
||||
'win32event',
|
||||
'sqlite3.dump',
|
||||
'BeautifulSoup', 'pyreadline',
|
||||
'pydoc', 'IPython.Extensions.*',
|
||||
'calibre.web.feeds.recipes.*',
|
||||
'calibre.gui2.convert.*',
|
||||
'calibre.ebooks.lrf.fonts.prs500.*',
|
||||
'PyQt4.QtWebKit', 'PyQt4.QtNetwork',
|
||||
],
|
||||
'packages' : ['PIL', 'lxml', 'cherrypy',
|
||||
|
167
setup/installer/windows/notes.rst
Normal file
167
setup/installer/windows/notes.rst
Normal file
@ -0,0 +1,167 @@
|
||||
Notes on setting up the windows development environment
|
||||
========================================================
|
||||
|
||||
Set CMAKE_PREFIX_PATH to C:\cygwin\home\kovid\sw
|
||||
|
||||
jpeg-7
|
||||
-------
|
||||
|
||||
Copy
|
||||
jconfig.vc to jconfig.h, makejsln.vc9 to jpeg.sln,
|
||||
makeasln.vc9 to apps.sln, makejvcp.vc9 to jpeg.vcproj,
|
||||
makecvcp.vc9 to cjpeg.vcproj, makedvcp.vc9 to djpeg.vcproj,
|
||||
maketvcp.vc9 to jpegtran.vcproj, makervcp.vc9 to rdjpgcom.vcproj, and
|
||||
makewvcp.vc9 to wrjpgcom.vcproj. (Note that the renaming is critical!)
|
||||
|
||||
Load jpeg.sln in Visual Studio
|
||||
|
||||
Goto Project->Properties->General Properties and change Configuration Type to dll
|
||||
|
||||
Add
|
||||
|
||||
#define USE_WINDOWS_MESSAGEBOX
|
||||
|
||||
to jconfig.h (this will cause error messages to show up in a box)
|
||||
|
||||
Change the definitions of GLOBAL and EXTERN in jmorecfg.h to
|
||||
#define GLOBAL(type) __declspec(dllexport) type
|
||||
#define EXTERN(type) extern __declspec(dllexport) type
|
||||
|
||||
cp build/jpeg-7/Release/jpeg.dll bin/
|
||||
cp build/jpeg-7/Release/jpeg.lib build/jpeg-7/Release/jpeg.exp
|
||||
cp build/jpeg-7/jerror.h build/jpeg-7/jpeglib.h build/jpeg-7/jconfig.h build/jpeg-7/jmorecfg.h include/
|
||||
|
||||
zlib
|
||||
------
|
||||
|
||||
nmake -f win32/Makefile.msc
|
||||
nmake -f win32/Makefile.msc test
|
||||
|
||||
cp zlib1.dll* ../../bin
|
||||
cp zlib.lib zdll.* ../../lib
|
||||
cp zconf.h zlib.h ../../include
|
||||
|
||||
|
||||
libpng
|
||||
---------
|
||||
|
||||
cp scripts/CMakelists.txt .
|
||||
mkdir build
|
||||
Run cmake-gui.exe with source directory . and build directory build
|
||||
You will have to point to sw/lib/zdll.lib and sw/include for zlib
|
||||
Also disable PNG_NO_STDIO and PNG_NO_CONSOLE_IO
|
||||
|
||||
Now open PNG.sln in VS2008
|
||||
Set Build type to Release
|
||||
|
||||
cp build/libpng-1.2.40/build/Release/libpng12.dll bin/
|
||||
cp build/libpng-1.2.40/build/Release/png12.* lib/
|
||||
cp build/libpng-1.2.40/png.h build/libpng-1.2.40/pngconf.h include/
|
||||
|
||||
freetype
|
||||
-----------
|
||||
|
||||
Edit *all copies* of the file ftoption.h and add to generate a .lib
|
||||
and a correct dll
|
||||
|
||||
#define FT_EXPORT(return_type) __declspec(dllexport) return_type
|
||||
#define FT_EXPORT_DEF(return_type) __declspec(dllexport) return_type
|
||||
|
||||
|
||||
VS 2008 .sln file is present, open it
|
||||
|
||||
Change active build type to release mutithreaded
|
||||
|
||||
Project->Properties->Configuration Properties
|
||||
change configuration type to dll
|
||||
|
||||
cp build/freetype-2.3.9/objs/release_mt/freetype.dll bin/
|
||||
|
||||
Now change configuration back to static for .lib
|
||||
cp build/freetype-2.3.9/objs/win32/vc2008/freetype239MT.lib lib/
|
||||
cp -rf build/freetype-2.3.9/include/* include/
|
||||
|
||||
expat
|
||||
--------
|
||||
|
||||
Has a VC 6 project file expat.dsw
|
||||
|
||||
Set active build to Relase and change build type to dll
|
||||
|
||||
cp build/expat-2.0.1/win32/bin/Release/*.lib lib/
|
||||
cp build/expat-2.0.1/win32/bin/Release/*.exp lib/
|
||||
cp build/expat-2.0.1/win32/bin/Release/*.dll bin/
|
||||
cp build/expat-2.0.1/lib/expat.h build/expat-2.0.1/lib/expat_external.h include/
|
||||
|
||||
libxml2
|
||||
-------------
|
||||
|
||||
cd win32
|
||||
cscript configure.js include=C:\cygwin\home\kovid\sw\include lib=C:\cygwin\home\sw\lib prefix=C:\cygwin\home\kovid\sw zlib=yes iconv=no
|
||||
nmake /f Makefile.msvc
|
||||
nmake /f Makefile.msvc install
|
||||
mv lib/libxml2.dll bin/
|
||||
cp ./build/libxml2-2.7.5/win32/bin.msvc/*.manifest bin/
|
||||
|
||||
kdewin32-msvc
|
||||
----------------
|
||||
|
||||
Get it from http://www.winkde.org/pub/kde/ports/win32/repository/kdesupport/
|
||||
mkdir build
|
||||
Run cmake
|
||||
|
||||
Set build type to release and configuration to dll
|
||||
|
||||
Build
|
||||
|
||||
cp build/kdewin32-msvc-0.3.9/build/include/* include/
|
||||
cp build/kdewin32-msvc-0.3.9/build/bin/Release/*.dll bin/
|
||||
cp build/kdewin32-msvc-0.3.9/build/bin/Release/*.lib lib/
|
||||
cp build/kdewin32-msvc-0.3.9/build/bin/Release/*.exp lib/
|
||||
cp -r build/kdewin32-msvc-0.3.9/include/msvc/ include/
|
||||
cp build/kdewin32-msvc-0.3.9/include/*.h include/
|
||||
|
||||
fontconfig
|
||||
---------------
|
||||
|
||||
Get it from http://www.winkde.org/pub/kde/ports/win32/repository/win32libs/
|
||||
mkdir build
|
||||
Remove subdirectory test from the bottom of CMakeLists.txt
|
||||
run cmake
|
||||
|
||||
Set build type to release and project config to dll
|
||||
Right click on the fontconfig project and select properties. Add sw/include/msvc to the include paths
|
||||
Build only fontconfig
|
||||
|
||||
cp build/fontconfig-msvc-2.4.2-3/build/src/Release/*.dll bin
|
||||
cp build/fontconfig-msvc-2.4.2-3/build/src/Release/*.lib lib
|
||||
cp build/fontconfig-msvc-2.4.2-3/build/src/Release/*.exp lib
|
||||
cp -r build/fontconfig-msvc-2.4.2-3/fontconfig/ include/
|
||||
|
||||
Also install the etc files from the font-config-bin archive from kde win32libs
|
||||
It contains correct fonts.conf etc.
|
||||
|
||||
|
||||
poppler
|
||||
-------------
|
||||
|
||||
In Cmake: disable GTK, Qt, OPenjpeg, zlib, lcms, gtk_tests, qt_tests. Enable qt4, jpeg, png and zlib
|
||||
|
||||
NOTE: poppler must be built as a static library, unless you build the qt4 bindings
|
||||
|
||||
Now do the same for the pdftohtml project
|
||||
|
||||
cp poppler/*.h ~/sw/include/poppler && cp goo/*.h ~/sw/include/poppler/goo && cp splash/*.h ~/sw/include/poppler/splash && cp build/Release/poppler.lib ../../lib/ && cp build/utils/Release/*.exe ../../bin/
|
||||
|
||||
|
||||
podofo
|
||||
----------
|
||||
|
||||
Add the following three lines near the top of CMakeLists.txt
|
||||
SET(WANT_LIB64 FALSE)
|
||||
SET(PODOFO_BUILD_SHARED TRUE)
|
||||
SET(PODOFO_BUILD_STATIC FALSE)
|
||||
|
||||
cp build/podofo-0.7.0/build/src/Release/podofo.dll bin/
|
||||
cp build/podofo-0.7.0/build/src/Release/podofo.lib lib/
|
||||
cp build/podofo-0.7.0/build/src/Release/podofo.exp lib/
|
@ -2,7 +2,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = 'calibre'
|
||||
__version__ = '0.6.14'
|
||||
__version__ = '0.6.16'
|
||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
|
||||
import re
|
||||
|
@ -39,7 +39,7 @@ def get_metadata(stream, cover=True):
|
||||
if cover and 'cover' in info:
|
||||
data = info['cover']
|
||||
if data is None:
|
||||
prints(title, 'is an encrypted document, cover extraction not allowed.')
|
||||
prints(title, 'has no pages, cover extraction impossible.')
|
||||
else:
|
||||
mi.cover_data = ('png', data)
|
||||
|
||||
|
@ -52,7 +52,7 @@ extern "C" {
|
||||
reflow = new Reflow(pdfdata, size);
|
||||
info = reflow->get_info();
|
||||
if (PyObject_IsTrue(cover)) {
|
||||
if (!reflow->is_locked() && reflow->numpages() > 0) {
|
||||
if (reflow->numpages() > 0) {
|
||||
vector<char> *data = reflow->render_first_page();
|
||||
if (data && data->size() > 0) {
|
||||
PyObject *d = PyBytes_FromStringAndSize(&((*data)[0]), data->size());
|
||||
@ -168,6 +168,8 @@ extern "C" {
|
||||
int main(int argc, char **argv) {
|
||||
char *memblock;
|
||||
ifstream::pos_type size;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
if (argc != 2) {
|
||||
cerr << "Usage: " << argv[0] << " file.pdf" << endl;
|
||||
@ -186,7 +188,6 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
try {
|
||||
Reflow reflow(memblock, size);
|
||||
reflow.render();
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <Outline.h>
|
||||
#include <PDFDocEncoding.h>
|
||||
#include <poppler/ErrorCodes.h>
|
||||
#include <goo/GooList.h>
|
||||
#include <SplashOutputDev.h>
|
||||
#include <splash/SplashBitmap.h>
|
||||
@ -149,7 +150,7 @@ string XMLString::str() const {
|
||||
}
|
||||
|
||||
XMLString::~XMLString() {
|
||||
delete this->text; delete this->x_right;
|
||||
delete this->text; delete this->x_right; delete this->xml_text;
|
||||
}
|
||||
|
||||
|
||||
@ -684,6 +685,7 @@ void XMLOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
|
||||
Reflow::Reflow(char *pdfdata, size_t sz) :
|
||||
pdfdata(pdfdata), current_font_size(-1), doc(NULL), obj()
|
||||
{
|
||||
int err;
|
||||
this->obj.initNull();
|
||||
if (globalParams == NULL) {
|
||||
globalParams = new GlobalParams();
|
||||
@ -694,9 +696,14 @@ Reflow::Reflow(char *pdfdata, size_t sz) :
|
||||
this->doc = new PDFDoc(str, NULL, NULL);
|
||||
|
||||
if (!this->doc->isOk()) {
|
||||
err = this->doc->getErrorCode();
|
||||
ostringstream stm;
|
||||
if (err == errEncrypted)
|
||||
stm << "PDF is password protected.";
|
||||
else {
|
||||
stm << "Failed to open PDF file";
|
||||
stm << " with error code: " << doc->getErrorCode();
|
||||
stm << " with error code: " << err;
|
||||
}
|
||||
delete this->doc;
|
||||
this->doc = NULL;
|
||||
throw ReflowException(stm.str().c_str());
|
||||
@ -706,9 +713,6 @@ Reflow::Reflow(char *pdfdata, size_t sz) :
|
||||
|
||||
void
|
||||
Reflow::render() {
|
||||
if (this->doc->isEncrypted()) {
|
||||
throw ReflowException("Document is encrypted.");
|
||||
}
|
||||
|
||||
if (!this->doc->okToCopy())
|
||||
cout << "Warning, this document has the copy protection flag set, ignoring." << endl;
|
||||
@ -851,7 +855,6 @@ string Reflow::decode_info_string(Dict *info, const char *key) const {
|
||||
|
||||
vector<char>* Reflow::render_first_page(bool use_crop_box, double x_res,
|
||||
double y_res) {
|
||||
if (this->is_locked()) throw ReflowException("Document is locked.");
|
||||
if (this->numpages() < 1) throw ReflowException("Document has no pages.");
|
||||
globalParams->setTextEncoding(encoding);
|
||||
globalParams->setEnableFreeType(yes);
|
||||
|
@ -9,7 +9,7 @@ from PyQt4.Qt import QThread, SIGNAL, QObject, QTimer, Qt, \
|
||||
QProgressDialog
|
||||
|
||||
from calibre.gui2.dialogs.progress import ProgressDialog
|
||||
from calibre.gui2 import question_dialog, error_dialog
|
||||
from calibre.gui2 import question_dialog, error_dialog, info_dialog
|
||||
from calibre.ebooks.metadata.opf2 import OPF
|
||||
from calibre.ebooks.metadata import MetaInformation
|
||||
from calibre.constants import preferred_encoding
|
||||
@ -45,6 +45,7 @@ class RecursiveFind(QThread):
|
||||
def run(self):
|
||||
root = os.path.abspath(self.path)
|
||||
self.books = []
|
||||
try:
|
||||
for dirpath in os.walk(root):
|
||||
if self.canceled:
|
||||
return
|
||||
@ -52,6 +53,14 @@ class RecursiveFind(QThread):
|
||||
_('Searching in')+' '+dirpath[0])
|
||||
self.books += list(self.db.find_books_in_directory(dirpath[0],
|
||||
self.single_book_per_directory))
|
||||
except Exception, err:
|
||||
try:
|
||||
msg = unicode(err)
|
||||
except:
|
||||
msg = repr(err)
|
||||
self.emit(SIGNAL('found(PyQt_PyObject)'), msg)
|
||||
return
|
||||
|
||||
self.books = [formats for formats in self.books if formats]
|
||||
|
||||
if not self.canceled:
|
||||
@ -177,6 +186,15 @@ class Adder(QObject):
|
||||
self.rfind.start()
|
||||
|
||||
def add(self, books):
|
||||
if isinstance(books, basestring):
|
||||
error_dialog(self.pd, _('Path error'),
|
||||
_('The specified directory could not be processed.'),
|
||||
det_msg=books, show=True)
|
||||
return self.canceled()
|
||||
if not books:
|
||||
info_dialog(self.pd, _('No books'),
|
||||
_('No books found'), show=True)
|
||||
return self.canceled()
|
||||
books = [[b] if isinstance(b, basestring) else b for b in books]
|
||||
self.rfind = None
|
||||
from calibre.ebooks.metadata.worker import read_metadata
|
||||
|
@ -32,7 +32,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="opt_max_toc_links"/>
|
||||
<widget class="QSpinBox" name="opt_max_toc_links">
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
|
@ -1194,16 +1194,23 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
|
||||
previous = self.library_view.currentIndex()
|
||||
rows = [x.row() for x in \
|
||||
self.library_view.selectionModel().selectedRows()]
|
||||
num = 0
|
||||
if bulk or (bulk is None and len(book_ids) > 1):
|
||||
self.__bulk_queue = convert_bulk_ebook(self, self.queue_convert_jobs,
|
||||
self.library_view.model().db, book_ids,
|
||||
out_format=prefs['output_format'], args=(rows, previous,
|
||||
self.book_converted))
|
||||
num = len(self.__bulk_queue.book_ids)
|
||||
else:
|
||||
jobs, changed, bad = convert_single_ebook(self,
|
||||
self.library_view.model().db, book_ids, out_format=prefs['output_format'])
|
||||
self.queue_convert_jobs(jobs, changed, bad, rows, previous,
|
||||
self.book_converted)
|
||||
num = len(jobs)
|
||||
|
||||
if num > 0:
|
||||
self.status_bar.showMessage(_('Starting conversion of %d book(s)') %
|
||||
num, 2000)
|
||||
|
||||
def queue_convert_jobs(self, jobs, changed, bad, rows, previous,
|
||||
converted_func, extra_job_args=[]):
|
||||
|
@ -75,6 +75,13 @@ class TagTreeItem(object):
|
||||
elif self.type == self.TAG:
|
||||
self.tag, self.icon_map = data, list(map(QVariant, icon_map))
|
||||
|
||||
def __str__(self):
|
||||
if self.type == self.ROOT:
|
||||
return 'ROOT'
|
||||
if self.type == self.CATEGORY:
|
||||
return 'CATEGORY:'+self.name+':%d'%len(self.children)
|
||||
return 'TAG:'+self.tag.name
|
||||
|
||||
def row(self):
|
||||
if self.parent is not None:
|
||||
return self.parent.children.index(self)
|
||||
@ -132,11 +139,12 @@ class TagsModel(QAbstractItemModel):
|
||||
for tag in data[r]:
|
||||
t = TagTreeItem(parent=c, data=tag, icon_map=self.icon_map)
|
||||
|
||||
self.refresh()
|
||||
self.db.add_listener(self.database_changed)
|
||||
self.connect(self, SIGNAL('need_refresh()'), self.refresh,
|
||||
Qt.QueuedConnection)
|
||||
|
||||
def database_changed(self, event, ids):
|
||||
self.refresh()
|
||||
self.emit(SIGNAL('need_refresh()'))
|
||||
|
||||
def refresh(self):
|
||||
data = self.db.get_categories(config['sort_by_popularity'])
|
||||
@ -167,6 +175,13 @@ class TagsModel(QAbstractItemModel):
|
||||
item = index.internalPointer()
|
||||
return item.data(role)
|
||||
|
||||
def headerData(self, *args):
|
||||
return NONE
|
||||
|
||||
def flags(self, *args):
|
||||
return Qt.ItemIsEnabled|Qt.ItemIsSelectable
|
||||
|
||||
|
||||
def index(self, row, column, parent):
|
||||
if not self.hasIndex(row, column, parent):
|
||||
return QModelIndex()
|
||||
|
@ -31,7 +31,6 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, out_format
|
||||
total = len(book_ids)
|
||||
if total == 0:
|
||||
return None, None, None
|
||||
parent.status_bar.showMessage(_('Starting conversion of %d books') % total, 2000)
|
||||
|
||||
for i, book_id in enumerate(book_ids):
|
||||
temp_files = []
|
||||
@ -103,7 +102,6 @@ def convert_bulk_ebook(parent, queue, db, book_ids, out_format=None, args=[]):
|
||||
total = len(book_ids)
|
||||
if total == 0:
|
||||
return None, None, None
|
||||
parent.status_bar.showMessage(_('Starting conversion of %d books') % total, 2000)
|
||||
|
||||
d = BulkConfig(parent, db, out_format)
|
||||
if d.exec_() != QDialog.Accepted:
|
||||
|
@ -473,6 +473,7 @@ class LibraryPage(QWizardPage, LibraryUI):
|
||||
|
||||
def initializePage(self):
|
||||
lp = prefs['library_path']
|
||||
self.default_library_name = None
|
||||
if not lp:
|
||||
fname = _('Calibre Library')
|
||||
if isinstance(fname, unicode):
|
||||
@ -481,6 +482,7 @@ class LibraryPage(QWizardPage, LibraryUI):
|
||||
except:
|
||||
fname = 'Calibre Library'
|
||||
lp = os.path.expanduser('~'+os.sep+fname)
|
||||
self.default_library_name = lp
|
||||
if not os.path.exists(lp):
|
||||
try:
|
||||
os.makedirs(lp)
|
||||
@ -497,6 +499,17 @@ class LibraryPage(QWizardPage, LibraryUI):
|
||||
def commit(self, completed):
|
||||
oldloc = prefs['library_path']
|
||||
newloc = unicode(self.location.text())
|
||||
try:
|
||||
newloce = newloc.encode(filesystem_encoding)
|
||||
if self.default_library_name is not None and \
|
||||
os.path.exists(self.default_library_name) and \
|
||||
not os.listdir(self.default_library_name) and \
|
||||
newloce != self.default_library_name:
|
||||
os.rmdir(self.default_library_name)
|
||||
except:
|
||||
pass
|
||||
if not os.path.exists(newloc):
|
||||
os.mkdir(newloc)
|
||||
if not patheq(oldloc, newloc):
|
||||
move_library(oldloc, newloc, self.wizard(), completed)
|
||||
return True
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,9 +4,9 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: calibre 0.6.14\n"
|
||||
"POT-Creation-Date: 2009-09-28 17:09+MDT\n"
|
||||
"PO-Revision-Date: 2009-09-28 17:09+MDT\n"
|
||||
"Project-Id-Version: calibre 0.6.16\n"
|
||||
"POT-Creation-Date: 2009-10-01 23:15+MDT\n"
|
||||
"PO-Revision-Date: 2009-10-01 23:15+MDT\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: LANGUAGE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -95,8 +95,8 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/rtf/input.py:219
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:261
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:268
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:111
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:118
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:120
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:127
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:21
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:99
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:124
|
||||
@ -521,7 +521,7 @@ msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:686
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:434
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:115
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:122
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1007
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1011
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1334
|
||||
@ -948,7 +948,7 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/fb2/fb2ml.py:122
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/pml/pmlml.py:111
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/rb/rbml.py:98
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/txt/txtml.py:78
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/txt/txtml.py:77
|
||||
msgid "Table of Contents:"
|
||||
msgstr ""
|
||||
|
||||
@ -1276,7 +1276,7 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/library.py:1012
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/library.py:1072
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/status.py:60
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:115
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:122
|
||||
msgid "Tags"
|
||||
msgstr ""
|
||||
|
||||
@ -1284,7 +1284,7 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/library.py:166
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/library.py:354
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/status.py:59
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:115
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:122
|
||||
msgid "Series"
|
||||
msgstr ""
|
||||
|
||||
@ -1953,47 +1953,64 @@ msgstr ""
|
||||
msgid "Choose Files"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:52
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:53
|
||||
msgid "Searching in"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:155
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:164
|
||||
msgid "Adding..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:168
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:177
|
||||
msgid "Searching in all sub-directories..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:244
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:190
|
||||
msgid "Path error"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:191
|
||||
msgid "The specified directory could not be processed."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:195
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:482
|
||||
msgid "No books"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:196
|
||||
msgid "No books found"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:262
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:257
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:275
|
||||
msgid "Adding failed"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:258
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:276
|
||||
msgid "The add books process seems to have hung. Try restarting calibre and adding the books in smaller increments, until you find the problem book."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:270
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:288
|
||||
msgid "Duplicates found!"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:271
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:289
|
||||
msgid "Books with the same title as the following already exist in the database. Add them anyway?"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:274
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:292
|
||||
msgid "Adding duplicates..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:335
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:353
|
||||
msgid "Saving..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:388
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:406
|
||||
msgid "Saved"
|
||||
msgstr ""
|
||||
|
||||
@ -2050,7 +2067,7 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/pdf_output_ui.py:39
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/rb_output_ui.py:28
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/structure_detection_ui.py:59
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:61
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:62
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_input_ui.py:38
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/txt_output_ui.py:51
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/xexp_edit_ui.py:41
|
||||
@ -2581,7 +2598,7 @@ msgid "RB Output"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/regex_builder.py:76
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1322
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1329
|
||||
msgid "Choose the format to view"
|
||||
msgstr ""
|
||||
|
||||
@ -2730,23 +2747,23 @@ msgstr ""
|
||||
msgid "Level &3 TOC (XPath expression):"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:62
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:63
|
||||
msgid "Do not add &detected chapters to the Table of Contents"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:63
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:64
|
||||
msgid "Number of &links to add to Table of Contents"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:64
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:65
|
||||
msgid "Chapter &threshold"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:65
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:66
|
||||
msgid "&Force use of auto-generated Table of Contents"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:66
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/convert/toc_ui.py:67
|
||||
msgid "TOC &Filter:"
|
||||
msgstr ""
|
||||
|
||||
@ -2944,10 +2961,6 @@ msgstr ""
|
||||
msgid "Send specific format to storage card B"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:482
|
||||
msgid "No books"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:483
|
||||
msgid "selected to send"
|
||||
msgstr ""
|
||||
@ -3086,7 +3099,7 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config/__init__.py:216
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/library.py:344
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/status.py:57
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:115
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:122
|
||||
msgid "Formats"
|
||||
msgstr ""
|
||||
|
||||
@ -4691,7 +4704,7 @@ msgid "Save to disk in a single directory"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:280
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1424
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1431
|
||||
msgid "Save only %s format to disk"
|
||||
msgstr ""
|
||||
|
||||
@ -4726,12 +4739,12 @@ msgid "Bad database location"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:428
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:477
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:478
|
||||
msgid "Calibre Library"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:438
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1567
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1574
|
||||
msgid "Choose a location for your ebook library."
|
||||
msgstr ""
|
||||
|
||||
@ -4905,158 +4918,162 @@ msgstr ""
|
||||
msgid "Cannot convert"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1316
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1335
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1212
|
||||
msgid "Starting conversion of %d book(s)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1323
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1342
|
||||
msgid "No book selected"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1316
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1366
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1323
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1373
|
||||
msgid "Cannot view"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1334
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1341
|
||||
msgid "Cannot open folder"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1351
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1358
|
||||
msgid "Multiple Books Selected"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1352
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1359
|
||||
msgid "You are attempting to open %d books. Opening too many books at once can be slow and have a negative effect on the responsiveness of your computer. Once started the process cannot be stopped until complete. Do you wish to continue?"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1367
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1374
|
||||
msgid "%s has no available formats."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1408
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1415
|
||||
msgid "Cannot configure"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1409
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1416
|
||||
msgid "Cannot configure while there are running jobs."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1452
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1459
|
||||
msgid "No detailed info available"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1453
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1460
|
||||
msgid "No detailed information is available for books on the device."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1505
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1512
|
||||
msgid "Error talking to device"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1506
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1513
|
||||
msgid "There was a temporary error talking to the device. Please unplug and reconnect the device and or reboot."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1529
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1547
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1536
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1554
|
||||
msgid "Conversion Error"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1530
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1537
|
||||
msgid "<p>Could not convert: %s<p>It is a <a href=\"%s\">DRM</a>ed book. You must first remove the DRM using third party tools."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1548
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1555
|
||||
msgid "<b>Failed</b>"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1576
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1583
|
||||
msgid "Invalid library location"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1577
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1584
|
||||
msgid "Could not access %s. Using %s as the library."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1624
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1631
|
||||
msgid "is the result of the efforts of many volunteers from all over the world. If you find it useful, please consider donating to support its development."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1648
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1655
|
||||
msgid "There are active jobs. Are you sure you want to quit?"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1651
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1658
|
||||
msgid ""
|
||||
" is communicating with the device!<br>\n"
|
||||
" Quitting may cause corruption on the device.<br>\n"
|
||||
" Are you sure you want to quit?"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1655
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1662
|
||||
msgid "WARNING: Active jobs"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1706
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1713
|
||||
msgid "will keep running in the system tray. To close it, choose <b>Quit</b> in the context menu of the system tray."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1725
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1732
|
||||
msgid "<span style=\"color:red; font-weight:bold\">Latest version: <a href=\"%s\">%s</a></span>"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1733
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1740
|
||||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1734
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1741
|
||||
msgid "%s has been updated to version %s. See the <a href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. Visit the download page?"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1752
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1759
|
||||
msgid "Use the library located at the specified path."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1754
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1761
|
||||
msgid "Start minimized to system tray."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1756
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1763
|
||||
msgid "Log debugging information to console"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1758
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1765
|
||||
msgid "Do not check for updates"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1806
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1813
|
||||
msgid "If you are sure it is not running"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1808
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1815
|
||||
msgid "Cannot Start "
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1809
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1816
|
||||
msgid "%s is already running."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1812
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1819
|
||||
msgid "may be running in the system tray, in the"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1814
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1821
|
||||
msgid "upper right region of the screen."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1816
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1823
|
||||
msgid "lower right region of the screen."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1819
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1826
|
||||
msgid "try rebooting your computer."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1821
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1833
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1828
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1840
|
||||
msgid "try deleting the file"
|
||||
msgstr ""
|
||||
|
||||
@ -5234,55 +5251,50 @@ msgstr ""
|
||||
msgid "Click to browse books by tags"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:115
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:122
|
||||
msgid "Authors"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:115
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_view.py:122
|
||||
msgid "Publishers"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:34
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:106
|
||||
msgid "Starting conversion of %d books"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:64
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:184
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:63
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:182
|
||||
msgid "Convert book %d of %d (%s)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:91
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:204
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:90
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:202
|
||||
msgid "Could not convert some books"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:92
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:205
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:91
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:203
|
||||
msgid "Could not convert %d of %d books, because no suitable source format was found."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:123
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:121
|
||||
msgid "Queueing books for bulk conversion"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:183
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:181
|
||||
msgid "Queueing "
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:237
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:235
|
||||
msgid "You must set a username and password for %s"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:242
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:240
|
||||
msgid "Fetch news from "
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:253
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:251
|
||||
msgid "Convert existing"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:254
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tools.py:252
|
||||
msgid "The following books have already been converted to %s format. Do you wish to reconvert them?"
|
||||
msgstr ""
|
||||
|
||||
@ -5717,7 +5729,7 @@ msgstr ""
|
||||
msgid "Could not move library"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:528
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/wizard/__init__.py:541
|
||||
msgid "welcome wizard"
|
||||
msgstr ""
|
||||
|
||||
@ -6261,56 +6273,56 @@ msgid ""
|
||||
"Start the calibre content server."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:45
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:47
|
||||
msgid ""
|
||||
"%sUsage%s: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:89
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:91
|
||||
msgid "Created by "
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:90
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:92
|
||||
msgid "Whenever you pass arguments to %prog that have spaces in them, enclose the arguments in quotation marks."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:553
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:555
|
||||
msgid "Path to the database in which books are stored"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:555
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:557
|
||||
msgid "Pattern to guess metadata from filenames"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:557
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:559
|
||||
msgid "Access key for isbndb.com"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:559
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:561
|
||||
msgid "Default timeout for network operations (seconds)"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:561
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:563
|
||||
msgid "Path to directory in which your library of books is stored"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:563
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:565
|
||||
msgid "The language in which to display the user interface"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:565
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:567
|
||||
msgid "The default output format for ebook conversions."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:569
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:571
|
||||
msgid "Ordered list of formats to prefer for input."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:571
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:573
|
||||
msgid "Read metadata from files"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:573
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/config.py:575
|
||||
msgid "The priority of worker processes"
|
||||
msgstr ""
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,8 @@ def make_config_dir():
|
||||
if not os.path.exists(plugin_dir):
|
||||
os.makedirs(plugin_dir, mode=448) # 0700 == 448
|
||||
|
||||
def check_config_write_access():
|
||||
return os.access(config_dir, os.W_OK) and os.access(config_dir, os.X_OK)
|
||||
|
||||
class CustomHelpFormatter(IndentedHelpFormatter):
|
||||
|
||||
|
2
src/calibre/utils/fonts/Makefile.msvc
Normal file
2
src/calibre/utils/fonts/Makefile.msvc
Normal file
@ -0,0 +1,2 @@
|
||||
winfonts.exe : winfonts.cpp
|
||||
cl.exe /nologo /Ox /MD /W3 /EHsc winfonts.cpp
|
@ -33,7 +33,7 @@ class FontConfig(Thread):
|
||||
config = os.path.join(config_dir, 'fonts.conf')
|
||||
if iswindows and getattr(sys, 'frozen', False):
|
||||
config_dir = os.path.join(os.path.dirname(sys.executable),
|
||||
'etc', 'fonts')
|
||||
'fontconfig')
|
||||
if isinstance(config_dir, unicode):
|
||||
config_dir = config_dir.encode(sys.getfilesystemencoding())
|
||||
config = os.path.join(config_dir, 'fonts.conf')
|
||||
@ -148,9 +148,10 @@ fontconfig.start()
|
||||
|
||||
def test():
|
||||
from pprint import pprint;
|
||||
pprint(fontconfig.find_font_families());
|
||||
pprint(fontconfig.files_for_family('liberation serif'));
|
||||
pprint(fontconfig.match('liberation serif:slant=italic:weight=bold', verbose=True))
|
||||
pprint(fontconfig.find_font_families())
|
||||
pprint(fontconfig.files_for_family('liberation serif'))
|
||||
m = 'times new roman' if iswindows else 'liberation serif'
|
||||
pprint(fontconfig.match(m+':slant=italic:weight=bold', verbose=True))
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
||||
|
168
src/calibre/utils/fonts/winfonts.cpp
Normal file
168
src/calibre/utils/fonts/winfonts.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
:mod:`fontconfig` -- Pythonic interface to Windows font api
|
||||
============================================================
|
||||
|
||||
.. module:: fontconfig
|
||||
:platform: All
|
||||
:synopsis: Pythonic interface to the fontconfig library
|
||||
|
||||
.. moduleauthor:: Kovid Goyal <kovid@kovidgoyal.net> Copyright 2009
|
||||
|
||||
*/
|
||||
|
||||
#define UNICODE
|
||||
#include <Windows.h>
|
||||
#include <strsafe.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
vector<BYTE> *get_font_data(HDC hdc) {
|
||||
DWORD sz;
|
||||
vector<BYTE> *data;
|
||||
sz = GetFontData(hdc, 0, 0, NULL, 0);
|
||||
data = new vector<BYTE>(sz);
|
||||
if (GetFontData(hdc, 0, 0, &((*data)[0]), sz) == GDI_ERROR) {
|
||||
delete data; data = NULL;
|
||||
}
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
BOOL is_font_embeddable(ENUMLOGFONTEX *lpelfe) {
|
||||
HDC hdc;
|
||||
HFONT font;
|
||||
HFONT old_font = NULL;
|
||||
UINT sz;
|
||||
size_t i;
|
||||
LPOUTLINETEXTMETRICW metrics;
|
||||
BOOL ans = TRUE;
|
||||
hdc = GetDC(NULL);
|
||||
font = CreateFontIndirect(&lpelfe->elfLogFont);
|
||||
if (font != NULL) {
|
||||
old_font = SelectObject(hdc, font);
|
||||
sz = GetOutlineTextMetrics(hdc, 0, NULL);
|
||||
metrics = new OUTLINETEXTMETRICW[sz];
|
||||
if ( GetOutlineTextMetrics(hdc, sz, metrics) != 0) {
|
||||
for ( i = 0; i < sz; i++) {
|
||||
if (metrics[i].otmfsType & 0x01) {
|
||||
wprintf_s(L"Not embeddable: %s\n", lpelfe->elfLogFont.lfFaceName);
|
||||
ans = FALSE; break;
|
||||
}
|
||||
}
|
||||
} else ans = FALSE;
|
||||
delete[] metrics;
|
||||
DeleteObject(font);
|
||||
SelectObject(hdc, old_font);
|
||||
} else ans = FALSE;
|
||||
ReleaseDC(NULL, hdc);
|
||||
return ans;
|
||||
}
|
||||
|
||||
int CALLBACK find_families_callback (
|
||||
ENUMLOGFONTEX *lpelfe, /* pointer to logical-font data */
|
||||
NEWTEXTMETRICEX *lpntme, /* pointer to physical-font data */
|
||||
int FontType, /* type of font */
|
||||
LPARAM lParam /* a combo box HWND */
|
||||
) {
|
||||
size_t i;
|
||||
LPWSTR tmp;
|
||||
vector<LPWSTR> *families = (vector<LPWSTR>*)lParam;
|
||||
|
||||
if (FontType & TRUETYPE_FONTTYPE) {
|
||||
for (i = 0; i < families->size(); i++) {
|
||||
if (lstrcmp(families->at(i), lpelfe->elfLogFont.lfFaceName) == 0)
|
||||
return 1;
|
||||
}
|
||||
tmp = new WCHAR[LF_FACESIZE];
|
||||
swprintf_s(tmp, LF_FACESIZE, L"%s", lpelfe->elfLogFont.lfFaceName);
|
||||
families->push_back(tmp);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
vector<LPWSTR>* find_font_families(void) {
|
||||
LOGFONTW logfont;
|
||||
HDC hdc;
|
||||
vector<LPWSTR> *families;
|
||||
|
||||
families = new vector<LPWSTR>();
|
||||
SecureZeroMemory(&logfont, sizeof(logfont));
|
||||
|
||||
logfont.lfCharSet = DEFAULT_CHARSET;
|
||||
logfont.lfPitchAndFamily = VARIABLE_PITCH | FF_DONTCARE;
|
||||
StringCchCopyW(logfont.lfFaceName, 2, L"\0");
|
||||
|
||||
hdc = GetDC(NULL);
|
||||
EnumFontFamiliesExW(hdc, &logfont, (FONTENUMPROC)find_families_callback,
|
||||
(LPARAM)(families), 0);
|
||||
|
||||
ReleaseDC(NULL, hdc);
|
||||
|
||||
return families;
|
||||
}
|
||||
|
||||
inline void free_families_vector(vector<LPWSTR> *v) {
|
||||
for (size_t i = 0; i < v->size(); i++) delete[] v->at(i);
|
||||
delete v;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
vector<LPWSTR> *all_families;
|
||||
size_t i;
|
||||
|
||||
all_families = find_font_families();
|
||||
|
||||
for (i = 0; i < all_families->size(); i++)
|
||||
wprintf_s(L"%s\n", all_families->at(i));
|
||||
|
||||
free_families_vector(all_families);
|
||||
|
||||
HDC hdc = GetDC(NULL);
|
||||
HFONT font = CreateFont(72,0,0,0,0,0,0,0,0,0,0,0,0,L"Verdana");
|
||||
HFONT old_font = SelectObject(hdc, font);
|
||||
vector<BYTE> *data = get_font_data(hdc);
|
||||
DeleteObject(font);
|
||||
SelectObject(hdc, old_font);
|
||||
ReleaseDC(NULL, hdc);
|
||||
if (data != NULL) printf("\nyay: %d\n", data->size());
|
||||
delete data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
#
|
||||
|
||||
static
|
||||
PyMethodDef fontconfig_methods[] = {
|
||||
{"find_font_families", fontconfig_find_font_families, METH_VARARGS,
|
||||
"find_font_families(allowed_extensions)\n\n"
|
||||
"Find all font families on the system for fonts of the specified types. If no "
|
||||
"types are specified all font families are returned."
|
||||
},
|
||||
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
extern "C" {
|
||||
PyMODINIT_FUNC
|
||||
initfontconfig(void) {
|
||||
PyObject *m;
|
||||
m = Py_InitModule3(
|
||||
"fontconfig", fontconfig_methods,
|
||||
"Find fonts."
|
||||
);
|
||||
if (m == NULL) return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -9,20 +9,33 @@ class AdvancedUserRecipe1234144423(BasicNewsRecipe):
|
||||
oldest_article = 7
|
||||
language = 'en'
|
||||
|
||||
__author__ = 'Joseph Kitzmiller'
|
||||
__author__ = 'Joseph Kitzmiller and Sujata Raman'
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
remove_javascript = True
|
||||
encoding = 'cp1252'
|
||||
extra_css = ' p {font-size: medium; font-weight: normal;} '
|
||||
extra_css = '''
|
||||
h1{font-family:Arial,Helvetica,sans-serif; font-size:large; color:#0E5398; }
|
||||
h2{color:#666666;}
|
||||
.blog_title{color:#4E0000; font-family:Georgia,"Times New Roman",Times,serif; font-size:large;}
|
||||
.sidebar-photo{font-family:Arial,Helvetica,sans-serif; color:#333333; font-size:30%;}
|
||||
.blog_post{font-family:Arial,Helvetica,sans-serif; color:#222222; font-size:xx-small;}
|
||||
.article-bodytext{font-family:Arial,Helvetica,sans-serif; font-size:xx-small; color:#222222;font-weight:normal;}
|
||||
.blog caitlin{font-family:Arial,Helvetica,sans-serif; font-size:xx-small; color:#222222; font-weight:normal;}
|
||||
.ratingbyline{font-family:Arial,Helvetica,sans-serif; color:#333333; font-size:50%;}
|
||||
.author{font-family:Arial,Helvetica,sans-serif; color:#777777; font-size:50%;}
|
||||
.date{font-family:Arial,Helvetica,sans-serif; color:#777777; font-size:50%;}
|
||||
.padding{font-family:Arial,Helvetica,sans-serif; font-size:70%; color:#222222; font-weight:normal;}
|
||||
'''
|
||||
|
||||
keep_only_tags = [dict(name='div', attrs={'class':'padding'})]
|
||||
keep_only_tags = [dict(name='div', attrs={'class':['padding','sidebar-photo','blog caitlin']})]
|
||||
|
||||
remove_tags = [
|
||||
dict(name=['object','link','table','embed'])
|
||||
,dict(name='div',attrs={'id':'pluckcomments'})
|
||||
,dict(name='div',attrs={'class':'articleflex-container'})
|
||||
,dict(name='div',attrs={'id':["pluckcomments","StoryChat"]})
|
||||
,dict(name='div',attrs={'class':['articleflex-container',]})
|
||||
,dict(name='p',attrs={'class':['posted','tags']})
|
||||
]
|
||||
|
||||
feeds = [(u'Cincinnati Enquirer', u'http://rss.cincinnati.com/apps/pbcs.dll/section?category=rssenq01&mime=xml')]
|
||||
|
@ -16,26 +16,22 @@ class Honoluluadvertiser(BasicNewsRecipe):
|
||||
category = 'news, Honolulu, Hawaii'
|
||||
oldest_article = 2
|
||||
language = 'en'
|
||||
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
encoding = 'cp1252'
|
||||
remove_javascript = True
|
||||
cover_url = 'http://www.honoluluadvertiser.com/graphics/branding.gif'
|
||||
|
||||
html2lrf_options = [
|
||||
'--comment' , description
|
||||
, '--category' , category
|
||||
, '--publisher' , publisher
|
||||
]
|
||||
|
||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
||||
conversion_options = {
|
||||
'comments' : description
|
||||
,'tags' : category
|
||||
,'language' : language
|
||||
,'publisher' : publisher
|
||||
}
|
||||
|
||||
keep_only_tags = [dict(name='td')]
|
||||
|
||||
remove_tags = [dict(name=['object','link'])]
|
||||
|
||||
remove_attributes = ['style']
|
||||
|
||||
feeds = [
|
||||
(u'Breaking news', u'http://www.honoluluadvertiser.com/apps/pbcs.dll/section?Category=RSS01&MIME=XML' )
|
||||
@ -47,14 +43,13 @@ class Honoluluadvertiser(BasicNewsRecipe):
|
||||
]
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
for item in soup.findAll(style=True):
|
||||
del item['style']
|
||||
mtag = '\n<meta http-equiv="Content-Language" content="en"/>\n'
|
||||
soup.head.insert(0,mtag)
|
||||
st = soup.find('td')
|
||||
if st:
|
||||
st.name = 'div'
|
||||
return soup
|
||||
|
||||
def print_version(self, url):
|
||||
ubody, sep, rest = url.rpartition('/-1/')
|
||||
ubody, sep, rest = url.rpartition('?source')
|
||||
root, sep2, article_id = ubody.partition('/article/')
|
||||
return u'http://www.honoluluadvertiser.com/apps/pbcs.dll/article?AID=/' + article_id + '&template=printart'
|
||||
|
||||
|
@ -5,7 +5,6 @@ __copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
latimes.com
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class LATimes(BasicNewsRecipe):
|
||||
@ -15,7 +14,6 @@ class LATimes(BasicNewsRecipe):
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
language = 'en'
|
||||
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
encoding = 'utf-8'
|
||||
@ -41,19 +39,24 @@ class LATimes(BasicNewsRecipe):
|
||||
.subhead{font-family :Georgia,"Times New Roman",Times,serif; font-size:x-small;}
|
||||
'''
|
||||
|
||||
# recursions = 1
|
||||
# match_regexps = [r'http://www.latimes.com/.*page=[2-9]']
|
||||
|
||||
keep_only_tags = [dict(name='div', attrs={'class':["story" ,"entry"] })]
|
||||
|
||||
|
||||
remove_tags = [ dict(name='div', attrs={'class':['articlerail',"sphereTools","tools","toppaginate","entry-footer-left","entry-footer-right"]}),
|
||||
dict(name='div', attrs={'id':["moduleArticleToolsContainer",]}),
|
||||
dict(name='ul', attrs={'class':["article-nav clearfix",]}),
|
||||
dict(name='p', attrs={'class':["entry-footer",]}),
|
||||
dict(name='ul', attrs={'class':"article-nav clearfix"}),
|
||||
dict(name=['iframe'])
|
||||
]
|
||||
|
||||
|
||||
feeds = [(u'News', u'http://feeds.latimes.com/latimes/news')
|
||||
,(u'Local','http://feeds.latimes.com/latimes/news/local')
|
||||
,(u'Most Emailed','http://feeds.latimes.com/MostEmailed')
|
||||
,(u'California Politics','http://feeds.latimes.com/latimes/news/local/politics/cal/')
|
||||
,(u'MostEmailed','http://feeds.latimes.com/MostEmailed')
|
||||
,(u'Politics','http://feeds.latimes.com/latimes/news/local/politics/cal/')
|
||||
,('OrangeCounty','http://feeds.latimes.com/latimes/news/local/orange/')
|
||||
,('National','http://feeds.latimes.com/latimes/news/nationworld/nation')
|
||||
,('Politics','http://feeds.latimes.com/latimes/news/politics/')
|
||||
@ -62,5 +65,22 @@ class LATimes(BasicNewsRecipe):
|
||||
,('Entertainment','http://feeds.latimes.com/latimes/entertainment/')
|
||||
]
|
||||
|
||||
|
||||
def get_article_url(self, article):
|
||||
return article.get('feedburner_origlink')
|
||||
ans = article.get('feedburner_origlink').rpartition('?')[0]
|
||||
|
||||
try:
|
||||
self.log('Looking for full story link in', ans)
|
||||
soup = self.index_to_soup(ans)
|
||||
x = soup.find(text="single page")
|
||||
|
||||
if x is not None:
|
||||
a = x.parent
|
||||
if a and a.has_key('href'):
|
||||
ans = 'http://www.latimes.com'+a['href']
|
||||
self.log('Found full story link', ans)
|
||||
except:
|
||||
pass
|
||||
return ans
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user