diff --git a/.bzrignore b/.bzrignore index e27f39a864..37ab760e19 100644 --- a/.bzrignore +++ b/.bzrignore @@ -20,3 +20,6 @@ src/calibre/gui2/pictureflow/pictureflow_resource.rc src/calibre/gui2/pictureflow/release/ src/calibre/translations/compiled.py installer/windows/calibre/build.log +src/calibre/translations/.errors +src/calibre/plugins/* +src/calibre/gui2/pictureflow/.build diff --git a/Makefile b/Makefile index e2dc7770df..1990ad22bd 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,6 @@ PYTHON = python -all : plugins gui2 translations resources - -plugins : src/calibre/plugins pictureflow lzx - -src/calibre/plugins: - mkdir -p src/calibre/plugins +all : gui2 translations resources clean : cd src/calibre/gui2 && ${PYTHON} make.py clean @@ -25,26 +20,6 @@ resources: manual: make -C src/calibre/manual clean html -pictureflow : - mkdir -p src/calibre/plugins && rm -f src/calibre/plugins/*pictureflow* && \ - cd src/calibre/gui2/pictureflow && rm -f *.o && \ - mkdir -p .build && cd .build && rm -f * && \ - qmake ../pictureflow.pro && make staticlib && \ - cd ../PyQt && \ - mkdir -p .build && \ - cd .build && rm -f * && \ - ${PYTHON} ../configure.py && make && \ - cd ../../../../../.. && \ - cp src/calibre/gui2/pictureflow/PyQt/.build/pictureflow.so src/calibre/plugins/ && \ - rm -rf src/calibre/gui2/pictureflow/.build rm -rf src/calibre/gui2/pictureflow/PyQt/.build - -lzx : - mkdir -p src/calibre/plugins && rm -f src/calibre/plugins/lzx.so && \ - cd src/calibre/utils/lzx && \ - ${PYTHON} setup.py build --build-base=.build && cd - && \ - cp src/calibre/utils/lzx/.build/lib*/lzx.so src/calibre/plugins/ && \ - rm -rf src/calibre/utils/lzx/.build/ - pot : cd src/calibre/translations && ${PYTHON} __init__.py pot diff --git a/linux_installer.py b/installer/linux/freeze.py similarity index 91% rename from linux_installer.py rename to installer/linux/freeze.py index a1a0551afc..d79d3933d0 100644 --- a/linux_installer.py +++ b/installer/linux/freeze.py @@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en' ''' Create linux binary. ''' -import glob, sys, subprocess, tarfile, os, re, py_compile +import glob, sys, subprocess, tarfile, os, re, py_compile, shutil HOME = '/home/kovid' PYINSTALLER = os.path.expanduser('~/build/pyinstaller') CALIBREPREFIX = '___' @@ -33,7 +33,6 @@ open(os.path.join(PYINSTALLER, 'hooks', 'hook-calibre.parallel.py'), 'wb').write def run_pyinstaller(args=sys.argv): subprocess.check_call(('/usr/bin/sudo', 'chown', '-R', 'kovid:users', glob.glob('/usr/lib/python*/site-packages/')[-1])) subprocess.check_call('rm -rf %(py)s/dist/* %(py)s/build/*'%dict(py=PYINSTALLER), shell=True) - subprocess.check_call('make plugins', shell=True) cp = HOME+'/build/'+os.path.basename(os.getcwd()) spec = open(os.path.join(PYINSTALLER, 'calibre', 'calibre.spec'), 'wb') raw = re.sub(r'CALIBREPREFIX\s+=\s+\'___\'', 'CALIBREPREFIX = '+repr(cp), @@ -41,12 +40,14 @@ def run_pyinstaller(args=sys.argv): spec.write(raw) spec.close() os.chdir(PYINSTALLER) + shutil.rmtree('calibre/dist') + os.mkdir('calibre/dist') subprocess.check_call('python -OO Build.py calibre/calibre.spec', shell=True) return 0 -if __name__ == '__main__' and 'linux_installer.py' in __file__: +if __name__ == '__main__' and 'freeze.py' in __file__: sys.exit(run_pyinstaller()) @@ -59,7 +60,7 @@ os.chdir(os.environ.get("ORIGWD", ".")) sys.path.insert(0, os.path.join(sys.frozen_path, "library.pyz")) sys.path.insert(0, sys.frozen_path) from PyQt4.QtCore import QCoreApplication -QCoreApplication.setLibraryPaths([sys.frozen_path, os.path.join(sys.frozen_path, "plugins")]) +QCoreApplication.setLibraryPaths([sys.frozen_path, os.path.join(sys.frozen_path, "qtplugins")]) ''') excludes = ['gtk._gtk', 'gtk.glade', 'qt', 'matplotlib.nxutils', 'matplotlib._cntr', 'matplotlib.ttconv', 'matplotlib._image', 'matplotlib.ft2font', @@ -80,7 +81,7 @@ for entry in entry_points['console_scripts'] + entry_points['gui_scripts']: scripts.append(os.path.join(CALIBRESRC, *map(lambda x: x.strip(), fields[1].split(':')[0].split('.')))+'.py') analyses = [Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), loader, script], - pathex=[PYINSTALLER, CALIBRESRC, CALIBREPLUGINS], excludes=excludes) for script in scripts] + pathex=[PYINSTALLER, CALIBRESRC], excludes=excludes) for script in scripts] pyz = TOC() binaries = TOC() @@ -104,6 +105,8 @@ for script, exe, a in zip(scripts, executables, analyses): print 'Adding plugins...' for f in glob.glob(os.path.join(CALIBREPLUGINS, '*.so')): + binaries += [('plugins/'+os.path.basename(f), f, 'BINARY')] +for f in glob.glob(os.path.join(CALIBREPLUGINS, '*.so.*')): binaries += [(os.path.basename(f), f, 'BINARY')] print 'Adding external programs...' @@ -121,7 +124,7 @@ for dirpath, dirnames, filenames in os.walk(plugdir): for f in filenames: if not f.endswith('.so') or 'designer' in dirpath or 'codcs' in dirpath or 'sqldrivers' in dirpath : continue f = os.path.join(dirpath, f) - plugins.append(('plugins/'+f.replace(plugdir, ''), f, 'BINARY')) + plugins.append(('qtplugins/'+f.replace(plugdir, ''), f, 'BINARY')) binaries += plugins manifest = '/tmp/manifest' diff --git a/osx_installer.py b/installer/osx/freeze.py similarity index 81% rename from osx_installer.py rename to installer/osx/freeze.py index c07702727d..ddef24075c 100644 --- a/osx_installer.py +++ b/installer/osx/freeze.py @@ -4,7 +4,14 @@ __copyright__ = '2008, Kovid Goyal ' ''' Create an OSX installer ''' import sys, re, os, shutil, subprocess, stat, glob, zipfile -from setup import VERSION, APPNAME, scripts, main_modules, basenames, main_functions +l = {} +exec open('setup.py').read() in l +VERSION = l['VERSION'] +APPNAME = l['APPNAME'] +scripts = l['scripts'] +basenames = l['basenames'] +main_functions = l['main_functions'] +main_modules = l['main_modules'] from setuptools import setup from py2app.build_app import py2app from modulegraph.find_modules import find_modules @@ -170,64 +177,46 @@ _check_symlinks_prescript() for f in files: subprocess.check_call(['/usr/bin/install_name_tool', '-change', '/Library/Frameworks/Python.framework/Versions/2.5/Python', '@executable_path/../Frameworks/Python.framework/Versions/2.5/Python', f]) + def fix_misc_dependencies(self, files): + for path in files: + frameworks_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Frameworks') + pipe = subprocess.Popen('/usr/bin/otool -L '+path, shell=True, stdout=subprocess.PIPE).stdout + for l in pipe.readlines(): + match = re.search(r'\s+(.*?)\s+\(', l) + if match: + dep = match.group(1) + name = os.path.basename(dep) + if not name: + name = dep + bundle = os.path.join(frameworks_dir, name) + if os.path.exists(bundle): + subprocess.check_call(['/usr/bin/install_name_tool', '-change', dep, + '@executable_path/../Frameworks/'+name, path]) + - def build_distutils_plugins(self): - plugins = [ - ('lzx', os.path.join('utils', 'lzx')), - ] - files = [] - env = {'PATH':os.environ['PATH']} - for name, path in plugins: - print 'Building plugin', name - path = os.path.abspath(os.path.join('src', 'calibre', path)) - cwd = os.getcwd() - os.chdir(path) - try: - if os.path.exists('.build'): - shutil.rmtree('.build') - subprocess.check_call((sys.executable, 'setup.py', 'build', '--build-base', '.build'), - env=env) - plugin = os.path.abspath(glob.glob('.build/lib*/%s.so'%name)[0]) - files.append([plugin, os.path.basename(plugin)]) - finally: - os.chdir(cwd) - return files - - def build_plugins(self): - cwd = os.getcwd() - qmake = '/Users/kovid/qt/bin/qmake' - files = [] - try: - print 'Building pictureflow' - os.chdir('src/calibre/gui2/pictureflow') - if not os.path.exists('.build'): - os.mkdir('.build') - os.chdir('.build') - for f in glob.glob('*'): os.unlink(f) - subprocess.check_call([qmake, '../pictureflow.pro']) - subprocess.check_call(['make']) - files.append((os.path.abspath(os.path.realpath('libpictureflow.dylib')), 'libpictureflow.dylib')) - os.chdir('../PyQt') - if not os.path.exists('.build'): - os.mkdir('.build') - os.chdir('.build') - for f in glob.glob('*'): os.unlink(f) - subprocess.check_call([PYTHON, '../configure.py']) - subprocess.check_call(['/usr/bin/make']) - files.append((os.path.abspath('pictureflow.so'), 'pictureflow.so')) - subprocess.check_call(['/usr/bin/install_name_tool', '-change', 'libpictureflow.0.dylib', '@executable_path/../Frameworks/libpictureflow.dylib', 'pictureflow.so']) - self.fix_python_dependencies((files[0][0], files[1][0])) - for i in range(2): - deps = BuildAPP.qt_dependencies(files[i][0]) - BuildAPP.fix_qt_dependencies(files[i][0], deps) - - return files - finally: - os.chdir(cwd) - + def add_plugins(self): + self.add_qt_plugins() + frameworks_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Frameworks') + plugins_dir = os.path.join(frameworks_dir, 'plugins') + if not os.path.exists(plugins_dir): + os.mkdir(plugins_dir) + + maps = {} + for f in glob.glob('src/calibre/plugins/*'): + tgt = plugins_dir + if f.endswith('.dylib'): + tgt = frameworks_dir + maps[f] = os.path.join(tgt, os.path.basename(f)) + deps = [] + for src, dst in maps.items(): + shutil.copyfile(src, dst) + self.fix_qt_dependencies(dst, self.qt_dependencies(dst)) + deps.append(dst) + self.fix_python_dependencies(deps) + self.fix_misc_dependencies(deps) + def run(self): - plugin_files = self.build_distutils_plugins() py2app.run(self) resource_dir = os.path.join(self.dist_dir, APPNAME + '.app', 'Contents', 'Resources') @@ -249,8 +238,8 @@ _check_symlinks_prescript() f.close() os.chmod(path, stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH|stat.S_IREAD\ |stat.S_IWUSR|stat.S_IROTH|stat.S_IRGRP) - self.add_qt_plugins() - plugin_files += self.build_plugins() + self.add_plugins() + print print 'Adding clit' @@ -266,11 +255,6 @@ _check_symlinks_prescript() print 'Adding fontconfig' for f in glob.glob(os.path.expanduser('~/fontconfig2/*')): os.link(f, os.path.join(frameworks_dir, os.path.basename(f))) - for src, dest in plugin_files: - if 'dylib' in dest: - os.link(src, os.path.join(frameworks_dir, dest)) - else: - os.link(src, os.path.join(module_dir, dest)) dst = os.path.join(resource_dir, 'fonts') if os.path.exists(dst): shutil.rmtree(dst) diff --git a/installer/windows/calibre/calibre.mpi b/installer/windows/calibre/calibre.mpi index 6564c3183b..63d812f041 100644 --- a/installer/windows/calibre/calibre.mpi +++ b/installer/windows/calibre/calibre.mpi @@ -240,7 +240,6 @@ File ::B145A772-C20C-A6F2-E872-ACC229FFE1C7 -name fb2-meta.exe -parent 6CCF3F71- File ::168973D9-DEE6-7307-9A2E-746EB9456311 -name txt2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::BD39D6F0-5125-F3A3-043F-E8FD1C87A823 -name isbndb.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::6C294A11-52D4-C567-64F7-1DCF21AB06D7 -name epub2lrf.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::BBE8D78B-6646-5327-563C-7F8EE5842D7B -name pictureflow.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::A9BB9531-5BC4-92C1-F614-B84B93F8698F -name pywintypes25.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::AA725BD8-5FFA-B426-733F-5A1264A30DA2 -name Qt.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::B48D9BFD-326D-1C92-4D94-C17F9ACD9207 -name epub2lrf.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 @@ -264,7 +263,6 @@ File ::2AABAB06-38EF-6F8C-3675-575D8B044E0C -name calibredb.exe -parent 6CCF3F71 File ::A7EA318A-0542-FBB8-5C93-A39B364A51D9 -name epub-meta.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::4CD878C5-1487-1FFD-99A1-EDFC90892F0A -name win32security.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::ADFDF202-EED8-0319-0D69-DF1C44AE465B -name librarything.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 -File ::B522E7CC-3C9B-325B-B0BA-3CAFD0228B6D -name pictureflow0.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::0E83E956-FF8D-27AB-9BE9-A24C57F8886A -name pythoncom25.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::F8DAAE4E-9BF0-F75A-78BD-81E0F4BD1F99 -name epub-meta.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::E2982BD3-D0BB-70B4-0BF8-18B2B68C9918 -name QtWebKit4.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 @@ -351,6 +349,13 @@ File ::92701E8F-1D91-A796-C899-2A266029F61D -name _socket.pyd -parent 6CCF3F71-7 File ::45BD27B5-B910-7633-C827-37E82E89C27C -name w9xpopen.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::45C27909-D761-787F-84B2-66596E5C4E99 -name bz2.pyd -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 File ::7B2DE5D8-17A6-B167-ABC7-799AEBCC1C02 -name clit.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 +File ::36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 -type dir -name plugins -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 +File ::71930E14-A27B-C23C-8D94-C7E97ADB8723 -name pictureflow.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 +File ::293E6ABE-17C9-5E53-1B44-C27029C8C061 -name winutil.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 +File ::A5737158-18DF-7F20-2BDF-2DF615663891 -name lzx.pyd -parent 36E8EEAC-F54D-5DE9-02D8-ECDFEBB4B5E2 +File ::87085EC3-26D5-975D-A820-0691F193733D -name pictureflow1.dll -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 +File ::CA9E098C-2931-9781-1303-213C242F9A5E -name lit2oeb.exe -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 +File ::16B5A447-066C-C93E-F63D-8BC0D57CA544 -name lit2oeb.exe.local -parent 6CCF3F71-74BB-ED69-D0E6-9F12348ABDD3 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 diff --git a/installer/windows/freeze.py b/installer/windows/freeze.py index 576ea5c5a9..4474776dc3 100644 --- a/installer/windows/freeze.py +++ b/installer/windows/freeze.py @@ -50,58 +50,16 @@ class BuildEXE(py2exe.build_exe.py2exe): ''' - def build_distutil_plugins(self): - plugins = [ - ('lzx', os.path.join('utils', 'lzx')), - ] - for name, path in plugins: - print 'Building plugin', name - path = os.path.abspath(os.path.join('src', 'calibre', path)) - cwd = os.getcwd() - dd = os.path.join(cwd, self.dist_dir) - os.chdir(path) - try: - if os.path.exists('.build'): - shutil.rmtree('.build') - subprocess.check_call(('python', 'setup.py', 'build', '--build-base', '.build')) - plugin = os.path.abspath(glob.glob('.build\\lib*\\%s.pyd'%name)[0]) - shutil.copyfile(plugin, os.path.join(dd, os.path.basename(plugin))) - finally: - os.chdir(cwd) - - def build_plugins(self): - cwd = os.getcwd() - dd = os.path.join(cwd, self.dist_dir) - try: - os.chdir(os.path.join('src', 'calibre', 'gui2', 'pictureflow')) - if os.path.exists('.build'): - shutil.rmtree('.build') - os.mkdir('.build') - os.chdir('.build') - subprocess.check_call(['qmake', '../pictureflow.pro']) - subprocess.check_call(['mingw32-make', '-f', 'Makefile.Release']) - shutil.copyfile('release\\pictureflow0.dll', os.path.join(dd, 'pictureflow0.dll')) - os.chdir('..\\PyQt') - if not os.path.exists('.build'): - os.mkdir('.build') - os.chdir('.build') - subprocess.check_call(['python', '..\\configure.py']) - subprocess.check_call(['mingw32-make', '-f', 'Makefile']) - shutil.copyfile('pictureflow.pyd', os.path.join(dd, 'pictureflow.pyd')) - os.chdir('..') - shutil.rmtree('.build', True) - os.chdir('..') - shutil.rmtree('.build', True) - finally: - os.chdir(cwd) - def run(self): - if not os.path.exists(self.dist_dir): - os.makedirs(self.dist_dir) - print 'Building custom plugins...' - self.build_distutil_plugins() - self.build_plugins() py2exe.build_exe.py2exe.run(self) + print 'Adding plugins...' + tgt = os.path.join(self.dist_dir, 'plugins') + if not os.path.exists(tgt): + os.mkdir(tgt) + for f in glob.glob(os.path.join(BASE_DIR, 'src', 'calibre', 'plugins', '*.dll')): + shutil.copyfile(f, os.path.join(self.dist_dir, os.path.basename(f))) + for f in glob.glob(os.path.join(BASE_DIR, 'src', 'calibre', 'plugins', '*.pyd')): + shutil.copyfile(f, os.path.join(tgt, os.path.basename(f))) qtsvgdll = None for other in self.other_depends: if 'qtsvg4.dll' in other.lower(): @@ -116,7 +74,7 @@ class BuildEXE(py2exe.build_exe.py2exe): print 'Adding', qtxmldll shutil.copyfile(qtxmldll, os.path.join(self.dist_dir, os.path.basename(qtxmldll))) - print 'Adding plugins...', + print 'Adding Qt plugins...', qt_prefix = QT_DIR if qtsvgdll: qt_prefix = os.path.dirname(os.path.dirname(qtsvgdll)) diff --git a/setup.py b/setup.py index dcbacb47c4..608ffeed26 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,9 @@ __copyright__ = '2008, Kovid Goyal ' import sys, re, os, shutil sys.path.append('src') -islinux = not ('win32' in sys.platform or 'win64' in sys.platform or 'darwin' in sys.platform) +iswindows = re.search('win(32|64)', sys.platform) +isosx = 'darwin' in sys.platform +islinux = not isosx and not iswindows src = open('src/calibre/__init__.py', 'rb').read() VERSION = re.search(r'__version__\s+=\s+[\'"]([^\'"]+)[\'"]', src).group(1) APPNAME = re.search(r'__appname__\s+=\s+[\'"]([^\'"]+)[\'"]', src).group(1) @@ -44,10 +46,72 @@ main_functions = { } if __name__ == '__main__': - from setuptools import setup, find_packages + from setuptools import setup, find_packages, Extension import subprocess, glob entry_points['console_scripts'].append('calibre_postinstall = calibre.linux:post_install') + ext_modules = [Extension('calibre.plugins.lzx', + sources=['src/calibre/utils/lzx/lzxmodule.c', + 'src/calibre/utils/lzx/lzxd.c'], + include_dirs=['src/calibre/utils/lzx'])] + if iswindows: + ext_modules.append(Extension('calibre.plugins.winutil', + sources=['src/calibre/utils/winutil.c'], libraries=['shell32']) + ) + # Build PyQt extensions + for path in [(os.path.join('src', 'calibre', 'gui2', 'pictureflow'))]: + pro = glob.glob(os.path.join(path, '*.pro'))[0] + raw = open(pro).read() + base = qtplugin = re.search(r'TARGET\s*=\s*(.*)', raw).group(1) + ver = re.search(r'VERSION\s*=\s*(\d+)', raw).group(1) + cwd = os.getcwd() + os.chdir(os.path.dirname(pro)) + try: + if not os.path.exists('.build'): + os.mkdir('.build') + os.chdir('.build') + subprocess.check_call(( (os.path.expanduser('~/qt/bin/qmake') if isosx else 'qmake'), '..'+os.sep+os.path.basename(pro))) + subprocess.check_call(['mingw32-make' if iswindows else 'make']) + ext = '.dll' if iswindows else '.dylib' if isosx else '.so' + if iswindows: + pat = re.compile(qtplugin+ver+ext) + elif isosx: + pat = re.compile('lib'+qtplugin+'.'+ver+ext) + else: + pat = re.compile('lib'+qtplugin+ext+'.'+ver+'$') + if iswindows: + os.chdir('release') + qtplugin = None + + for f in glob.glob('*'+ext+'*'): + if pat.match(f): + qtplugin = os.path.realpath(os.path.abspath(f)) + f = os.path.join(cwd, 'src', 'calibre', 'plugins', f) + shutil.copyfile(qtplugin, f) + if islinux: + os.symlink(f, f.rpartition(ext)[0]+ext) + if isosx: + os.symlink(f, f.replace('.'+ver, '')) + break + os.chdir(os.path.join('..'+(os.sep+'..' if iswindows else ''), 'PyQt')) + if not os.path.exists('.build'): + os.mkdir('.build') + os.chdir('.build') + python = '/Library/Frameworks/Python.framework/Versions/Current/bin/python' if isosx else 'python' + subprocess.check_call([python, '..'+os.sep+'configure.py']) + subprocess.check_call(['mingw32-make' if iswindows else 'make']) + ext = '.pyd' if iswindows else '.so' + plugin = glob.glob(base+ext)[0] + shutil.copyfile(plugin, os.path.join(cwd, 'src', 'calibre', 'plugins', plugin)) + finally: + os.chdir(cwd) + if islinux or isosx: + for f in glob.glob(os.path.join('src', 'calibre', 'plugins', '*')): + try: + os.readlink(f) + os.unlink(f) + except: + continue setup( name=APPNAME, @@ -62,6 +126,7 @@ if __name__ == '__main__': entry_points = entry_points, zip_safe = False, options = { 'bdist_egg' : {'exclude_source_files': True,}, }, + ext_modules=ext_modules, description = ''' E-book management application. diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 0a11a02705..1568dc8710 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -43,6 +43,39 @@ try: except: preferred_encoding = 'utf-8' +if getattr(sys, 'frozen', False): + if iswindows: + plugin_path = os.path.join(os.path.dirname(sys.executable), 'plugins') + elif isosx: + plugin_path = os.path.join(getattr(sys, 'frameworks_dir'), 'plugins') + elif islinux: + plugin_path = os.path.join(getattr(sys, 'frozen_path'), 'plugins') + sys.path.insert(0, plugin_path) +else: + import pkg_resources + plugins = getattr(pkg_resources, 'resource_filename')(__appname__, 'plugins') + sys.path.insert(0, plugins) + +if iswindows and getattr(sys, 'frozen', False): + sys.path.insert(1, os.path.dirname(sys.executable)) + + +plugins = {} +for plugin in ['pictureflow', 'lzx'] + (['winutil'] if iswindows else []): + try: + p, err = __import__(plugin), '' + except Exception, err: + p = None + err = str(err) + plugins[plugin] = (p, err) + +if iswindows: + winutil, winutilerror = plugins['winutil'] + if not winutil: + raise RuntimeError('Failed to load the winutil plugin: %s'%winutilerror) + sys.argv[1:] = winutil.argv()[1:] + + _abspath = os.path.abspath def my_abspath(path, encoding=sys.getfilesystemencoding()): ''' @@ -606,22 +639,3 @@ if isosx: exec 'from calibre.ebooks.lrf.fonts.liberation.'+font+' import font_data' open(os.path.join(fdir, font+'.ttf'), 'wb').write(font_data) -if islinux and not getattr(sys, 'frozen', False): - import pkg_resources - plugins = pkg_resources.resource_filename(__appname__, 'plugins') - sys.path.insert(1, plugins) - -if iswindows and getattr(sys, 'frozen', False): - sys.path.insert(1, os.path.dirname(sys.executable)) - - -plugins = {} -for plugin in ['pictureflow', 'lzx']: - try: - p, err = __import__(plugin), '' - except Exception, err: - p = None - err = str(err) - plugins[plugin] = (p, err) - - diff --git a/src/calibre/ebooks/lrf/lit/convert_from.py b/src/calibre/ebooks/lrf/lit/convert_from.py index 486a1e4cda..66d7b1182e 100644 --- a/src/calibre/ebooks/lrf/lit/convert_from.py +++ b/src/calibre/ebooks/lrf/lit/convert_from.py @@ -64,7 +64,8 @@ def process_file(path, options, logger=None): logger = logging.getLogger('lit2lrf') setup_cli_handlers(logger, level) lit = os.path.abspath(os.path.expanduser(path)) - tdir = generate_html2(lit, logger) if options.lit2oeb else generate_html(lit, logger) + tdir = generate_html2(lit, logger) if getattr(options, 'lit2oeb', False) \ + else generate_html(lit, logger) try: opf = glob.glob(os.path.join(tdir, '*.opf')) if opf: diff --git a/src/calibre/gui2/pictureflow/PyQt/Makefile b/src/calibre/gui2/pictureflow/PyQt/Makefile deleted file mode 100644 index f22d6515c6..0000000000 --- a/src/calibre/gui2/pictureflow/PyQt/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -TARGET = pictureflow.so -OFILES = sippictureflowcmodule.o sippictureflowPictureFlow.o -HFILES = sipAPIpictureflow.h - -CC = gcc -CXX = g++ -LINK = g++ -CPPFLAGS = -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -I. -I/usr/include/python2.5 -I/usr/lib/qt-3.3/mkspecs/default -I/usr/lib/qt-3.3/include -CFLAGS = -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -fPIC -Wall -W -D_REENTRANT -CXXFLAGS = -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -fPIC -Wall -W -D_REENTRANT -LFLAGS = -shared -Wl,--version-script=pictureflow.exp -LIBS = -L.. -L/usr/lib/qt-3.3/lib -lpictureflow -lqt-mt -lXext -lX11 -lm -lpthread -MOC = /usr/lib/qt-3.3/bin/moc -.SUFFIXES: .c .o .cpp .cc .cxx .C - - -.cpp.o: - $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< - -.cc.o: - $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< - -.cxx.o: - $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< - -.C.o: - $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $< - -.c.o: - $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< - -$(TARGET): $(OFILES) - @echo '{ global: initpictureflow; local: *; };' > pictureflow.exp - $(LINK) $(LFLAGS) -o $(TARGET) $(OFILES) $(LIBS) - -$(OFILES): $(HFILES) - -install: $(TARGET) - @test -d $(DESTDIR)/usr/lib/python2.5/site-packages || mkdir -p $(DESTDIR)/usr/lib/python2.5/site-packages - cp -f $(TARGET) $(DESTDIR)/usr/lib/python2.5/site-packages/$(TARGET) - -clean: - -rm -f $(TARGET) - -rm -f sippictureflowcmodule.o - -rm -f sippictureflowPictureFlow.o - -rm -f pictureflow.exp diff --git a/src/calibre/gui2/pictureflow/PyQt/configure.py b/src/calibre/gui2/pictureflow/PyQt/configure.py index 8b6295d817..61115f5fa6 100644 --- a/src/calibre/gui2/pictureflow/PyQt/configure.py +++ b/src/calibre/gui2/pictureflow/PyQt/configure.py @@ -1,4 +1,4 @@ -import os, sys, glob, shutil +import os, sys import sipconfig if os.environ.get('PYQT4PATH', None): print os.environ['PYQT4PATH'] @@ -35,16 +35,14 @@ makefile = pyqtconfig.QtGuiModuleMakefile ( # Add the library we are wrapping. The name doesn't include any platform # specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the # ".dll" extension on Windows). -if 'linux' in sys.platform: - for f in glob.glob('../../.build/libpictureflow.a'): - shutil.copyfile(f, os.path.basename(f)) - makefile.extra_lib_dirs = ['.'] -else: - makefile.extra_lib_dirs = ['..\\..\\.build\\release', '../../.build', '.'] -makefile.extra_libs = ['pictureflow0' if 'win' in sys.platform and 'darwin' not in sys.platform else "pictureflow"] +d = os.path.dirname +makefile.extra_lib_dirs += [os.path.abspath(os.path.join(d(d(d(d(os.getcwd())))), 'plugins')).replace(os.sep, '/')] +makefile.extra_libs += ['pictureflow1' if 'win32' in sys.platform else 'pictureflow'] makefile.extra_cflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else [] makefile.extra_lflags = ['-arch i386', '-arch ppc'] if 'darwin' in sys.platform else [] makefile.extra_cxxflags = makefile.extra_cflags +if 'win32' in sys.platform: + makefile.extra_lib_dirs += ['C:/Python25/libs'] # Generate the Makefile itself. makefile.generate() @@ -60,6 +58,6 @@ content = { # This creates the helloconfig.py module from the helloconfig.py.in # template and the dictionary. -sipconfig.create_config_module("pictureflowconfig.py", "../pictureflowconfig.py.in", content) +sipconfig.create_config_module("pictureflowconfig.py", '..'+os.sep+'pictureflowconfig.py.in', content) diff --git a/src/calibre/gui2/pictureflow/pictureflow.pro b/src/calibre/gui2/pictureflow/pictureflow.pro index 6632b7eede..a299ab9ce1 100644 --- a/src/calibre/gui2/pictureflow/pictureflow.pro +++ b/src/calibre/gui2/pictureflow/pictureflow.pro @@ -1,6 +1,6 @@ -TARGET = pictureflow +TARGET = pictureflow TEMPLATE = lib -HEADERS = pictureflow.h -SOURCES = pictureflow.cpp -VERSION = 0.2.0 -CONFIG += x86 ppc +HEADERS = pictureflow.h +SOURCES = pictureflow.cpp +VERSION = 1.0.0 +CONFIG += x86 ppc diff --git a/src/calibre/linux_installer.py b/src/calibre/linux_installer.py index d2266720f9..b433c36ffc 100644 --- a/src/calibre/linux_installer.py +++ b/src/calibre/linux_installer.py @@ -251,8 +251,14 @@ def download_tarball(): except ValueError: print 'Downloading calibre...' pb = None - src = urllib2.urlopen(MOBILEREAD+'calibre-%version-i686.tar.bz2') - size = int(src.info()['content-length']) + local = 'calibre-test.tar.bz2' + src = open(local) if os.access(local, os.R_OK) else urllib2.urlopen(MOBILEREAD+'calibre-%version-i686.tar.bz2') + if hasattr(src, 'info'): + size = int(src.info()['content-length']) + else: + src.seek(0, 2) + size = src.tell() + src.seek(0) f = tempfile.NamedTemporaryFile() while f.tell() < size: f.write(src.read(4*1024)) diff --git a/src/calibre/translations/ru.po b/src/calibre/translations/ru.po index 8e788d14d2..b0277eed95 100644 --- a/src/calibre/translations/ru.po +++ b/src/calibre/translations/ru.po @@ -6,23 +6,23 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.4.55\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-07-09 04:18+0000\n" -"PO-Revision-Date: 2008-07-02 21:26+0000\n" -"Last-Translator: Danil Semelenov \n" +"POT-Creation-Date: 2008-07-21 22:18+0000\n" +"PO-Revision-Date: 2008-07-22 05:27+0000\n" +"Last-Translator: Kovid Goyal \n" "Language-Team: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2008-07-19 02:36+0000\n" +"X-Launchpad-Export-Date: 2008-07-22 05:44+0000\n" "X-Generator: Launchpad (build Unknown)\n" "Generated-By: pygettext.py 1.5\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:133 +#: /home/kovid/work/calibre/src/calibre/__init__.py:138 #, fuzzy msgid "%sUsage%s: %s\n" msgstr "%sИспользовано%s: %s\n" -#: /home/kovid/work/calibre/src/calibre/__init__.py:170 +#: /home/kovid/work/calibre/src/calibre/__init__.py:175 msgid "Created by " msgstr "Сделано " @@ -55,9 +55,9 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf.py:429 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:278 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:685 -#: /home/kovid/work/calibre/src/calibre/library/database.py:925 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1433 -#: /home/kovid/work/calibre/src/calibre/library/database.py:1563 +#: /home/kovid/work/calibre/src/calibre/library/database.py:879 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1387 +#: /home/kovid/work/calibre/src/calibre/library/database.py:1517 msgid "Unknown" msgstr "Неизвестно" @@ -307,16 +307,13 @@ msgstr "" "Устанавливать разрывы страниц после тегов, имена которых соответствуют этому " "регулярному выражению." -# (pofilter) escapes: escapes in original ('"h\d,class,chapter".') don't match escapes in translation () #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:179 -#, fuzzy msgid "" "Force a page break before an element having the specified attribute. The " "format for this option is tagname regexp,attribute name,attribute value " "regexp. For example to match all heading tags that have the attribute " "class=\"chapter\" you would use \"h\\d,class,chapter\". Default is %default" msgstr "" -"Устанавливать разрывы страниц до элементов, имеющих определенный атрибут." #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:182 msgid "Add detected chapters to the table of contents." @@ -394,7 +391,7 @@ msgstr "" "распространенный вариант — utf-8. По умолчанию будет сделана попытка угадать " "кодировку." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:144 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:146 msgid "" "any2lrf [options] myfile\n" "\n" @@ -413,7 +410,7 @@ msgstr "" "ZIP, пытаясь обнаружить электронную книгу в архиве.\n" " " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:159 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/any/convert_from.py:161 msgid "No file to convert specified." msgstr "Не указан файл для преобразования." @@ -429,7 +426,7 @@ msgstr "" "\n" "%prog преобразует mybook.epub в mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:19 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:17 msgid "" "%prog [options] mybook.fb2\n" "\n" @@ -441,11 +438,15 @@ msgstr "" "\n" "%prog преобразует mybook.fb2 в mybook.lrf" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:22 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/txt/convert_from.py:22 msgid "Print generated HTML to stdout and quit." msgstr "Распечатать сгенерированный HTML в stdout и выйти." +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/fb2/convert_from.py:24 +msgid "Keep generated HTML files after completing conversion to LRF." +msgstr "" + #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/feeds/convert_from.py:22 msgid "Options to control the behavior of feeds2disk" msgstr "Опции управления поведением feeds2disk" @@ -458,96 +459,96 @@ msgstr "Опции управления поведением html2lrf" msgid "Fetching of recipe failed: " msgstr "Скачивание подпорки не удалось: " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:315 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:316 msgid "\tBook Designer file detected." msgstr "\tОпределен файл в формате Book Designer." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:317 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:318 msgid "\tParsing HTML..." msgstr "\tРазбор HTML..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:339 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:340 msgid "\tBaen file detected. Re-parsing..." msgstr "\tОпределен файл в формате Baen. Повторный разбор..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:355 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:356 #, fuzzy msgid "Written preprocessed HTML to " msgstr "Предварительно обработанный HTML сохранен в " -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:373 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:374 msgid "Processing %s" msgstr "Обработка %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:387 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:388 msgid "\tConverting to BBeB..." msgstr "\tПреобразование в BBeB..." -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:530 -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:543 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:531 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:544 msgid "Could not parse file: %s" msgstr "Не удалось разобрать файл: %s" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:535 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:536 msgid "%s is an empty file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:555 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:556 msgid "Failed to parse link %s %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:599 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:600 msgid "Cannot add link %s to TOC" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:944 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:949 msgid "Unable to process image %s. Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:982 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:987 msgid "Unable to process interlaced PNG %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:997 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1002 msgid "" "Could not process image: %s\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1744 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1749 msgid "" "An error occurred while processing a table: %s. Ignoring table markup." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1746 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1751 msgid "" "Bad table:\n" "%s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1768 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1773 msgid "Table has cell that is too large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1798 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1803 msgid "" "You have to save the website %s as an html file first and then run html2lrf " "on it." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1841 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1846 msgid "Could not read cover image: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1844 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1849 msgid "Cannot read from: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1978 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1984 msgid "Failed to process opf file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1984 +#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1990 msgid "" "Usage: %prog [options] mybook.html\n" "\n" @@ -745,7 +746,7 @@ msgid "mybook.epub" msgstr "" #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/epub.py:100 -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:34 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fb2.py:50 msgid "Usage:" msgstr "" @@ -818,19 +819,19 @@ msgstr "" msgid "No filename specified." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:344 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:391 msgid "%prog [options] myebook.mobi" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:346 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:393 msgid "Output directory. Defaults to current directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:365 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:412 msgid "Raw MOBI HTML saved in" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:367 +#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:414 msgid "OEB ebook created in" msgstr "" @@ -847,7 +848,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:27 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info_ui.py:58 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:531 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search.py:20 #: /home/kovid/work/calibre/src/calibre/gui2/library.py:246 msgid "Comments" @@ -876,52 +877,53 @@ msgstr "" msgid "Advanced" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:105 msgid "
Must be a directory." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:104 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:105 msgid "Invalid database location " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:104 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:105 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:108 msgid "Invalid database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:107 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:108 msgid "Invalid database location.
Cannot write to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:120 msgid "Compacting database. This may take a while." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:119 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:120 msgid "Compacting..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:206 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:216 #: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:265 msgid "Configuration" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:207 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:217 msgid "&Location of books database (library1.db)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:208 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:218 msgid "Browse for the new database location" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:209 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:237 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:239 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:513 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:300 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:126 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:131 @@ -935,85 +937,89 @@ msgstr "" msgid "..." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:210 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 msgid "Use &Roman numerals for series number" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:211 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:221 +msgid "&Number of covers to show in browse mode (after restart):" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 msgid "Show notification when &new version is available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:212 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 msgid "Format for &single file save:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:213 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 msgid "&Priority for conversion jobs:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:214 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 msgid "Default network &timeout:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:215 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:226 msgid "" "Set the default timeout for network fetches (i.e. anytime we go out to the " "internet to get information)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:216 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 msgid " seconds" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:217 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:228 msgid "Toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:218 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 msgid "Large" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 msgid "Medium" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:220 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:231 msgid "Small" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:221 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:232 msgid "&Button size in toolbar" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:222 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:233 msgid "Show &text in toolbar buttons" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:223 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:234 msgid "Select visible &columns in library view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:224 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:235 msgid "Frequently used directories" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:225 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:236 msgid "Add a directory to the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:227 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:238 msgid "Remove a directory from the frequently used directories list" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:229 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:240 msgid "Free unused diskspace from the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:230 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:241 msgid "&Compact database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:231 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:242 msgid "&Metadata from file name" msgstr "" @@ -1145,7 +1151,7 @@ msgid "Convert %s to LRF" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:108 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:177 msgid "Set conversion defaults" msgstr "" @@ -1236,17 +1242,17 @@ msgid "Options" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:290 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297 msgid "Book Cover" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:511 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298 msgid "Change &cover image:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:299 msgid "Browse for an image to use as the cover of this book." msgstr "" @@ -1255,25 +1261,25 @@ msgid "Use cover from &source file" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:515 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:258 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:263 msgid "&Title: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:516 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:259 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:264 msgid "Change the title of this book" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:517 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:116 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:260 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 msgid "&Author(s): " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:520 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:117 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 msgid "" "Change the author(s) of this book. Multiple authors should be separated by a " "comma" @@ -1285,24 +1291,24 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:521 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:124 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:268 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 msgid "&Publisher: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:522 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:125 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 msgid "Change the publisher of this book" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:523 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 msgid "Ta&gs: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:524 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:127 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:278 msgid "" "Tags categorize the book. This is particularly useful while searching. " "

They can be any words or phrases, separated by commas." @@ -1310,7 +1316,7 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:525 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:132 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 msgid "&Series:" msgstr "" @@ -1318,20 +1324,20 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:527 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:133 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:134 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:275 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:276 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:283 msgid "List of known series. You can add new series." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:528 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:529 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:287 msgid "Series index." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:530 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 msgid "Book " msgstr "" @@ -1507,36 +1513,36 @@ msgid "Edit Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:115 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:257 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 msgid "Meta information" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:118 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:262 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:269 msgid "Author S&ort: " msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:119 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:263 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:270 msgid "" "Specify how the author(s) of this book should be sorted. For example Charles " "Dickens should be sorted as Dickens, Charles." msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:120 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:264 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:271 msgid "&Rating:" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:266 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 msgid "Rating of this book. 0-5 stars" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:123 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:267 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:274 msgid " stars" msgstr "" @@ -1546,8 +1552,8 @@ msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:128 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:129 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:272 -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:273 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:279 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:280 msgid "Open Tag Editor" msgstr "" @@ -1559,67 +1565,71 @@ msgstr "" msgid "Comma separated list of tags to remove from the books. " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:235 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:241 msgid "" "

Enter your username and password for LibraryThing.com.
If you " "do not have one, you can register " "for free!.

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 msgid "Could not fetch cover.
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:265 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 msgid "Could not fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 msgid "Cannot fetch cover" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:271 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:277 msgid "You must specify the ISBN identifier for this book." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:256 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:261 msgid "Edit Meta Information" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277 -msgid "Remove unused series (Series that have no books)" -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:282 -msgid "IS&BN:" +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:265 +msgid "Swap the author and title" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:284 +msgid "Remove unused series (Series that have no books)" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:289 +msgid "IS&BN:" +msgstr "" + +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:291 msgid "Fetch metadata from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:285 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:292 msgid "Available Formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:286 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:293 msgid "Add a new format for this book to the database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:288 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 msgid "Remove the selected formats for this book from the database." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:301 msgid "Fetch cover image from server" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:295 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:302 msgid "" "Change the username and/or password for your account at LibraryThing.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:296 +#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:303 msgid "Change password" msgstr "" @@ -2164,110 +2174,110 @@ msgstr "" msgid "Configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:80 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:82 msgid "Error communicating with device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:93 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:95 msgid "" "

For help visit %s.kovidgoyal.net
" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:94 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:96 msgid "%s: %s by Kovid Goyal %%(version)s
%%(device)s

" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:112 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 msgid "Send to main memory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:113 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 msgid "Send to storage card" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:114 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:115 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:116 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 msgid "and delete from library" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:117 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:119 msgid "Send to storage card by default" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:129 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:131 msgid "Edit metadata individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:130 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:132 msgid "Edit metadata in bulk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:133 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 msgid "Add books from a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:134 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:136 msgid "" "Add books recursively (One book per directory, assumes every ebook file is " "the same book in a different format)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:135 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:137 msgid "" "Add books recursively (Multiple books per directory, assumes every ebook " "file is a different book)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:150 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 #: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:275 msgid "Save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:151 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153 msgid "Save to disk in a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:154 msgid "Save only %s format to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:155 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:157 #: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:281 msgid "View" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:156 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:158 msgid "View specific format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:172 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174 msgid "Convert individually" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:173 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:175 msgid "Bulk convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:309 msgid " detected." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:307 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:309 msgid "Device: " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:332 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:334 msgid "Connected " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:344 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:346 msgid "Device database corrupted" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:345 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:347 msgid "" "\n" "

The database of books on the reader is corrupted. Try the " @@ -2283,190 +2293,190 @@ msgid "" " " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:397 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:471 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:399 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:473 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/main.py:400 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:474 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:402 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:476 msgid "Duplicates found!" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:433 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:446 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:435 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:448 msgid "Uploading books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:505 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:507 msgid "No space on device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:506 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:508 msgid "" "

    Cannot upload books to device there is no more free space available " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:544 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:546 msgid "Deleting books from device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:576 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:597 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:578 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:599 msgid "Cannot edit metadata" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:576 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:597 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:692 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:578 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:599 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:694 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:764 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:834 msgid "No books selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:672 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:674 msgid "Sending books to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:675 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:677 msgid "No suitable formats" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:676 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:678 msgid "" "Could not upload the following books to the device, as no suitable formats " "were found:

      %s
    " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:692 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:694 msgid "Cannot save to disk" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:703 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:705 msgid "" "

    Could not save the following books to disk, because the %s format is not " "available for them:

      " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:707 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:709 msgid "Could not save some ebooks" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:740 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 msgid "Fetch news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:742 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:744 msgid "Fetching news from " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:752 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:754 msgid "News fetched. Uploading to device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:762 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:832 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:764 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:834 msgid "Cannot convert" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:771 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:773 msgid "Starting Bulk conversion of %d books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:903 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:921 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:905 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:923 msgid "No book selected" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:903 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:921 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:935 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:905 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:923 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:937 msgid "Cannot view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:909 -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:940 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:911 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:942 msgid "Choose the format to view" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:936 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:938 msgid "%s has no available formats." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:974 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:976 msgid "Cannot configure" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:974 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:976 msgid "Cannot configure while there are running jobs." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:997 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:999 msgid "Copying database to " msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1012 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1014 msgid "Invalid database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1013 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1015 msgid "" "

      An invalid database already exists at %s, delete it before trying to move " "the existing database.
      Error: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1021 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1023 msgid "Could not move database" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1042 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1044 msgid "No detailed info available" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1043 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1045 msgid "No detailed information is available for books on the device." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1085 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1087 msgid "Error talking to device" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1086 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1088 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:1137 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1139 msgid "Conversion Error" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1156 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1158 msgid "Database does not exist" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1156 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1158 msgid "" "The directory in which the database should be: %s no longer exists. Please " "choose a new database location." msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1207 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1209 msgid "" "Latest version: %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1213 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1215 msgid "" "%s has been updated to version %s. See the new features. " "Visit the download page?" msgstr "" -#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1213 +#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1215 msgid "Update available" msgstr "" @@ -2684,13 +2694,13 @@ msgstr "" msgid "Invalid sort field. Available fields:" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:173 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:174 msgid "" "The following books were not added as they already exist in the database " "(see --duplicates option):" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:197 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:198 msgid "" "%prog add [options] file1 file2 file3 ...\n" "\n" @@ -2699,27 +2709,27 @@ msgid "" "the directory related options below. \n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:206 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:207 msgid "" "Assume that each directory has only a single logical book and that all files " "in it are different e-book formats of that book" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:208 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:209 msgid "Process directories recursively" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:210 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:211 msgid "" "Add books to database even if they already exist. Comparison is done based " "on book titles." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:215 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:216 msgid "You must specify at least one file to add" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:233 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:234 msgid "" "%prog remove ids\n" "\n" @@ -2728,11 +2738,11 @@ msgid "" "command). For example, 23,34,57-85\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:245 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:246 msgid "You must specify at least one book to remove" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:265 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:266 msgid "" "%prog add_format [options] id ebook_file\n" "\n" @@ -2741,15 +2751,15 @@ msgid "" "already exists, it is replaced.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:276 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:277 msgid "You must specify an id and an ebook file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:281 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:282 msgid "ebook file must have an extension" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:289 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:290 msgid "" "\n" "%prog remove_format [options] id fmt\n" @@ -2759,11 +2769,11 @@ msgid "" "EPUB. If the logical book does not have fmt available, do nothing.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:302 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:303 msgid "You must specify an id and a format" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:320 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:321 msgid "" "\n" "%prog show_metadata [options] id\n" @@ -2773,15 +2783,15 @@ msgid "" "id is an id number from the list command. \n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:328 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:329 msgid "Print metadata in OPF form (XML)" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:333 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:334 msgid "You must specify an id" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:347 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:348 msgid "" "\n" "%prog set_metadata [options] id /path/to/metadata.opf\n" @@ -2794,11 +2804,11 @@ msgid "" "show_metadata command.\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:360 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:361 msgid "You must specify an id and a metadata file" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:372 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:373 msgid "" "%prog export [options] ids \n" "\n" @@ -2809,27 +2819,27 @@ msgid "" "an opf file). You can get id numbers from the list command. \n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:380 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:381 msgid "Export all books in database, ignoring the list of ids." msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:382 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:383 msgid "Export books to the specified directory. Default is" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:384 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:385 msgid "Export all books into a single directory" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:386 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:387 msgid "Create file names as author - title instead of title - author" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:391 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:392 msgid "You must specify some ids or the %s option" msgstr "" -#: /home/kovid/work/calibre/src/calibre/library/cli.py:401 +#: /home/kovid/work/calibre/src/calibre/library/cli.py:402 msgid "" "%%prog command [options] [arguments]\n" "\n" @@ -2841,11 +2851,11 @@ msgid "" "For help on an individual command: %%prog command --help\n" msgstr "" -#: /home/kovid/work/calibre/src/calibre/parallel.py:321 +#: /home/kovid/work/calibre/src/calibre/parallel.py:344 msgid "Could not launch worker process." msgstr "" -#: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:146 +#: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:157 msgid "Could not initialize the fontconfig library" msgstr "" diff --git a/src/calibre/utils/lzx-setup.py b/src/calibre/utils/lzx-setup.py deleted file mode 100644 index 87e523b9c3..0000000000 --- a/src/calibre/utils/lzx-setup.py +++ /dev/null @@ -1,5 +0,0 @@ -from distutils.core import setup, Extension - -setup(name="lzx", version="1.0", - ext_modules=[Extension('lzx', sources=['lzx/lzxmodule.c', 'lzx/lzxd.c'], - include_dirs=['lzx'])]) diff --git a/src/calibre/utils/lzx/setup.py b/src/calibre/utils/lzx/setup.py deleted file mode 100644 index 62fb37b12c..0000000000 --- a/src/calibre/utils/lzx/setup.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python -__license__ = 'GPL v3' -__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' -__docformat__ = 'restructuredtext en' - -''' -Build the lzx decompressor extension -''' -from distutils.core import setup, Extension - -setup(name="lzx", version="1.0", - ext_modules=[Extension('lzx', - sources=['lzxmodule.c', 'lzxd.c'], - include_dirs=['.'])]) - diff --git a/src/calibre/utils/winutil.c b/src/calibre/utils/winutil.c new file mode 100644 index 0000000000..04a4c3a49b --- /dev/null +++ b/src/calibre/utils/winutil.c @@ -0,0 +1,99 @@ +#define UNICODE +#include +#include +#include +#include + + +static PyObject * +winutil_folder_path(PyObject *self, PyObject *args) { + int res; DWORD dwFlags; + PyObject *ans = NULL; + TCHAR wbuf[MAX_PATH]; CHAR buf[4*MAX_PATH]; + memset(wbuf, 0, sizeof(TCHAR)*MAX_PATH); memset(buf, 0, sizeof(CHAR)*MAX_PATH); + + if (!PyArg_ParseTuple(args, "l", &dwFlags)) return NULL; + + res = SHGetFolderPath(NULL, dwFlags, NULL, 0, wbuf); + if (res != S_OK) { + if (res == E_FAIL) PyErr_SetString(PyExc_ValueError, "Folder does not exist."); + PyErr_SetString(PyExc_ValueError, "Folder not valid"); + return NULL; + } + res = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, 4*MAX_PATH, NULL, NULL); + ans = PyUnicode_DecodeUTF8(buf, res-1, "strict"); + return ans; +} + +static PyObject * +winutil_argv(PyObject *self, PyObject *args) { + PyObject *argv, *v; + LPWSTR *_argv; + LPSTR buf; + int argc, i, bytes; + if (!PyArg_ParseTuple(args, "")) return NULL; + _argv = CommandLineToArgvW(GetCommandLine(), &argc); + if (_argv == NULL) { PyErr_SetString(PyExc_RuntimeError, "Out of memory."); return NULL; } + argv = PyList_New(argc); + if (argv != NULL) { + for (i = 0; i < argc; i++) { + bytes = WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, NULL, 0, NULL, NULL); + buf = (LPSTR)PyMem_Malloc(sizeof(CHAR)*bytes); + if (buf == NULL) { Py_DECREF(argv); argv = NULL; break; } + WideCharToMultiByte(CP_UTF8, 0, _argv[i], -1, buf, bytes, NULL, NULL); + v = PyUnicode_DecodeUTF8(buf, bytes-1, "strict"); + PyMem_Free(buf); + if (v == NULL) { Py_DECREF(argv); argv = NULL; break; } + PyList_SetItem(argv, i, v); + } + } + LocalFree(_argv); + return argv; +} + +static PyMethodDef WinutilMethods[] = { + {"folder_path", winutil_folder_path, METH_VARARGS, + "folder_path(csidl_id) -> path\n\n" + "Get paths to common system folders. " + "See windows documentation of SHGetFolderPath. " + "The paths are returned as unicode objects. csidl_id should be one " + "of the symbolic constants defined in this module. You can also OR " + "a symbolic constant with CSIDL_FLAG_CREATE to force the operating " + "system to create a folder if it does not exist."}, + {"argv", winutil_argv, METH_VARARGS, + "argv() -> list of command line arguments\n\n" + "Get command line arguments as unicode objects. Note that the " + "first argument will be the path to the interpreter, *not* the " + "script being run. So to replace sys.argv, you should use " + "sys.argv[1:] = argv()[1:]."}, + + {NULL, NULL, 0, NULL} +}; + +PyMODINIT_FUNC +initwinutil(void) { + PyObject *m; + m = Py_InitModule3("winutil", WinutilMethods, + "Defines utility methods to interface with windows." + ); + if (m == NULL) return; + PyModule_AddIntConstant(m, "CSIDL_ADMINTOOLS", CSIDL_ADMINTOOLS); + PyModule_AddIntConstant(m, "CSIDL_APPDATA", CSIDL_APPDATA); + PyModule_AddIntConstant(m, "CSIDL_COMMON_ADMINTOOLS", CSIDL_COMMON_ADMINTOOLS); + PyModule_AddIntConstant(m, "CSIDL_COMMON_APPDATA", CSIDL_COMMON_APPDATA); + PyModule_AddIntConstant(m, "CSIDL_COMMON_DOCUMENTS", CSIDL_COMMON_DOCUMENTS); + PyModule_AddIntConstant(m, "CSIDL_COOKIES", CSIDL_COOKIES); + PyModule_AddIntConstant(m, "CSIDL_FLAG_CREATE", CSIDL_FLAG_CREATE); + PyModule_AddIntConstant(m, "CSIDL_FLAG_DONT_VERIFY", CSIDL_FLAG_DONT_VERIFY); + PyModule_AddIntConstant(m, "CSIDL_HISTORY", CSIDL_HISTORY); + PyModule_AddIntConstant(m, "CSIDL_INTERNET_CACHE", CSIDL_INTERNET_CACHE); + PyModule_AddIntConstant(m, "CSIDL_LOCAL_APPDATA", CSIDL_LOCAL_APPDATA); + PyModule_AddIntConstant(m, "CSIDL_MYPICTURES", CSIDL_MYPICTURES); + PyModule_AddIntConstant(m, "CSIDL_PERSONAL", CSIDL_PERSONAL); + PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES", CSIDL_PROGRAM_FILES); + PyModule_AddIntConstant(m, "CSIDL_PROGRAM_FILES_COMMON", CSIDL_PROGRAM_FILES_COMMON); + PyModule_AddIntConstant(m, "CSIDL_SYSTEM", CSIDL_SYSTEM); + PyModule_AddIntConstant(m, "CSIDL_WINDOWS", CSIDL_WINDOWS); + +} + diff --git a/upload.py b/upload.py index dfec9905c3..4d5dcf5121 100644 --- a/upload.py +++ b/upload.py @@ -29,10 +29,10 @@ BUILD_SCRIPT ='''\ #!/bin/bash cd ~/build && \ rsync -avz --exclude src/calibre/plugins --exclude docs --exclude .bzr --exclude .build --exclude build --exclude dist --exclude "*.pyc" --exclude "*.pyo" rsync://%(host)s/work/%(project)s . && \ -cd %(project)s && \ +cd %(project)s && rm -rf build dist src/calibre/plugins && \ mkdir -p build dist src/calibre/plugins && \ %%s && \ -rm -rf build/* dist/* && \ +rm -rf build/* && \ %%s %%s '''%dict(host=HOST, project=PROJECT) check_call = partial(_check_call, shell=True) @@ -63,6 +63,15 @@ def start_vm(vm, ssh_host, build_script, sleep=75): subprocess.check_call(('scp', t.name, ssh_host+':build-'+PROJECT)) subprocess.check_call('ssh -t %s bash build-%s'%(ssh_host, PROJECT), shell=True) +def run_windows_install_jammer(installer): + ibp = os.path.abspath('installer/windows') + sys.path.insert(0, ibp) + import build_installer + sys.path.remove(ibp) + build_installer.run_install_jammer(installer_name=os.path.basename(installer)) + if not os.path.exists(installer): + raise Exception('Failed to run installjammer') + def build_windows(shutdown=True): installer = installer_name('exe') vm = '/vmware/Windows XP/Windows XP Professional.vmx' @@ -72,20 +81,14 @@ def build_windows(shutdown=True): raise Exception('Failed to run py2exe') if shutdown: subprocess.Popen(('ssh', 'windows', 'shutdown', '-s', '-t', '0')) - ibp = os.path.abspath('installer/windows') - sys.path.insert(0, ibp) - import build_installer - sys.path.remove(ibp) - build_installer.run_install_jammer(installer_name=os.path.basename(installer)) - if not os.path.exists(installer): - raise Exception('Failed to run installjammer') + run_windows_install_jammer(installer) return os.path.basename(installer) def build_osx(shutdown=True): installer = installer_name('dmg') vm = '/vmware/Mac OSX/Mac OSX.vmx' python = '/Library/Frameworks/Python.framework/Versions/Current/bin/python' - start_vm(vm, 'osx', BUILD_SCRIPT%('sudo %s setup.py develop'%python, python, 'osx_installer.py')) + start_vm(vm, 'osx', (BUILD_SCRIPT%('sudo %s setup.py develop'%python, python, 'installer/osx/freeze.py')).replace('rm ', 'sudo rm ')) subprocess.check_call(('scp', 'osx:build/%s/dist/*.dmg'%PROJECT, 'dist')) if not os.path.exists(installer): raise Exception('Failed to build installer '+installer) @@ -97,7 +100,7 @@ def build_osx(shutdown=True): def build_linux(shutdown=True): installer = installer_name('tar.bz2') vm = '/vmware/linux/libprs500-gentoo.vmx' - start_vm(vm, 'linux', BUILD_SCRIPT%('sudo python setup.py develop', 'python','linux_installer.py')) + start_vm(vm, 'linux', (BUILD_SCRIPT%('sudo python setup.py develop', 'python','installer/linux/freeze.py')).replace('rm ', 'sudo rm ')) subprocess.check_call(('scp', 'linux:/tmp/%s'%os.path.basename(installer), 'dist')) if not os.path.exists(installer): raise Exception('Failed to build installer '+installer)