Merge upstream changes.

This commit is contained in:
Marshall T. Vandegrift 2008-12-12 09:11:31 -05:00
commit e2310c9970
98 changed files with 11443 additions and 1816 deletions

View File

@ -0,0 +1,244 @@
Changes from 4.0 to 4.0.1
1) Added support for Python 2.6. On Windows a manifest file is now required
because of the switch to using the new Microsoft C runtime.
2) Ensure that hooks are run for builtin modules.
Changes from 4.0b1 to 4.0
1) Added support for copying files to the target directory.
2) Added support for a hook that runs when a module is missing.
3) Added support for binary path includes as well as excludes; use sequences
rather than dictionaries as a more convenient API; exclude the standard
locations for 32-bit and 64-bit libaries in multi-architecture systems.
4) Added support for searching zip files (egg files) for modules.
5) Added support for handling system exit exceptions similarly to what Python
does itself as requested by Sylvain.
6) Added code to wait for threads to shut down like the normal Python
interpreter does. Thanks to Mariano Disanzo for discovering this
discrepancy.
7) Hooks added or modified based on feedback from many people.
8) Don't include the version name in the display name of the MSI.
9) Use the OS dependent path normalization routines rather than simply use the
lowercase value as on Unix case is important; thanks to Artie Eoff for
pointing this out.
10) Include a version attribute in the cx_Freeze package and display it in the
output for the --version option to the script.
11) Include build instructions as requested by Norbert Sebok.
12) Add support for copying files when modules are included which require data
files to operate properly; add support for copying the necessary files for
the Tkinter and matplotlib modules.
13) Handle deferred imports recursively as needed; ensure that from lists do
not automatically indicate that they are part of the module or the deferred
import processing doesn't actually work!
14) Handle the situation where a module imports everything from a package and
the __all__ variable has been defined but the package has not actually
imported everything in the __all__ variable during initialization.
15) Modified license text to more closely match the Python Software Foundation
license as was intended.
16) Added sample script for freezing an application using matplotlib.
17) Renamed freeze to cxfreeze to avoid conflict with another package that uses
that executable as requested by Siegfried Gevatter.
Changes from 3.0.3 to 4.0b1
1) Added support for placing modules in library.zip or in a separate zip file
for each executable that is produced.
2) Added support for copying binary dependent files (DLLs and shared
libraries)
3) Added support for including all submodules in a package
4) Added support for including icons in Windows executables
5) Added support for constants module which can be used for determining
certain build constants at runtime
6) Added support for relative imports available in Python 2.5 and up
7) Added support for building Windows installers (Python 2.5 and up) and
RPM packages
8) Added support for distutils configuration scripts
9) Added support for hooks which can force inclusion or exclusion of modules
when certain modules are included
10) Added documentation and samples
11) Added setup.py for building the cx_Freeze package instead of a script
used to build only the frozen bases
12) FreezePython renamed to a script called freeze in the Python distribution
13) On Linux and other platforms that support it set LD_RUN_PATH to include
the directory in which the executable is located
Changes from 3.0.2 to 3.0.3
1) In Common.c, used MAXPATHLEN defined in the Python OS independent include
file rather than the PATH_MAX define which is OS dependent and is not
available on IRIX as noted by Andrew Jones.
2) In the initscript ConsoleSetLibPath.py, added lines from initscript
Console.py that should have been there since the only difference between
that script and this one is the automatic re-execution of the executable.
3) Added an explicit "import encodings" to the initscripts in order to handle
Unicode encodings a little better. Thanks to Ralf Schmitt for pointing out
the problem and its solution.
4) Generated a meaningful name for the extension loader script so that it is
clear which particular extension module is being loaded when an exception
is being raised.
5) In MakeFrozenBases.py, use distutils to figure out a few more
platform-dependent linker flags as suggested by Ralf Schmitt.
Changes from 3.0.1 to 3.0.2
1) Add support for compressing the byte code in the zip files that are
produced.
2) Add better support for the win32com package as requested by Barry Scott.
3) Prevent deletion of target file if it happens to be identical to the
source file.
4) Include additional flags for local modifications to a Python build as
suggested by Benjamin Rutt.
5) Expanded instructions for building cx_Freeze from source based on a
suggestion from Gregg Lind.
6) Fix typo in help string.
Changes from 3.0 to 3.0.1
1) Added option --default-path which is used to specify the path used when
finding modules. This is particularly useful when performing cross
compilations (such as for building a frozen executable for Windows CE).
2) Added option --shared-lib-name which can be used to specify the name of
the shared library (DLL) implementing the Python runtime that is required
for the frozen executable to work. This option is also particularly useful
when cross compiling since the normal method for determining this
information cannot be used.
3) Added option --zip-include which allows for additional files to be added
to the zip file that contains the modules that implement the Python
script. Thanks to Barray Warsaw for providing the initial patch.
4) Added support for handling read-only files properly. Thanks to Peter
Grayson for pointing out the problem and providing a solution.
5) Added support for a frozen executable to be a symbolic link. Thanks to
Robert Kiendl for providing the initial patch.
6) Enhanced the support for running a frozen executable that uses an existing
Python installation to locate modules it requires. This is primarily of
use for embedding Python where the interface is C but the ability to run
from source is still desired.
7) Modified the documentation to indicate that building from source on
Windows currently requires the mingw compiler (http://www.mingw.org).
8) Workaround the problem in Python 2.3 (fixed in Python 2.4) which causes a
broken module to be left in sys.modules if an ImportError takes place
during the execution of the code in that module. Thanks to Roger Binns
for pointing this out.
Changes from 3.0 beta3 to 3.0
1) Ensure that ldd is only run on extension modules.
2) Allow for using a compiler other than gcc for building the frozen base
executables by setting the environment variable CC.
3) Ensure that the import lock is not held while executing the main script;
otherwise, attempts to import a module within a thread will hang that
thread as noted by Roger Binns.
4) Added support for replacing the paths in all frozen modules with something
else (so that for example the path of the machine on which the freezing
was done is not displayed in tracebacks)
Changes from 3.0 beta2 to 3.0 beta3
1) Explicitly include the warnings module so that at runtime warnings are
suppressed as when running Python normally.
2) Improve the extension loader so that an ImportError is raised when the
dynamic module is not located; otherwise an error about missing attributes
is raised instead.
3) Extension loaders are only created when copying dependencies since the
normal module should be loadable in the situation where a Python
installation is available.
4) Added support for Python 2.4.
5) Fixed the dependency checking for wxPython to be a little more
intelligent.
Changes from 3.0 beta1 to 3.0 beta2
1) Fix issues with locating the initscripts and bases relative to the
directory in which the executable was started.
2) Added new base executable ConsoleKeepPath which is used when an existing
Python installation is required (such as for FreezePython itself).
3) Forced the existence of a Python installation to be ignored when using the
standard Console base executable.
4) Remove the existing file when copying dependent files; otherwise, an error
is raised when attempting to overwrite read-only files.
5) Added option -O (or -OO) to FreezePython to set the optimization used when
generating bytecode.
Changes from 2.2 to 3.0 beta1
1) cx_Freeze now requires Python 2.3 or higher since it takes advantage of
the ability of Python 2.3 and higher to import modules from zip files.
This makes the freezing process considerably simpler and also allows for
the execution of multiple frozen packages (such as found in COM servers or
shared libraries) without requiring modification to the Python modules.
2) All external dependencies have been removed. cx_Freeze now only requires
a standard Python distribution to do its work.
3) Added the ability to define the initialization scripts that cx_Freeze uses
on startup of the frozen program. Previously, these scripts were written
in C and could not easily be changed; now they are written in Python and
can be found in the initscripts directory (and chosen with the
new --init-script option to FreezePython).
4) The base executable ConsoleSetLibPath has been removed and replaced with
the initscript ConsoleSetLibPath.
5) Removed base executables for Win32 services and Win32 COM servers. This
functionality will be restored in the future but it is not currently in a
state that is ready for release. If this functionality is required, please
use py2exe or contact me for my work in progress.
6) The attribute sys.frozen is now set so that more recent pywin32 modules
work as expected when frozen.
7) Added option --include-path to FreezePython to allow overriding of
sys.path without modifying the environment variable PYTHONPATH.
8) Added option --target-dir/--install-dir to specify the directory in which
the frozen executable and its dependencies will be placed.
9) Removed the option --shared-lib since it was used for building shared
libraries and can be managed with the initscript SharedLib.py.
10) MakeFrozenBases.py now checks the platform specific include directory as
requested by Michael Partridge.
Changes from 2.1 to 2.2
1) Add option (--ext-list-file) to FreezePython to write the list of
extensions copied to the installation directory to a file. This option is
useful in cases where multiple builds are performed into the same
installation directory.
2) Pass the arguments on the command line through to Win32 GUI applications.
Thanks to Michael Porter for pointing this out.
3) Link directly against the python DLL when building the frozen bases on
Windows, thus eliminating the need for building an import library.
4) Force sys.path to include the directory in which the script to be frozen
is found.
5) Make sure that the installation directory exists before attempting to
copy the target binary into it.
6) The Win32GUI base has been modified to display fatal errors in message
boxes, rather than printing errors to stderr, since on Windows the
standard file IO handles are all closed.
Changes from 2.0 to 2.1
1) Remove dependency on Python 2.2. Thanks to Paul Moore for not only
pointing it out but providing patches.
2) Set up the list of frozen modules in advance, rather than doing it after
Python is initialized so that implicit imports done by Python can be
satisfied. The bug in Python 2.3 that demonstrated this issue has been
fixed in the first release candidate. Thanks to Thomas Heller for pointing
out the obvious in this instance!
3) Added additional base executable (ConsoleSetLibPath) to support setting
the LD_LIBRARY_PATH variable on Unix platforms and restarting the
executable to put the new setting into effect. This is primarily of use
in distributing wxPython applications on Unix where the shared library
has an embedded RPATH value which can cause problems.
4) Small improvements of documentation based on feedback from several people.
5) Print information about the files written or copied during the freezing
process.
6) Do not copy extensions when freezing if the path is being overridden since
it is expected that a full Python installation is available to the target
users of the frozen binary.
7) Provide meaningful error message when the wxPython library cannot be
found during the freezing process.
Changes from 1.1 to 2.0
1) Added support for in process (DLL) COM servers using PythonCOM.
2) Ensured that the frozen flag is set prior to determining the full path for
the program in order to avoid warnings about Python not being found on
some platforms.
3) Added include file and resource file to the source tree to avoid the
dependency on the Wine message compiler for Win32 builds.
4) Dropped the option --copy-extensions; this now happens automatically since
the resulting binary is useless without them.
5) Added a sample for building a Win32 service.
6) Make use of improved modules from Python 2.3 (which function under 2.2)
Changes from 1.0 to 1.1
1) Fixed import error with C extensions in packages; thanks to Thomas Heller
for pointing out the solution to this problem.
2) Added options to FreezePython to allow for the inclusion of modules which
will not be found by the module finder (--include-modules) and the
exclusion of modules which will be found by the module finder but should
not be included (--exclude-modules).
3) Fixed typo in README.txt.

View File

@ -0,0 +1,53 @@
Copyright © 2007-2008, Colt Engineering, Edmonton, Alberta, Canada.
Copyright © 2001-2006, Computronix (Canada) Ltd., Edmonton, Alberta, Canada.
All rights reserved.
NOTE: this license is derived from the Python Software Foundation License
which can be found at http://www.python.org/psf/license
License for cx_Freeze 4.0.1
---------------------------
1. This LICENSE AGREEMENT is between the copyright holders and the Individual
or Organization ("Licensee") accessing and otherwise using cx_Freeze
software in source or binary form and its associated documentation.
2. Subject to the terms and conditions of this License Agreement, the
copyright holders hereby grant Licensee a nonexclusive, royalty-free,
world-wide license to reproduce, analyze, test, perform and/or display
publicly, prepare derivative works, distribute, and otherwise use cx_Freeze
alone or in any derivative version, provided, however, that this License
Agreement and this notice of copyright are retained in cx_Freeze alone or in
any derivative version prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on or
incorporates cx_Freeze or any part thereof, and wants to make the derivative
work available to others as provided herein, then Licensee hereby agrees to
include in any such work a brief summary of the changes made to cx_Freeze.
4. The copyright holders are making cx_Freeze available to Licensee on an
"AS IS" basis. THE COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES,
EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, THE COPYRIGHT
HOLDERS MAKE NO AND DISCLAIM ANY REPRESENTATION OR WARRANTY OF
MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF
CX_FREEZE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
5. THE COPYRIGHT HOLDERS SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF
CX_FREEZE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING CX_FREEZE, OR ANY
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material breach
of its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any relationship
of agency, partnership, or joint venture between the copyright holders and
Licensee. This License Agreement does not grant permission to use
copyright holder's trademarks or trade name in a trademark sense to endorse
or promote products or services of Licensee, or any third party.
8. By copying, installing or otherwise using cx_Freeze, Licensee agrees to be
bound by the terms and conditions of this License Agreement.
Computronix® is a registered trademark of Computronix (Canada) Ltd.

View File

@ -0,0 +1,6 @@
include MANIFEST.in
include *.txt
recursive-include doc *.html
recursive-include initscripts *.py
recursive-include samples *.py
recursive-include source *.c *.rc

View File

@ -0,0 +1,22 @@
Metadata-Version: 1.0
Name: cx_Freeze
Version: 4.0.1
Summary: create standalone executables from Python scripts
Home-page: http://cx-freeze.sourceforge.net
Author: Anthony Tuininga
Author-email: anthony.tuininga@gmail.com
License: Python Software Foundation License
Description: create standalone executables from Python scripts
Keywords: freeze
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Python Software Foundation License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: C
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Software Distribution
Classifier: Topic :: Utilities

View File

@ -0,0 +1,12 @@
Please see cx_Freeze.html for documentation on how to use cx_Freeze.
To build:
python setup.py build
python setup.py install
On Windows I have used the MinGW compiler (http://www.mingw.org)
python setup.py build --compiler=mingw32
python setup.py build --compiler=mingw32 install

View File

@ -0,0 +1,14 @@
version = "4.0.1"
import sys
from dist import *
if sys.platform == "win32" and sys.version_info[:2] >= (2, 5):
from windist import *
from finder import *
from freezer import *
from main import *
del dist
del finder
del freezer

View File

@ -0,0 +1,279 @@
import distutils.command.bdist_rpm
import distutils.command.build
import distutils.command.install
import distutils.core
import distutils.dir_util
import distutils.dist
import distutils.util
import distutils.version
import os
import sys
import cx_Freeze
__all__ = [ "bdist_rpm", "build", "build_exe", "install", "install_exe",
"setup" ]
class Distribution(distutils.dist.Distribution):
def __init__(self, attrs):
self.executables = []
distutils.dist.Distribution.__init__(self, attrs)
class bdist_rpm(distutils.command.bdist_rpm.bdist_rpm):
def finalize_options(self):
distutils.command.bdist_rpm.bdist_rpm.finalize_options(self)
self.use_rpm_opt_flags = 1
def _make_spec_file(self):
contents = distutils.command.bdist_rpm.bdist_rpm._make_spec_file(self)
return [c for c in contents if c != 'BuildArch: noarch']
class build(distutils.command.build.build):
user_options = distutils.command.build.build.user_options + [
('build-exe=', None, 'build directory for executables')
]
def get_sub_commands(self):
subCommands = distutils.command.build.build.get_sub_commands(self)
if self.distribution.executables:
subCommands.append("build_exe")
return subCommands
def initialize_options(self):
distutils.command.build.build.initialize_options(self)
self.build_exe = None
def finalize_options(self):
distutils.command.build.build.finalize_options(self)
if self.build_exe is None:
dirName = "exe.%s-%s" % \
(distutils.util.get_platform(), sys.version[0:3])
self.build_exe = os.path.join(self.build_base, dirName)
class build_exe(distutils.core.Command):
description = "build executables from Python scripts"
user_options = [
('build-exe=', 'b',
'directory for built executables'),
('optimize=', 'O',
'optimization level: -O1 for "python -O", '
'-O2 for "python -OO" and -O0 to disable [default: -O0]'),
('excludes=', 'e',
'comma-separated list of modules to exclude'),
('includes=', 'i',
'comma-separated list of modules to include'),
('packages=', 'p',
'comma-separated list of packages to include'),
('replace-paths=', None,
'comma-separated list of paths to replace in included modules'),
('path=', None,
'comma-separated list of paths to search'),
('init-script=', 'i',
'name of script to use during initialization'),
('base=', None,
'name of base executable to use'),
('compressed', 'c',
'create a compressed zipfile'),
('copy-dependent-files', None,
'copy all dependent files'),
('create-shared-zip', None,
'create a shared zip file containing shared modules'),
('append-script-to-exe', None,
'append the script module to the exe'),
('include-in-shared-zip', None,
'include the script module in the shared zip file'),
('icon', None,
'include the icon along with the frozen executable(s)'),
('constants=', None,
'comma-separated list of constants to include'),
('include-files=', 'f',
'list of tuples of additional files to include in distribution'),
('bin-includes', None,
'list of names of files to include when determining dependencies'),
('bin-excludes', None,
'list of names of files to exclude when determining dependencies')
]
boolean_options = ["compressed", "copy_dependent_files",
"create_shared_zip", "append_script_to_exe",
"include_in_shared_zip"]
def _normalize(self, attrName):
value = getattr(self, attrName)
if value is None:
normalizedValue = []
elif isinstance(value, basestring):
normalizedValue = value.split()
else:
normalizedValue = list(value)
setattr(self, attrName, normalizedValue)
def initialize_options(self):
self.optimize = 0
self.build_exe = None
self.excludes = []
self.includes = []
self.packages = []
self.replace_paths = []
self.compressed = None
self.copy_dependent_files = None
self.init_script = None
self.base = None
self.path = None
self.create_shared_zip = None
self.append_script_to_exe = None
self.include_in_shared_zip = None
self.icon = None
self.constants = []
self.include_files = []
self.bin_excludes = []
self.bin_includes = []
def finalize_options(self):
self.set_undefined_options('build', ('build_exe', 'build_exe'))
self.optimize = int(self.optimize)
self._normalize("excludes")
self._normalize("includes")
self._normalize("packages")
self._normalize("constants")
def run(self):
metadata = self.distribution.metadata
constantsModule = cx_Freeze.ConstantsModule(metadata.version)
for constant in self.constants:
parts = constant.split("=")
if len(parts) == 1:
name = constant
value = None
else:
name, stringValue = parts
value = eval(stringValue)
constantsModule.values[name] = value
freezer = cx_Freeze.Freezer(self.distribution.executables,
[constantsModule], self.includes, self.excludes, self.packages,
self.replace_paths, self.compressed, self.optimize,
self.copy_dependent_files, self.init_script, self.base,
self.path, self.create_shared_zip, self.append_script_to_exe,
self.include_in_shared_zip, self.build_exe, icon = self.icon,
includeFiles = self.include_files,
binIncludes = self.bin_includes,
binExcludes = self.bin_excludes)
freezer.Freeze()
class install(distutils.command.install.install):
user_options = distutils.command.install.install.user_options + [
('install-exe=', None,
'installation directory for executables')
]
def expand_dirs(self):
distutils.command.install.install.expand_dirs(self)
self._expand_attrs(['install_exe'])
def get_sub_commands(self):
subCommands = distutils.command.install.install.get_sub_commands(self)
if self.distribution.executables:
subCommands.append("install_exe")
return [s for s in subCommands if s != "install_egg_info"]
def initialize_options(self):
distutils.command.install.install.initialize_options(self)
self.install_exe = None
def finalize_options(self):
if self.prefix is None and sys.platform == "win32":
import _winreg
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
r"Software\Microsoft\Windows\CurrentVersion")
prefix = str(_winreg.QueryValueEx(key, "ProgramFilesDir")[0])
metadata = self.distribution.metadata
dirName = "%s-%s" % (metadata.name, metadata.version)
self.prefix = "%s/%s" % (prefix, dirName)
distutils.command.install.install.finalize_options(self)
self.convert_paths('exe')
if self.root is not None:
self.change_roots('exe')
def select_scheme(self, name):
distutils.command.install.install.select_scheme(self, name)
if self.install_exe is None:
if sys.platform == "win32":
self.install_exe = '$base'
else:
metadata = self.distribution.metadata
dirName = "%s-%s" % (metadata.name, metadata.version)
self.install_exe = '$base/lib/%s' % dirName
class install_exe(distutils.core.Command):
description = "install executables built from Python scripts"
user_options = [
('install-dir=', 'd', 'directory to install executables to'),
('build-dir=', 'b', 'build directory (where to install from)'),
('force', 'f', 'force installation (overwrite existing files)'),
('skip-build', None, 'skip the build steps')
]
def initialize_options(self):
self.install_dir = None
self.force = 0
self.build_dir = None
self.skip_build = None
def finalize_options(self):
self.set_undefined_options('build', ('build_exe', 'build_dir'))
self.set_undefined_options('install',
('install_exe', 'install_dir'),
('force', 'force'),
('skip_build', 'skip_build'))
def run(self):
if not self.skip_build:
self.run_command('build_exe')
self.outfiles = self.copy_tree(self.build_dir, self.install_dir)
if sys.platform != "win32":
baseDir = os.path.dirname(os.path.dirname(self.install_dir))
binDir = os.path.join(baseDir, "bin")
if not os.path.exists(binDir):
os.makedirs(binDir)
sourceDir = os.path.join("..", self.install_dir[len(baseDir) + 1:])
for executable in self.distribution.executables:
name = os.path.basename(executable.targetName)
source = os.path.join(sourceDir, name)
target = os.path.join(binDir, name)
if os.path.exists(target):
os.unlink(target)
os.symlink(source, target)
self.outfiles.append(target)
def get_inputs(self):
return self.distribution.executables or []
def get_outputs(self):
return self.outfiles or []
def _AddCommandClass(commandClasses, name, cls):
if name not in commandClasses:
commandClasses[name] = cls
def setup(**attrs):
attrs["distclass"] = Distribution
commandClasses = attrs.setdefault("cmdclass", {})
if sys.platform == "win32":
if sys.version_info[:2] >= (2, 5):
_AddCommandClass(commandClasses, "bdist_msi", cx_Freeze.bdist_msi)
else:
_AddCommandClass(commandClasses, "bdist_rpm", cx_Freeze.bdist_rpm)
_AddCommandClass(commandClasses, "build", build)
_AddCommandClass(commandClasses, "build_exe", build_exe)
_AddCommandClass(commandClasses, "install", install)
_AddCommandClass(commandClasses, "install_exe", install_exe)
distutils.core.setup(**attrs)

View File

@ -0,0 +1,455 @@
"""
Base class for finding modules.
"""
import dis
import imp
import marshal
import new
import opcode
import os
import sys
import zipfile
import cx_Freeze.hooks
BUILD_LIST = opcode.opmap["BUILD_LIST"]
INPLACE_ADD = opcode.opmap["INPLACE_ADD"]
LOAD_CONST = opcode.opmap["LOAD_CONST"]
IMPORT_NAME = opcode.opmap["IMPORT_NAME"]
IMPORT_FROM = opcode.opmap["IMPORT_FROM"]
STORE_NAME = opcode.opmap["STORE_NAME"]
STORE_GLOBAL = opcode.opmap["STORE_GLOBAL"]
STORE_OPS = (STORE_NAME, STORE_GLOBAL)
__all__ = [ "Module", "ModuleFinder" ]
class ModuleFinder(object):
def __init__(self, includeFiles, excludes, path, replacePaths):
self.includeFiles = includeFiles
self.excludes = dict.fromkeys(excludes)
self.replacePaths = replacePaths
self.path = path or sys.path
self.modules = []
self.aliases = {}
self._modules = dict.fromkeys(excludes)
self._builtinModules = dict.fromkeys(sys.builtin_module_names)
self._badModules = {}
self._zipFileEntries = {}
self._zipFiles = {}
cx_Freeze.hooks.initialize(self)
def _AddModule(self, name):
"""Add a module to the list of modules but if one is already found,
then return it instead; this is done so that packages can be
handled properly."""
module = self._modules.get(name)
if module is None:
module = self._modules[name] = Module(name)
self.modules.append(module)
if name in self._badModules:
del self._badModules[name]
return module
def _DetermineParent(self, caller):
"""Determine the parent to use when searching packages."""
if caller is not None:
if caller.path is not None:
return caller
return self._GetParentByName(caller.name)
def _EnsureFromList(self, caller, packageModule, fromList,
deferredImports):
"""Ensure that the from list is satisfied. This is only necessary for
package modules. If the caller is the package itself, actually
attempt to import right then since it must be a submodule; otherwise
defer until after all global names are defined in order to avoid
spurious complaints about missing modules."""
if caller is not packageModule:
deferredImports.append((packageModule, fromList))
else:
if fromList == ("*",):
fromList = packageModule.allNames
for name in fromList:
if name in packageModule.globalNames:
continue
subModuleName = "%s.%s" % (packageModule.name, name)
self._ImportModule(subModuleName, deferredImports, caller)
def _FindModule(self, name, path):
try:
return imp.find_module(name, path)
except ImportError:
if not path:
path = []
for location in path:
if name in self._zipFileEntries:
break
if location in self._zipFiles:
continue
if os.path.isdir(location) or not zipfile.is_zipfile(location):
self._zipFiles[location] = None
continue
zip = zipfile.ZipFile(location)
for archiveName in zip.namelist():
baseName, ext = os.path.splitext(archiveName)
if ext not in ('.pyc', '.pyo'):
continue
moduleName = ".".join(baseName.split("/"))
if moduleName in self._zipFileEntries:
continue
self._zipFileEntries[moduleName] = (zip, archiveName)
self._zipFiles[location] = None
info = self._zipFileEntries.get(name)
if info is not None:
zip, archiveName = info
fp = zip.read(archiveName)
info = (".pyc", "rb", imp.PY_COMPILED)
return fp, os.path.join(zip.filename, archiveName), info
raise
def _GetParentByName(self, name):
"""Return the parent module given the name of a module."""
pos = name.rfind(".")
if pos > 0:
parentName = name[:pos]
return self._modules[parentName]
def _ImportAllSubModules(self, module, deferredImports, recursive = True):
"""Import all sub modules to the given package."""
suffixes = dict.fromkeys([s[0] for s in imp.get_suffixes()])
for dir in module.path:
try:
fileNames = os.listdir(dir)
except os.error:
continue
for fileName in fileNames:
name, ext = os.path.splitext(fileName)
if ext not in suffixes:
continue
if name == "__init__":
continue
subModuleName = "%s.%s" % (module.name, name)
subModule, returnError = \
self._InternalImportModule(subModuleName,
deferredImports)
if returnError and subModule is None:
raise ImportError, "No module named %s" % subModuleName
module.globalNames[name] = None
if subModule.path and recursive:
self._ImportAllSubModules(subModule, deferredImports,
recursive)
def _ImportDeferredImports(self, deferredImports):
"""Import any sub modules that were deferred, if applicable."""
while deferredImports:
newDeferredImports = []
for packageModule, subModuleNames in deferredImports:
self._EnsureFromList(packageModule, packageModule,
subModuleNames, newDeferredImports)
deferredImports = newDeferredImports
def _ImportModule(self, name, deferredImports, caller = None,
relativeImportIndex = 0):
"""Attempt to find the named module and return it or None if no module
by that name could be found."""
# absolute import (available in Python 2.5 and up)
# the name given is the only name that will be searched
if relativeImportIndex == 0:
module, returnError = self._InternalImportModule(name,
deferredImports)
# old style relative import (only possibility in Python 2.4 and prior)
# the name given is tried in all parents until a match is found and if
# no match is found, the global namespace is searched
elif relativeImportIndex < 0:
parent = self._DetermineParent(caller)
while parent is not None:
fullName = "%s.%s" % (parent.name, name)
module, returnError = self._InternalImportModule(fullName,
deferredImports)
if module is not None:
parent.globalNames[name] = None
return module
parent = self._GetParentByName(parent.name)
module, returnError = self._InternalImportModule(name,
deferredImports)
# new style relative import (available in Python 2.5 and up)
# the index indicates how many levels to traverse and only that level
# is searched for the named module
elif relativeImportIndex > 0:
parent = caller
if parent.path is not None:
relativeImportIndex -= 1
while parent is not None and relativeImportIndex > 0:
parent = self._GetParentByName(parent.name)
relativeImportIndex -= 1
if parent is None:
module = None
returnError = True
elif not name:
module = parent
else:
name = "%s.%s" % (parent.name, name)
module, returnError = self._InternalImportModule(name,
deferredImports)
# if module not found, track that fact
if module is None:
if caller is None:
raise ImportError, "No module named %s" % name
self._RunHook("missing", name, caller)
if returnError and name not in caller.ignoreNames:
callers = self._badModules.setdefault(name, {})
callers[caller.name] = None
return module
def _InternalImportModule(self, name, deferredImports):
"""Internal method used for importing a module which assumes that the
name given is an absolute name. None is returned if the module
cannot be found."""
try:
return self._modules[name], False
except KeyError:
pass
if name in self._builtinModules:
module = self._AddModule(name)
self._RunHook("load", module.name, module)
return module, False
pos = name.rfind(".")
if pos < 0:
path = self.path
searchName = name
parentModule = None
else:
parentName = name[:pos]
parentModule, returnError = \
self._InternalImportModule(parentName, deferredImports)
if parentModule is None:
return None, returnError
path = parentModule.path
searchName = name[pos + 1:]
if name in self.aliases:
actualName = self.aliases[name]
module, returnError = \
self._InternalImportModule(actualName, deferredImports)
self._modules[name] = module
return module, returnError
try:
fp, path, info = self._FindModule(searchName, path)
except ImportError:
self._modules[name] = None
return None, True
module = self._LoadModule(name, fp, path, info, deferredImports,
parentModule)
return module, False
def _LoadModule(self, name, fp, path, info, deferredImports,
parent = None):
"""Load the module, given the information acquired by the finder."""
suffix, mode, type = info
if type == imp.PKG_DIRECTORY:
return self._LoadPackage(name, path, parent, deferredImports)
module = self._AddModule(name)
module.file = path
module.parent = parent
if type == imp.PY_SOURCE:
module.code = compile(fp.read() + "\n", path, "exec")
elif type == imp.PY_COMPILED:
if isinstance(fp, str):
magic = fp[:4]
else:
magic = fp.read(4)
if magic != imp.get_magic():
raise ImportError, "Bad magic number in %s" % path
if isinstance(fp, str):
module.code = marshal.loads(fp[8:])
module.inZipFile = True
else:
fp.read(4)
module.code = marshal.load(fp)
self._RunHook("load", module.name, module)
if module.code is not None:
if self.replacePaths:
topLevelModule = module
while topLevelModule.parent is not None:
topLevelModule = topLevelModule.parent
module.code = self._ReplacePathsInCode(topLevelModule,
module.code)
self._ScanCode(module.code, module, deferredImports)
return module
def _LoadPackage(self, name, path, parent, deferredImports):
"""Load the package, given its name and path."""
module = self._AddModule(name)
module.path = [path]
fp, path, info = imp.find_module("__init__", module.path)
self._LoadModule(name, fp, path, info, deferredImports, parent)
return module
def _ReplacePathsInCode(self, topLevelModule, co):
"""Replace paths in the code as directed, returning a new code object
with the modified paths in place."""
origFileName = newFileName = os.path.normpath(co.co_filename)
for searchValue, replaceValue in self.replacePaths:
if searchValue == "*":
searchValue = os.path.dirname(topLevelModule.file)
if topLevelModule.path:
searchValue = os.path.dirname(searchValue)
if searchValue:
searchValue = searchValue + os.pathsep
elif not origFileName.startswith(searchValue):
continue
newFileName = replaceValue + origFileName[len(searchValue):]
break
constants = list(co.co_consts)
for i, value in enumerate(constants):
if isinstance(value, type(co)):
constants[i] = self._ReplacePathsInCode(topLevelModule, value)
return new.code(co.co_argcount, co.co_nlocals, co.co_stacksize,
co.co_flags, co.co_code, tuple(constants), co.co_names,
co.co_varnames, newFileName, co.co_name, co.co_firstlineno,
co.co_lnotab, co.co_freevars, co.co_cellvars)
def _RunHook(self, hookName, moduleName, *args):
"""Run hook for the given module if one is present."""
name = "%s_%s" % (hookName, moduleName.replace(".", "_"))
method = getattr(cx_Freeze.hooks, name, None)
if method is not None:
method(self, *args)
def _ScanCode(self, co, module, deferredImports):
"""Scan code, looking for imported modules and keeping track of the
constants that have been created in order to better tell which
modules are truly missing."""
opIndex = 0
arguments = []
code = co.co_code
numOps = len(code)
while opIndex < numOps:
op = ord(code[opIndex])
opIndex += 1
if op >= dis.HAVE_ARGUMENT:
opArg = ord(code[opIndex]) + ord(code[opIndex + 1]) * 256
opIndex += 2
if op == LOAD_CONST:
arguments.append(co.co_consts[opArg])
elif op == IMPORT_NAME:
name = co.co_names[opArg]
if len(arguments) == 2:
relativeImportIndex, fromList = arguments
else:
relativeImportIndex = -1
fromList, = arguments
if name not in module.excludeNames:
subModule = self._ImportModule(name, deferredImports,
module, relativeImportIndex)
if subModule is not None:
module.globalNames.update(subModule.globalNames)
if fromList and subModule.path is not None:
self._EnsureFromList(module, subModule, fromList,
deferredImports)
elif op == IMPORT_FROM:
opIndex += 3
elif op not in (BUILD_LIST, INPLACE_ADD):
if op in STORE_OPS:
name = co.co_names[opArg]
if name == "__all__":
module.allNames.extend(arguments)
module.globalNames[name] = None
arguments = []
for constant in co.co_consts:
if isinstance(constant, type(co)):
self._ScanCode(constant, module, deferredImports)
def AddAlias(self, name, aliasFor):
"""Add an alias for a particular module; when an attempt is made to
import a module using the alias name, import the actual name
instead."""
self.aliases[name] = aliasFor
def ExcludeModule(self, name):
"""Exclude the named module from the resulting frozen executable."""
self.excludes[name] = None
self._modules[name] = None
def IncludeFile(self, path, moduleName = None):
"""Include the named file as a module in the frozen executable."""
name, ext = os.path.splitext(os.path.basename(path))
if moduleName is None:
moduleName = name
info = (ext, "r", imp.PY_SOURCE)
deferredImports = []
module = self._LoadModule(moduleName, file(path, "U"), path, info,
deferredImports)
self._ImportDeferredImports(deferredImports)
return module
def IncludeFiles(self, sourcePath, targetPath):
"""Include the files in the given directory in the target build."""
self.includeFiles.append((sourcePath, targetPath))
def IncludeModule(self, name):
"""Include the named module in the frozen executable."""
deferredImports = []
module = self._ImportModule(name, deferredImports)
self._ImportDeferredImports(deferredImports)
return module
def IncludePackage(self, name):
"""Include the named package and any submodules in the frozen
executable."""
deferredImports = []
module = self._ImportModule(name, deferredImports)
if module.path:
self._ImportAllSubModules(module, deferredImports)
self._ImportDeferredImports(deferredImports)
return module
def ReportMissingModules(self):
if self._badModules:
print "Missing modules:"
names = self._badModules.keys()
names.sort()
for name in names:
callers = self._badModules[name].keys()
callers.sort()
print "?", name, "imported from", ", ".join(callers)
print
class Module(object):
def __init__(self, name):
self.name = name
self.file = None
self.path = None
self.code = None
self.parent = None
self.globalNames = {}
self.excludeNames = {}
self.ignoreNames = {}
self.allNames = []
self.inZipFile = False
def __repr__(self):
parts = ["name=%s" % repr(self.name)]
if self.file is not None:
parts.append("file=%s" % repr(self.file))
if self.path is not None:
parts.append("path=%s" % repr(self.path))
return "<Module %s>" % ", ".join(parts)
def AddGlobalName(self, name):
self.globalNames[name] = None
def ExcludeName(self, name):
self.excludeNames[name] = None
def IgnoreName(self, name):
self.ignoreNames[name] = None

View File

@ -0,0 +1,550 @@
"""
Base class for freezing scripts into executables.
"""
import datetime
import distutils.sysconfig
import imp
import marshal
import os
import shutil
import socket
import stat
import struct
import sys
import time
import zipfile
import cx_Freeze
import cx_Freeze.util
__all__ = [ "ConfigError", "ConstantsModule", "Executable", "Freezer" ]
if sys.platform == "win32":
pythonDll = "python%s%s.dll" % sys.version_info[:2]
GLOBAL_BIN_PATH_EXCLUDES = [cx_Freeze.util.GetSystemDir()]
GLOBAL_BIN_INCLUDES = [
pythonDll,
"gdiplus.dll",
"mfc71.dll",
"msvcp71.dll",
"msvcr71.dll"
]
GLOBAL_BIN_EXCLUDES = [
"comctl32.dll",
"oci.dll",
"cx_Logging.pyd"
]
else:
extension = distutils.sysconfig.get_config_var("SO")
pythonSharedLib = "libpython%s.%s%s" % \
(sys.version_info[:2] + (extension,))
GLOBAL_BIN_INCLUDES = [pythonSharedLib]
GLOBAL_BIN_EXCLUDES = [
"libclntsh.so",
"libwtc9.so"
]
GLOBAL_BIN_PATH_EXCLUDES = ["/lib", "/lib32", "/lib64", "/usr/lib",
"/usr/lib32", "/usr/lib64"]
# NOTE: the try: except: block in this code is not necessary under Python 2.4
# and higher and can be removed once support for Python 2.3 is no longer needed
EXTENSION_LOADER_SOURCE = \
"""
import imp, os, sys
found = False
for p in sys.path:
if not os.path.isdir(p):
continue
f = os.path.join(p, "%s")
if not os.path.exists(f):
continue
try:
m = imp.load_dynamic(__name__, f)
except ImportError:
del sys.modules[__name__]
raise
sys.modules[__name__] = m
found = True
break
if not found:
del sys.modules[__name__]
raise ImportError, "No module named %%s" %% __name__
"""
class Freezer(object):
def __init__(self, executables, constantsModules = [], includes = [],
excludes = [], packages = [], replacePaths = [], compress = None,
optimizeFlag = 0, copyDependentFiles = None, initScript = None,
base = None, path = None, createLibraryZip = None,
appendScriptToExe = None, appendScriptToLibrary = None,
targetDir = None, binIncludes = [], binExcludes = [],
binPathIncludes = [], binPathExcludes = [], icon = None,
includeFiles = []):
self.executables = executables
self.constantsModules = constantsModules
self.includes = includes
self.excludes = excludes
self.packages = packages
self.replacePaths = replacePaths
self.compress = compress
self.optimizeFlag = optimizeFlag
self.copyDependentFiles = copyDependentFiles
self.initScript = initScript
self.base = base
self.path = path
self.createLibraryZip = createLibraryZip
self.appendScriptToExe = appendScriptToExe
self.appendScriptToLibrary = appendScriptToLibrary
self.targetDir = targetDir
self.binIncludes = [os.path.normcase(n) \
for n in GLOBAL_BIN_INCLUDES + binIncludes]
self.binExcludes = [os.path.normcase(n) \
for n in GLOBAL_BIN_EXCLUDES + binExcludes]
self.binPathIncludes = [os.path.normcase(n) for n in binPathIncludes]
self.binPathExcludes = [os.path.normcase(n) \
for n in GLOBAL_BIN_PATH_EXCLUDES + binPathExcludes]
self.icon = icon
self.includeFiles = includeFiles
self._VerifyConfiguration()
def _CopyFile(self, source, target, copyDependentFiles,
includeMode = False):
normalizedSource = os.path.normcase(os.path.normpath(source))
normalizedTarget = os.path.normcase(os.path.normpath(target))
if normalizedTarget in self.filesCopied:
return
if normalizedSource == normalizedTarget:
return
self._RemoveFile(target)
targetDir = os.path.dirname(target)
self._CreateDirectory(targetDir)
print "copying", source, "->", target
shutil.copyfile(source, target)
if includeMode:
shutil.copymode(source, target)
self.filesCopied[normalizedTarget] = None
if copyDependentFiles:
for source in self._GetDependentFiles(source):
target = os.path.join(targetDir, os.path.basename(source))
self._CopyFile(source, target, copyDependentFiles)
def _CreateDirectory(self, path):
if not os.path.isdir(path):
print "creating directory", path
os.makedirs(path)
def _FreezeExecutable(self, exe):
if self.createLibraryZip:
finder = self.finder
else:
finder = self._GetModuleFinder(exe)
if exe.script is None:
scriptModule = None
else:
scriptModule = finder.IncludeFile(exe.script, exe.moduleName)
self._CopyFile(exe.base, exe.targetName, exe.copyDependentFiles,
includeMode = True)
if exe.icon is not None:
if sys.platform == "win32":
cx_Freeze.util.AddIcon(exe.targetName, exe.icon)
else:
targetName = os.path.join(os.path.dirname(exe.targetName),
os.path.basename(exe.icon))
self._CopyFile(exe.icon, targetName,
copyDependentFiles = False)
if not os.access(exe.targetName, os.W_OK):
mode = os.stat(exe.targetName).st_mode
os.chmod(exe.targetName, mode | stat.S_IWUSR)
if not exe.appendScriptToLibrary:
if exe.appendScriptToExe:
fileName = exe.targetName
else:
baseFileName, ext = os.path.splitext(exe.targetName)
fileName = baseFileName + ".zip"
self._RemoveFile(fileName)
if not self.createLibraryZip and exe.copyDependentFiles:
scriptModule = None
self._WriteModules(fileName, exe.initScript, finder, exe.compress,
exe.copyDependentFiles, scriptModule)
def _GetBaseFileName(self, argsSource = None):
if argsSource is None:
argsSource = self
name = argsSource.base
if name is None:
if argsSource.copyDependentFiles:
name = "Console"
else:
name = "ConsoleKeepPath"
argsSource.base = self._GetFileName("bases", name)
if argsSource.base is None:
raise ConfigError("no base named %s", name)
def _GetDependentFiles(self, path):
dependentFiles = self.dependentFiles.get(path)
if dependentFiles is None:
if sys.platform == "win32":
origPath = os.environ["PATH"]
os.environ["PATH"] = origPath + os.pathsep + \
os.pathsep.join(sys.path)
dependentFiles = cx_Freeze.util.GetDependentFiles(path)
os.environ["PATH"] = origPath
else:
dependentFiles = []
for line in os.popen('ldd "%s"' % path):
parts = line.strip().split(" => ")
if len(parts) != 2:
continue
dependentFile = parts[1]
if dependentFile == "not found":
print "WARNING: cannot find", parts[0]
continue
pos = dependentFile.find(" (")
if pos >= 0:
dependentFile = dependentFile[:pos].strip()
if dependentFile:
dependentFiles.append(dependentFile)
dependentFiles = self.dependentFiles[path] = \
[f for f in dependentFiles if self._ShouldCopyFile(f)]
return dependentFiles
def _GetFileName(self, dir, name):
if os.path.isabs(name):
return name
name = os.path.normcase(name)
fullDir = os.path.join(os.path.dirname(cx_Freeze.__file__), dir)
if os.path.isdir(fullDir):
for fileName in os.listdir(fullDir):
if name == os.path.splitext(os.path.normcase(fileName))[0]:
return os.path.join(fullDir, fileName)
def _GetInitScriptFileName(self, argsSource = None):
if argsSource is None:
argsSource = self
name = argsSource.initScript
if name is None:
if argsSource.copyDependentFiles:
name = "Console"
else:
name = "ConsoleKeepPath"
argsSource.initScript = self._GetFileName("initscripts", name)
if argsSource.initScript is None:
raise ConfigError("no initscript named %s", name)
def _GetModuleFinder(self, argsSource = None):
if argsSource is None:
argsSource = self
finder = cx_Freeze.ModuleFinder(self.includeFiles, argsSource.excludes,
argsSource.path, argsSource.replacePaths)
if argsSource.copyDependentFiles:
finder.IncludeModule("imp")
finder.IncludeModule("os")
finder.IncludeModule("sys")
if argsSource.compress:
finder.IncludeModule("zlib")
for name in argsSource.includes:
finder.IncludeModule(name)
for name in argsSource.packages:
finder.IncludePackage(name)
return finder
def _PrintReport(self, fileName, modules):
print "writing zip file", fileName
print
print " %-25s %s" % ("Name", "File")
print " %-25s %s" % ("----", "----")
for module in modules:
if module.path:
print "P",
else:
print "m",
print "%-25s" % module.name, module.file or ""
print
def _RemoveFile(self, path):
if os.path.exists(path):
os.chmod(path, 0777)
os.remove(path)
def _ShouldCopyFile(self, path):
dir, name = os.path.split(os.path.normcase(path))
parts = name.split(".")
tweaked = False
while True:
if not parts[-1].isdigit():
break
parts.pop(-1)
tweaked = True
if tweaked:
name = ".".join(parts)
if name in self.binIncludes:
return True
if name in self.binExcludes:
return False
for path in self.binPathIncludes:
if dir.startswith(path):
return True
for path in self.binPathExcludes:
if dir.startswith(path):
return False
return True
def _VerifyCanAppendToLibrary(self):
if not self.createLibraryZip:
raise ConfigError("script cannot be appended to library zip if "
"one is not being created")
def _VerifyConfiguration(self):
if self.compress is None:
self.compress = True
if self.copyDependentFiles is None:
self.copyDependentFiles = True
if self.createLibraryZip is None:
self.createLibraryZip = True
if self.appendScriptToExe is None:
self.appendScriptToExe = False
if self.appendScriptToLibrary is None:
self.appendScriptToLibrary = \
self.createLibraryZip and not self.appendScriptToExe
if self.targetDir is None:
self.targetDir = os.path.abspath("dist")
self._GetInitScriptFileName()
self._GetBaseFileName()
if self.path is None:
self.path = sys.path
if self.appendScriptToLibrary:
self._VerifyCanAppendToLibrary()
for sourceFileName, targetFileName in self.includeFiles:
if not os.path.exists(sourceFileName):
raise ConfigError("cannot find file/directory named %s",
sourceFileName)
if os.path.isabs(targetFileName):
raise ConfigError("target file/directory cannot be absolute")
for executable in self.executables:
executable._VerifyConfiguration(self)
def _WriteModules(self, fileName, initScript, finder, compress,
copyDependentFiles, scriptModule = None):
initModule = finder.IncludeFile(initScript, "cx_Freeze__init__")
if scriptModule is None:
for module in self.constantsModules:
module.Create(finder)
modules = [m for m in finder.modules \
if m.name not in self.excludeModules]
else:
modules = [initModule, scriptModule]
self.excludeModules[initModule.name] = None
self.excludeModules[scriptModule.name] = None
itemsToSort = [(m.name, m) for m in modules]
itemsToSort.sort()
modules = [m for n, m in itemsToSort]
self._PrintReport(fileName, modules)
if scriptModule is None:
finder.ReportMissingModules()
targetDir = os.path.dirname(fileName)
self._CreateDirectory(targetDir)
filesToCopy = []
if os.path.exists(fileName):
mode = "a"
else:
mode = "w"
outFile = zipfile.PyZipFile(fileName, mode, zipfile.ZIP_DEFLATED)
for module in modules:
if module.code is None and module.file is not None:
fileName = os.path.basename(module.file)
baseFileName, ext = os.path.splitext(fileName)
if baseFileName != module.name and module.name != "zlib":
if "." in module.name:
fileName = module.name + ext
generatedFileName = "ExtensionLoader_%s.py" % \
module.name.replace(".", "_")
module.code = compile(EXTENSION_LOADER_SOURCE % fileName,
generatedFileName, "exec")
target = os.path.join(targetDir, fileName)
filesToCopy.append((module, target))
if module.code is None:
continue
fileName = "/".join(module.name.split("."))
if module.path:
fileName += "/__init__"
if module.file is not None and os.path.exists(module.file):
mtime = os.stat(module.file).st_mtime
else:
mtime = time.time()
zipTime = time.localtime(mtime)[:6]
data = imp.get_magic() + struct.pack("<i", mtime) + \
marshal.dumps(module.code)
zinfo = zipfile.ZipInfo(fileName + ".pyc", zipTime)
if compress:
zinfo.compress_type = zipfile.ZIP_DEFLATED
outFile.writestr(zinfo, data)
origPath = os.environ["PATH"]
for module, target in filesToCopy:
try:
if module.parent is not None:
path = os.pathsep.join([origPath] + module.parent.path)
os.environ["PATH"] = path
self._CopyFile(module.file, target, copyDependentFiles)
finally:
os.environ["PATH"] = origPath
def Freeze(self):
self.finder = None
self.excludeModules = {}
self.dependentFiles = {}
self.filesCopied = {}
cx_Freeze.util.SetOptimizeFlag(self.optimizeFlag)
if self.createLibraryZip:
self.finder = self._GetModuleFinder()
for executable in self.executables:
self._FreezeExecutable(executable)
if self.createLibraryZip:
fileName = os.path.join(self.targetDir, "library.zip")
self._RemoveFile(fileName)
self._WriteModules(fileName, self.initScript, self.finder,
self.compress, self.copyDependentFiles)
for sourceFileName, targetFileName in self.includeFiles:
fullName = os.path.join(self.targetDir, targetFileName)
if os.path.isdir(sourceFileName):
for path, dirNames, fileNames in os.walk(sourceFileName):
shortPath = path[len(sourceFileName) + 1:]
if ".svn" in dirNames:
dirNames.remove(".svn")
if "CVS" in dirNames:
dirNames.remove("CVS")
for fileName in fileNames:
fullSourceName = os.path.join(path, fileName)
fullTargetName = os.path.join(self.targetDir,
targetFileName, shortPath, fileName)
self._CopyFile(fullSourceName, fullTargetName,
copyDependentFiles = False)
else:
self._CopyFile(sourceFileName, fullName,
copyDependentFiles = False)
class ConfigError(Exception):
def __init__(self, format, *args):
self.what = format % args
def __str__(self):
return self.what
class Executable(object):
def __init__(self, script, initScript = None, base = None, path = None,
targetDir = None, targetName = None, includes = None,
excludes = None, packages = None, replacePaths = None,
compress = None, copyDependentFiles = None,
appendScriptToExe = None, appendScriptToLibrary = None,
icon = None):
self.script = script
self.initScript = initScript
self.base = base
self.path = path
self.targetDir = targetDir
self.targetName = targetName
self.includes = includes
self.excludes = excludes
self.packages = packages
self.replacePaths = replacePaths
self.compress = compress
self.copyDependentFiles = copyDependentFiles
self.appendScriptToExe = appendScriptToExe
self.appendScriptToLibrary = appendScriptToLibrary
self.icon = icon
def __repr__(self):
return "<Executable script=%s>" % self.script
def _VerifyConfiguration(self, freezer):
if self.path is None:
self.path = freezer.path
if self.targetDir is None:
self.targetDir = freezer.targetDir
if self.includes is None:
self.includes = freezer.includes
if self.excludes is None:
self.excludes = freezer.excludes
if self.packages is None:
self.packages = freezer.packages
if self.replacePaths is None:
self.replacePaths = freezer.replacePaths
if self.compress is None:
self.compress = freezer.compress
if self.copyDependentFiles is None:
self.copyDependentFiles = freezer.copyDependentFiles
if self.appendScriptToExe is None:
self.appendScriptToExe = freezer.appendScriptToExe
if self.appendScriptToLibrary is None:
self.appendScriptToLibrary = freezer.appendScriptToLibrary
if self.initScript is None:
self.initScript = freezer.initScript
else:
freezer._GetInitScriptFileName(self)
if self.base is None:
self.base = freezer.base
else:
freezer._GetBaseFileName(self)
if self.appendScriptToLibrary:
freezer._VerifyCanAppendToLibrary()
if self.icon is None:
self.icon = freezer.icon
if self.script is not None:
name, ext = os.path.splitext(os.path.basename(self.script))
if self.appendScriptToLibrary:
self.moduleName = "%s__main__" % os.path.normcase(name)
else:
self.moduleName = "__main__"
if self.targetName is None:
baseName, ext = os.path.splitext(self.base)
self.targetName = name + ext
self.targetName = os.path.join(self.targetDir, self.targetName)
class ConstantsModule(object):
def __init__(self, releaseString = None, copyright = None,
moduleName = "BUILD_CONSTANTS", timeFormat = "%B %d, %Y %H:%M:%S"):
self.moduleName = moduleName
self.timeFormat = timeFormat
self.values = {}
self.values["BUILD_RELEASE_STRING"] = releaseString
self.values["BUILD_COPYRIGHT"] = copyright
def Create(self, finder):
"""Create the module which consists of declaration statements for each
of the values."""
today = datetime.datetime.today()
sourceTimestamp = 0
for module in finder.modules:
if module.file is None:
continue
if module.inZipFile:
continue
if not os.path.exists(module.file):
raise ConfigError("no file named %s", module.file)
timestamp = os.stat(module.file).st_mtime
sourceTimestamp = max(sourceTimestamp, timestamp)
sourceTimestamp = datetime.datetime.fromtimestamp(sourceTimestamp)
self.values["BUILD_TIMESTAMP"] = today.strftime(self.timeFormat)
self.values["BUILD_HOST"] = socket.gethostname().split(".")[0]
self.values["SOURCE_TIMESTAMP"] = \
sourceTimestamp.strftime(self.timeFormat)
module = finder._AddModule(self.moduleName)
sourceParts = []
names = self.values.keys()
names.sort()
for name in names:
value = self.values[name]
sourceParts.append("%s = %r" % (name, value))
source = "\n".join(sourceParts)
module.code = compile(source, "%s.py" % self.moduleName, "exec")

View File

@ -0,0 +1,281 @@
import os
import sys
def initialize(finder):
"""upon initialization of the finder, this routine is called to set up some
automatic exclusions for various platforms."""
finder.ExcludeModule("FCNTL")
finder.ExcludeModule("os.path")
if os.name == "nt":
finder.ExcludeModule("fcntl")
finder.ExcludeModule("grp")
finder.ExcludeModule("pwd")
finder.ExcludeModule("termios")
else:
finder.ExcludeModule("_winreg")
finder.ExcludeModule("msilib")
finder.ExcludeModule("msvcrt")
finder.ExcludeModule("nt")
if os.name not in ("os2", "ce"):
finder.ExcludeModule("ntpath")
finder.ExcludeModule("nturl2path")
finder.ExcludeModule("pythoncom")
finder.ExcludeModule("pywintypes")
finder.ExcludeModule("winerror")
finder.ExcludeModule("winsound")
finder.ExcludeModule("win32api")
finder.ExcludeModule("win32con")
finder.ExcludeModule("win32event")
finder.ExcludeModule("win32file")
finder.ExcludeModule("win32pdh")
finder.ExcludeModule("win32pipe")
finder.ExcludeModule("win32process")
finder.ExcludeModule("win32security")
finder.ExcludeModule("win32service")
finder.ExcludeModule("wx.activex")
if os.name != "posix":
finder.ExcludeModule("posix")
if os.name != "mac":
finder.ExcludeModule("Carbon")
finder.ExcludeModule("gestalt")
finder.ExcludeModule("ic")
finder.ExcludeModule("mac")
finder.ExcludeModule("MacOS")
finder.ExcludeModule("macpath")
finder.ExcludeModule("macurl2path")
if os.name != "nt":
finder.ExcludeModule("EasyDialogs")
if os.name != "os2":
finder.ExcludeModule("os2")
finder.ExcludeModule("os2emxpath")
finder.ExcludeModule("_emx_link")
if os.name != "ce":
finder.ExcludeModule("ce")
if os.name != "riscos":
finder.ExcludeModule("riscos")
finder.ExcludeModule("riscosenviron")
finder.ExcludeModule("riscospath")
finder.ExcludeModule("rourl2path")
if sys.platform[:4] != "java":
finder.ExcludeModule("java.lang")
finder.ExcludeModule("org.python.core")
def load_cElementTree(finder, module):
"""the cElementTree module implicitly loads the elementtree.ElementTree
module; make sure this happens."""
finder.IncludeModule("elementtree.ElementTree")
def load_ceODBC(finder, module):
"""the ceODBC module implicitly imports both datetime and decimal; make
sure this happens."""
finder.IncludeModule("datetime")
finder.IncludeModule("decimal")
def load_cx_Oracle(finder, module):
"""the cx_Oracle module implicitly imports datetime; make sure this
happens."""
finder.IncludeModule("datetime")
def load_docutils_frontend(finder, module):
"""The optik module is the old name for the optparse module; ignore the
module if it cannot be found."""
module.IgnoreName("optik")
def load_dummy_threading(finder, module):
"""the dummy_threading module plays games with the name of the threading
module for its own purposes; ignore that here"""
finder.ExcludeModule("_dummy_threading")
def load_email(finder, module):
"""the email package has a bunch of aliases as the submodule names were
all changed to lowercase in Python 2.5; mimic that here."""
if sys.version_info[:2] >= (2, 5):
for name in ("Charset", "Encoders", "Errors", "FeedParser",
"Generator", "Header", "Iterators", "Message", "Parser",
"Utils", "base64MIME", "quopriMIME"):
finder.AddAlias("email.%s" % name, "email.%s" % name.lower())
def load_ftplib(finder, module):
"""the ftplib module attempts to import the SOCKS module; ignore this
module if it cannot be found"""
module.IgnoreName("SOCKS")
def load_matplotlib(finder, module):
"""the matplotlib module requires data to be found in mpl-data in the
same directory as the frozen executable so oblige it"""
dir = os.path.join(module.path[0], "mpl-data")
finder.IncludeFiles(dir, "mpl-data")
def load_matplotlib_numerix(finder, module):
"""the numpy.numerix module loads a number of modules dynamically"""
for name in ("ma", "fft", "linear_algebra", "random_array", "mlab"):
finder.IncludeModule("%s.%s" % (module.name, name))
def load_numpy_linalg(finder, module):
"""the numpy.linalg module implicitly loads the lapack_lite module; make
sure this happens"""
finder.IncludeModule("numpy.linalg.lapack_lite")
def load_pty(finder, module):
"""The sgi module is not needed for this module to function."""
module.IgnoreName("sgi")
def load_pythoncom(finder, module):
"""the pythoncom module is actually contained in a DLL but since those
cannot be loaded directly in Python 2.5 and higher a special module is
used to perform that task; simply use that technique directly to
determine the name of the DLL and ensure it is included as a normal
extension; also load the pywintypes module which is implicitly
loaded."""
import pythoncom
module.file = pythoncom.__file__
module.code = None
finder.IncludeModule("pywintypes")
def load_pywintypes(finder, module):
"""the pywintypes module is actually contained in a DLL but since those
cannot be loaded directly in Python 2.5 and higher a special module is
used to perform that task; simply use that technique directly to
determine the name of the DLL and ensure it is included as a normal
extension."""
import pywintypes
module.file = pywintypes.__file__
module.code = None
def load_PyQt4_Qt(finder, module):
"""the PyQt4.Qt module is an extension module which imports a number of
other modules and injects their namespace into its own. It seems a
foolish way of doing things but perhaps there is some hidden advantage
to this technique over pure Python; ignore the absence of some of
the modules since not every installation includes all of them."""
finder.IncludeModule("PyQt4.QtCore")
finder.IncludeModule("PyQt4.QtGui")
finder.IncludeModule("sip")
for name in ("PyQt4.QtSvg", "PyQt4.Qsci", "PyQt4.QtAssistant",
"PyQt4.QtNetwork", "PyQt4.QtOpenGL", "PyQt4.QtScript", "PyQt4._qt",
"PyQt4.QtSql", "PyQt4.QtSvg", "PyQt4.QtTest", "PyQt4.QtXml"):
try:
finder.IncludeModule(name)
except ImportError:
pass
def load_Tkinter(finder, module):
"""the Tkinter module has data files that are required to be loaded so
ensure that they are copied into the directory that is expected at
runtime."""
import Tkinter
import _tkinter
tk = _tkinter.create()
tclDir = os.path.dirname(tk.call("info", "library"))
tclSourceDir = os.path.join(tclDir, "tcl%s" % _tkinter.TCL_VERSION)
tkSourceDir = os.path.join(tclDir, "tk%s" % _tkinter.TK_VERSION)
finder.IncludeFiles(tclSourceDir, "tcl")
finder.IncludeFiles(tkSourceDir, "tk")
def load_tempfile(finder, module):
"""the tempfile module attempts to load the fcntl and thread modules but
continues if these modules cannot be found; ignore these modules if they
cannot be found."""
module.IgnoreName("fcntl")
module.IgnoreName("thread")
def load_time(finder, module):
"""the time module implicitly loads _strptime; make sure this happens."""
finder.IncludeModule("_strptime")
def load_win32api(finder, module):
"""the win32api module implicitly loads the pywintypes module; make sure
this happens."""
finder.IncludeModule("pywintypes")
def load_win32com(finder, module):
"""the win32com package manipulates its search path at runtime to include
the sibling directory called win32comext; simulate that by changing the
search path in a similar fashion here."""
baseDir = os.path.dirname(os.path.dirname(module.file))
module.path.append(os.path.join(baseDir, "win32comext"))
def load_win32file(finder, module):
"""the win32api module implicitly loads the pywintypes module; make sure
this happens."""
finder.IncludeModule("pywintypes")
def load_xml(finder, module):
"""the builtin xml package attempts to load the _xmlplus module to see if
that module should take its role instead; ignore the failure to find
this module, though."""
module.IgnoreName("_xmlplus")
def load_xml_etree_cElementTree(finder, module):
"""the xml.etree.cElementTree module implicitly loads the
xml.etree.ElementTree module; make sure this happens."""
finder.IncludeModule("xml.etree.ElementTree")
def load_IPython(finder, module):
ipy = os.path.join(os.path.dirname(module.file), 'Extensions')
extensions = set([])
for m in os.listdir(ipy):
extensions.add(os.path.splitext(m)[0])
extensions.remove('__init__')
for m in extensions:
finder.IncludeModule('IPython.Extensions.'+m)
def load_lxml(finder, module):
finder.IncludeModule('lxml._elementpath')
def load_cherrypy(finder, module):
finder.IncludeModule('cherrypy.lib.encoding')
def missing_cElementTree(finder, caller):
"""the cElementTree has been incorporated into the standard library in
Python 2.5 so ignore its absence if it cannot found."""
if sys.version_info[:2] >= (2, 5):
caller.IgnoreName("cElementTree")
def missing_EasyDialogs(finder, caller):
"""the EasyDialogs module is not normally present on Windows but it also
may be so instead of excluding it completely, ignore it if it can't be
found"""
if sys.platform == "win32":
caller.IgnoreName("EasyDialogs")
def missing_readline(finder, caller):
"""the readline module is not normally present on Windows but it also may
be so instead of excluding it completely, ignore it if it can't be
found"""
if sys.platform == "win32":
caller.IgnoreName("readline")
def missing_xml_etree(finder, caller):
"""the xml.etree package is new for Python 2.5 but it is common practice
to use a try..except.. block in order to support versions earlier than
Python 2.5 transparently; ignore the absence of the package in this
situation."""
if sys.version_info[:2] < (2, 5):
caller.IgnoreName("xml.etree")

View File

@ -0,0 +1,171 @@
import optparse
import os
import shutil
import stat
import sys
import cx_Freeze
__all__ = ["main"]
USAGE = \
"""
%prog [options] [SCRIPT]
Freeze a Python script and all of its referenced modules to a base
executable which can then be distributed without requiring a Python
installation."""
VERSION = \
"""
%%prog %s
Copyright (c) 2007-2008 Colt Engineering. All rights reserved.
Copyright (c) 2001-2006 Computronix Corporation. All rights reserved.""" % \
cx_Freeze.version
def ParseCommandLine():
parser = optparse.OptionParser(version = VERSION.strip(),
usage = USAGE.strip())
parser.add_option("-O",
action = "count",
default = 0,
dest = "optimized",
help = "optimize generated bytecode as per PYTHONOPTIMIZE; "
"use -OO in order to remove doc strings")
parser.add_option("-c", "--compress",
action = "store_true",
dest = "compress",
help = "compress byte code in zip files")
parser.add_option("--base-name",
dest = "baseName",
metavar = "NAME",
help = "file on which to base the target file; if the name of the "
"file is not an absolute file name, the subdirectory bases "
"(rooted in the directory in which the freezer is found) "
"will be searched for a file matching the name")
parser.add_option("--init-script",
dest = "initScript",
metavar = "NAME",
help = "script which will be executed upon startup; if the name "
"of the file is not an absolute file name, the "
"subdirectory initscripts (rooted in the directory in "
"which the cx_Freeze package is found) will be searched "
"for a file matching the name")
parser.add_option("--target-dir", "--install-dir",
dest = "targetDir",
metavar = "DIR",
help = "the directory in which to place the target file and "
"any dependent files")
parser.add_option("--target-name",
dest = "targetName",
metavar = "NAME",
help = "the name of the file to create instead of the base name "
"of the script and the extension of the base binary")
parser.add_option("--no-copy-deps",
dest = "copyDeps",
default = True,
action = "store_false",
help = "do not copy the dependent files (extensions, shared "
"libraries, etc.) to the target directory; this also "
"modifies the default init script to ConsoleKeepPath.py "
"and means that the target executable requires a Python "
"installation to execute properly")
parser.add_option("--default-path",
action = "append",
dest = "defaultPath",
metavar = "DIRS",
help = "list of paths separated by the standard path separator "
"for the platform which will be used to initialize "
"sys.path prior to running the module finder")
parser.add_option("--include-path",
action = "append",
dest = "includePath",
metavar = "DIRS",
help = "list of paths separated by the standard path separator "
"for the platform which will be used to modify sys.path "
"prior to running the module finder")
parser.add_option("--replace-paths",
dest = "replacePaths",
metavar = "DIRECTIVES",
help = "replace all the paths in modules found in the given paths "
"with the given replacement string; multiple values are "
"separated by the standard path separator and each value "
"is of the form path=replacement_string; path can be * "
"which means all paths not already specified")
parser.add_option("--include-modules",
dest = "includeModules",
metavar = "NAMES",
help = "comma separated list of modules to include")
parser.add_option("--exclude-modules",
dest = "excludeModules",
metavar = "NAMES",
help = "comma separated list of modules to exclude")
parser.add_option("--ext-list-file",
dest = "extListFile",
metavar = "NAME",
help = "name of file in which to place the list of dependent files "
"which were copied into the target directory")
parser.add_option("-z", "--zip-include",
dest = "zipIncludes",
action = "append",
default = [],
metavar = "SPEC",
help = "name of file to add to the zip file or a specification of "
"the form name=arcname which will specify the archive name "
"to use; multiple --zip-include arguments can be used")
options, args = parser.parse_args()
if len(args) == 0:
options.script = None
elif len(args) == 1:
options.script, = args
else:
parser.error("only one script can be specified")
if not args and options.includeModules is None and options.copyDeps:
parser.error("script or a list of modules must be specified")
if not args and options.targetName is None:
parser.error("script or a target name must be specified")
if options.excludeModules:
options.excludeModules = options.excludeModules.split(",")
else:
options.excludeModules = []
if options.includeModules:
options.includeModules = options.includeModules.split(",")
else:
options.includeModules = []
replacePaths = []
if options.replacePaths:
for directive in options.replacePaths.split(os.pathsep):
fromPath, replacement = directive.split("=")
replacePaths.append((fromPath, replacement))
options.replacePaths = replacePaths
if options.defaultPath is not None:
sys.path = [p for mp in options.defaultPath \
for p in mp.split(os.pathsep)]
if options.includePath is not None:
paths = [p for mp in options.includePath for p in mp.split(os.pathsep)]
sys.path = paths + sys.path
if options.script is not None:
sys.path.insert(0, os.path.dirname(options.script))
return options
def main():
options = ParseCommandLine()
executables = [cx_Freeze.Executable(options.script,
targetName = options.targetName)]
freezer = cx_Freeze.Freezer(executables,
includes = options.includeModules,
excludes = options.excludeModules,
replacePaths = options.replacePaths,
compress = options.compress,
optimizeFlag = options.optimized,
copyDependentFiles = options.copyDeps,
initScript = options.initScript,
base = options.baseName,
path = None,
createLibraryZip = False,
appendScriptToExe = True,
targetDir = options.targetDir)
freezer.Freeze()

View File

@ -0,0 +1,337 @@
import distutils.command.bdist_msi
import msilib
import os
__all__ = [ "bdist_msi" ]
# force the remove existing products action to happen first since Windows
# installer appears to be braindead and doesn't handle files shared between
# different "products" very well
sequence = msilib.sequence.InstallExecuteSequence
for index, info in enumerate(sequence):
if info[0] == u'RemoveExistingProducts':
sequence[index] = (info[0], info[1], 1450)
class bdist_msi(distutils.command.bdist_msi.bdist_msi):
user_options = distutils.command.bdist_msi.bdist_msi.user_options + [
('add-to-path=', None, 'add target dir to PATH environment variable'),
('upgrade-code=', None, 'upgrade code to use')
]
x = y = 50
width = 370
height = 300
title = "[ProductName] Setup"
modeless = 1
modal = 3
def add_config(self, fullname):
initialTargetDir = self.get_initial_target_dir(fullname)
if self.add_to_path is None:
self.add_to_path = False
for executable in self.distribution.executables:
if os.path.basename(executable.base).startswith("Console"):
self.add_to_path = True
break
if self.add_to_path:
msilib.add_data(self.db, 'Environment',
[("E_PATH", "Path", r"[~];[TARGETDIR]", "TARGETDIR")])
msilib.add_data(self.db, 'CustomAction',
[("InitialTargetDir", 256 + 51, "TARGETDIR", initialTargetDir)
])
msilib.add_data(self.db, 'InstallExecuteSequence',
[("InitialTargetDir", 'TARGETDIR=""', 401)])
msilib.add_data(self.db, 'InstallUISequence',
[("PrepareDlg", None, 140),
("InitialTargetDir", 'TARGETDIR=""', 401),
("SelectDirectoryDlg", "not Installed", 1230),
("MaintenanceTypeDlg",
"Installed and not Resume and not Preselected", 1250),
("ProgressDlg", None, 1280)
])
def add_cancel_dialog(self):
dialog = msilib.Dialog(self.db, "CancelDlg", 50, 10, 260, 85, 3,
self.title, "No", "No", "No")
dialog.text("Text", 48, 15, 194, 30, 3,
"Are you sure you want to cancel [ProductName] installation?")
button = dialog.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No")
button.event("EndDialog", "Exit")
button = dialog.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes")
button.event("EndDialog", "Return")
def add_error_dialog(self):
dialog = msilib.Dialog(self.db, "ErrorDlg", 50, 10, 330, 101, 65543,
self.title, "ErrorText", None, None)
dialog.text("ErrorText", 50, 9, 280, 48, 3, "")
for text, x in [("No", 120), ("Yes", 240), ("Abort", 0),
("Cancel", 42), ("Ignore", 81), ("Ok", 159), ("Retry", 198)]:
button = dialog.pushbutton(text[0], x, 72, 81, 21, 3, text, None)
button.event("EndDialog", "Error%s" % text)
def add_exit_dialog(self):
dialog = distutils.command.bdist_msi.PyDialog(self.db, "ExitDialog",
self.x, self.y, self.width, self.height, self.modal,
self.title, "Finish", "Finish", "Finish")
dialog.title("Completing the [ProductName] installer")
dialog.back("< Back", "Finish", active = False)
dialog.cancel("Cancel", "Back", active = False)
dialog.text("Description", 15, 235, 320, 20, 0x30003,
"Click the Finish button to exit the installer.")
button = dialog.next("Finish", "Cancel", name = "Finish")
button.event("EndDialog", "Return")
def add_fatal_error_dialog(self):
dialog = distutils.command.bdist_msi.PyDialog(self.db, "FatalError",
self.x, self.y, self.width, self.height, self.modal,
self.title, "Finish", "Finish", "Finish")
dialog.title("[ProductName] installer ended prematurely")
dialog.back("< Back", "Finish", active = False)
dialog.cancel("Cancel", "Back", active = False)
dialog.text("Description1", 15, 70, 320, 80, 0x30003,
"[ProductName] setup ended prematurely because of an error. "
"Your system has not been modified. To install this program "
"at a later time, please run the installation again.")
dialog.text("Description2", 15, 155, 320, 20, 0x30003,
"Click the Finish button to exit the installer.")
button = dialog.next("Finish", "Cancel", name = "Finish")
button.event("EndDialog", "Exit")
def add_files_in_use_dialog(self):
dialog = distutils.command.bdist_msi.PyDialog(self.db, "FilesInUse",
self.x, self.y, self.width, self.height, 19, self.title,
"Retry", "Retry", "Retry", bitmap = False)
dialog.text("Title", 15, 6, 200, 15, 0x30003,
r"{\DlgFontBold8}Files in Use")
dialog.text("Description", 20, 23, 280, 20, 0x30003,
"Some files that need to be updated are currently in use.")
dialog.text("Text", 20, 55, 330, 50, 3,
"The following applications are using files that need to be "
"updated by this setup. Close these applications and then "
"click Retry to continue the installation or Cancel to exit "
"it.")
dialog.control("List", "ListBox", 20, 107, 330, 130, 7,
"FileInUseProcess", None, None, None)
button = dialog.back("Exit", "Ignore", name = "Exit")
button.event("EndDialog", "Exit")
button = dialog.next("Ignore", "Retry", name = "Ignore")
button.event("EndDialog", "Ignore")
button = dialog.cancel("Retry", "Exit", name = "Retry")
button.event("EndDialog", "Retry")
def add_maintenance_type_dialog(self):
dialog = distutils.command.bdist_msi.PyDialog(self.db,
"MaintenanceTypeDlg", self.x, self.y, self.width, self.height,
self.modal, self.title, "Next", "Next", "Cancel")
dialog.title("Welcome to the [ProductName] Setup Wizard")
dialog.text("BodyText", 15, 63, 330, 42, 3,
"Select whether you want to repair or remove [ProductName].")
group = dialog.radiogroup("RepairRadioGroup", 15, 108, 330, 60, 3,
"MaintenanceForm_Action", "", "Next")
group.add("Repair", 0, 18, 300, 17, "&Repair [ProductName]")
group.add("Remove", 0, 36, 300, 17, "Re&move [ProductName]")
dialog.back("< Back", None, active = False)
button = dialog.next("Finish", "Cancel")
button.event("[REINSTALL]", "ALL",
'MaintenanceForm_Action="Repair"', 5)
button.event("[Progress1]", "Repairing",
'MaintenanceForm_Action="Repair"', 6)
button.event("[Progress2]", "repairs",
'MaintenanceForm_Action="Repair"', 7)
button.event("Reinstall", "ALL",
'MaintenanceForm_Action="Repair"', 8)
button.event("[REMOVE]", "ALL",
'MaintenanceForm_Action="Remove"', 11)
button.event("[Progress1]", "Removing",
'MaintenanceForm_Action="Remove"', 12)
button.event("[Progress2]", "removes",
'MaintenanceForm_Action="Remove"', 13)
button.event("Remove", "ALL",
'MaintenanceForm_Action="Remove"', 14)
button.event("EndDialog", "Return",
'MaintenanceForm_Action<>"Change"', 20)
button = dialog.cancel("Cancel", "RepairRadioGroup")
button.event("SpawnDialog", "CancelDlg")
def add_prepare_dialog(self):
dialog = distutils.command.bdist_msi.PyDialog(self.db, "PrepareDlg",
self.x, self.y, self.width, self.height, self.modeless,
self.title, "Cancel", "Cancel", "Cancel")
dialog.text("Description", 15, 70, 320, 40, 0x30003,
"Please wait while the installer prepares to guide you through"
"the installation.")
dialog.title("Welcome to the [ProductName] installer")
text = dialog.text("ActionText", 15, 110, 320, 20, 0x30003,
"Pondering...")
text.mapping("ActionText", "Text")
text = dialog.text("ActionData", 15, 135, 320, 30, 0x30003, None)
text.mapping("ActionData", "Text")
dialog.back("Back", None, active = False)
dialog.next("Next", None, active = False)
button = dialog.cancel("Cancel", None)
button.event("SpawnDialog", "CancelDlg")
def add_progress_dialog(self):
dialog = distutils.command.bdist_msi.PyDialog(self.db, "ProgressDlg",
self.x, self.y, self.width, self.height, self.modeless,
self.title, "Cancel", "Cancel", "Cancel", bitmap = False)
dialog.text("Title", 20, 15, 200, 15, 0x30003,
r"{\DlgFontBold8}[Progress1] [ProductName]")
dialog.text("Text", 35, 65, 300, 30, 3,
"Please wait while the installer [Progress2] [ProductName].")
dialog.text("StatusLabel", 35, 100 ,35, 20, 3, "Status:")
text = dialog.text("ActionText", 70, 100, self.width - 70, 20, 3,
"Pondering...")
text.mapping("ActionText", "Text")
control = dialog.control("ProgressBar", "ProgressBar", 35, 120, 300,
10, 65537, None, "Progress done", None, None)
control.mapping("SetProgress", "Progress")
dialog.back("< Back", "Next", active = False)
dialog.next("Next >", "Cancel", active = False)
button = dialog.cancel("Cancel", "Back")
button.event("SpawnDialog", "CancelDlg")
def add_properties(self):
metadata = self.distribution.metadata
props = [
('DistVersion', metadata.get_version()),
('DefaultUIFont', 'DlgFont8'),
('ErrorDialog', 'ErrorDlg'),
('Progress1', 'Install'),
('Progress2', 'installs'),
('MaintenanceForm_Action', 'Repair')
]
email = metadata.author_email or metadata.maintainer_email
if email:
props.append(("ARPCONTACT", email))
if metadata.url:
props.append(("ARPURLINFOABOUT", metadata.url))
if self.upgrade_code is not None:
props.append(("UpgradeCode", self.upgrade_code))
msilib.add_data(self.db, 'Property', props)
def add_select_directory_dialog(self):
dialog = distutils.command.bdist_msi.PyDialog(self.db,
"SelectDirectoryDlg", self.x, self.y, self.width, self.height,
self.modal, self.title, "Next", "Next", "Cancel")
dialog.title("Select destination directory")
dialog.back("< Back", None, active = False)
button = dialog.next("Next >", "Cancel")
button.event("SetTargetPath", "TARGETDIR", ordering = 1)
button.event("SpawnWaitDialog", "WaitForCostingDlg", ordering = 2)
button.event("EndDialog", "Return", ordering = 3)
button = dialog.cancel("Cancel", "DirectoryCombo")
button.event("SpawnDialog", "CancelDlg")
dialog.control("DirectoryCombo", "DirectoryCombo", 15, 70, 272, 80,
393219, "TARGETDIR", None, "DirectoryList", None)
dialog.control("DirectoryList", "DirectoryList", 15, 90, 308, 136, 3,
"TARGETDIR", None, "PathEdit", None)
dialog.control("PathEdit", "PathEdit", 15, 230, 306, 16, 3,
"TARGETDIR", None, "Next", None)
button = dialog.pushbutton("Up", 306, 70, 18, 18, 3, "Up", None)
button.event("DirectoryListUp", "0")
button = dialog.pushbutton("NewDir", 324, 70, 30, 18, 3, "New", None)
button.event("DirectoryListNew", "0")
def add_text_styles(self):
msilib.add_data(self.db, 'TextStyle',
[("DlgFont8", "Tahoma", 9, None, 0),
("DlgFontBold8", "Tahoma", 8, None, 1),
("VerdanaBold10", "Verdana", 10, None, 1),
("VerdanaRed9", "Verdana", 9, 255, 0)
])
def add_ui(self):
self.add_text_styles()
self.add_error_dialog()
self.add_fatal_error_dialog()
self.add_cancel_dialog()
self.add_exit_dialog()
self.add_user_exit_dialog()
self.add_files_in_use_dialog()
self.add_wait_for_costing_dialog()
self.add_prepare_dialog()
self.add_select_directory_dialog()
self.add_progress_dialog()
self.add_maintenance_type_dialog()
def add_upgrade_config(self, sversion):
if self.upgrade_code is not None:
msilib.add_data(self.db, 'Upgrade',
[(self.upgrade_code, None, sversion, None, 513, None,
"REMOVEOLDVERSION"),
(self.upgrade_code, sversion, None, None, 257, None,
"REMOVENEWVERSION")
])
def add_user_exit_dialog(self):
dialog = distutils.command.bdist_msi.PyDialog(self.db, "UserExit",
self.x, self.y, self.width, self.height, self.modal,
self.title, "Finish", "Finish", "Finish")
dialog.title("[ProductName] installer was interrupted")
dialog.back("< Back", "Finish", active = False)
dialog.cancel("Cancel", "Back", active = False)
dialog.text("Description1", 15, 70, 320, 80, 0x30003,
"[ProductName] setup was interrupted. Your system has not "
"been modified. To install this program at a later time, "
"please run the installation again.")
dialog.text("Description2", 15, 155, 320, 20, 0x30003,
"Click the Finish button to exit the installer.")
button = dialog.next("Finish", "Cancel", name = "Finish")
button.event("EndDialog", "Exit")
def add_wait_for_costing_dialog(self):
dialog = msilib.Dialog(self.db, "WaitForCostingDlg", 50, 10, 260, 85,
self.modal, self.title, "Return", "Return", "Return")
dialog.text("Text", 48, 15, 194, 30, 3,
"Please wait while the installer finishes determining your "
"disk space requirements.")
button = dialog.pushbutton("Return", 102, 57, 56, 17, 3, "Return",
None)
button.event("EndDialog", "Exit")
def get_initial_target_dir(self, fullname):
return r"[ProgramFilesFolder]\%s" % fullname
def get_installer_filename(self, fullname):
return os.path.join(self.dist_dir, "%s.msi" % fullname)
def initialize_options(self):
distutils.command.bdist_msi.bdist_msi.initialize_options(self)
self.upgrade_code = None
self.add_to_path = None
def run(self):
if not self.skip_build:
self.run_command('build')
install = self.reinitialize_command('install', reinit_subcommands = 1)
install.prefix = self.bdist_dir
install.skip_build = self.skip_build
install.warn_dir = 0
distutils.log.info("installing to %s", self.bdist_dir)
install.ensure_finalized()
install.run()
self.mkpath(self.dist_dir)
fullname = self.distribution.get_fullname()
filename = os.path.abspath(self.get_installer_filename(fullname))
if os.path.exists(filename):
os.unlink(filename)
metadata = self.distribution.metadata
author = metadata.author or metadata.maintainer or "UNKNOWN"
version = metadata.get_version()
sversion = "%d.%d.%d" % \
distutils.version.StrictVersion(version).version
self.db = msilib.init_database(filename, msilib.schema,
self.distribution.metadata.name, msilib.gen_uuid(), sversion,
author)
msilib.add_tables(self.db, msilib.sequence)
self.add_properties()
self.add_config(fullname)
self.add_upgrade_config(sversion)
self.add_ui()
self.add_files()
self.db.Commit()
if not self.keep_temp:
distutils.dir_util.remove_tree(self.bdist_dir,
dry_run = self.dry_run)

6
installer/cx_Freeze/cxfreeze Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/python
from cx_Freeze import main
main()

View File

@ -0,0 +1,35 @@
#------------------------------------------------------------------------------
# Console.py
# Initialization script for cx_Freeze which manipulates the path so that the
# directory in which the executable is found is searched for extensions but
# no other directory is searched. It also sets the attribute sys.frozen so that
# the Win32 extensions behave as expected.
#------------------------------------------------------------------------------
import encodings
import os
import sys
import warnings
import zipimport
sys.frozen = True
sys.path = sys.path[:4]
os.environ["TCL_LIBRARY"] = os.path.join(DIR_NAME, "tcl")
os.environ["TK_LIBRARY"] = os.path.join(DIR_NAME, "tk")
m = __import__("__main__")
importer = zipimport.zipimporter(INITSCRIPT_ZIP_FILE_NAME)
if INITSCRIPT_ZIP_FILE_NAME != SHARED_ZIP_FILE_NAME:
moduleName = m.__name__
else:
name, ext = os.path.splitext(os.path.basename(os.path.normcase(FILE_NAME)))
moduleName = "%s__main__" % name
code = importer.get_code(moduleName)
exec code in m.__dict__
if sys.version_info[:2] >= (2, 5):
module = sys.modules.get("threading")
if module is not None:
module._shutdown()

View File

@ -0,0 +1,19 @@
#------------------------------------------------------------------------------
# ConsoleKeepPath.py
# Initialization script for cx_Freeze which leaves the path alone and does
# not set the sys.frozen attribute.
#------------------------------------------------------------------------------
import sys
import zipimport
m = __import__("__main__")
importer = zipimport.zipimporter(INITSCRIPT_ZIP_FILE_NAME)
code = importer.get_code(m.__name__)
exec code in m.__dict__
if sys.version_info[:2] >= (2, 5):
module = sys.modules.get("threading")
if module is not None:
module._shutdown()

View File

@ -0,0 +1,38 @@
#------------------------------------------------------------------------------
# ConsoleSetLibPath.py
# Initialization script for cx_Freeze which manipulates the path so that the
# directory in which the executable is found is searched for extensions but
# no other directory is searched. The environment variable LD_LIBRARY_PATH is
# manipulated first, however, to ensure that shared libraries found in the
# target directory are found. This requires a restart of the executable because
# the environment variable LD_LIBRARY_PATH is only checked at startup.
#------------------------------------------------------------------------------
import encodings
import os
import sys
import warnings
import zipimport
paths = os.environ.get("LD_LIBRARY_PATH", "").split(os.pathsep)
if DIR_NAME not in paths:
paths.insert(0, DIR_NAME)
os.environ["LD_LIBRARY_PATH"] = os.pathsep.join(paths)
os.execv(sys.executable, sys.argv)
sys.frozen = True
sys.path = sys.path[:4]
os.environ["TCL_LIBRARY"] = os.path.join(DIR_NAME, "tcl")
os.environ["TK_LIBRARY"] = os.path.join(DIR_NAME, "tk")
m = __import__("__main__")
importer = zipimport.zipimporter(INITSCRIPT_ZIP_FILE_NAME)
code = importer.get_code(m.__name__)
exec code in m.__dict__
if sys.version_info[:2] >= (2, 5):
module = sys.modules.get("threading")
if module is not None:
module._shutdown()

View File

@ -0,0 +1,20 @@
#------------------------------------------------------------------------------
# SharedLib.py
# Initialization script for cx_Freeze which behaves similarly to the one for
# console based applications but must handle the case where Python has already
# been initialized and another DLL of this kind has been loaded. As such it
# does not block the path unless sys.frozen is not already set.
#------------------------------------------------------------------------------
import encodings
import os
import sys
import warnings
if not hasattr(sys, "frozen"):
sys.frozen = True
sys.path = sys.path[:4]
os.environ["TCL_LIBRARY"] = os.path.join(DIR_NAME, "tcl")
os.environ["TK_LIBRARY"] = os.path.join(DIR_NAME, "tk")

View File

@ -0,0 +1,23 @@
#------------------------------------------------------------------------------
# SharedLibSource.py
# Initialization script for cx_Freeze which imports the site module (as per
# normal processing of a Python script) and then searches for a file with the
# same name as the shared library but with the extension .pth. The entries in
# this file are used to modify the path to use for subsequent imports.
#------------------------------------------------------------------------------
import os
import sys
import warnings
# the site module must be imported for normal behavior to take place; it is
# done dynamically so that cx_Freeze will not add all modules referenced by
# the site module to the frozen executable
__import__("site")
# now locate the pth file to modify the path appropriately
baseName, ext = os.path.splitext(FILE_NAME)
pathFileName = baseName + ".pth"
sys.path = [s.strip() for s in file(pathFileName).read().splitlines()] + \
sys.path

View File

@ -0,0 +1,7 @@
import sys
print "Hello from cx_Freeze Advanced #1"
print
module = __import__("testfreeze_1")

View File

@ -0,0 +1,7 @@
import sys
print "Hello from cx_Freeze Advanced #2"
print
module = __import__("testfreeze_2")

View File

@ -0,0 +1 @@
print "Test freeze module #1"

View File

@ -0,0 +1 @@
print "Test freeze module #2"

View File

@ -0,0 +1,31 @@
# An advanced setup script to create multiple executables and demonstrate a few
# of the features available to setup scripts
#
# hello.py is a very simple "Hello, world" type script which also displays the
# environment in which the script runs
#
# Run the build process by running the command 'python setup.py build'
#
# If everything works well you should find a subdirectory in the build
# subdirectory that contains the files needed to run the script without Python
import sys
from cx_Freeze import setup, Executable
executables = [
Executable("advanced_1.py"),
Executable("advanced_2.py")
]
buildOptions = dict(
compressed = True,
includes = ["testfreeze_1", "testfreeze_2"],
path = sys.path + ["modules"])
setup(
name = "advanced_cx_Freeze_sample",
version = "0.1",
description = "Advanced sample cx_Freeze script",
options = dict(build_exe = buildOptions),
executables = executables)

View File

@ -0,0 +1,27 @@
# A simple setup script to create an executable using matplotlib.
#
# test_matplotlib.py is a very simple matplotlib application that demonstrates
# its use.
#
# Run the build process by running the command 'python setup.py build'
#
# If everything works well you should find a subdirectory in the build
# subdirectory that contains the files needed to run the application
import cx_Freeze
import sys
base = None
if sys.platform == "win32":
base = "Win32GUI"
executables = [
cx_Freeze.Executable("test_matplotlib.py", base = base)
]
cx_Freeze.setup(
name = "test_matplotlib",
version = "0.1",
description = "Sample matplotlib script",
executables = executables)

View File

@ -0,0 +1,48 @@
from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure
from wx import *
class CanvasFrame(Frame):
def __init__(self):
Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350))
self.SetBackgroundColour(NamedColor("WHITE"))
self.figure = Figure()
self.axes = self.figure.add_subplot(111)
t = arange(0.0,3.0,0.01)
s = sin(2*pi*t)
self.axes.plot(t,s)
self.canvas = FigureCanvas(self, -1, self.figure)
self.sizer = BoxSizer(VERTICAL)
self.sizer.Add(self.canvas, 1, LEFT | TOP | GROW)
self.SetSizerAndFit(self.sizer)
self.add_toolbar()
def add_toolbar(self):
self.toolbar = NavigationToolbar2Wx(self.canvas)
self.toolbar.Realize()
if Platform == '__WXMAC__':
self.SetToolBar(self.toolbar)
else:
tw, th = self.toolbar.GetSizeTuple()
fw, fh = self.canvas.GetSizeTuple()
self.toolbar.SetSize(Size(fw, th))
self.sizer.Add(self.toolbar, 0, LEFT | EXPAND)
self.toolbar.update()
def OnPaint(self, event):
self.canvas.draw()
class App(App):
def OnInit(self):
'Create the main window and insert the custom frame'
frame = CanvasFrame()
frame.Show(True)
return True
app = App(0)
app.MainLoop()

View File

@ -0,0 +1,3 @@
print "importing pkg1"
from . import sub1
from . import pkg2

View File

@ -0,0 +1,3 @@
print "importing pkg1.pkg2"
from . import sub3
from .. import sub4

View File

@ -0,0 +1,3 @@
print "importing pkg1.pkg2.sub3"
from . import sub5
from .. import sub6

View File

@ -0,0 +1 @@
print "importing pkg1.pkg2.sub5"

View File

@ -0,0 +1,2 @@
print "importing pkg1.sub1"
from . import sub2

View File

@ -0,0 +1 @@
print "importing pkg1.sub2"

View File

@ -0,0 +1 @@
print 'importing pkg1.sub4'

View File

@ -0,0 +1 @@
print "importing pkg1.sub6"

View File

@ -0,0 +1 @@
import pkg1

View File

@ -0,0 +1,16 @@
# relimport.py is a very simple script that tests importing using relative
# imports (available in Python 2.5 and up)
#
# Run the build process by running the command 'python setup.py build'
#
# If everything works well you should find a subdirectory in the build
# subdirectory that contains the files needed to run the script without Python
from cx_Freeze import setup, Executable
setup(
name = "relimport",
version = "0.1",
description = "Sample cx_Freeze script for relative imports",
executables = [Executable("relimport.py")])

View File

@ -0,0 +1,19 @@
import sys
print "Hello from cx_Freeze"
print
print "sys.executable", sys.executable
print "sys.prefix", sys.prefix
print
print "ARGUMENTS:"
for a in sys.argv:
print a
print
print "PATH:"
for p in sys.path:
print p
print

View File

@ -0,0 +1,18 @@
# A very simple setup script to create a single executable
#
# hello.py is a very simple "Hello, world" type script which also displays the
# environment in which the script runs
#
# Run the build process by running the command 'python setup.py build'
#
# If everything works well you should find a subdirectory in the build
# subdirectory that contains the files needed to run the script without Python
from cx_Freeze import setup, Executable
setup(
name = "hello",
version = "0.1",
description = "Sample cx_Freeze script",
executables = [Executable("hello.py")])

View File

@ -0,0 +1,25 @@
# A simple setup script to create an executable running wxPython. This also
# demonstrates the method for creating a Windows executable that does not have
# an associated console.
#
# wxapp.py is a very simple "Hello, world" type wxPython application
#
# Run the build process by running the command 'python setup.py build'
#
# If everything works well you should find a subdirectory in the build
# subdirectory that contains the files needed to run the application
import sys
from cx_Freeze import setup, Executable
base = None
if sys.platform == "win32":
base = "Win32GUI"
setup(
name = "hello",
version = "0.1",
description = "Sample cx_Freeze wxPython script",
executables = [Executable("wxapp.py", base = base)])

View File

@ -0,0 +1,42 @@
import wx
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent = None, title = "Hello from cx_Freeze")
panel = wx.Panel(self)
closeMeButton = wx.Button(panel, -1, "Close Me")
wx.EVT_BUTTON(self, closeMeButton.GetId(), self.OnCloseMe)
wx.EVT_CLOSE(self, self.OnCloseWindow)
pushMeButton = wx.Button(panel, -1, "Push Me")
wx.EVT_BUTTON(self, pushMeButton.GetId(), self.OnPushMe)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(closeMeButton, flag = wx.ALL, border = 20)
sizer.Add(pushMeButton, flag = wx.ALL, border = 20)
panel.SetSizer(sizer)
topSizer = wx.BoxSizer(wx.VERTICAL)
topSizer.Add(panel, flag = wx.ALL | wx.EXPAND)
topSizer.Fit(self)
def OnCloseMe(self, event):
self.Close(True)
def OnPushMe(self, event):
1 / 0
def OnCloseWindow(self, event):
self.Destroy()
class App(wx.App):
def OnInit(self):
frame = Frame()
frame.Show(True)
self.SetTopWindow(frame)
return True
app = App(1)
app.MainLoop()

197
installer/cx_Freeze/setup.py Executable file
View File

@ -0,0 +1,197 @@
"""
Distutils script for cx_Freeze.
"""
import distutils.command.bdist_rpm
import distutils.command.build_ext
import distutils.command.build_scripts
import distutils.command.install
import distutils.command.install_data
import distutils.sysconfig
import os
import sys
from distutils.core import setup
from distutils.extension import Extension
class bdist_rpm(distutils.command.bdist_rpm.bdist_rpm):
# rpm automatically byte compiles all Python files in a package but we
# don't want that to happen for initscripts and samples so we tell it to
# ignore those files
def _make_spec_file(self):
specFile = distutils.command.bdist_rpm.bdist_rpm._make_spec_file(self)
specFile.insert(0, "%define _unpackaged_files_terminate_build 0%{nil}")
return specFile
def run(self):
distutils.command.bdist_rpm.bdist_rpm.run(self)
specFile = os.path.join(self.rpm_base, "SPECS",
"%s.spec" % self.distribution.get_name())
queryFormat = "%{name}-%{version}-%{release}.%{arch}.rpm"
command = "rpm -q --qf '%s' --specfile %s" % (queryFormat, specFile)
origFileName = os.popen(command).read()
parts = origFileName.split("-")
parts.insert(2, "py%s%s" % sys.version_info[:2])
newFileName = "-".join(parts)
self.move_file(os.path.join("dist", origFileName),
os.path.join("dist", newFileName))
class build_ext(distutils.command.build_ext.build_ext):
def build_extension(self, ext):
if ext.name.find("bases") < 0:
distutils.command.build_ext.build_ext.build_extension(self, ext)
return
os.environ["LD_RUN_PATH"] = "${ORIGIN}:${ORIGIN}/../lib"
objects = self.compiler.compile(ext.sources,
output_dir = self.build_temp,
include_dirs = ext.include_dirs,
debug = self.debug,
depends = ext.depends)
fileName = os.path.splitext(self.get_ext_filename(ext.name))[0]
fullName = os.path.join(self.build_lib, fileName)
libraryDirs = ext.library_dirs or []
libraries = self.get_libraries(ext)
extraArgs = ext.extra_link_args or []
if sys.platform != "win32":
vars = distutils.sysconfig.get_config_vars()
libraryDirs.append(vars["LIBPL"])
libraries.append("python%s.%s" % sys.version_info[:2])
if vars["LINKFORSHARED"]:
extraArgs.extend(vars["LINKFORSHARED"].split())
if vars["LIBS"]:
extraArgs.extend(vars["LIBS"].split())
if vars["LIBM"]:
extraArgs.append(vars["LIBM"])
if vars["BASEMODLIBS"]:
extraArgs.extend(vars["BASEMODLIBS"].split())
if vars["LOCALMODLIBS"]:
extraArgs.extend(vars["LOCALMODLIBS"].split())
extraArgs.append("-s")
self.compiler.link_executable(objects, fullName,
libraries = libraries,
library_dirs = libraryDirs,
runtime_library_dirs = ext.runtime_library_dirs,
extra_postargs = extraArgs,
debug = self.debug)
def get_ext_filename(self, name):
fileName = distutils.command.build_ext.build_ext.get_ext_filename(self,
name)
if name.find("bases") < 0:
return fileName
ext = self.compiler.exe_extension or ""
return os.path.splitext(fileName)[0] + ext
class build_scripts(distutils.command.build_scripts.build_scripts):
def copy_scripts(self):
distutils.command.build_scripts.build_scripts.copy_scripts(self)
if sys.platform == "win32":
for script in self.scripts:
batFileName = os.path.join(self.build_dir, script + ".bat")
fullScriptName = r"%s\Scripts\%s" % \
(os.path.dirname(sys.executable), script)
command = "%s %s %%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9" % \
(sys.executable, fullScriptName)
file(batFileName, "w").write("@echo off\n\n%s" % command)
class install(distutils.command.install.install):
def get_sub_commands(self):
subCommands = distutils.command.install.install.get_sub_commands(self)
subCommands.append("install_packagedata")
return subCommands
class install_packagedata(distutils.command.install_data.install_data):
def run(self):
installCommand = self.get_finalized_command("install")
installDir = getattr(installCommand, "install_lib")
sourceDirs = ["samples", "initscripts"]
while sourceDirs:
sourceDir = sourceDirs.pop(0)
targetDir = os.path.join(installDir, "cx_Freeze", sourceDir)
self.mkpath(targetDir)
for name in os.listdir(sourceDir):
if name == "build" or name.startswith("."):
continue
fullSourceName = os.path.join(sourceDir, name)
if os.path.isdir(fullSourceName):
sourceDirs.append(fullSourceName)
else:
fullTargetName = os.path.join(targetDir, name)
self.copy_file(fullSourceName, fullTargetName)
self.outfiles.append(fullTargetName)
commandClasses = dict(
build_ext = build_ext,
build_scripts = build_scripts,
bdist_rpm = bdist_rpm,
install = install,
install_packagedata = install_packagedata)
if sys.platform == "win32":
libraries = ["imagehlp"]
else:
libraries = []
utilModule = Extension("cx_Freeze.util", ["source/util.c"],
libraries = libraries)
depends = ["source/bases/Common.c"]
if sys.platform == "win32":
if sys.version_info[:2] >= (2, 6):
extraSources = ["source/bases/manifest.rc"]
else:
extraSources = ["source/bases/dummy.rc"]
else:
extraSources = []
console = Extension("cx_Freeze.bases.Console",
["source/bases/Console.c"] + extraSources, depends = depends)
consoleKeepPath = Extension("cx_Freeze.bases.ConsoleKeepPath",
["source/bases/ConsoleKeepPath.c"] + extraSources, depends = depends)
extensions = [utilModule, console, consoleKeepPath]
if sys.platform == "win32":
gui = Extension("cx_Freeze.bases.Win32GUI",
["source/bases/Win32GUI.c"] + extraSources,
depends = depends, extra_link_args = ["-mwindows"])
extensions.append(gui)
docFiles = "LICENSE.txt README.txt HISTORY.txt doc/cx_Freeze.html"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: Python Software Foundation License",
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: C",
"Programming Language :: Python",
"Topic :: Software Development :: Build Tools",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: System :: Software Distribution",
"Topic :: Utilities"
]
setup(name = "cx_Freeze",
description = "create standalone executables from Python scripts",
long_description = "create standalone executables from Python scripts",
version = "4.0.1",
cmdclass = commandClasses,
options = dict(bdist_rpm = dict(doc_files = docFiles),
install = dict(optimize = 1)),
ext_modules = extensions,
packages = ['cx_Freeze'],
maintainer="Anthony Tuininga",
maintainer_email="anthony.tuininga@gmail.com",
url = "http://cx-freeze.sourceforge.net",
scripts = ["cxfreeze"],
classifiers = classifiers,
keywords = "freeze",
license = "Python Software Foundation License")

View File

@ -0,0 +1,262 @@
//-----------------------------------------------------------------------------
// Common.c
// Routines which are common to running frozen executables.
//-----------------------------------------------------------------------------
#include <compile.h>
#include <eval.h>
#include <osdefs.h>
// global variables (used for simplicity)
static PyObject *g_FileName = NULL;
static PyObject *g_DirName = NULL;
static PyObject *g_ExclusiveZipFileName = NULL;
static PyObject *g_SharedZipFileName = NULL;
static PyObject *g_InitScriptZipFileName = NULL;
//-----------------------------------------------------------------------------
// GetDirName()
// Return the directory name of the given path.
//-----------------------------------------------------------------------------
static int GetDirName(
const char *path, // path to calculate dir name for
PyObject **dirName) // directory name (OUT)
{
int i;
for (i = strlen(path); i > 0 && path[i] != SEP; --i);
*dirName = PyString_FromStringAndSize(path, i);
if (!*dirName)
return FatalError("cannot create string for directory name");
return 0;
}
//-----------------------------------------------------------------------------
// SetExecutableName()
// Set the script to execute and calculate the directory in which the
// executable is found as well as the exclusive (only for this executable) and
// shared zip file names.
//-----------------------------------------------------------------------------
static int SetExecutableName(
const char *fileName) // script to execute
{
char temp[MAXPATHLEN + 12], *ptr;
#ifndef WIN32
char linkData[MAXPATHLEN + 1];
struct stat statData;
size_t linkSize, i;
PyObject *dirName;
#endif
// store file name
g_FileName = PyString_FromString(fileName);
if (!g_FileName)
return FatalError("cannot create string for file name");
#ifndef WIN32
for (i = 0; i < 25; i++) {
if (lstat(fileName, &statData) < 0) {
PyErr_SetFromErrnoWithFilename(PyExc_OSError, (char*) fileName);
return FatalError("unable to stat file");
}
if (!S_ISLNK(statData.st_mode))
break;
linkSize = readlink(fileName, linkData, sizeof(linkData));
if (linkSize < 0) {
PyErr_SetFromErrnoWithFilename(PyExc_OSError, (char*) fileName);
return FatalError("unable to stat file");
}
if (linkData[0] == '/') {
Py_DECREF(g_FileName);
g_FileName = PyString_FromStringAndSize(linkData, linkSize);
} else {
if (GetDirName(PyString_AS_STRING(g_FileName), &dirName) < 0)
return -1;
if (PyString_GET_SIZE(dirName) + linkSize + 1 > MAXPATHLEN) {
Py_DECREF(dirName);
return FatalError("cannot dereference link, path too large");
}
strcpy(temp, PyString_AS_STRING(dirName));
strcat(temp, "/");
strcat(temp, linkData);
Py_DECREF(g_FileName);
g_FileName = PyString_FromString(temp);
}
if (!g_FileName)
return FatalError("cannot create string for linked file name");
fileName = PyString_AS_STRING(g_FileName);
}
#endif
// calculate and store directory name
if (GetDirName(fileName, &g_DirName) < 0)
return -1;
// calculate and store exclusive zip file name
strcpy(temp, fileName);
ptr = temp + strlen(temp) - 1;
while (ptr > temp && *ptr != SEP && *ptr != '.')
ptr--;
if (*ptr == '.')
*ptr = '\0';
strcat(temp, ".zip");
g_ExclusiveZipFileName = PyString_FromString(temp);
if (!g_ExclusiveZipFileName)
return FatalError("cannot create string for exclusive zip file name");
// calculate and store shared zip file name
strcpy(temp, PyString_AS_STRING(g_DirName));
ptr = temp + strlen(temp);
*ptr++ = SEP;
strcpy(ptr, "library.zip");
g_SharedZipFileName = PyString_FromString(temp);
if (!g_SharedZipFileName)
return FatalError("cannot create string for shared zip file name");
return 0;
}
//-----------------------------------------------------------------------------
// SetPathToSearch()
// Set the path to search. This includes the file (for those situations where
// a zip file is attached to the executable itself), the directory where the
// executable is found (to search for extensions), the exclusive zip file
// name and the shared zip file name.
//-----------------------------------------------------------------------------
static int SetPathToSearch(void)
{
PyObject *pathList;
pathList = PySys_GetObject("path");
if (!pathList)
return FatalError("cannot acquire sys.path");
if (PyList_Insert(pathList, 0, g_FileName) < 0)
return FatalError("cannot insert file name into sys.path");
if (PyList_Insert(pathList, 1, g_DirName) < 0)
return FatalError("cannot insert directory name into sys.path");
if (PyList_Insert(pathList, 2, g_ExclusiveZipFileName) < 0)
return FatalError("cannot insert exclusive zip name into sys.path");
if (PyList_Insert(pathList, 3, g_SharedZipFileName) < 0)
return FatalError("cannot insert shared zip name into sys.path");
return 0;
}
//-----------------------------------------------------------------------------
// GetImporterHelper()
// Helper which is used to locate the importer for the initscript.
//-----------------------------------------------------------------------------
static PyObject *GetImporterHelper(
PyObject *module, // zipimport module
PyObject *fileName) // name of file to search
{
PyObject *importer;
importer = PyObject_CallMethod(module, "zipimporter", "O", fileName);
if (importer)
g_InitScriptZipFileName = fileName;
else
PyErr_Clear();
return importer;
}
//-----------------------------------------------------------------------------
// GetImporter()
// Return the importer which will be used for importing the initialization
// script. The executable itself is searched first, followed by the exclusive
// zip file and finally by the shared zip file.
//-----------------------------------------------------------------------------
static int GetImporter(
PyObject **importer) // importer (OUT)
{
PyObject *module;
module = PyImport_ImportModule("zipimport");
if (!module)
return FatalError("cannot import zipimport module");
*importer = GetImporterHelper(module, g_FileName);
if (!*importer) {
*importer = GetImporterHelper(module, g_ExclusiveZipFileName);
if (!*importer)
*importer = GetImporterHelper(module, g_SharedZipFileName);
}
Py_DECREF(module);
if (!*importer)
return FatalError("cannot get zipimporter instance");
return 0;
}
//-----------------------------------------------------------------------------
// PopulateInitScriptDict()
// Return the dictionary used by the initialization script.
//-----------------------------------------------------------------------------
static int PopulateInitScriptDict(
PyObject *dict) // dictionary to populate
{
if (!dict)
return FatalError("unable to create temporary dictionary");
if (PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins()) < 0)
return FatalError("unable to set __builtins__");
if (PyDict_SetItemString(dict, "FILE_NAME", g_FileName) < 0)
return FatalError("unable to set FILE_NAME");
if (PyDict_SetItemString(dict, "DIR_NAME", g_DirName) < 0)
return FatalError("unable to set DIR_NAME");
if (PyDict_SetItemString(dict, "EXCLUSIVE_ZIP_FILE_NAME",
g_ExclusiveZipFileName) < 0)
return FatalError("unable to set EXCLUSIVE_ZIP_FILE_NAME");
if (PyDict_SetItemString(dict, "SHARED_ZIP_FILE_NAME",
g_SharedZipFileName) < 0)
return FatalError("unable to set SHARED_ZIP_FILE_NAME");
if (PyDict_SetItemString(dict, "INITSCRIPT_ZIP_FILE_NAME",
g_InitScriptZipFileName) < 0)
return FatalError("unable to set INITSCRIPT_ZIP_FILE_NAME");
return 0;
}
//-----------------------------------------------------------------------------
// ExecuteScript()
// Execute the script found within the file.
//-----------------------------------------------------------------------------
static int ExecuteScript(
const char *fileName) // name of file containing Python code
{
PyObject *importer, *dict, *code, *temp;
if (SetExecutableName(fileName) < 0)
return -1;
if (SetPathToSearch() < 0)
return -1;
importer = NULL;
if (GetImporter(&importer) < 0)
return -1;
// create and populate dictionary for initscript module
dict = PyDict_New();
if (PopulateInitScriptDict(dict) < 0) {
Py_XDECREF(dict);
Py_DECREF(importer);
return -1;
}
// locate and execute script
code = PyObject_CallMethod(importer, "get_code", "s", "cx_Freeze__init__");
Py_DECREF(importer);
if (!code)
return FatalError("unable to locate initialization module");
temp = PyEval_EvalCode( (PyCodeObject*) code, dict, dict);
Py_DECREF(code);
Py_DECREF(dict);
if (!temp)
return FatalScriptError();
Py_DECREF(temp);
return 0;
}

View File

@ -0,0 +1,72 @@
//-----------------------------------------------------------------------------
// Console.c
// Main routine for frozen programs which run in a console.
//-----------------------------------------------------------------------------
#include <Python.h>
#ifdef __WIN32__
#include <windows.h>
#endif
//-----------------------------------------------------------------------------
// FatalError()
// Prints a fatal error.
//-----------------------------------------------------------------------------
static int FatalError(
const char *message) // message to print
{
PyErr_Print();
Py_FatalError(message);
return -1;
}
//-----------------------------------------------------------------------------
// FatalScriptError()
// Prints a fatal error in the initialization script.
//-----------------------------------------------------------------------------
static int FatalScriptError(void)
{
PyErr_Print();
return -1;
}
#include "Common.c"
//-----------------------------------------------------------------------------
// main()
// Main routine for frozen programs.
//-----------------------------------------------------------------------------
int main(int argc, char **argv)
{
const char *fileName;
char *encoding;
// initialize Python
Py_NoSiteFlag = 1;
Py_FrozenFlag = 1;
Py_IgnoreEnvironmentFlag = 1;
encoding = getenv("PYTHONIOENCODING");
if (encoding != NULL) {
Py_FileSystemDefaultEncoding = strndup(encoding, 100);
}
Py_SetPythonHome("");
Py_SetProgramName(argv[0]);
fileName = Py_GetProgramFullPath();
Py_Initialize();
PySys_SetArgv(argc, argv);
// do the work
if (ExecuteScript(fileName) < 0)
return 1;
Py_Finalize();
return 0;
}

View File

@ -0,0 +1,60 @@
//-----------------------------------------------------------------------------
// ConsoleKeepPath.c
// Main routine for frozen programs which need a Python installation to do
// their work.
//-----------------------------------------------------------------------------
#include <Python.h>
#ifdef __WIN32__
#include <windows.h>
#endif
//-----------------------------------------------------------------------------
// FatalError()
// Prints a fatal error.
//-----------------------------------------------------------------------------
static int FatalError(
const char *message) // message to print
{
PyErr_Print();
Py_FatalError(message);
return -1;
}
//-----------------------------------------------------------------------------
// FatalScriptError()
// Prints a fatal error in the initialization script.
//-----------------------------------------------------------------------------
static int FatalScriptError(void)
{
PyErr_Print();
return -1;
}
#include "Common.c"
//-----------------------------------------------------------------------------
// main()
// Main routine for frozen programs.
//-----------------------------------------------------------------------------
int main(int argc, char **argv)
{
const char *fileName;
// initialize Python
Py_SetProgramName(argv[0]);
fileName = Py_GetProgramFullPath();
Py_Initialize();
PySys_SetArgv(argc, argv);
// do the work
if (ExecuteScript(fileName) < 0)
return 1;
Py_Finalize();
return 0;
}

View File

@ -0,0 +1,242 @@
//-----------------------------------------------------------------------------
// Win32GUI.c
// Main routine for frozen programs written for the Win32 GUI subsystem.
//-----------------------------------------------------------------------------
#include <Python.h>
#include <windows.h>
//-----------------------------------------------------------------------------
// FatalError()
// Handle a fatal error.
//-----------------------------------------------------------------------------
static int FatalError(
char *a_Message) // message to display
{
MessageBox(NULL, a_Message, "cx_Freeze Fatal Error", MB_ICONERROR);
Py_Finalize();
return -1;
}
//-----------------------------------------------------------------------------
// StringifyObject()
// Stringify a Python object.
//-----------------------------------------------------------------------------
static char *StringifyObject(
PyObject *object, // object to stringify
PyObject **stringRep) // string representation
{
if (object) {
*stringRep = PyObject_Str(object);
if (*stringRep)
return PyString_AS_STRING(*stringRep);
return "Unable to stringify";
}
// object is NULL
*stringRep = NULL;
return "None";
}
//-----------------------------------------------------------------------------
// FatalPythonErrorNoTraceback()
// Handle a fatal Python error without traceback.
//-----------------------------------------------------------------------------
static int FatalPythonErrorNoTraceback(
PyObject *origType, // exception type
PyObject *origValue, // exception value
char *message) // message to display
{
PyObject *typeStrRep, *valueStrRep, *origTypeStrRep, *origValueStrRep;
char *totalMessage, *typeStr, *valueStr, *origTypeStr, *origValueStr;
PyObject *type, *value, *traceback;
int totalMessageLength;
char *messageFormat;
// fetch error and string representations of the error
PyErr_Fetch(&type, &value, &traceback);
origTypeStr = StringifyObject(origType, &origTypeStrRep);
origValueStr = StringifyObject(origValue, &origValueStrRep);
typeStr = StringifyObject(type, &typeStrRep);
valueStr = StringifyObject(value, &valueStrRep);
// fill out the message to be displayed
messageFormat = "Type: %s\nValue: %s\nOther Type: %s\nOtherValue: %s\n%s";
totalMessageLength = strlen(origTypeStr) + strlen(origValueStr) +
strlen(typeStr) + strlen(valueStr) + strlen(message) +
strlen(messageFormat) + 1;
totalMessage = malloc(totalMessageLength);
if (!totalMessage)
return FatalError("Out of memory!");
sprintf(totalMessage, messageFormat, typeStr, valueStr, origTypeStr,
origValueStr, message);
// display the message
MessageBox(NULL, totalMessage,
"cx_Freeze: Python error in main script (traceback unavailable)",
MB_ICONERROR);
free(totalMessage);
return -1;
}
//-----------------------------------------------------------------------------
// ArgumentValue()
// Return a suitable argument value by replacing NULL with Py_None.
//-----------------------------------------------------------------------------
static PyObject *ArgumentValue(
PyObject *object) // argument to massage
{
if (object) {
Py_INCREF(object);
return object;
}
Py_INCREF(Py_None);
return Py_None;
}
//-----------------------------------------------------------------------------
// HandleSystemExitException()
// Handles a system exit exception differently. If an integer value is passed
// through then that becomes the exit value; otherwise the string value of the
// value passed through is displayed in a message box.
//-----------------------------------------------------------------------------
static void HandleSystemExitException()
{
PyObject *type, *value, *traceback, *valueStr;
int exitCode = 0;
char *message;
PyErr_Fetch(&type, &value, &traceback);
if (PyInstance_Check(value)) {
PyObject *code = PyObject_GetAttrString(value, "code");
if (code) {
Py_DECREF(value);
value = code;
if (value == Py_None)
Py_Exit(0);
}
}
if (PyInt_Check(value))
exitCode = PyInt_AsLong(value);
else {
message = StringifyObject(value, &valueStr);
MessageBox(NULL, message, "cx_Freeze: Application Terminated",
MB_ICONERROR);
Py_XDECREF(valueStr);
exitCode = 1;
}
Py_Exit(exitCode);
}
//-----------------------------------------------------------------------------
// FatalScriptError()
// Handle a fatal Python error with traceback.
//-----------------------------------------------------------------------------
static int FatalScriptError()
{
PyObject *type, *value, *traceback, *argsTuple, *module, *method, *result;
int tracebackLength, i;
char *tracebackStr;
// if a system exception, handle it specially
if (PyErr_ExceptionMatches(PyExc_SystemExit))
HandleSystemExitException();
// get the exception details
PyErr_Fetch(&type, &value, &traceback);
// import the traceback module
module = PyImport_ImportModule("traceback");
if (!module)
return FatalPythonErrorNoTraceback(type, value,
"Cannot import traceback module.");
// get the format_exception method
method = PyObject_GetAttrString(module, "format_exception");
Py_DECREF(module);
if (!method)
return FatalPythonErrorNoTraceback(type, value,
"Cannot get format_exception method.");
// create a tuple for the arguments
argsTuple = PyTuple_New(3);
if (!argsTuple) {
Py_DECREF(method);
return FatalPythonErrorNoTraceback(type, value,
"Cannot create arguments tuple for traceback.");
}
PyTuple_SET_ITEM(argsTuple, 0, ArgumentValue(type));
PyTuple_SET_ITEM(argsTuple, 1, ArgumentValue(value));
PyTuple_SET_ITEM(argsTuple, 2, ArgumentValue(traceback));
// call the format_exception method
result = PyObject_CallObject(method, argsTuple);
Py_DECREF(method);
Py_DECREF(argsTuple);
if (!result)
return FatalPythonErrorNoTraceback(type, value,
"Failed calling format_exception method.");
// determine length of string representation of formatted traceback
tracebackLength = 1;
for (i = 0; i < PyList_GET_SIZE(result); i++)
tracebackLength += PyString_GET_SIZE(PyList_GET_ITEM(result, i));
// create a string representation of the formatted traceback
tracebackStr = malloc(tracebackLength);
if (!tracebackStr) {
Py_DECREF(result);
return FatalError("Out of memory!");
}
tracebackStr[0] = '\0';
for (i = 0; i < PyList_GET_SIZE(result); i++)
strcat(tracebackStr, PyString_AS_STRING(PyList_GET_ITEM(result, i)));
Py_DECREF(result);
// bring up the error
MessageBox(NULL, tracebackStr, "cx_Freeze: Python error in main script",
MB_ICONERROR);
Py_Finalize();
return 1;
}
#include "Common.c"
//-----------------------------------------------------------------------------
// WinMain()
// Main routine for the executable in Windows.
//-----------------------------------------------------------------------------
int WINAPI WinMain(
HINSTANCE instance, // handle to application
HINSTANCE prevInstance, // previous handle to application
LPSTR commandLine, // command line
int showFlag) // show flag
{
const char *fileName;
// initialize Python
Py_NoSiteFlag = 1;
Py_FrozenFlag = 1;
Py_IgnoreEnvironmentFlag = 1;
Py_SetPythonHome("");
Py_SetProgramName(__argv[0]);
fileName = Py_GetProgramFullPath();
Py_Initialize();
PySys_SetArgv(__argc, __argv);
// do the work
if (ExecuteScript(fileName) < 0)
return 1;
// terminate Python
Py_Finalize();
return 0;
}

View File

@ -0,0 +1,5 @@
STRINGTABLE
{
1, "Just to ensure that buggy EndUpdateResource doesn't fall over."
}

View File

@ -0,0 +1,3 @@
#include "dummy.rc"
1 24 source/bases/manifest.txt

View File

@ -0,0 +1,418 @@
//-----------------------------------------------------------------------------
// util.c
// Shared library for use by cx_Freeze.
//-----------------------------------------------------------------------------
#include <Python.h>
#ifdef WIN32
#include <windows.h>
#include <imagehlp.h>
#pragma pack(2)
typedef struct {
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
BYTE bColorCount; // Number of colors in image
BYTE bReserved; // Reserved ( must be 0)
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // How many bytes in this resource?
DWORD dwImageOffset; // Where in the file is this image?
} ICONDIRENTRY;
typedef struct {
WORD idReserved; // Reserved (must be 0)
WORD idType; // Resource Type (1 for icons)
WORD idCount; // How many images?
ICONDIRENTRY idEntries[0]; // An entry for each image
} ICONDIR;
typedef struct {
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
BYTE bColorCount; // Number of colors in image
BYTE bReserved; // Reserved ( must be 0)
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // How many bytes in this resource?
WORD nID; // resource ID
} GRPICONDIRENTRY;
typedef struct {
WORD idReserved; // Reserved (must be 0)
WORD idType; // Resource Type (1 for icons)
WORD idCount; // How many images?
GRPICONDIRENTRY idEntries[0]; // An entry for each image
} GRPICONDIR;
#endif
//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------
#ifdef WIN32
static PyObject *g_BindErrorException = NULL;
static PyObject *g_ImageNames = NULL;
#endif
#ifdef WIN32
//-----------------------------------------------------------------------------
// BindStatusRoutine()
// Called by BindImageEx() at various points. This is used to determine the
// dependency tree which is later examined by cx_Freeze.
//-----------------------------------------------------------------------------
static BOOL __stdcall BindStatusRoutine(
IMAGEHLP_STATUS_REASON reason, // reason called
PSTR imageName, // name of image being examined
PSTR dllName, // name of DLL
ULONG virtualAddress, // computed virtual address
ULONG parameter) // parameter (value depends on reason)
{
char fileName[MAX_PATH + 1];
switch (reason) {
case BindImportModule:
if (!SearchPath(NULL, dllName, NULL, sizeof(fileName), fileName,
NULL))
return FALSE;
Py_INCREF(Py_None);
if (PyDict_SetItemString(g_ImageNames, fileName, Py_None) < 0)
return FALSE;
break;
default:
break;
}
return TRUE;
}
//-----------------------------------------------------------------------------
// GetFileData()
// Return the data for the given file.
//-----------------------------------------------------------------------------
static int GetFileData(
const char *fileName, // name of file to read
char **data) // pointer to data (OUT)
{
DWORD numberOfBytesRead, dataSize;
HANDLE file;
file = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE)
return -1;
dataSize = GetFileSize(file, NULL);
if (dataSize == INVALID_FILE_SIZE) {
CloseHandle(file);
return -1;
}
*data = PyMem_Malloc(dataSize);
if (!*data) {
CloseHandle(file);
return -1;
}
if (!ReadFile(file, *data, dataSize, &numberOfBytesRead, NULL)) {
CloseHandle(file);
return -1;
}
CloseHandle(file);
return 0;
}
//-----------------------------------------------------------------------------
// CreateGroupIconResource()
// Return the group icon resource given the icon file data.
//-----------------------------------------------------------------------------
static GRPICONDIR *CreateGroupIconResource(
ICONDIR *iconDir, // icon information
DWORD *resourceSize) // size of resource (OUT)
{
GRPICONDIR *groupIconDir;
int i;
*resourceSize = sizeof(GRPICONDIR) +
sizeof(GRPICONDIRENTRY) * iconDir->idCount;
groupIconDir = PyMem_Malloc(*resourceSize);
if (!groupIconDir)
return NULL;
groupIconDir->idReserved = iconDir->idReserved;
groupIconDir->idType = iconDir->idType;
groupIconDir->idCount = iconDir->idCount;
for (i = 0; i < iconDir->idCount; i++) {
groupIconDir->idEntries[i].bWidth = iconDir->idEntries[i].bWidth;
groupIconDir->idEntries[i].bHeight = iconDir->idEntries[i].bHeight;
groupIconDir->idEntries[i].bColorCount =
iconDir->idEntries[i].bColorCount;
groupIconDir->idEntries[i].bReserved = iconDir->idEntries[i].bReserved;
groupIconDir->idEntries[i].wPlanes = iconDir->idEntries[i].wPlanes;
groupIconDir->idEntries[i].wBitCount = iconDir->idEntries[i].wBitCount;
groupIconDir->idEntries[i].dwBytesInRes =
iconDir->idEntries[i].dwBytesInRes;
groupIconDir->idEntries[i].nID = i + 1;
}
return groupIconDir;
}
//-----------------------------------------------------------------------------
// ExtAddIcon()
// Add the icon as a resource to the specified file.
//-----------------------------------------------------------------------------
static PyObject *ExtAddIcon(
PyObject *self, // passthrough argument
PyObject *args) // arguments
{
char *executableName, *iconName, *data, *iconData;
GRPICONDIR *groupIconDir;
DWORD resourceSize;
ICONDIR *iconDir;
BOOL succeeded;
HANDLE handle;
int i;
if (!PyArg_ParseTuple(args, "ss", &executableName, &iconName))
return NULL;
// begin updating the executable
handle = BeginUpdateResource(executableName, FALSE);
if (!handle) {
PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,
GetLastError(), executableName);
return NULL;
}
// first attempt to get the data from the icon file
data = NULL;
succeeded = TRUE;
groupIconDir = NULL;
if (GetFileData(iconName, &data) < 0)
succeeded = FALSE;
iconDir = (ICONDIR*) data;
// next, attempt to add a group icon resource
if (succeeded) {
groupIconDir = CreateGroupIconResource(iconDir, &resourceSize);
if (groupIconDir)
succeeded = UpdateResource(handle, RT_GROUP_ICON,
MAKEINTRESOURCE(1),
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
groupIconDir, resourceSize);
else succeeded = FALSE;
}
// next, add each icon as a resource
if (succeeded) {
for (i = 0; i < iconDir->idCount; i++) {
iconData = &data[iconDir->idEntries[i].dwImageOffset];
resourceSize = iconDir->idEntries[i].dwBytesInRes;
succeeded = UpdateResource(handle, RT_ICON, MAKEINTRESOURCE(i + 1),
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), iconData,
resourceSize);
if (!succeeded)
break;
}
}
// finish writing the resource (or discarding the changes upon an error)
if (!EndUpdateResource(handle, !succeeded)) {
if (succeeded) {
succeeded = FALSE;
PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,
GetLastError(), executableName);
}
}
// clean up
if (groupIconDir)
PyMem_Free(groupIconDir);
if (data)
PyMem_Free(data);
if (!succeeded)
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
//-----------------------------------------------------------------------------
// ExtBeginUpdateResource()
// Wrapper for BeginUpdateResource().
//-----------------------------------------------------------------------------
static PyObject *ExtBeginUpdateResource(
PyObject *self, // passthrough argument
PyObject *args) // arguments
{
BOOL deleteExistingResources;
char *fileName;
HANDLE handle;
deleteExistingResources = TRUE;
if (!PyArg_ParseTuple(args, "s|i", &fileName, &deleteExistingResources))
return NULL;
handle = BeginUpdateResource(fileName, deleteExistingResources);
if (!handle) {
PyErr_SetExcFromWindowsErrWithFilename(PyExc_WindowsError,
GetLastError(), fileName);
return NULL;
}
return PyInt_FromLong((long) handle);
}
//-----------------------------------------------------------------------------
// ExtUpdateResource()
// Wrapper for UpdateResource().
//-----------------------------------------------------------------------------
static PyObject *ExtUpdateResource(
PyObject *self, // passthrough argument
PyObject *args) // arguments
{
int resourceType, resourceId, resourceDataSize;
char *resourceData;
HANDLE handle;
if (!PyArg_ParseTuple(args, "iiis#", &handle, &resourceType, &resourceId,
&resourceData, &resourceDataSize))
return NULL;
if (!UpdateResource(handle, MAKEINTRESOURCE(resourceType),
MAKEINTRESOURCE(resourceId),
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), resourceData,
resourceDataSize)) {
PyErr_SetExcFromWindowsErr(PyExc_WindowsError, GetLastError());
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
//-----------------------------------------------------------------------------
// ExtEndUpdateResource()
// Wrapper for EndUpdateResource().
//-----------------------------------------------------------------------------
static PyObject *ExtEndUpdateResource(
PyObject *self, // passthrough argument
PyObject *args) // arguments
{
BOOL discardChanges;
HANDLE handle;
discardChanges = FALSE;
if (!PyArg_ParseTuple(args, "i|i", &handle, &discardChanges))
return NULL;
if (!EndUpdateResource(handle, discardChanges)) {
PyErr_SetExcFromWindowsErr(PyExc_WindowsError, GetLastError());
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
//-----------------------------------------------------------------------------
// ExtGetDependentFiles()
// Return a list of files that this file depends on.
//-----------------------------------------------------------------------------
static PyObject *ExtGetDependentFiles(
PyObject *self, // passthrough argument
PyObject *args) // arguments
{
PyObject *results;
char *imageName;
if (!PyArg_ParseTuple(args, "s", &imageName))
return NULL;
g_ImageNames = PyDict_New();
if (!g_ImageNames)
return NULL;
if (!BindImageEx(BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE | BIND_ALL_IMAGES,
imageName, NULL, NULL, BindStatusRoutine)) {
Py_DECREF(g_ImageNames);
PyErr_SetExcFromWindowsErrWithFilename(g_BindErrorException,
GetLastError(), imageName);
return NULL;
}
results = PyDict_Keys(g_ImageNames);
Py_DECREF(g_ImageNames);
return results;
}
//-----------------------------------------------------------------------------
// ExtGetSystemDir()
// Return the Windows directory (C:\Windows for example).
//-----------------------------------------------------------------------------
static PyObject *ExtGetSystemDir(
PyObject *self, // passthrough argument
PyObject *args) // arguments (ignored)
{
char dir[MAX_PATH + 1];
if (GetSystemDirectory(dir, sizeof(dir)))
return PyString_FromString(dir);
PyErr_SetExcFromWindowsErr(PyExc_RuntimeError, GetLastError());
return NULL;
}
#endif
//-----------------------------------------------------------------------------
// ExtSetOptimizeFlag()
// Set the optimize flag as needed.
//-----------------------------------------------------------------------------
static PyObject *ExtSetOptimizeFlag(
PyObject *self, // passthrough argument
PyObject *args) // arguments
{
if (!PyArg_ParseTuple(args, "i", &Py_OptimizeFlag))
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
//-----------------------------------------------------------------------------
// Methods
//-----------------------------------------------------------------------------
static PyMethodDef g_ModuleMethods[] = {
{ "SetOptimizeFlag", ExtSetOptimizeFlag, METH_VARARGS },
#ifdef WIN32
{ "BeginUpdateResource", ExtBeginUpdateResource, METH_VARARGS },
{ "UpdateResource", ExtUpdateResource, METH_VARARGS },
{ "EndUpdateResource", ExtEndUpdateResource, METH_VARARGS },
{ "AddIcon", ExtAddIcon, METH_VARARGS },
{ "GetDependentFiles", ExtGetDependentFiles, METH_VARARGS },
{ "GetSystemDir", ExtGetSystemDir, METH_NOARGS },
#endif
{ NULL }
};
//-----------------------------------------------------------------------------
// initutil()
// Initialization routine for the shared libary.
//-----------------------------------------------------------------------------
void initutil(void)
{
PyObject *module;
module = Py_InitModule("cx_Freeze.util", g_ModuleMethods);
if (!module)
return;
#ifdef WIN32
g_BindErrorException = PyErr_NewException("cx_Freeze.util.BindError",
NULL, NULL);
if (!g_BindErrorException)
return;
if (PyModule_AddObject(module, "BindError", g_BindErrorException) < 0)
return;
#endif
}

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python
from __future__ import with_statement
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
@ -6,162 +7,212 @@ __docformat__ = 'restructuredtext en'
'''
Create linux binary.
'''
import glob, sys, subprocess, tarfile, os, re, py_compile, shutil
HOME = '/home/kovid'
PYINSTALLER = os.path.expanduser('~/build/pyinstaller')
CALIBREPREFIX = '___'
PDFTOHTML = '/usr/bin/pdftohtml'
LIBUNRAR = '/usr/lib/libunrar.so'
def freeze():
import glob, sys, subprocess, tarfile, os, re, textwrap, shutil, cStringIO, bz2, codecs
from contextlib import closing
from cx_Freeze import Executable, setup
from calibre.constants import __version__, __appname__
from calibre.linux import entry_points
from calibre import walk
from calibre.web.feeds.recipes import recipe_modules
import calibre
QTDIR = '/usr/lib/qt4'
QTDLLS = ('QtCore', 'QtGui', 'QtNetwork', 'QtSvg', 'QtXml', 'QtWebKit')
EXTRAS = ('/usr/lib/python2.5/site-packages/PIL', os.path.expanduser('~/ipython/IPython'))
SQLITE = '/usr/lib/libsqlite3.so.0'
DBUS = '/usr/lib/libdbus-1.so.3'
LIBMNG = '/usr/lib/libmng.so.1'
LIBZ = '/lib/libz.so.1'
LIBBZ2 = '/lib/libbz2.so.1'
LIBUSB = '/usr/lib/libusb.so'
LIBPOPPLER = '/usr/lib/libpoppler.so.3'
LIBXML2 = '/usr/lib/libxml2.so.2'
LIBXSLT = '/usr/lib/libxslt.so.1'
LIBEXSLT = '/usr/lib/libexslt.so.0'
binary_excludes = ['libGLcore*', 'libGL*', 'libnvidia*']
binary_includes = [
'/usr/bin/pdftohtml',
'/usr/lib/libunrar.so',
'/usr/lib/libsqlite3.so.0',
'/usr/lib/libsqlite3.so.0',
'/usr/lib/libmng.so.1',
'/lib/libz.so.1',
'/lib/libbz2.so.1',
'/lib/libbz2.so.1',
'/usr/lib/libpoppler.so.4',
'/usr/lib/libxml2.so.2',
'/usr/lib/libxslt.so.1',
'/usr/lib/libxslt.so.1'
]
binary_includes += [os.path.join(QTDIR, 'lib%s.so.4'%x) for x in QTDLLS]
CALIBRESRC = os.path.join(CALIBREPREFIX, 'src')
CALIBREPLUGINS = os.path.join(CALIBRESRC, 'calibre', 'plugins')
d = os.path.dirname
CALIBRESRC = d(d(d(os.path.abspath(calibre.__file__))))
CALIBREPLUGINS = os.path.join(CALIBRESRC, 'src', 'calibre', 'plugins')
FREEZE_DIR = os.path.join(CALIBRESRC, 'build', 'cx_freeze')
DIST_DIR = os.path.join(CALIBRESRC, 'dist')
sys.path.insert(0, CALIBRESRC)
from calibre import __version__
from calibre.parallel import PARALLEL_FUNCS
from calibre.web.feeds.recipes import recipes
hiddenimports = list(map(lambda x: x[0], PARALLEL_FUNCS.values()))
hiddenimports += ['PyQt4.QtWebKit']
hiddenimports += ['lxml._elementpath', 'keyword', 'codeop', 'commands', 'shlex', 'pydoc']
hiddenimports += map(lambda x: x.__module__, recipes)
open(os.path.join(PYINSTALLER, 'hooks', 'hook-calibre.parallel.py'), 'wb').write('hiddenimports = %s'%repr(hiddenimports))
os.chdir(CALIBRESRC)
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)
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),
open(__file__).read())
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)
print 'Freezing calibre located at', CALIBRESRC
return 0
sys.path.insert(0, os.path.join(CALIBRESRC, 'src'))
entry_points = entry_points['console_scripts'] + entry_points['gui_scripts']
entry_points = ['calibre_postinstall=calibre.linux:binary_install',
'calibre-parallel=calibre.parallel:main'] + entry_points
executables = {}
for ep in entry_points:
executables[ep.split('=')[0].strip()] = (ep.split('=')[1].split(':')[0].strip(),
ep.split(':')[-1].strip())
if __name__ == '__main__' and 'freeze.py' in __file__:
sys.exit(run_pyinstaller())
if os.path.exists(FREEZE_DIR):
shutil.rmtree(FREEZE_DIR)
os.makedirs(FREEZE_DIR)
if not os.path.exists(DIST_DIR):
os.makedirs(DIST_DIR)
loader = os.path.join(os.path.expanduser('~/temp'), 'calibre_installer_loader.py')
if not os.path.exists(loader):
open(loader, 'wb').write('''
import sys, os
sys.frozen_path = os.getcwd()
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, "qtplugins")])
''')
excludes = ['gtk._gtk', 'gtk.glade', 'qt', 'matplotlib.nxutils', 'matplotlib._cntr',
'matplotlib.ttconv', 'matplotlib._image', 'matplotlib.ft2font',
'matplotlib._transforms', 'matplotlib._agg', 'matplotlib.backends._backend_agg',
'matplotlib.axes', 'matplotlib', 'matplotlib.pyparsing',
'TKinter', 'atk', 'gobject._gobject', 'pango', 'PIL', 'Image', 'IPython']
includes = [x[0] for x in executables.values()]
excludes = ['matplotlib', "Tkconstants", "Tkinter", "tcl", "_imagingtk",
"ImageTk", "FixTk", 'wx', 'PyQt4.QtAssistant', 'PyQt4.QtOpenGL.so',
'PyQt4.QtScript.so', 'PyQt4.QtSql.so', 'PyQt4.QtTest.so', 'qt',
'glib', 'gobject']
sys.path.insert(0, CALIBRESRC)
from calibre.linux import entry_points
packages = ['calibre', 'encodings', 'cherrypy', 'cssutils', 'xdg']
executables, scripts = ['calibre_postinstall', 'calibre-parallel'], \
[os.path.join(CALIBRESRC, 'calibre', 'linux.py'), os.path.join(CALIBRESRC, 'calibre', 'parallel.py')]
includes += ['calibre.web.feeds.recipes.'+r for r in recipe_modules]
for entry in entry_points['console_scripts'] + entry_points['gui_scripts']:
fields = entry.split('=')
executables.append(fields[0].strip())
scripts.append(os.path.join(CALIBRESRC, *map(lambda x: x.strip(), fields[1].split(':')[0].split('.')))+'.py')
LOADER = '/tmp/loader.py'
open(LOADER, 'wb').write('# This script is never actually used.\nimport sys')
analyses = [Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), loader, script],
pathex=[PYINSTALLER, CALIBRESRC], excludes=excludes) for script in scripts]
INIT_SCRIPT = '/tmp/init.py'
open(INIT_SCRIPT, 'wb').write(textwrap.dedent('''
## Load calibre module specified in the environment variable CALIBRE_CX_EXE
## Also restrict sys.path to the executables' directory and add the
## executables directory to LD_LIBRARY_PATH
import encodings
import os
import sys
import warnings
import zipimport
import locale
import codecs
pyz = TOC()
binaries = TOC()
enc = locale.getdefaultlocale()[1]
if not enc:
enc = locale.nl_langinfo(locale.CODESET)
enc = codecs.lookup(enc if enc else 'UTF-8').name
sys.setdefaultencoding(enc)
for a in analyses:
pyz = a.pure + pyz
binaries = a.binaries + binaries
pyz = PYZ(pyz, name='library.pyz')
paths = os.environ.get('LD_LIBRARY_PATH', '').split(os.pathsep)
if DIR_NAME not in paths or not sys.getfilesystemencoding():
paths.insert(0, DIR_NAME)
os.environ['LD_LIBRARY_PATH'] = os.pathsep.join(paths)
os.environ['PYTHONIOENCODING'] = enc
os.execv(sys.executable, sys.argv)
built_executables = []
for script, exe, a in zip(scripts, executables, analyses):
built_executables.append(EXE(PYZ(TOC()),
a.scripts+[('O','','OPTION'),],
exclude_binaries=1,
name=os.path.join('buildcalibre', exe),
debug=False,
strip=True,
upx=False,
excludes=excludes,
console=1))
sys.path = sys.path[:3]
sys.frozen = True
sys.frozen_path = DIR_NAME
print 'Adding plugins...'
executables = %(executables)s
exe = os.environ.get('CALIBRE_CX_EXE', False)
ret = 1
if not exe:
print >>sys.stderr, 'Invalid invocation of calibre loader. CALIBRE_CX_EXE not set'
elif exe not in executables:
print >>sys.stderr, 'Invalid invocation of calibre loader. CALIBRE_CX_EXE=%%s is unknown'%%exe
else:
sys.argv[0] = exe
module, func = executables[exe]
module = __import__(module, fromlist=[1])
func = getattr(module, func)
ret = func()
module = sys.modules.get("threading")
if module is not None:
module._shutdown()
sys.exit(ret)
''')%dict(executables=repr(executables)))
sys.argv = ['freeze', 'build_exe']
setup(
name = __appname__,
version = __version__,
executables = [Executable(script=LOADER, targetName='loader', compress=False)],
options = { 'build_exe' :
{
'build_exe' : os.path.join(CALIBRESRC, 'build/cx_freeze'),
'optimize' : 2,
'excludes' : excludes,
'includes' : includes,
'packages' : packages,
'init_script' : INIT_SCRIPT,
'copy_dependent_files' : True,
'create_shared_zip' : False,
}
}
)
def copy_binary(src, dest_dir):
dest = os.path.join(dest_dir, os.path.basename(src))
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
shutil.copyfile(src, dest)
shutil.copymode(src, dest)
for f in binary_includes:
copy_binary(f, FREEZE_DIR)
for pat in binary_excludes:
matches = glob.glob(os.path.join(FREEZE_DIR, pat))
for f in matches:
os.remove(f)
print 'Adding calibre plugins...'
os.makedirs(os.path.join(FREEZE_DIR, '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')]
copy_binary(f, os.path.join(FREEZE_DIR, 'plugins'))
print 'Adding external programs...'
binaries += [('pdftohtml', PDFTOHTML, 'BINARY'),
('libunrar.so', LIBUNRAR, 'BINARY')]
print 'Adding external libraries...'
binaries += [ (os.path.basename(x), x, 'BINARY') for x in (SQLITE, DBUS,
LIBMNG, LIBZ, LIBBZ2, LIBUSB, LIBPOPPLER, LIBXML2, LIBXSLT, LIBEXSLT)]
qt = []
for dll in QTDLLS:
path = os.path.join(QTDIR, 'lib'+dll+'.so.4')
qt.append((os.path.basename(path), path, 'BINARY'))
binaries += qt
plugins = []
print 'Adding Qt plugins...'
plugdir = os.path.join(QTDIR, 'plugins')
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
if not f.endswith('.so') or 'designer' in dirpath or 'codecs' in dirpath or 'sqldrivers' in dirpath:
continue
f = os.path.join(dirpath, f)
plugins.append(('qtplugins/'+f.replace(plugdir, ''), f, 'BINARY'))
binaries += plugins
dest_dir = dirpath.replace(plugdir, os.path.join(FREEZE_DIR, 'qtlugins'))
copy_binary(f, dest_dir)
manifest = '/tmp/manifest'
open(manifest, 'wb').write('\n'.join(executables))
version = '/tmp/version'
open(version, 'wb').write(__version__)
coll = COLLECT(binaries, pyz,
[('manifest', manifest, 'DATA'), ('version', version, 'DATA')],
*built_executables,
**dict(strip=True,
upx=False,
excludes=excludes,
name='dist'))
print 'Creating launchers'
for exe in executables:
path = os.path.join(FREEZE_DIR, exe)
open(path, 'wb').write(textwrap.dedent('''\
#!/bin/sh
export CALIBRE_CX_EXE=%s
path=`readlink -e $0`
base=`dirname $path`
loader=$base/loader
export LD_LIBRARY_PATH=$base:$LD_LIBRARY_PATH
$loader "$@"
''')%exe)
os.chmod(path, 0755)
os.chdir(os.path.join(HOMEPATH, 'calibre', 'dist'))
for folder in EXTRAS:
subprocess.check_call('cp -rf %s .'%folder, shell=True)
exes = list(executables.keys())
exes.remove('calibre_postinstall')
exes.remove('calibre-parallel')
open(os.path.join(FREEZE_DIR, 'manifest'), 'wb').write('\n'.join(exes))
print 'Building tarball...'
tbz2 = 'calibre-%s-i686.tar.bz2'%__version__
tf = tarfile.open(os.path.join('/tmp', tbz2), 'w:bz2')
print 'Creating archive...'
dist = open(os.path.join(DIST_DIR, 'calibre-%s-i686.tar.bz2'%__version__), 'wb')
with closing(tarfile.open(fileobj=dist, mode='w:bz2',
format=tarfile.PAX_FORMAT)) as tf:
for f in walk(FREEZE_DIR):
name = f.replace(FREEZE_DIR, '')[1:]
if name:
tf.add(f, name)
dist.flush()
dist.seek(0, 2)
print 'Archive %s created: %.2f MB'%(dist.name, dist.tell()/(1024.**2))
return 0
for f in os.listdir('.'):
tf.add(f)
if __name__ == '__main__':
freeze()

View File

@ -177,7 +177,7 @@ _check_symlinks_prescript()
def fix_python_dependencies(self, files):
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])
subprocess.check_call(['/usr/bin/install_name_tool', '-change', '/Library/Frameworks/Python.framework/Versions/2.6/Python', '@executable_path/../Frameworks/Python.framework/Versions/2.6/Python', f])
def fix_misc_dependencies(self, files):
for path in files:
@ -247,10 +247,13 @@ _check_symlinks_prescript()
print 'Adding pdftohtml'
os.link(os.path.expanduser('~/pdftohtml'), os.path.join(frameworks_dir, 'pdftohtml'))
print 'Adding plugins'
module_dir = os.path.join(resource_dir, 'lib', 'python2.5', 'lib-dynload')
module_dir = os.path.join(resource_dir, 'lib', 'python2.6', 'lib-dynload')
print 'Adding fontconfig'
for f in glob.glob(os.path.expanduser('~/fontconfig-bundled/*')):
os.link(f, os.path.join(frameworks_dir, os.path.basename(f)))
dest = os.path.join(frameworks_dir, os.path.basename(f))
if os.path.exists(dest):
os.remove(dest)
os.link(f, dest)
dst = os.path.join(resource_dir, 'fonts')
if os.path.exists(dst):
shutil.rmtree(dst)
@ -258,7 +261,7 @@ _check_symlinks_prescript()
print
print 'Adding IPython'
dst = os.path.join(resource_dir, 'lib', 'python2.5', 'IPython')
dst = os.path.join(resource_dir, 'lib', 'python2.6', 'IPython')
if os.path.exists(dst): shutil.rmtree(dst)
shutil.copytree(os.path.expanduser('~/build/ipython/IPython'), dst)
@ -280,6 +283,7 @@ _check_symlinks_prescript()
f = open(launcher_path, 'r')
src = f.read()
f.close()
src = src.replace('import Image', 'from PIL import Image')
src = re.sub('(_run\s*\(.*?.py.*?\))', cs+'%s'%(
'''
sys.frameworks_dir = os.path.join(os.path.dirname(os.environ['RESOURCEPATH']), 'Frameworks')
@ -290,7 +294,7 @@ sys.frameworks_dir = os.path.join(os.path.dirname(os.environ['RESOURCEPATH']), '
f.close()
print
print 'Adding main scripts to site-packages'
f = zipfile.ZipFile(os.path.join(self.dist_dir, APPNAME+'.app', 'Contents', 'Resources', 'lib', 'python2.5', 'site-packages.zip'), 'a', zipfile.ZIP_DEFLATED)
f = zipfile.ZipFile(os.path.join(self.dist_dir, APPNAME+'.app', 'Contents', 'Resources', 'lib', 'python2.6', 'site-packages.zip'), 'a', zipfile.ZIP_DEFLATED)
for script in scripts['gui']+scripts['console']:
f.write(script, script.partition('/')[-1])
f.close()
@ -322,7 +326,8 @@ def main():
'genshi', 'calibre.web.feeds.recipes.*',
'calibre.ebooks.lrf.any.*', 'calibre.ebooks.lrf.feeds.*',
'keyword', 'codeop', 'pydoc', 'readline',
'BeautifulSoup'],
'BeautifulSoup'
],
'packages' : ['PIL', 'Authorization', 'lxml'],
'excludes' : ['IPython'],
'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.'''

View File

@ -401,7 +401,8 @@ if __name__ == '__main__':
))
if isosx:
ext_modules.append(Extension('calibre.plugins.usbobserver',
sources=['src/calibre/devices/usbobserver/usbobserver.c'])
sources=['src/calibre/devices/usbobserver/usbobserver.c'],
extra_link_args=['-framework', 'IOKit'])
)
setup(

View File

@ -20,6 +20,11 @@ mimetypes.add_type('application/epub+zip', '.epub')
mimetypes.add_type('text/x-sony-bbeb+xml', '.lrs')
mimetypes.add_type('application/x-sony-bbeb', '.lrf')
def to_unicode(raw, encoding='utf-8', errors='strict'):
if isinstance(raw, unicode):
return raw
return raw.decode(encoding, errors)
def unicode_path(path, abs=False):
if not isinstance(path, unicode):
path = path.decode(sys.getfilesystemencoding())
@ -317,7 +322,12 @@ class LoggingInterface:
def ___log(self, func, msg, args, kwargs):
args = [msg] + list(args)
for i in range(len(args)):
if isinstance(args[i], unicode):
if not isinstance(args[i], basestring):
continue
if sys.version_info[:2] > (2, 5):
if not isinstance(args[i], unicode):
args[i] = args[i].decode(preferred_encoding, 'replace')
elif isinstance(args[i], unicode):
args[i] = args[i].encode(preferred_encoding, 'replace')
func(*args, **kwargs)

View File

@ -2,7 +2,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
__appname__ = 'calibre'
__version__ = '0.4.112'
__version__ = '0.4.113'
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
'''
Various run time constants.

View File

@ -48,8 +48,7 @@ from calibre.ebooks.epub import initialize_container, PROFILES
from calibre.ebooks.epub.split import split
from calibre.ebooks.epub.fonts import Rationalizer
from calibre.constants import preferred_encoding
from calibre import walk
from calibre import CurrentDir
from calibre import walk, CurrentDir, to_unicode
content = functools.partial(os.path.join, u'content')
@ -79,7 +78,7 @@ def check(opf_path, pretty_print):
base = os.path.dirname(path)
root = html.fromstring(open(content(path), 'rb').read())
for element, attribute, link, pos in list(root.iterlinks()):
link = link.decode('utf-8')
link = to_unicode(link)
plink = Link(link, base)
bad = False
if plink.path is not None and not os.path.exists(plink.path):
@ -204,7 +203,7 @@ TITLEPAGE = '''\
</head>
<body>
<div>
<img src="%s" alt="cover" />
<img src="%s" alt="cover" style="height: 100%%" />
</div>
</body>
</html>

View File

@ -168,7 +168,8 @@ class EbookIterator(object):
if bookmarks is None:
bookmarks = self.bookmarks
dat = self.serialize_bookmarks(bookmarks)
if os.path.splitext(self.pathtoebook)[1].lower() == '.epub':
if os.path.splitext(self.pathtoebook)[1].lower() == '.epub' and \
os.access(self.pathtoebook, os.R_OK):
zf = open(self.pathtoebook, 'r+b')
zipf = ZipFile(zf, mode='a')
for name in zipf.namelist():

View File

@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
Split the flows in an epub file to conform to size limitations.
'''
import os, math, logging, functools, collections, re, copy
import os, math, logging, functools, collections, re, copy, sys
from lxml.etree import XPath as _XPath
from lxml import etree, html
@ -34,30 +34,62 @@ class SplitError(ValueError):
class Splitter(LoggingInterface):
def __init__(self, path, opts, stylesheet_map, always_remove=False):
def __init__(self, path, opts, stylesheet_map, opf):
LoggingInterface.__init__(self, logging.getLogger('htmlsplit'))
self.setup_cli_handler(opts.verbose)
self.path = path
self.always_remove = always_remove
self.always_remove = not opts.preserve_tag_structure or \
os.stat(content(path)).st_size > 5*opts.profile.flow_size
self.base = (os.path.splitext(path)[0].replace('%', '%%') + '_split_%d.html')
self.opts = opts
self.orig_size = os.stat(content(path)).st_size
self.log_info('\tSplitting %s (%d KB)', path, self.orig_size/1024.)
root = html.fromstring(open(content(path)).read())
self.page_breaks = []
self.find_page_breaks(stylesheet_map[self.path], root)
self.trees = []
self.page_breaks, self.trees = [], []
self.split_size = 0
self.split(root.getroottree())
# Split on page breaks
self.log_info('\tSplitting on page breaks...')
if self.path in stylesheet_map:
self.find_page_breaks(stylesheet_map[self.path], root)
self.split_on_page_breaks(root.getroottree())
trees = list(self.trees)
# Split any remaining over-sized trees
if self.opts.profile.flow_size < sys.maxint:
lt_found = False
self.log_info('\tLooking for large trees...')
for i, tree in enumerate(list(trees)):
self.trees = []
size = len(tostring(tree.getroot()))
if size > self.opts.profile.flow_size:
lt_found = True
try:
self.split_to_size(tree)
except (SplitError, RuntimeError): # Splitting fails
if not self.always_remove:
self.always_remove = True
self.split_to_size(tree)
else:
raise
trees[i:i+1] = list(self.trees)
if not lt_found:
self.log_info('\tNo large trees found')
self.trees = trees
self.was_split = len(self.trees) > 1
if self.was_split:
self.commit()
self.log_info('\t\tSplit into %d parts.', len(self.trees))
if self.opts.verbose:
for f in self.files:
self.log_info('\t\t\t%s - %d KB', f, os.stat(content(f)).st_size/1024.)
self.fix_opf(opf)
self.trees = None
def split_text(self, text, root, size):
self.log_debug('\t\t\tSplitting text of length: %d'%len(text))
rest = text.replace('\r', '')
@ -76,12 +108,7 @@ class Splitter(LoggingInterface):
return ans
def split(self, tree):
'''
Split ``tree`` into a *before* and *after* tree, preserving tag structure,
but not duplicating any text. All tags that have had their text and tail
removed have the attribute ``calibre_split`` set to 1.
'''
def split_to_size(self, tree):
self.log_debug('\t\tSplitting...')
root = tree.getroot()
# Split large <pre> tags
@ -108,10 +135,50 @@ class Splitter(LoggingInterface):
if not self.always_remove:
self.log_warn(_('\t\tToo much markup. Re-splitting without structure preservation. This may cause incorrect rendering.'))
raise SplitError(self.path, root)
tree2 = copy.deepcopy(tree)
for t in self.do_split(tree, split_point, before):
r = t.getroot()
if self.is_page_empty(r):
continue
size = len(tostring(r))
if size <= self.opts.profile.flow_size:
self.trees.append(t)
#print tostring(t.getroot(), pretty_print=True)
self.log_debug('\t\t\tCommitted sub-tree #%d (%d KB)', len(self.trees), size/1024.)
self.split_size += size
else:
self.split_to_size(t)
def is_page_empty(self, root):
body = root.find('body')
if body is None:
return False
txt = re.sub(r'\s+', '', html.tostring(body, method='text', encoding=unicode))
if len(txt) > 4:
#if len(txt) < 100:
# print 1111111, html.tostring(body, method='html', encoding=unicode)
return False
for img in root.xpath('//img'):
if img.get('style', '') != 'display:none':
return False
return True
def do_split(self, tree, split_point, before):
'''
Split ``tree`` into a *before* and *after* tree at ``split_point``,
preserving tag structure, but not duplicating any text.
All tags that have had their text and tail
removed have the attribute ``calibre_split`` set to 1.
:param before: If True tree is split before split_point, otherwise after split_point
:return: before_tree, after_tree
'''
path = tree.getpath(split_point)
tree, tree2 = copy.deepcopy(tree), copy.deepcopy(tree)
root = tree.getroot()
root2 = tree2.getroot()
body, body2 = root.body, root2.body
path = tree.getpath(split_point)
split_point = root.xpath(path)[0]
split_point2 = root2.xpath(path)[0]
def nix_element(elem, top=True):
@ -129,7 +196,7 @@ class Splitter(LoggingInterface):
elem.tail = u''
elem.set(SPLIT_ATTR, '1')
if elem.tag.lower() in ['ul', 'ol', 'dl', 'table', 'hr', 'img']:
elem.set('style', 'display:none;')
elem.set('style', 'display:none')
def fix_split_point(sp):
sp.set('style', sp.get('style', '')+'page-break-before:avoid;page-break-after:avoid')
@ -163,20 +230,35 @@ class Splitter(LoggingInterface):
if not hit_split_point:
nix_element(elem, top=False)
for t, r in [(tree, root), (tree2, root2)]:
size = len(tostring(r))
if size <= self.opts.profile.flow_size:
self.trees.append(t)
#print tostring(t.getroot(), pretty_print=True)
self.log_debug('\t\t\tCommitted sub-tree #%d (%d KB)', len(self.trees), size/1024.)
self.split_size += size
else:
self.split(t)
return tree, tree2
def split_on_page_breaks(self, orig_tree):
ordered_ids = []
for elem in orig_tree.xpath('//*[@id]'):
id = elem.get('id')
if id in self.page_break_ids:
ordered_ids.append(self.page_breaks[self.page_break_ids.index(id)])
self.trees = []
tree = orig_tree
for pattern, before in ordered_ids:
self.log_info('\t\tSplitting on page-break')
elem = pattern(tree)
if elem:
before, after = self.do_split(tree, elem[0], before)
self.trees.append(before)
tree = after
self.trees.append(tree)
self.trees = [t for t in self.trees if not self.is_page_empty(t.getroot())]
def find_page_breaks(self, stylesheets, root):
'''
Find all elements that have either page-break-before or page-break-after set.
Populates `self.page_breaks` with id based XPath selectors (for elements that don't
have ids, an id is created).
'''
page_break_selectors = set([])
for rule in rules(stylesheets):
@ -204,16 +286,18 @@ class Splitter(LoggingInterface):
page_breaks = list(page_breaks)
page_breaks.sort(cmp=lambda x,y : cmp(x.pb_order, y.pb_order))
self.page_break_ids = []
for i, x in enumerate(page_breaks):
x.set('id', x.get('id', 'calibre_pb_%d'%i))
self.page_breaks.append((XPath('//*[@id="%s"]'%x.get('id')), x.pb_before))
id = x.get('id')
self.page_breaks.append((XPath('//*[@id="%s"]'%id), x.pb_before))
self.page_break_ids.append(id)
def find_split_point(self, root):
'''
Find the tag at which to split the tree rooted at `root`.
Search order is:
* page breaks
* Heading tags
* <div> tags
* <p> tags
@ -229,19 +313,6 @@ class Splitter(LoggingInterface):
elems[i].set(SPLIT_POINT_ATTR, '1')
return elems[i]
page_breaks = []
for x in self.page_breaks:
pb = x[0](root)
if pb:
page_breaks.append(pb[0])
elem = pick_elem(page_breaks)
if elem is not None:
i = page_breaks.index(elem)
return elem, self.page_breaks[i][1]
for path in (
'//*[re:match(name(), "h[1-6]", "i")]',
'/html/body/div',
@ -315,6 +386,9 @@ class Splitter(LoggingInterface):
frag = None
if len(href) > 1:
frag = href[1]
if frag not in self.anchor_map:
self.log_warning('\t\tUnable to re-map OPF link', href)
continue
new_file = self.anchor_map[frag]
ref.set('href', 'content/'+new_file+('' if frag is None else ('#'+frag)))
@ -341,7 +415,11 @@ def fix_content_links(html_files, changes, opts):
anchor = href[1] if len(href) > 1 else None
href = href[0]
if href in split_files:
try:
newf = anchor_maps[split_files.index(href)][anchor]
except:
print '\t\tUnable to remap HTML link:', href, anchor
continue
frag = ('#'+anchor) if anchor else ''
a.set('href', newf+frag)
changed = True
@ -354,24 +432,28 @@ def fix_ncx(path, changes):
anchor_maps = [f.anchor_map for f in changes]
tree = etree.parse(path)
changed = False
for content in tree.getroot().xpath('//x:content[@src]', namespaces={'x':"http://www.daisy.org/z3986/2005/ncx/"}):
for content in tree.getroot().xpath('//x:content[@src]',
namespaces={'x':"http://www.daisy.org/z3986/2005/ncx/"}):
href = content.get('src')
if not href.startswith('#'):
href = href.split('#')
anchor = href[1] if len(href) > 1 else None
href = href[0].split('/')[-1]
if href in split_files:
try:
newf = anchor_maps[split_files.index(href)][anchor]
except:
print 'Unable to remap NCX link:', href, anchor
frag = ('#'+anchor) if anchor else ''
content.set('src', 'content/'+newf+frag)
changed = True
if changed:
open(path, 'wb').write(etree.tostring(tree.getroot(), encoding='UTF-8', xml_declaration=True))
def split(pathtoopf, opts, stylesheet_map):
pathtoopf = os.path.abspath(pathtoopf)
with CurrentDir(os.path.dirname(pathtoopf)):
opf = OPF(open(pathtoopf, 'rb'), os.path.dirname(pathtoopf))
def find_html_files(opf):
'''
Find all HTML files referenced by `opf`.
'''
html_files = []
for item in opf.itermanifest():
if 'html' in item.get('media-type', '').lower():
@ -380,26 +462,24 @@ def split(pathtoopf, opts, stylesheet_map):
if not os.path.exists(content(f)) and os.path.exists(content(f2)):
f = f2
item.set('href', item.get('href').replace('&', '%26'))
if os.path.exists(content(f)):
html_files.append(f)
changes = []
always_remove = not opts.preserve_tag_structure
for f in html_files:
if os.stat(content(f)).st_size > opts.profile.flow_size:
try:
changes.append(Splitter(f, opts, stylesheet_map,
always_remove=(always_remove or \
os.stat(content(f)).st_size > 5*opts.profile.flow_size)))
except (SplitError, RuntimeError):
if not always_remove:
changes.append(Splitter(f, opts, stylesheet_map, always_remove=True))
else:
raise
changes[-1].fix_opf(opf)
return html_files
def split(pathtoopf, opts, stylesheet_map):
pathtoopf = os.path.abspath(pathtoopf)
opf = OPF(open(pathtoopf, 'rb'), os.path.dirname(pathtoopf))
with CurrentDir(os.path.dirname(pathtoopf)):
html_files = find_html_files(opf)
changes = [Splitter(f, opts, stylesheet_map, opf) for f in html_files]
changes = [c for c in changes if c.was_split]
open(pathtoopf, 'wb').write(opf.render())
fix_content_links(html_files, changes, opts)
for item in opf.itermanifest():
if item.get('media-type', '') == 'application/x-dtbncx+xml':
fix_ncx(item.get('href'), changes)
break
open(pathtoopf, 'wb').write(opf.render())

View File

@ -1948,7 +1948,8 @@ def try_opf(path, options, logger):
return
dirpath = os.path.dirname(os.path.abspath(opf))
opf = OPFReader(open(opf, 'rb'), dirpath)
from calibre.ebooks.metadata.opf2 import OPF as OPF2
opf = OPF2(open(opf, 'rb'), dirpath)
try:
title = opf.title
if title and not getattr(options, 'title', None):
@ -1962,10 +1963,6 @@ def try_opf(path, options, logger):
publisher = opf.publisher
if publisher:
options.publisher = publisher
if not getattr(options, 'category', None):
category = opf.category
if category:
options.category = category
if not getattr(options, 'cover', None) or options.use_metadata_cover:
orig_cover = getattr(options, 'cover', None)
options.cover = None

View File

@ -0,0 +1,89 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
'''
Read metadata from LRX files
'''
import sys, struct
from zlib import decompress
from lxml import etree
from calibre.ebooks.metadata import MetaInformation, string_to_authors
def _read(f, at, amount):
f.seek(at)
return f.read(amount)
def word_be(buf):
return struct.unpack('>L', buf)[0]
def word_le(buf):
return struct.unpack('<L', buf)[0]
def short_le(buf):
return struct.unpack('<H', buf)[0]
def short_be(buf):
return struct.unpack('>H', buf)[0]
def get_metadata(f):
read = lambda at, amount: _read(f, at, amount)
f.seek(0)
buf = f.read(12)
if buf[4:] == 'ftypLRX2':
offset = 0
while True:
offset += word_be(buf[:4])
try:
buf = read(offset, 8)
except:
raise ValueError('Not a valid LRX file')
if buf[4:] == 'bbeb':
break
offset += 8
buf = read(offset, 16)
if buf[:8].decode('utf-16-le') != 'LRF\x00':
raise ValueError('Not a valid LRX file')
lrf_version = word_le(buf[8:12])
offset += 0x4c
compressed_size = short_le(read(offset, 2))
offset += 2
if lrf_version >= 800:
offset += 6
compressed_size -= 4
uncompressed_size = word_le(read(offset, 4))
info = decompress(f.read(compressed_size))
if len(info) != uncompressed_size:
raise ValueError('LRX file has malformed metadata section')
root = etree.fromstring(info)
bi = root.find('BookInfo')
title = bi.find('Title')
title_sort = title.get('reading', None)
title = title.text
author = bi.find('Author')
author_sort = author.get('reading', None)
mi = MetaInformation(title, string_to_authors(author.text))
mi.title_sort, mi.author_sort = title_sort, author_sort
author = author.text
publisher = bi.find('Publisher')
mi.publisher = getattr(publisher, 'text', None)
mi.tags = [x.text for x in bi.findall('Category')]
mi.language = root.find('DocInfo').find('Language').text
return mi
elif buf[4:8] == 'LRX':
raise ValueError('Librie LRX format not supported')
else:
raise ValueError('Not a LRX file')
def main(args=sys.argv):
print get_metadata(open(args[1], 'rb'))
return 0
if __name__ == '__main__':
sys.exit(main())

View File

@ -16,6 +16,7 @@ from calibre.ebooks.metadata.epub import get_metadata as epub_metadata
from calibre.ebooks.metadata.html import get_metadata as html_metadata
from calibre.ebooks.mobi.reader import get_metadata as mobi_metadata
from calibre.ebooks.metadata.odt import get_metadata as odt_metadata
from calibre.ebooks.metadata.lrx import get_metadata as lrx_metadata
from calibre.ebooks.metadata.opf2 import OPF
from calibre.ebooks.metadata.rtf import set_metadata as set_rtf_metadata
from calibre.ebooks.lrf.meta import set_metadata as set_lrf_metadata
@ -29,12 +30,12 @@ except OSError:
from calibre.libunzip import extract_member as zip_extract_first
from calibre.ebooks.metadata import MetaInformation
from calibre.ptempfile import TemporaryDirectory
_METADATA_PRIORITIES = [
'html', 'htm', 'xhtml', 'xhtm',
'rtf', 'fb2', 'pdf', 'prc', 'odt',
'epub', 'lit', 'lrf', 'mobi', 'rb', 'imp'
'epub', 'lit', 'lrx', 'lrf', 'mobi',
'rb', 'imp'
]
# The priorities for loading metadata from different file types

View File

@ -70,7 +70,7 @@ class Manifest(ResourceCollection):
@staticmethod
def from_opf_manifest_element(manifest, dir):
m = Manifest()
for item in manifest.findAll('item'):
for item in manifest.findAll(re.compile('item')):
try:
m.append(ManifestItem.from_opf_manifest_item(item, dir))
id = item.get('id', '')
@ -130,7 +130,7 @@ class Spine(ResourceCollection):
@staticmethod
def from_opf_spine_element(spine, manifest):
s = Spine(manifest)
for itemref in spine.findAll('itemref'):
for itemref in spine.findAll(re.compile('itemref')):
if itemref.has_key('idref'):
r = Spine.Item(s.manifest.id_for_path,
s.manifest.path_for_id(itemref['idref']), is_path=True)
@ -242,14 +242,27 @@ class OPF(MetaInformation):
def __init__(self):
raise NotImplementedError('Abstract base class')
@apply
def package():
def fget(self):
return self.soup.find(re.compile('package'))
return property(fget=fget)
@apply
def metadata():
def fget(self):
return self.package.find(re.compile('metadata'))
return property(fget=fget)
def get_title(self):
title = self.soup.package.metadata.find('dc:title')
title = self.metadata.find('dc:title')
if title and title.string:
return self.ENTITY_PATTERN.sub(entity_to_unicode, title.string).strip()
return self.default_title.strip()
def get_authors(self):
creators = self.soup.package.metadata.findAll('dc:creator')
creators = self.metadata.findAll('dc:creator')
for elem in creators:
role = elem.get('role')
if not role:
@ -266,7 +279,7 @@ class OPF(MetaInformation):
return []
def get_author_sort(self):
creators = self.soup.package.metadata.findAll('dc:creator')
creators = self.metadata.findAll('dc:creator')
for elem in creators:
role = elem.get('role')
if not role:
@ -277,7 +290,7 @@ class OPF(MetaInformation):
return None
def get_title_sort(self):
title = self.soup.package.find('dc:title')
title = self.package.find('dc:title')
if title:
if title.has_key('file-as'):
return title['file-as'].strip()
@ -290,7 +303,7 @@ class OPF(MetaInformation):
return None
def get_uid(self):
package = self.soup.find('package')
package = self.package
if package.has_key('unique-identifier'):
return package['unique-identifier']
@ -307,7 +320,7 @@ class OPF(MetaInformation):
return None
def get_isbn(self):
for item in self.soup.package.metadata.findAll('dc:identifier'):
for item in self.metadata.findAll('dc:identifier'):
scheme = item.get('scheme')
if not scheme:
scheme = item.get('opf:scheme')
@ -316,13 +329,13 @@ class OPF(MetaInformation):
return None
def get_language(self):
item = self.soup.package.metadata.find('dc:language')
item = self.metadata.find('dc:language')
if not item:
return _('Unknown')
return ''.join(item.findAll(text=True)).strip()
def get_application_id(self):
for item in self.soup.package.metadata.findAll('dc:identifier'):
for item in self.metadata.findAll('dc:identifier'):
scheme = item.get('scheme', None)
if scheme is None:
scheme = item.get('opf:scheme', None)
@ -342,7 +355,7 @@ class OPF(MetaInformation):
def possible_cover_prefixes(self):
isbn, ans = [], []
for item in self.soup.package.metadata.findAll('dc:identifier'):
for item in self.metadata.findAll('dc:identifier'):
scheme = item.get('scheme')
if not scheme:
scheme = item.get('opf:scheme')
@ -352,13 +365,13 @@ class OPF(MetaInformation):
return ans
def get_series(self):
s = self.soup.package.metadata.find('series')
s = self.metadata.find('series')
if s is not None:
return str(s.string).strip()
return None
def get_series_index(self):
s = self.soup.package.metadata.find('series-index')
s = self.metadata.find('series-index')
if s and s.string:
try:
return int(str(s.string).strip())
@ -367,7 +380,7 @@ class OPF(MetaInformation):
return None
def get_rating(self):
s = self.soup.package.metadata.find('rating')
s = self.metadata.find('rating')
if s and s.string:
try:
return int(str(s.string).strip())
@ -400,17 +413,17 @@ class OPFReader(OPF):
if manage:
stream.close()
self.manifest = Manifest()
m = self.soup.find('manifest')
m = self.soup.find(re.compile('manifest'))
if m is not None:
self.manifest = Manifest.from_opf_manifest_element(m, dir)
self.spine = None
spine = self.soup.find('spine')
spine = self.soup.find(re.compile('spine'))
if spine is not None:
self.spine = Spine.from_opf_spine_element(spine, self.manifest)
self.toc = TOC(base_path=dir)
self.toc.read_from_opf(self)
guide = self.soup.find('guide')
guide = self.soup.find(re.compile('guide'))
if guide is not None:
self.guide = Guide.from_opf_guide(guide, dir)
self.base_dir = dir

View File

@ -30,7 +30,6 @@ class Resource(object):
:member:`path`
:member:`mime_type`
:method:`href`
'''
def __init__(self, href_or_path, basedir=os.getcwd(), is_path=True):

View File

@ -351,7 +351,7 @@ class SGMLParser(markupbase.ParserBase):
if tag not in self.stack:
try:
method = getattr(self, 'end_' + tag)
except AttributeError:
except (AttributeError, ValueError):
self.unknown_endtag(tag)
else:
self.report_unbalanced(tag)

View File

@ -9,9 +9,10 @@ from PyQt4.QtGui import QDialog
from calibre.gui2 import qstring_to_unicode
from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog
from calibre.gui2.dialogs.tag_editor import TagEditor
from calibre.ebooks.metadata import string_to_authors
from calibre.ebooks.metadata import string_to_authors, authors_to_sort_string
class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
def __init__(self, window, rows, db):
QDialog.__init__(self, window)
Ui_MetadataBulkDialog.__init__(self)
@ -54,8 +55,15 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
if au:
au = string_to_authors(au)
self.db.set_authors(id, au, notify=False)
if self.auto_author_sort.isChecked():
aut = self.db.authors(id, index_is_id=True)
aut = aut if aut else ''
aut = [a.strip().replace('|', ',') for a in aut.strip().split(',')]
x = authors_to_sort_string(aut)
if x:
self.db.set_author_sort(id, x, notify=False)
aus = qstring_to_unicode(self.author_sort.text())
if aus:
if aus and self.author_sort.isEnabled():
self.db.set_author_sort(id, aus, notify=False)
if self.write_rating:
self.db.set_rating(id, 2*self.rating.value(), notify=False)

View File

@ -56,7 +56,7 @@
</property>
</widget>
</item>
<item row="1" column="0" >
<item row="2" column="0" >
<widget class="QLabel" name="label_8" >
<property name="text" >
<string>Author S&amp;ort: </string>
@ -69,14 +69,14 @@
</property>
</widget>
</item>
<item row="1" column="1" colspan="2" >
<item row="2" column="1" colspan="2" >
<widget class="QLineEdit" name="author_sort" >
<property name="toolTip" >
<string>Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles.</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<item row="3" column="0" >
<widget class="QLabel" name="label_6" >
<property name="text" >
<string>&amp;Rating:</string>
@ -89,7 +89,7 @@
</property>
</widget>
</item>
<item row="2" column="1" colspan="2" >
<item row="3" column="1" colspan="2" >
<widget class="QSpinBox" name="rating" >
<property name="toolTip" >
<string>Rating of this book. 0-5 stars</string>
@ -108,7 +108,7 @@
</property>
</widget>
</item>
<item row="3" column="0" >
<item row="4" column="0" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>&amp;Publisher: </string>
@ -121,14 +121,14 @@
</property>
</widget>
</item>
<item row="3" column="1" colspan="2" >
<item row="4" column="1" colspan="2" >
<widget class="QLineEdit" name="publisher" >
<property name="toolTip" >
<string>Change the publisher of this book</string>
</property>
</widget>
</item>
<item row="4" column="0" >
<item row="5" column="0" >
<widget class="QLabel" name="label_4" >
<property name="text" >
<string>Add Ta&amp;gs: </string>
@ -141,14 +141,14 @@
</property>
</widget>
</item>
<item row="4" column="1" >
<item row="5" column="1" >
<widget class="QLineEdit" name="tags" >
<property name="toolTip" >
<string>Tags categorize the book. This is particularly useful while searching. &lt;br>&lt;br>They can be any words or phrases, separated by commas.</string>
</property>
</widget>
</item>
<item row="4" column="2" >
<item row="5" column="2" >
<widget class="QToolButton" name="tag_editor_button" >
<property name="toolTip" >
<string>Open Tag Editor</string>
@ -162,7 +162,7 @@
</property>
</widget>
</item>
<item row="5" column="0" >
<item row="6" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>&amp;Remove tags:</string>
@ -172,14 +172,14 @@
</property>
</widget>
</item>
<item row="5" column="1" colspan="2" >
<item row="6" column="1" colspan="2" >
<widget class="QLineEdit" name="remove_tags" >
<property name="toolTip" >
<string>Comma separated list of tags to remove from the books. </string>
</property>
</widget>
</item>
<item row="6" column="0" >
<item row="7" column="0" >
<widget class="QLabel" name="label_7" >
<property name="text" >
<string>&amp;Series:</string>
@ -195,7 +195,7 @@
</property>
</widget>
</item>
<item row="6" column="1" >
<item row="7" column="1" >
<widget class="QComboBox" name="series" >
<property name="toolTip" >
<string>List of known series. You can add new series.</string>
@ -214,10 +214,10 @@
</property>
</widget>
</item>
<item row="7" column="1" >
<item row="8" column="1" >
<widget class="QComboBox" name="remove_format" />
</item>
<item row="7" column="0" >
<item row="8" column="0" >
<widget class="QLabel" name="label_5" >
<property name="text" >
<string>Remove &amp;format:</string>
@ -227,6 +227,13 @@
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QCheckBox" name="auto_author_sort" >
<property name="text" >
<string>A&amp;utomatically set author sort</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -257,8 +264,8 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>248</x>
<y>254</y>
<x>252</x>
<y>382</y>
</hint>
<hint type="destinationlabel" >
<x>157</x>
@ -273,8 +280,8 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>260</y>
<x>320</x>
<y>382</y>
</hint>
<hint type="destinationlabel" >
<x>286</x>
@ -282,5 +289,21 @@
</hint>
</hints>
</connection>
<connection>
<sender>auto_author_sort</sender>
<signal>toggled(bool)</signal>
<receiver>author_sort</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>240</x>
<y>95</y>
</hint>
<hint type="destinationlabel" >
<x>240</x>
<y>113</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -129,6 +129,7 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog):
QDialog.__init__(self, window)
Ui_MetadataSingleDialog.__init__(self)
self.setupUi(self)
self.bc_box.layout().setAlignment(self.cover, Qt.AlignCenter|Qt.AlignHCenter)
self.splitter.setStretchFactor(100, 1)
self.db = db
self.accepted_callback = accepted_callback

View File

@ -439,7 +439,7 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4" >
<widget class="QGroupBox" name="bc_box" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
<horstretch>0</horstretch>

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

View File

@ -163,11 +163,18 @@ class BooksModel(QAbstractTableModel):
self.reset()
def add_books(self, paths, formats, metadata, uris=[], add_duplicates=False):
return self.db.add_books(paths, formats, metadata, uris,
ret = self.db.add_books(paths, formats, metadata, uris,
add_duplicates=add_duplicates)
self.count_changed()
return ret
def add_news(self, path, recipe):
return self.db.add_news(path, recipe)
ret = self.db.add_news(path, recipe)
self.count_changed()
return ret
def count_changed(self, *args):
self.emit(SIGNAL('count_changed(int)'), self.db.count())
def row_indices(self, index):
''' Return list indices of all cells in index.row()'''
@ -189,9 +196,11 @@ class BooksModel(QAbstractTableModel):
self.beginRemoveRows(QModelIndex(), row, row)
self.db.delete_book(id)
self.endRemoveRows()
self.count_changed()
self.clear_caches()
self.reset()
def delete_books_by_id(self, ids):
for id in ids:
try:
@ -203,12 +212,14 @@ class BooksModel(QAbstractTableModel):
self.db.delete_book(id)
if row > -1:
self.endRemoveRows()
self.count_changed()
self.clear_caches()
def books_added(self, num):
if num > 0:
self.beginInsertRows(QModelIndex(), 0, num-1)
self.endInsertRows()
self.count_changed()
def search(self, text, refinement, reset=True):
self.db.search(text)

View File

@ -297,6 +297,8 @@ class Main(MainWindow, Ui_MainWindow):
self.connect(self.status_bar.tag_view_button, SIGNAL('toggled(bool)'), self.toggle_tags_view)
self.connect(self.search, SIGNAL('search(PyQt_PyObject, PyQt_PyObject)'),
self.tags_view.model().reinit)
self.connect(self.library_view.model(), SIGNAL('count_changed(int)'), self.location_view.count_changed)
self.library_view.model().count_changed()
########################### Cover Flow ################################
self.cover_flow = None
if CoverFlow is not None:
@ -344,12 +346,12 @@ class Main(MainWindow, Ui_MainWindow):
self.library_view.setCurrentIndex(self.library_view.currentIndex())
self.cover_flow.setVisible(True)
self.cover_flow.setFocus(Qt.OtherFocusReason)
self.status_bar.book_info.book_data.setMaximumHeight(100)
self.status_bar.setMaximumHeight(120)
#self.status_bar.book_info.book_data.setMaximumHeight(100)
#self.status_bar.setMaximumHeight(120)
self.library_view.scrollTo(self.library_view.currentIndex())
else:
self.cover_flow.setVisible(False)
self.status_bar.book_info.book_data.setMaximumHeight(1000)
#self.status_bar.book_info.book_data.setMaximumHeight(1000)
self.setMaximumHeight(available_height())
def toggle_tags_view(self, show):

View File

@ -2,16 +2,18 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import re, collections
from PyQt4.QtGui import QStatusBar, QMovie, QLabel, QFrame, QHBoxLayout, QPixmap, \
QVBoxLayout, QSizePolicy, QToolButton, QIcon
from PyQt4.QtGui import QStatusBar, QMovie, QLabel, QWidget, QHBoxLayout, QPixmap, \
QVBoxLayout, QSizePolicy, QToolButton, QIcon, QScrollArea, QFrame
from PyQt4.QtCore import Qt, QSize, SIGNAL, QCoreApplication
from calibre import fit_image, preferred_encoding
from calibre.gui2 import qstring_to_unicode
class BookInfoDisplay(QFrame):
class BookInfoDisplay(QWidget):
class BookCoverDisplay(QLabel):
WIDTH = 80
HEIGHT = 100
WIDTH = 81
HEIGHT = 108
def __init__(self, coverpath=':/images/book.svg'):
QLabel.__init__(self)
self.default_pixmap = QPixmap(coverpath).scaled(self.__class__.WIDTH,
@ -19,6 +21,7 @@ class BookInfoDisplay(QFrame):
Qt.IgnoreAspectRatio,
Qt.SmoothTransformation)
self.setScaledContents(True)
self.setMaximumHeight(self.HEIGHT)
self.setPixmap(self.default_pixmap)
@ -39,11 +42,9 @@ class BookInfoDisplay(QFrame):
class BookDataDisplay(QLabel):
def __init__(self):
QLabel.__init__(self)
#self.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.setText('')
self.setWordWrap(True)
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
self.setMaximumHeight(100)
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
def mouseReleaseEvent(self, ev):
self.emit(SIGNAL('mr(int)'), 1)
@ -56,18 +57,20 @@ class BookInfoDisplay(QFrame):
WEIGHTS[_('Tags')] = 4
def __init__(self, clear_message):
QFrame.__init__(self)
QWidget.__init__(self)
self.setCursor(Qt.PointingHandCursor)
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
self._layout = QHBoxLayout()
self.setLayout(self._layout)
self.clear_message = clear_message
self.layout = QHBoxLayout()
self.setLayout(self.layout)
self.cover_display = BookInfoDisplay.BookCoverDisplay()
self.layout.addWidget(self.cover_display)
self._layout.addWidget(self.cover_display)
self.book_data = BookInfoDisplay.BookDataDisplay()
self.connect(self.book_data, SIGNAL('mr(int)'), self.mouseReleaseEvent)
self.layout.addWidget(self.book_data)
self._layout.addWidget(self.book_data)
self.data = {}
self.setVisible(False)
self._layout.setAlignment(self.cover_display, Qt.AlignTop|Qt.AlignLeft)
def mouseReleaseEvent(self, ev):
self.emit(SIGNAL('show_book_info()'))
@ -85,7 +88,6 @@ class BookInfoDisplay(QFrame):
keys.sort(cmp=lambda x, y: cmp(self.WEIGHTS[x], self.WEIGHTS[y]))
for key in keys:
txt = data[key]
#txt = '<br />\n'.join(textwrap.wrap(txt, 120))
if isinstance(key, str):
key = key.decode(preferred_encoding, 'replace')
if isinstance(txt, str):
@ -94,6 +96,8 @@ class BookInfoDisplay(QFrame):
self.book_data.setText(u'<table>'+rows+u'</table>')
self.clear_message()
self.book_data.updateGeometry()
self.updateGeometry()
self.setVisible(True)
class MovieButton(QFrame):
@ -164,6 +168,7 @@ class TagViewButton(QToolButton):
class StatusBar(QStatusBar):
def __init__(self, jobs_dialog, systray=None):
QStatusBar.__init__(self)
self.systray = systray
@ -174,9 +179,15 @@ class StatusBar(QStatusBar):
self.addPermanentWidget(self.tag_view_button)
self.addPermanentWidget(self.movie_button)
self.book_info = BookInfoDisplay(self.clearMessage)
self.scroll_area = QScrollArea()
self.scroll_area.setWidget(self.book_info)
self.scroll_area.setMaximumHeight(120)
self.scroll_area.setWidgetResizable(True)
self.connect(self.book_info, SIGNAL('show_book_info()'), self.show_book_info)
self.addWidget(self.book_info)
self.addWidget(self.scroll_area, 100)
self.setMinimumHeight(120)
self.setMaximumHeight(120)
def reset_info(self):
self.book_info.show_data({})

View File

@ -512,10 +512,18 @@ class DocumentView(QWebView):
def wheelEvent(self, event):
if event.delta() < -14:
self.next_page()
elif event.delta() > 14:
self.previous_page()
if self.document.at_bottom:
if self.manager is not None:
self.manager.next_document()
event.accept()
return
elif event.delta() > 14:
if self.document.at_top:
if self.manager is not None:
self.manager.previous_document()
event.accept()
return
return QWebView.wheelEvent(self, event)
def keyPressEvent(self, event):
key = event.key()

View File

@ -136,10 +136,11 @@ class LocationModel(QAbstractListModel):
self.icons = [QVariant(QIcon(':/library')),
QVariant(QIcon(':/images/reader.svg')),
QVariant(QIcon(':/images/sd.svg'))]
self.text = [_('Library'),
self.text = [_('Library\n%d\nbooks'),
_('Reader\n%s\navailable'),
_('Card\n%s\navailable')]
self.free = [-1, -1]
self.count = 0
self.highlight_row = 0
self.tooltips = [
_('Click to see the list of books available on your computer'),
@ -155,7 +156,7 @@ class LocationModel(QAbstractListModel):
data = NONE
if role == Qt.DisplayRole:
text = self.text[row]%(human_readable(self.free[row-1])) if row > 0 \
else self.text[row]
else self.text[row]%self.count
data = QVariant(text)
elif role == Qt.DecorationRole:
data = self.icons[row]
@ -192,6 +193,10 @@ class LocationView(QListView):
QObject.connect(self.selectionModel(), SIGNAL('currentChanged(QModelIndex, QModelIndex)'), self.current_changed)
self.setCursor(Qt.PointingHandCursor)
def count_changed(self, new_count):
self.model().count = new_count
self.model().reset()
def current_changed(self, current, previous):
i = current.row()
location = 'library' if i == 0 else 'main' if i == 1 else 'card'

View File

@ -255,6 +255,9 @@ class ResultCache(SearchQueryParser):
if id in self._map: self._map.remove(id)
if id in self._map_filtered: self._map_filtered.remove(id)
def count(self):
return len(self._map)
def refresh(self, db, field=None, ascending=True):
temp = db.conn.get('SELECT * FROM meta')
self._data = list(itertools.repeat(None, temp[-1][0]+2)) if temp else []
@ -375,6 +378,7 @@ class LibraryDatabase2(LibraryDatabase):
self.refresh_ids = functools.partial(self.data.refresh_ids, self.conn)
self.row = self.data.row
self.has_id = self.data.has_id
self.count = self.data.count
self.refresh()
@ -1191,9 +1195,6 @@ class LibraryDatabase2(LibraryDatabase):
for i in iter(self):
yield i['id']
def count(self):
return len(self.data._map)
def get_data_as_dict(self, prefix=None, authors_as_string=False):
'''
Return all metadata stored in the database as a dict. Includes paths to

View File

@ -465,6 +465,17 @@ def post_install():
if os.stat(f).st_uid == 0:
os.unlink(f)
def binary_install():
manifest = os.path.join(sys.frozen_path, 'manifest')
exes = [x.strip() for x in open(manifest).readlines()]
print 'Creating symlinks...'
for exe in exes:
dest = os.path.join('/usr', 'bin', exe)
if os.path.exists(dest):
os.remove(dest)
os.symlink(os.path.join(sys.frozen_path, exe), dest)
post_install()
return 0
VIEWER = '''\
[Desktop Entry]
@ -580,7 +591,7 @@ def setup_desktop_integration(fatal_errors):
print >>sys.stderr, 'Could not setup desktop integration. Error:'
print err
main = post_install
if __name__ == '__main__':
post_install()

View File

@ -1,327 +0,0 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
'''
Download and install the linux binary.
'''
import sys, os, shutil, tarfile, subprocess, tempfile, urllib2, re, stat
MOBILEREAD='https://dev.mobileread.com/dist/kovid/calibre/'
class TerminalController:
"""
A class that can be used to portably generate formatted output to
a terminal.
`TerminalController` defines a set of instance variables whose
values are initialized to the control sequence necessary to
perform a given action. These can be simply included in normal
output to the terminal:
>>> term = TerminalController()
>>> print 'This is '+term.GREEN+'green'+term.NORMAL
Alternatively, the `render()` method can used, which replaces
'${action}' with the string required to perform 'action':
>>> term = TerminalController()
>>> print term.render('This is ${GREEN}green${NORMAL}')
If the terminal doesn't support a given action, then the value of
the corresponding instance variable will be set to ''. As a
result, the above code will still work on terminals that do not
support color, except that their output will not be colored.
Also, this means that you can test whether the terminal supports a
given action by simply testing the truth value of the
corresponding instance variable:
>>> term = TerminalController()
>>> if term.CLEAR_SCREEN:
... print 'This terminal supports clearning the screen.'
Finally, if the width and height of the terminal are known, then
they will be stored in the `COLS` and `LINES` attributes.
"""
# Cursor movement:
BOL = '' #: Move the cursor to the beginning of the line
UP = '' #: Move the cursor up one line
DOWN = '' #: Move the cursor down one line
LEFT = '' #: Move the cursor left one char
RIGHT = '' #: Move the cursor right one char
# Deletion:
CLEAR_SCREEN = '' #: Clear the screen and move to home position
CLEAR_EOL = '' #: Clear to the end of the line.
CLEAR_BOL = '' #: Clear to the beginning of the line.
CLEAR_EOS = '' #: Clear to the end of the screen
# Output modes:
BOLD = '' #: Turn on bold mode
BLINK = '' #: Turn on blink mode
DIM = '' #: Turn on half-bright mode
REVERSE = '' #: Turn on reverse-video mode
NORMAL = '' #: Turn off all modes
# Cursor display:
HIDE_CURSOR = '' #: Make the cursor invisible
SHOW_CURSOR = '' #: Make the cursor visible
# Terminal size:
COLS = None #: Width of the terminal (None for unknown)
LINES = None #: Height of the terminal (None for unknown)
# Foreground colors:
BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
# Background colors:
BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = ''
BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = ''
_STRING_CAPABILITIES = """
BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold
BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0
HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split()
_COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
_ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
def __init__(self, term_stream=sys.stdout):
"""
Create a `TerminalController` and initialize its attributes
with appropriate values for the current terminal.
`term_stream` is the stream that will be used for terminal
output; if this stream is not a tty, then the terminal is
assumed to be a dumb terminal (i.e., have no capabilities).
"""
# Curses isn't available on all platforms
try: import curses
except: return
# If the stream isn't a tty, then assume it has no capabilities.
if not hasattr(term_stream, 'isatty') or not term_stream.isatty(): return
# Check the terminal type. If we fail, then assume that the
# terminal has no capabilities.
try: curses.setupterm()
except: return
# Look up numeric capabilities.
self.COLS = curses.tigetnum('cols')
self.LINES = curses.tigetnum('lines')
# Look up string capabilities.
for capability in self._STRING_CAPABILITIES:
(attrib, cap_name) = capability.split('=')
setattr(self, attrib, self._tigetstr(cap_name) or '')
# Colors
set_fg = self._tigetstr('setf')
if set_fg:
for i,color in zip(range(len(self._COLORS)), self._COLORS):
setattr(self, color, curses.tparm(set_fg, i) or '')
set_fg_ansi = self._tigetstr('setaf')
if set_fg_ansi:
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
set_bg = self._tigetstr('setb')
if set_bg:
for i,color in zip(range(len(self._COLORS)), self._COLORS):
setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '')
set_bg_ansi = self._tigetstr('setab')
if set_bg_ansi:
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
def _tigetstr(self, cap_name):
# String capabilities can include "delays" of the form "$<2>".
# For any modern terminal, we should be able to just ignore
# these, so strip them out.
import curses
cap = curses.tigetstr(cap_name) or ''
return re.sub(r'\$<\d+>[/*]?', '', cap)
def render(self, template):
"""
Replace each $-substitutions in the given template string with
the corresponding terminal control string (if it's defined) or
'' (if it's not).
"""
return re.sub(r'\$\$|\${\w+}', self._render_sub, template)
def _render_sub(self, match):
s = match.group()
if s == '$$': return s
else: return getattr(self, s[2:-1])
#######################################################################
# Example use case: progress bar
#######################################################################
class ProgressBar:
"""
A 3-line progress bar, which looks like::
Header
20% [===========----------------------------------]
progress message
The progress bar is colored, if the terminal supports color
output; and adjusts to the width of the terminal.
"""
BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n'
HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n'
def __init__(self, term, header):
self.term = term
if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
raise ValueError("Terminal isn't capable enough -- you "
"should use a simpler progress dispaly.")
self.width = self.term.COLS or 75
self.bar = term.render(self.BAR)
self.header = self.term.render(self.HEADER % header.center(self.width))
self.cleared = 1 #: true if we haven't drawn the bar yet.
def update(self, percent, message=''):
if isinstance(message, unicode):
message = message.encode('utf-8', 'ignore')
if self.cleared:
sys.stdout.write(self.header)
self.cleared = 0
n = int((self.width-10)*percent)
msg = message.center(self.width)
sys.stdout.write(
self.term.BOL + self.term.UP + self.term.CLEAR_EOL +
(self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) +
self.term.CLEAR_EOL + msg)
sys.stdout.flush()
def clear(self):
if not self.cleared:
sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL +
self.term.UP + self.term.CLEAR_EOL +
self.term.UP + self.term.CLEAR_EOL)
self.cleared = 1
LAUNCHER='''\
#!/bin/bash
frozen_path=%s
export ORIGWD=`pwd`
export LD_LIBRARY_PATH=$frozen_path:$LD_LIBRARY_PATH
cd $frozen_path
./%s "$@"
'''
def extract_tarball(tar, destdir):
print 'Extracting application files...'
if hasattr(tar, 'read'):
try:
tarfile.open(fileobj=tar, mode='r').extractall(destdir)
except: # tarfile.py on Fedora 9 is buggy
subprocess.check_call(['tar', 'xjf', tar.name, '-C', destdir])
else:
tarfile.open(tar, 'r').extractall(destdir)
def create_launchers(destdir, bindir='/usr/bin'):
manifest = []
for launcher in open(os.path.join(destdir, 'manifest')).readlines():
if 'postinstall' in launcher:
continue
launcher = launcher.strip()
lp = os.path.join(bindir, launcher)
print 'Creating', lp
open(lp, 'wb').write(LAUNCHER%(destdir, launcher))
os.chmod(lp, stat.S_IXUSR|stat.S_IXOTH|stat.S_IXGRP|stat.S_IREAD|stat.S_IWRITE|stat.S_IRGRP|stat.S_IROTH)
manifest.append(lp)
return manifest
def do_postinstall(destdir):
cwd = os.getcwd()
t = tempfile.NamedTemporaryFile()
try:
os.chdir(destdir)
os.environ['LD_LIBRARY_PATH'] = destdir+':'+os.environ.get('LD_LIBRARY_PATH', '')
os.environ['PYTHONPATH'] = destdir
os.environ['PYTHONSTARTUP'] = ''
subprocess.call((os.path.join(destdir, 'calibre_postinstall'), '--save-manifest-to', t.name))
finally:
os.chdir(cwd)
t.seek(0)
return list(t.readlines())
def download_tarball():
try:
pb = ProgressBar(TerminalController(sys.stdout), 'Downloading calibre...')
except ValueError:
print 'Downloading calibre...'
pb = None
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))
percent = f.tell()/float(size)
if pb is not None:
pb.update(percent)
else:
print '%d%%, '%int(percent*100),
f.seek(0)
return f
def main(args=sys.argv):
defdir = '/opt/calibre'
destdir = raw_input('Enter the installation directory for calibre (Its contents will be deleted!)[%s]: '%defdir).strip()
if not destdir:
destdir = defdir
if os.path.exists(destdir):
shutil.rmtree(destdir)
os.makedirs(destdir)
f = download_tarball()
print 'Extracting...'
extract_tarball(f, destdir)
manifest = create_launchers(destdir)
manifest += do_postinstall(destdir)
manifest += ['/usr/bin/calibre-uninstall']
UNINSTALLER = '''\
#!/usr/bin/env python
import os, sys
if os.geteuid() != 0:
print 'You must run this uninstaller as root'
sys.exit(0)
manifest = %s
failures = []
for path in manifest:
print 'Deleting', path
try:
os.unlink(path)
except:
failures.append(path)
print 'Uninstalling complete.'
if failures:
print 'Failed to remove the following files:'
for f in failures: print f
'''%repr(manifest)
open('/usr/bin/calibre-uninstall', 'wb').write(UNINSTALLER)
os.chmod('/usr/bin/calibre-uninstall',
stat.S_IXUSR|stat.S_IXOTH|stat.S_IXGRP|stat.S_IREAD|stat.S_IWRITE|stat.S_IRGRP|stat.S_IROTH)
print 'You can uninstall calibre by running sudo calibre-uninstall'
return 0
if __name__ == '__main__':
sys.exit(main())

View File

@ -85,6 +85,8 @@ if not _run_once:
to byte strings using `encoding`, calls abspath and then decodes back to unicode.
'''
to_unicode = False
if encoding is None:
encoding = preferred_encoding
if isinstance(path, unicode):
path = path.encode(encoding)
to_unicode = True
@ -97,6 +99,8 @@ if not _run_once:
_join = os.path.join
def my_join(a, *p):
encoding=sys.getfilesystemencoding()
if not encoding:
encoding = preferred_encoding
p = [a] + list(p)
_unicode = False
for i in p:

View File

@ -11,7 +11,6 @@ from trac.util import Markup
__appname__ = 'calibre'
DOWNLOAD_DIR = '/var/www/calibre.kovidgoyal.net/htdocs/downloads'
LINUX_INSTALLER = '/var/www/calibre.kovidgoyal.net/calibre/src/calibre/linux_installer.py'
MOBILEREAD = 'https://dev.mobileread.com/dist/kovid/calibre/'
class OS(dict):
@ -114,7 +113,7 @@ class Download(Component):
if req.path_info == '/download':
return self.top_level(req)
elif req.path_info == '/download_linux_binary_installer':
req.send(open(LINUX_INSTALLER).read().replace('%version', self.version_from_filename()), 'text/x-python')
req.send(LINUX_INSTALLER.replace('%version', self.version_from_filename()), 'text/x-python')
else:
match = re.match(r'\/download_(\S+)', req.path_info)
if match:
@ -240,3 +239,196 @@ If not, head over to <a href="http://calibre.kovidgoyal.net/wiki/Development#Tra
operating_systems=operating_systems, font_size='x-large', top_level=False)
return 'download.html', data, None
LINUX_INSTALLER = '''
import sys, os, shutil, tarfile, subprocess, tempfile, urllib2, re, stat
MOBILEREAD='https://dev.mobileread.com/dist/kovid/calibre/'
class TerminalController:
BOL = '' #: Move the cursor to the beginning of the line
UP = '' #: Move the cursor up one line
DOWN = '' #: Move the cursor down one line
LEFT = '' #: Move the cursor left one char
RIGHT = '' #: Move the cursor right one char
# Deletion:
CLEAR_SCREEN = '' #: Clear the screen and move to home position
CLEAR_EOL = '' #: Clear to the end of the line.
CLEAR_BOL = '' #: Clear to the beginning of the line.
CLEAR_EOS = '' #: Clear to the end of the screen
# Output modes:
BOLD = '' #: Turn on bold mode
BLINK = '' #: Turn on blink mode
DIM = '' #: Turn on half-bright mode
REVERSE = '' #: Turn on reverse-video mode
NORMAL = '' #: Turn off all modes
# Cursor display:
HIDE_CURSOR = '' #: Make the cursor invisible
SHOW_CURSOR = '' #: Make the cursor visible
# Terminal size:
COLS = None #: Width of the terminal (None for unknown)
LINES = None #: Height of the terminal (None for unknown)
# Foreground colors:
BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
# Background colors:
BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = ''
BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = ''
_STRING_CAPABILITIES = """
BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold
BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0
HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split()
_COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
_ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
def __init__(self, term_stream=sys.stdout):
# Curses isn't available on all platforms
try: import curses
except: return
# If the stream isn't a tty, then assume it has no capabilities.
if not hasattr(term_stream, 'isatty') or not term_stream.isatty(): return
# Check the terminal type. If we fail, then assume that the
# terminal has no capabilities.
try: curses.setupterm()
except: return
# Look up numeric capabilities.
self.COLS = curses.tigetnum('cols')
self.LINES = curses.tigetnum('lines')
# Look up string capabilities.
for capability in self._STRING_CAPABILITIES:
(attrib, cap_name) = capability.split('=')
setattr(self, attrib, self._tigetstr(cap_name) or '')
# Colors
set_fg = self._tigetstr('setf')
if set_fg:
for i,color in zip(range(len(self._COLORS)), self._COLORS):
setattr(self, color, curses.tparm(set_fg, i) or '')
set_fg_ansi = self._tigetstr('setaf')
if set_fg_ansi:
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
set_bg = self._tigetstr('setb')
if set_bg:
for i,color in zip(range(len(self._COLORS)), self._COLORS):
setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '')
set_bg_ansi = self._tigetstr('setab')
if set_bg_ansi:
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
def _tigetstr(self, cap_name):
# String capabilities can include "delays" of the form "$<2>".
# For any modern terminal, we should be able to just ignore
# these, so strip them out.
import curses
cap = curses.tigetstr(cap_name) or ''
return re.sub(r'\$<\d+>[/*]?', '', cap)
def render(self, template):
return re.sub(r'\$\$|\${\w+}', self._render_sub, template)
def _render_sub(self, match):
s = match.group()
if s == '$$': return s
else: return getattr(self, s[2:-1])
class ProgressBar:
BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n'
HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n'
def __init__(self, term, header):
self.term = term
if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
raise ValueError("Terminal isn't capable enough -- you "
"should use a simpler progress dispaly.")
self.width = self.term.COLS or 75
self.bar = term.render(self.BAR)
self.header = self.term.render(self.HEADER % header.center(self.width))
self.cleared = 1 #: true if we haven't drawn the bar yet.
def update(self, percent, message=''):
if isinstance(message, unicode):
message = message.encode('utf-8', 'ignore')
if self.cleared:
sys.stdout.write(self.header)
self.cleared = 0
n = int((self.width-10)*percent)
msg = message.center(self.width)
sys.stdout.write(
self.term.BOL + self.term.UP + self.term.CLEAR_EOL +
(self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) +
self.term.CLEAR_EOL + msg)
sys.stdout.flush()
def clear(self):
if not self.cleared:
sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL +
self.term.UP + self.term.CLEAR_EOL +
self.term.UP + self.term.CLEAR_EOL)
self.cleared = 1
def download_tarball():
try:
pb = ProgressBar(TerminalController(sys.stdout), 'Downloading calibre...')
except ValueError:
print 'Downloading calibre...'
pb = None
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))
percent = f.tell()/float(size)
if pb is not None:
pb.update(percent)
else:
print '%d%%, '%int(percent*100),
f.seek(0)
return f
def extract_tarball(tar, destdir):
print 'Extracting application files...'
if hasattr(tar, 'read'):
try:
tarfile.open(fileobj=tar, mode='r').extractall(destdir)
except: # tarfile.py on Fedora 9 is buggy
subprocess.check_call(['tar', 'xjf', tar.name, '-C', destdir])
else:
tarfile.open(tar, 'r').extractall(destdir)
def main():
defdir = '/opt/calibre'
destdir = raw_input('Enter the installation directory for calibre (Its contents will be deleted!)[%s]: '%defdir).strip()
if not destdir:
destdir = defdir
destdir = os.path.abspath(destdir)
if os.path.exists(destdir):
shutil.rmtree(destdir)
os.makedirs(destdir)
f = download_tarball()
print 'Extracting files to %s ...'%destdir
extract_tarball(f, destdir)
pi = os.path.join(destdir, calibre_postinstall)
subprocess.call('pi', shell=True)
return 0
'''

View File

@ -6,14 +6,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre 0.4.51\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-05-24 06:23+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: bg\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:41+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n"
@ -1546,49 +1546,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1612,7 +1612,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -1993,22 +1993,22 @@ msgid "Book Cover"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2503,8 +2503,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2700,7 +2700,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -2904,25 +2904,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -2934,7 +2934,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3088,11 +3088,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4134,39 +4134,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4521,13 +4523,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""

View File

@ -10,14 +10,14 @@ msgid ""
msgstr ""
"Project-Id-Version: ca\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-05-24 06:21+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:41+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1592,49 +1592,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Ubicació de la base de dades no vàlida"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr "<br>Cal que siga un directori."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Ubicació de la base de dades no vàlida "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Ubicació de la base de dades no vàlida.<br>No es pot escriure "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1658,7 +1658,7 @@ msgstr "Cerca la nova ubicació de la base de dades"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2039,22 +2039,22 @@ msgid "Book Cover"
msgstr "Coberta"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr "Canvia la imatge de la &coberta:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr "Cerca una imatge per a utilitzar com a coberta d'aquest llibre."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2563,8 +2563,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2763,7 +2763,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -2967,25 +2967,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -2997,7 +2997,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3151,11 +3151,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4203,43 +4203,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr "Biblioteca"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
"El Sony Reader\n"
"%s està disponible"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
"La targeta\n"
"%s està disponible"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4594,13 +4592,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""
@ -4912,6 +4910,20 @@ msgstr ""
#~ msgid "<b>Changes will only take affect after a restart."
#~ msgstr "<b>Els canvis s'ignoren fins que el re-inicieu."
#~ msgid ""
#~ "Reader\n"
#~ "%s available"
#~ msgstr ""
#~ "El Sony Reader\n"
#~ "%s està disponible"
#~ msgid ""
#~ "Card\n"
#~ "%s available"
#~ msgstr ""
#~ "La targeta\n"
#~ "%s està disponible"
#~ msgid "%s is not available in LRF format. Please convert it first."
#~ msgstr "%s no està disponible en LRF. Ha de ser convertir primer."

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-10-23 12:18+0000\n"
"Last-Translator: raduz <raduzator@gmail.com>\n"
"Language-Team: Czech <cs@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:49+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1627,49 +1627,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1693,7 +1693,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2074,22 +2074,22 @@ msgid "Book Cover"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2584,8 +2584,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2781,7 +2781,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -2985,25 +2985,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -3015,7 +3015,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3169,11 +3169,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4215,39 +4215,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4602,13 +4604,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: de\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"PO-Revision-Date: 2008-12-06 14:13+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-12-09 09:15+0000\n"
"Last-Translator: S. Dorscht <Unknown>\n"
"Language-Team: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n"
@ -1868,50 +1868,50 @@ msgstr ""
"Content\n"
"Server"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr "Fehler Log:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr "Zugriffs-Protokolldatei:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr "Content Server konnte nicht gestartet werden"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr "Ungültige Größe"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
"Die Größe %s ist ungültig. Sie muss der Form BreitexHöhe entsprechen."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Ortsangabe der Datenbank ungültig"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr "<br>Muss ein Verzeichnis sein."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Ortsangabe der Datenbank ungültig "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Ortsangabe der Datenbank ungültig.<br>Speichern nicht möglich "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr "Komprimiere Datenbank. Das kann etwas dauern..."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr "Komprimiere Datenbank..."
@ -1938,7 +1938,7 @@ msgstr "Zu einem neuen Ort der Datenbank wechseln"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2349,22 +2349,22 @@ msgid "Book Cover"
msgstr "Umschlagbild"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Um&schlagbild der Quelldatei verwenden"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr "&Umschlagbild ändern:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr "Nach Umschlagbild durchsuchen..."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Um&schlagbild der Quelldatei verwenden"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2904,8 +2904,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
@ -2915,8 +2915,8 @@ msgstr ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
msgid "Edit Meta information"
@ -3121,7 +3121,7 @@ msgid "News"
msgstr "Nachrichten"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr "Rezepte"
@ -3342,25 +3342,25 @@ msgstr "Dieser Feed wurde schon zu diesem Rezept hinzugefügt"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr "Ungültige Eingabe"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr "<p>Konnte Rezept nicht erstellen. Fehler:<br>%s"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr "Rezept ersetzen?"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
"Es gibt schon ein erstelltes Rezept mit dem Namen %s. Soll es ersetzt werden?"
@ -3373,7 +3373,7 @@ msgstr "Rezept wählen"
msgid "Pick the recipe to customize"
msgstr "Rezept zum Anpassen auswählen"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr "Eine Rezept Datei auswählen"
@ -3563,11 +3563,11 @@ msgstr "Regulärer Ausdruck (?P&lt;title&gt;)"
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr "Kein Treffer"
@ -4680,44 +4680,48 @@ msgstr "Verweismodus"
msgid "Bookmark"
msgstr "Lesezeichen"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr "Ungültiger regulärer Ausdruck"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr "Ungültiger regulärer Ausdruck: %s"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr "Bibliothek"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Reader\n"
"%s verfügbar"
"%s\n"
"verfügbar"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Karte\n"
"%s verfügbar"
"%s\n"
"verfügbar"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr "Ein Klick zeigt die Liste der auf dem Computer vorhandenen Bücher"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
"Ein Klick zeigt die Liste der im Hauptspeicher des Geräts vorhandenen Bücher"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
"Ein Klick zeigt die Liste der auf der Speicherkarte des Geräts vorhandenen "
@ -5170,13 +5174,13 @@ msgstr "Konnte SSH Sitzung nicht abschließen: "
msgid "Failed to authenticate with server: %s"
msgstr "Authentifizierung schlug fehl am Server: %s"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr "Feed unbekannt"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr "Artikel ohne Titel"
@ -5634,6 +5638,20 @@ msgstr "Zeige detailierte Ausgabeinformation. Hilfreich zur Fehlersuche."
#~ msgid "Custom news sources"
#~ msgstr "Individuelle Nachrichtenquellen"
#~ msgid ""
#~ "Reader\n"
#~ "%s available"
#~ msgstr ""
#~ "Reader\n"
#~ "%s verfügbar"
#~ msgid ""
#~ "Card\n"
#~ "%s available"
#~ msgstr ""
#~ "Karte\n"
#~ "%s verfügbar"
#~ msgid "Job killed by user"
#~ msgstr "Auftrag durch Benutzer abgebrochen"
@ -5650,6 +5668,29 @@ msgstr "Zeige detailierte Ausgabeinformation. Hilfreich zur Fehlersuche."
#~ msgid " does not allow copying of text."
#~ msgstr " lässt das Kopieren von Text nicht zu."
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgstr ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgid ""
#~ "Path to the calibre database. Default is to use the path stored in the "
#~ "settings."

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-06-24 07:23+0000\n"
"Last-Translator: Thanos Petkakis <thanospet@gmail.com>\n"
"Language-Team: Greek <el@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:41+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1546,49 +1546,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1612,7 +1612,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -1993,22 +1993,22 @@ msgid "Book Cover"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2503,8 +2503,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2700,7 +2700,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -2904,25 +2904,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -2934,7 +2934,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3088,11 +3088,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4134,39 +4134,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4521,13 +4523,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""

View File

@ -10,14 +10,14 @@ msgid ""
msgstr ""
"Project-Id-Version: es\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-11-15 16:21+0000\n"
"Last-Translator: Pablo Carmona A. <Unknown>\n"
"Language-Team: Spanish\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:41+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1730,49 +1730,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Ubicación no válida"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr "<br>Debe ser un directorio."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Ubicación no válida "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Ubicación no válida.<br>Imposible escribir en "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr "Compactando base de datos. Esto podría durar un rato"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr "Compactando..."
@ -1798,7 +1798,7 @@ msgstr "Navegar a la nueva ubicación de la base de datos"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2181,22 +2181,22 @@ msgid "Book Cover"
msgstr "Portada"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Usar portada del archivo &fuente"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr "Cambia la imagen de &portada:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr "Localizar una imagen a utilizar como portada de este libro."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Usar portada del archivo &fuente"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2708,19 +2708,9 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
"type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
msgid "Edit Meta information"
@ -2923,7 +2913,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr "Recetas"
@ -3136,25 +3126,25 @@ msgstr "Este Feed ya se ha añadido a la receta"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr "Entrada incorrecta"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr "<p>No se puede crear la receta. Error:<br>%s"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr "Reemplazar la receta?"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr "una receta personalizada llamada %s ya existe. Quiere reemplazarla?"
@ -3166,7 +3156,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr "Seleccionar un archivo de receta"
@ -3333,11 +3323,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr "Ninguna coincidencia"
@ -4428,43 +4418,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr "Expresión regular no válida"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr "Expresión regular no valida: %s"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr "Biblioteca"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Sony Reader\n"
"%s disponible"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Tarjeta\n"
"%s disponible"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr "Haga click para ver la lista de libros disponibles en su ordenador"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr "Haga click para ver la lista de libros disponibles en su lector"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
"Haga click para ver la lista de libros en la tarjeta de almacenamiento de su "
@ -4855,13 +4843,13 @@ msgstr "No se ha podido negociar período de sesiones SSH: "
msgid "Failed to authenticate with server: %s"
msgstr "No se ha podido autenticar con el servidor: %s"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr "Newsfeed desconocido"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr "Artículo sin título"
@ -5327,6 +5315,20 @@ msgstr "Mostrar información de salida detallada. Útil para depuración"
#~ msgid "Custom news sources"
#~ msgstr "Nueva fuente de noticias personalizada"
#~ msgid ""
#~ "Reader\n"
#~ "%s available"
#~ msgstr ""
#~ "Sony Reader\n"
#~ "%s disponible"
#~ msgid ""
#~ "Card\n"
#~ "%s available"
#~ msgstr ""
#~ "Tarjeta\n"
#~ "%s disponible"
#~ msgid "Job killed by user"
#~ msgstr "Trabajo detenido por el usuario"
@ -5410,6 +5412,29 @@ msgstr "Mostrar información de salida detallada. Útil para depuración"
#~ msgid " does not allow copying of text."
#~ msgstr " no permite copiar texto."
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgstr ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgid ""
#~ "Path to the calibre database. Default is to use the path stored in the "
#~ "settings."

View File

@ -6,14 +6,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre 0.4.22\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-08-28 13:18+0000\n"
"Last-Translator: Anthony Guéchoum <Unknown>\n"
"Language-Team: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:41+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n"
@ -1690,49 +1690,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Chemin de la database invalide"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr "<br>Doit être un répertoire."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Chemin de la database invalide "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Chemin de la database invalide.<br>Erreur en écriture "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1756,7 +1756,7 @@ msgstr "Choisir un nouvel emplacement pour la base de données"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2140,22 +2140,22 @@ msgid "Book Cover"
msgstr "Couverture du livre"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Utilise l'image de couverture du fichier &source"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr "Modifie l'image &cover :"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr "Rechercher une image à utiliser en tant que couverture du livre."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Utilise l'image de couverture du fichier &source"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2671,8 +2671,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2876,7 +2876,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -3083,25 +3083,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -3113,7 +3113,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3267,11 +3267,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4330,43 +4330,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr "Librairie"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
"Lecteur \n"
"%s disponible"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
"Carte\n"
"%s disponible"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4721,13 +4719,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""
@ -5061,6 +5059,20 @@ msgstr ""
#~ "<b>Les modifications ne seront prises en compte qu'après avoir relancé le "
#~ "programme."
#~ msgid ""
#~ "Reader\n"
#~ "%s available"
#~ msgstr ""
#~ "Lecteur \n"
#~ "%s disponible"
#~ msgid ""
#~ "Card\n"
#~ "%s available"
#~ msgstr ""
#~ "Carte\n"
#~ "%s disponible"
#~ msgid "%s is not available in LRF format. Please convert it first."
#~ msgstr "%s n'est pas disponible au format LRF. Veuillez le convertir avant."

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-09-30 12:33+0000\n"
"Last-Translator: Calidonia <Unknown>\n"
"Language-Team: Galician <gl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:41+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1551,49 +1551,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1617,7 +1617,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -1998,22 +1998,22 @@ msgid "Book Cover"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2508,8 +2508,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2705,7 +2705,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -2909,25 +2909,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -2939,7 +2939,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3093,11 +3093,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4139,39 +4139,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4526,13 +4528,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""

View File

@ -8,14 +8,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre_calibre-it\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"PO-Revision-Date: 2008-12-05 09:30+0000\n"
"Last-Translator: Iacopo Benesperi <Unknown>\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-12-08 21:59+0000\n"
"Last-Translator: S. Dorscht <Unknown>\n"
"Language-Team: italiano\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n"
@ -1845,49 +1845,49 @@ msgstr ""
"Server dei\n"
"contenuti"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr "File di log degli errori:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr "File di log degli accessi:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr "Avvio del server dei contenuti fallito"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Percorso database non valido"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr "<br>Deve essere una cartella"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Percorso database non valido "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Percorso database non valido.<br>Impossibile scrivere su "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr "Compattazione database. Poterbbe richiedere un po' di tempo"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr "Compattazione..."
@ -1913,7 +1913,7 @@ msgstr "Sfoglia per specificare una nuova posizione del database"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2320,23 +2320,23 @@ msgid "Book Cover"
msgstr "Copertina del libro"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Usa copertina del file di &origine"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr "Ca&mbia l'immagine di copertina:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
"Sfoglia per trovare un'immagine da usare come copertina per questo libro"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Usa copertina del file di &origine"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2871,8 +2871,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
@ -2882,8 +2882,8 @@ msgstr ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
msgid "Edit Meta information"
@ -3086,7 +3086,7 @@ msgid "News"
msgstr "Notizie"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr "Formule"
@ -3303,25 +3303,25 @@ msgstr "Questo feed è già stato aggiunto alla formula"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr "Input non valido"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr "<p>Impossibile creare la formula. Errore:<br>%s"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr "Sovrascrivere la formula?"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr "Esiste già una formula personalizzata di nome %s. Sovrascriverla?"
@ -3333,7 +3333,7 @@ msgstr "Prendi formula"
msgid "Pick the recipe to customize"
msgstr "Prende la formula per personalizzarla"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr "Scegliere un file di formula"
@ -3521,11 +3521,11 @@ msgstr "Espressione regolare (?P&lt;title&gt;)"
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr "Nessuna corrispondenza"
@ -4635,46 +4635,44 @@ msgstr "Modalità riferimento"
msgid "Bookmark"
msgstr "Segnalibro"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr "Espressione regolare non valida"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr "Espressione regolare non valida: %s"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr "Biblioteca"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Lettore\n"
"%s disponibili"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Scheda\n"
"%s disponibili"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
"Fare clic per vedere la lista di libri disponibili sul proprio computer"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
"Fare clic per vedere la lista di libri nella memoria principale del proprio "
"lettore"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
"Fare clic per vedere la lista di libri nella scheda di memoria del proprio "
@ -5119,13 +5117,13 @@ msgstr "Negoziazione della sessione SSH fallita: "
msgid "Failed to authenticate with server: %s"
msgstr "Autenticazione fallita col server: %s"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr "Feed sconosciuto"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr "Articolo senza titolo"
@ -5519,6 +5517,43 @@ msgstr "Mostra un output dettagliato. Utile per il debugging"
#~ msgid "Custom news sources"
#~ msgstr "Fonti di notizie personalizzate"
#~ msgid ""
#~ "Reader\n"
#~ "%s available"
#~ msgstr ""
#~ "Lettore\n"
#~ "%s disponibili"
#~ msgid ""
#~ "Card\n"
#~ "%s available"
#~ msgstr ""
#~ "Scheda\n"
#~ "%s disponibili"
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgstr ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgid ""
#~ "The fields to display when listing books in the database. Should be a comma "
#~ "separated list of fields.\n"

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-12-05 23:40+0000\n"
"Last-Translator: Helene Klungvik <Unknown>\n"
"Language-Team: Norwegian Bokmal <nb@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1709,49 +1709,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1775,7 +1775,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2156,22 +2156,22 @@ msgid "Book Cover"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2666,8 +2666,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2863,7 +2863,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -3067,25 +3067,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -3097,7 +3097,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3251,11 +3251,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4297,39 +4297,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4684,13 +4686,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: de\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"PO-Revision-Date: 2008-12-06 14:15+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-12-09 09:16+0000\n"
"Last-Translator: S. Dorscht <Unknown>\n"
"Language-Team: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n"
@ -1868,50 +1868,50 @@ msgstr ""
"Content\n"
"Server"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr "Fehler-Protokolldatei:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr "Zugriffs-Protokolldatei:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr "Content Server konnte nicht gestartet werden"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr "Ungültige Größe"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
"Die Größe %s ist ungültig. Sie muss der Form BreitexHöhe entsprechen."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Ortsangabe der Datenbank ungültig"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr "<br>Muss ein Verzeichnis sein."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Ortsangabe der Datenbank ungültig "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Ortsangabe der Datenbank ungültig.<br>Speichern nicht möglich "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr "Komprimiere Datenbank. Das kann etwas dauern..."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr "Komprimiere Datenbank..."
@ -1938,7 +1938,7 @@ msgstr "Zu einem neuen Ort der Datenbank wechseln"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2349,22 +2349,22 @@ msgid "Book Cover"
msgstr "Umschlagbild"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Um&schlagbild der Quelldatei verwenden"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr "&Umschlagbild ändern:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr "Nach Umschlagbild durchsuchen..."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Um&schlagbild der Quelldatei verwenden"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2904,8 +2904,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
@ -2915,8 +2915,8 @@ msgstr ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
msgid "Edit Meta information"
@ -3121,7 +3121,7 @@ msgid "News"
msgstr "Nachrichten"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr "Rezepte"
@ -3342,25 +3342,25 @@ msgstr "Dieser Feed wurde schon zu diesem Rezept hinzugefügt"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr "Ungültige Eingabe"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr "<p>Konnte Rezept nicht erstellen. Fehler:<br>%s"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr "Rezept ersetzen?"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
"Es gibt schon ein erstelltes Rezept mit dem Namen %s. Soll es ersetzt werden?"
@ -3373,7 +3373,7 @@ msgstr "Rezept wählen"
msgid "Pick the recipe to customize"
msgstr "Rezept zum Anpassen auswählen"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr "Eine Rezept Datei auswählen"
@ -3563,11 +3563,11 @@ msgstr "Regulärer Ausdruck (?P&lt;title&gt;)"
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr "Kein Treffer"
@ -4680,44 +4680,48 @@ msgstr "Verweismodus"
msgid "Bookmark"
msgstr "Lesezeichen"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr "Ungültiger regulärer Ausdruck"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr "Ungültiger regulärer Ausdruck: %s"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr "Bibliothek"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Reader\n"
"%s verfügbar"
"%s\n"
"verfügbar"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Karte\n"
"%s verfügbar"
"%s\n"
"verfügbar"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr "Ein Klick zeigt die Liste der auf dem Computer vorhandenen Bücher"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
"Ein Klick zeigt die Liste der im Hauptspeicher des Geräts vorhandenen Bücher"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
"Ein Klick zeigt die Liste der auf der Speicherkarte des Geräts vorhandenen "
@ -5170,13 +5174,13 @@ msgstr "Konnte SSH Sitzung nicht abschließen: "
msgid "Failed to authenticate with server: %s"
msgstr "Authentifizierung schlug fehl am Server: %s"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr "Feed unbekannt"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr "Artikel ohne Titel"
@ -5634,6 +5638,20 @@ msgstr "Zeige detailierte Ausgabeinformation. Hilfreich zur Fehlersuche."
#~ msgid "Custom news sources"
#~ msgstr "Individuelle Nachrichtenquellen"
#~ msgid ""
#~ "Reader\n"
#~ "%s available"
#~ msgstr ""
#~ "Reader\n"
#~ "%s verfügbar"
#~ msgid ""
#~ "Card\n"
#~ "%s available"
#~ msgstr ""
#~ "Karte\n"
#~ "%s verfügbar"
#~ msgid "Job killed by user"
#~ msgstr "Auftrag durch Benutzer abgebrochen"
@ -5650,6 +5668,29 @@ msgstr "Zeige detailierte Ausgabeinformation. Hilfreich zur Fehlersuche."
#~ msgid " does not allow copying of text."
#~ msgstr " lässt das Kopieren von Text nicht zu."
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgstr ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgid ""
#~ "Path to the calibre database. Default is to use the path stored in the "
#~ "settings."

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-09-04 01:49+0000\n"
"Last-Translator: Marc van den Dikkenberg <Unknown>\n"
"Language-Team: Dutch <nl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:49+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1732,49 +1732,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Foutieve database locatie"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr "<br>Moet een folder zijn."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Foutieve database locatie "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Foutieve database locatie.<br>Kan niet schrijven naar "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr "Database aan het comprimeren. Dit kan even duren."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr "Comprimeren..."
@ -1800,7 +1800,7 @@ msgstr "Blader naar de nieuwe database locatie"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2184,22 +2184,22 @@ msgid "Book Cover"
msgstr "Boek Omslag"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Gebruik omslag van &bron bestand"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr "Verander &Omslag Afbeelding"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr "Zoek een afbeelding om als omslag voor dit boek te gebruiken."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Gebruik omslag van &bron bestand"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2718,19 +2718,9 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
"type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
msgid "Edit Meta information"
@ -2933,7 +2923,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr "Recepten"
@ -3146,25 +3136,25 @@ msgstr "Deze feed is al aan een recept toegevoegd"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr "Ongeldige invoer"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr "<p>Een recept kon niet worden aangemaakt. Foutmelding:<br>%s"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr "Recept vervangen?"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr "Een persoonlijk recept genaat %s bestaat al. Wilt u deze vervangen?"
@ -3176,7 +3166,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr "Kies een recept"
@ -3344,11 +3334,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr "Geen overeenkomst"
@ -4441,44 +4431,42 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr "Ongeldige reguliere expressie"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr "Ongeldige reguliere expressie: %s"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr "Bibliotheek"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Lezer\n"
"%s beschikbaar"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Kaart\n"
"%s beschikbaar"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr "Klik om een de lijst met boeken op uw computer te zien"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
"Klik om de lijst met boeken in het hoofdgeheugen van uw lezer te zien"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr "Klik om de lijst met boeken op de opslag kaart van uw lezer te zien"
@ -4902,13 +4890,13 @@ msgstr "SSH sessie kon niet tot stand worden gebracht: "
msgid "Failed to authenticate with server: %s"
msgstr "Authenticatie met server mislukt: %s"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr "Onbekende feed"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr "Artikel zonder naam"
@ -5358,6 +5346,20 @@ msgstr ""
#~ msgid "Custom news sources"
#~ msgstr "Persoonlijke nieuws bronnen"
#~ msgid ""
#~ "Reader\n"
#~ "%s available"
#~ msgstr ""
#~ "Lezer\n"
#~ "%s beschikbaar"
#~ msgid ""
#~ "Card\n"
#~ "%s available"
#~ msgstr ""
#~ "Kaart\n"
#~ "%s beschikbaar"
#~ msgid "Job killed by user"
#~ msgstr "Opdracht beëindigd door gebruiker"
@ -5374,6 +5376,29 @@ msgstr ""
#~ msgid " does not allow copying of text."
#~ msgstr " staat copieren van tekst niet toe."
#~ msgid ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgstr ""
#~ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
#~ "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
#~ "<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
#~ "type=\"text/css\">\n"
#~ "p, li { white-space: pre-wrap; }\n"
#~ "</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
#~ "font-weight:400; font-style:normal;\">\n"
#~ "<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
#~ "margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
#~ "family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#~ msgid ""
#~ "Path to the calibre database. Default is to use the path stored in the "
#~ "settings."

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"PO-Revision-Date: 2008-12-07 20:51+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-12-10 13:38+0000\n"
"Last-Translator: Bartosz Kaszubowski <gosimek@gmail.com>\n"
"Language-Team: Polish <pl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:49+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -402,7 +402,7 @@ msgstr "Temat(y) tej książki, jako lista rozdzielona przecinkami."
#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:847
msgid "Set the publisher of this book."
msgstr "Ustaw wydawcę tego e-booka."
msgstr "Ustaw wydawcę tej książki"
#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:849
msgid "A summary of this book."
@ -421,10 +421,12 @@ msgid ""
"Be more verbose while processing. Can be specified multiple times to "
"increase verbosity."
msgstr ""
"Wyświetlaj szczegółowe komunikaty w czasie pracy. Zaznaczenie w wielu "
"miejscach zwiększa liczbę szczegółów."
#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:857
msgid "Output HTML is \"pretty printed\" for easier parsing by humans"
msgstr ""
msgstr "Wyjściowy HTML jest \"ładnie drukowany\" dla łatwiejszej analizy"
#: /home/kovid/work/calibre/src/calibre/ebooks/html.py:863
msgid ""
@ -711,10 +713,12 @@ msgid ""
"You must add this option if processing files generated by pdftohtml, "
"otherwise conversion will fail."
msgstr ""
"Musisz dodać tą opcję jeśli generowałeś plik przez pdftohtml, w innym "
"przypadku konwersja nie powiedzie się."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:192
msgid "Use this option on html0 files from Book Designer."
msgstr ""
msgstr "Użyj tej opcji dla plików html0 z Book Designer."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:195
msgid ""
@ -726,19 +730,19 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:203
msgid "The serif family of fonts to embed"
msgstr ""
msgstr "Rodzina czcionek szeryfowych do umieszczenia"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:206
msgid "The sans-serif family of fonts to embed"
msgstr ""
msgstr "Rodzina czcionek sans-serif do umieszczenia"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:209
msgid "The monospace family of fonts to embed"
msgstr ""
msgstr "Rodzina czcionek monospace do umieszczenia"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:213
msgid "Be verbose while processing"
msgstr ""
msgstr "Wyświetlaj szczegółowe kominukaty w czasie pracy"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:215
msgid "Convert to LRS"
@ -873,6 +877,8 @@ msgid ""
"Be verbose, useful for debugging. Can be specified multiple times for "
"greater verbosity."
msgstr ""
"Wyświetlaj szczegółowe komunikaty przydatne przy debugowaniu. Zaznaczenie w "
"wielu miejscach zwiększa liczbę szczegółów."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:317
msgid "Don't show progress bar."
@ -932,7 +938,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:316
msgid "\tBook Designer file detected."
msgstr ""
msgstr "\twykryto plik Book Designer."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:318
msgid "\tParsing HTML..."
@ -1010,7 +1016,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1862
msgid "Could not read cover image: %s"
msgstr ""
msgstr "Nie można odczytać grafiki okładki: %s"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1865
msgid "Cannot read from: %s"
@ -1078,7 +1084,7 @@ msgstr "Ścieżka do pliku wyjściowego"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:272
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/isbndb.py:115
msgid "Verbose processing"
msgstr ""
msgstr "Szczegółowe komunikaty w czasie pracy"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrs/convert_from.py:274
msgid "Convert LRS to LRS, useful for debugging."
@ -1181,7 +1187,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:405
msgid "Be more verbose."
msgstr ""
msgstr "Wyświetlaj szczegółowe kominukaty."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/reflow.py:417
msgid "You must specify a single PDF file."
@ -1354,7 +1360,7 @@ msgstr " nie znaleziono"
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:51
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:82
msgid "LibraryThing.com server error. Try again later."
msgstr ""
msgstr "Błąd serwera LibraryThing.com. Spróbuj ponownie poźniej."
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/library_thing.py:60
msgid ""
@ -1475,7 +1481,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/__init__.py:59
msgid "Delete books from library after uploading to device"
msgstr ""
msgstr "Usuń książki z biblioteki po przesłaniu ich na urządzenie"
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:72
msgid "Device no longer connected."
@ -1491,7 +1497,7 @@ msgstr "Pozyskaj listę książek na urządzeniu"
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:137
msgid "Send metadata to device"
msgstr ""
msgstr "Prześlij metadane do urządzenia"
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:144
msgid "Upload %d books to device"
@ -1568,7 +1574,7 @@ msgstr "&Tytuł:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:90
msgid "&Author(s):"
msgstr ""
msgstr "&Autor(zy):"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf_ui.py:91
msgid "&Number of Colors:"
@ -1630,49 +1636,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr "Dziennik błędów:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr "Dziennik dostępów:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr "Niewłaściwy rozmiar"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Niewłaściwa lokalizacja bazy danych"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Niewłaściwa lokalizacja bazy danych "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Niewłaściwa lokalizacja bazy danych.<br>Nie można zapisać do "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1696,7 +1702,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -1734,7 +1740,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:371
msgid "Read &metadata from files"
msgstr ""
msgstr "Wczytytuj &metadane z plików"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:372
msgid "Format for &single file save:"
@ -1756,7 +1762,7 @@ msgstr " sekund"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:376
msgid "Choose &language (requires restart):"
msgstr ""
msgstr "Wybierz &język (wymaga restartu):"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:377
#: /home/kovid/work/calibre/src/calibre/utils/config.py:536
@ -1825,7 +1831,7 @@ msgstr "Małe"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:396
msgid "&Button size in toolbar"
msgstr ""
msgstr "&Rozmiar przycisków na pasku narzędzi"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:397
msgid "Show &text in toolbar buttons"
@ -1833,7 +1839,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:398
msgid "Select visible &columns in library view"
msgstr ""
msgstr "Wybierz &kolumny pokazywane w widoku biblioteki"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:401
msgid "Use internal &viewer for the following formats:"
@ -1861,7 +1867,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:407
msgid "&Metadata from file name"
msgstr ""
msgstr "&Metadane z nazwy pliku"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:408
msgid ""
@ -1956,7 +1962,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:143
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:155
msgid "Metadata"
msgstr ""
msgstr "Metadane"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:85
@ -2004,7 +2010,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:93
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:167
msgid "Choose cover for "
msgstr ""
msgstr "Wybierz okładkę dla "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub.py:100
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:174
@ -2074,30 +2080,30 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:506
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:315
msgid "Book Cover"
msgstr ""
msgstr "Okładka książki"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr ""
msgstr "Zmień grafikę &okładki:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
msgid "&Title: "
msgstr ""
msgstr "&Tytuł: "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:376
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:512
@ -2110,7 +2116,7 @@ msgstr ""
#: /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:283
msgid "&Author(s): "
msgstr ""
msgstr "&Autor(zy): "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:378
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:514
@ -2138,14 +2144,14 @@ msgstr ""
#: /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:293
msgid "&Publisher: "
msgstr ""
msgstr "&Wydawca: "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:382
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:518
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:133
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:294
msgid "Change the publisher of this book"
msgstr ""
msgstr "Zmień wydawcę tej ksiązki"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:383
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:519
@ -2321,11 +2327,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:139
msgid "Error fetching metadata"
msgstr ""
msgstr "Błąd podczas pobierania metadanych"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:144
msgid "No metadata found"
msgstr ""
msgstr "Nie znaleziono metadanych"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:144
msgid ""
@ -2334,11 +2340,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:77
msgid "Fetch metadata"
msgstr ""
msgstr "Pobierz metadane"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:78
msgid "Fetching metadata for <b>%1</b>"
msgstr ""
msgstr "Pobierz metadane dla <b>%1</b>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:79
msgid ""
@ -2352,7 +2358,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:81
msgid "Fetch"
msgstr ""
msgstr "Pobierz"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:82
msgid "Matches"
@ -2373,15 +2379,15 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs.py:38
msgid " - Jobs"
msgstr ""
msgstr " - Zadania"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:38
msgid "Active Jobs"
msgstr ""
msgstr "Aktywne zadanie"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/jobs_ui.py:39
msgid "&Stop selected job"
msgstr ""
msgstr "&Zatrzymaj zaznaczone zadanie"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:98
msgid "Choose the format to convert into LRF"
@ -2415,6 +2421,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:263
msgid "<li><b>book-designer</b> - HTML0 files from Book Designer</li>"
msgstr ""
"<li><b>book-designer</b> - pliki HTML0 stworzone w Book Designer</li>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single.py:296
msgid ""
@ -2587,22 +2594,13 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
"type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin:0; -qt-block-indent:0; text-"
"indent:0; font-family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
msgid "Edit Meta information"
msgstr ""
msgstr "Edytuj metadane"
#: /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:278
@ -2647,11 +2645,11 @@ msgstr "Dodaj ta&gi: "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:297
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:298
msgid "Open Tag Editor"
msgstr "Otwórz edytor tagów"
msgstr "Otwórz edytor etykiet"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:138
msgid "&Remove tags:"
msgstr "&Usuń tagi:"
msgstr "&Usuń etykiety:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:139
msgid "Comma separated list of tags to remove from the books. "
@ -2670,7 +2668,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:294
msgid "<b>Could not fetch cover.</b><br/>"
msgstr ""
msgstr "<b>Nie można pobrać okładki.</b><br/>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single.py:294
msgid "Could not fetch cover"
@ -2686,7 +2684,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:277
msgid "Edit Meta Information"
msgstr ""
msgstr "Edytuj metadane"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:281
msgid "Swap the author and title"
@ -2793,7 +2791,7 @@ msgid "News"
msgstr "Aktualności"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -2918,7 +2916,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:124
msgid "A&vailable tags"
msgstr ""
msgstr "&Dostępne etykiety"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tag_editor_ui.py:125
msgid ""
@ -3001,25 +2999,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -3031,7 +3029,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3185,11 +3183,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -3227,7 +3225,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:46
msgid "Job"
msgstr ""
msgstr "Zadanie"
#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:47
msgid "Status"
@ -3235,15 +3233,15 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:48
msgid "Progress"
msgstr ""
msgstr "Postęp"
#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:49
msgid "Running time"
msgstr ""
msgstr "Czas pracy"
#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:65
msgid "Unknown job"
msgstr ""
msgstr "Nieznane zadanie"
#: /home/kovid/work/calibre/src/calibre/gui2/jobs2.py:70
msgid "Finished"
@ -3292,7 +3290,7 @@ msgstr "Ocena"
#: /home/kovid/work/calibre/src/calibre/gui2/library.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/library.py:274
msgid "None"
msgstr ""
msgstr "Brak"
#: /home/kovid/work/calibre/src/calibre/gui2/library.py:280
msgid "Book <font face=\"serif\">%s</font> of %s."
@ -3309,6 +3307,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library.py:922
msgid "Search (For Advanced Search click the button to the left)"
msgstr ""
"Szukaj (Aby użyć zaawansowanego wyszukiwania kliknij przycisk po lewej)"
#: /home/kovid/work/calibre/src/calibre/gui2/lrf_renderer/config_ui.py:47
msgid "Configure Viewer"
@ -3388,7 +3387,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:98
msgid "&Restore"
msgstr ""
msgstr "&Przywróć"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:99
msgid "&Donate"
@ -3427,7 +3426,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:152
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:153
msgid "and delete from library"
msgstr ""
msgstr "i usuń z biblioteki"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:155
msgid "Send to storage card by default"
@ -3435,7 +3434,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:168
msgid "Edit metadata individually"
msgstr ""
msgstr "Edytuj metadane pjedyńczo"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:170
msgid "Edit metadata in bulk"
@ -3443,7 +3442,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:173
msgid "Add books from a single directory"
msgstr ""
msgstr "Dodaj książki z pojedyńczego folderu"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:174
msgid ""
@ -3460,11 +3459,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:190
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:311
msgid "Save to disk"
msgstr ""
msgstr "Zapisz na dysku"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:191
msgid "Save to disk in a single directory"
msgstr ""
msgstr "Zapisz na dysku w pojedyńczym folderze"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:192
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1106
@ -3622,7 +3621,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:708
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:730
msgid "Cannot edit metadata"
msgstr ""
msgstr "Nie można edytować metadanych"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:708
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:730
@ -3651,11 +3650,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:849
msgid "Cannot save to disk"
msgstr ""
msgstr "Nie można zapisać na dysku"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:853
msgid "Choose destination directory"
msgstr ""
msgstr "Wyberz folder docelowy"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:860
msgid ""
@ -3714,7 +3713,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1118
msgid "Copying library to "
msgstr ""
msgstr "Kopiowanie biblioteki do "
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1128
msgid "Invalid database"
@ -3772,7 +3771,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1251
msgid "Choose new location for database"
msgstr ""
msgstr "Wybierz nową lokalizację dla bazy danych"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1304
msgid ""
@ -3840,7 +3839,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:293
msgid "&Search:"
msgstr ""
msgstr "&Szukaj:"
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:294
msgid ""
@ -3868,11 +3867,11 @@ msgstr "Dopasuj wszystkie"
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:302
msgid "Sort by &popularity"
msgstr "Sorduj według &popularności"
msgstr "Sortuj według &popularności"
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:303
msgid "Add books"
msgstr ""
msgstr "Dodaj książki"
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:304
msgid "A"
@ -3881,7 +3880,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:305
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:306
msgid "Remove books"
msgstr ""
msgstr "Usuń książki"
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:307
msgid "Del"
@ -3889,7 +3888,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:308
msgid "Edit meta information"
msgstr ""
msgstr "Edytuj metadane"
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:309
msgid "E"
@ -3897,7 +3896,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:310
msgid "Send to device"
msgstr ""
msgstr "Preślij na urządzenie"
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:312
msgid "S"
@ -3925,7 +3924,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:319
msgid "Open containing folder"
msgstr ""
msgstr "Otwórz folder zawierający"
#: /home/kovid/work/calibre/src/calibre/gui2/main_ui.py:320
msgid "Show book details"
@ -3951,7 +3950,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146
msgid "Click to browse books by their covers"
msgstr ""
msgstr "Kliknij, aby przeglądać książki po okładkach"
#: /home/kovid/work/calibre/src/calibre/gui2/status.py:146
msgid "Click to turn off Cover Browsing"
@ -3965,7 +3964,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/status.py:159
msgid "Click to browse books by tags"
msgstr ""
msgstr "Kliknij, aby przeglądać ksiązki po etykietach"
#: /home/kovid/work/calibre/src/calibre/gui2/tags.py:42
msgid "Authors"
@ -4233,39 +4232,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
msgid ""
"Reader\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
msgstr "Biblioteka"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
msgid ""
"Reader\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4397,6 +4398,8 @@ msgid ""
"Add books to database even if they already exist. Comparison is done based "
"on book titles."
msgstr ""
"Dodaj książki do bazy danych nawet jeśli już są w niej. Porównanie odbywa "
"się na podstawie tytułów."
#: /home/kovid/work/calibre/src/calibre/library/cli.py:316
msgid "You must specify at least one file to add"
@ -4594,7 +4597,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/utils/config.py:538
msgid "Read metadata from files"
msgstr ""
msgstr "Wczytaj metadane z plików"
#: /home/kovid/work/calibre/src/calibre/utils/config.py:540
msgid "The priority of worker processes"
@ -4620,13 +4623,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr "Nieznany kanał"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr "Artukył bez tytułu"
@ -4695,7 +4698,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:37
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:92
msgid "Be more verbose while processing."
msgstr ""
msgstr "Wyświetlaj szczegółowe kominukaty w czasie pracy."
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:39
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:94
@ -4735,7 +4738,7 @@ msgstr "Ukryj pasek postępu"
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:55
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:105
msgid "Very verbose output, useful for debugging."
msgstr ""
msgstr "Bardzo szczegółowy wynik. Przydatny do debugowania."
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:57
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:107

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-07-05 03:33+0000\n"
"Last-Translator: Tiago Silva <Unknown>\n"
"Language-Team: Portuguese <pt@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1546,49 +1546,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1612,7 +1612,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -1993,22 +1993,22 @@ msgid "Book Cover"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2503,8 +2503,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2700,7 +2700,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -2904,25 +2904,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -2934,7 +2934,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3088,11 +3088,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4134,39 +4134,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4521,13 +4523,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""

View File

@ -6,21 +6,20 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre 0.4.55\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"PO-Revision-Date: 2008-12-07 14:04-0800\n"
"Last-Translator: Kovid Goyal <kovid@kovidgoyal.net>\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-12-07 22:09+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: American English <kde-i18n-doc@lists.kde.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Generator: Lokalize 0.2\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"X-Poedit-Country: RUSSIAN FEDERATION\n"
"X-Poedit-Language: Russian\n"
"X-Poedit-SourceCharset: utf-8\n"
"Generated-By: pygettext.py 1.5\n"
"X-Poedit-Bookmarks: -1,-1,-1,-1,-1,-1,-1,329,-1,-1\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:153
@ -41,7 +40,8 @@ msgstr "Опции контроля преобразования в EPUB"
msgid ""
"The output EPUB file. If not specified, it is derived from the input file "
"name."
msgstr "Выходной файл EPUB. Если не назначено, извлекается имя входящего файла."
msgstr ""
"Выходной файл EPUB. Если не назначено, извлекается имя входящего файла."
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:105
msgid ""
@ -108,7 +108,8 @@ msgstr "Путь к обложке используемой для этой кн
msgid ""
"Use the cover detected from the source file in preference to the specified "
"cover."
msgstr "Вместо заданной, использовать определение обложки из исходного файла."
msgstr ""
"Вместо заданной, использовать определение обложки из исходного файла."
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:127
msgid ""
@ -243,7 +244,8 @@ msgid "Keep intermediate files during processing by html2epub"
msgstr "Сохранить промежуточную копию файла во время обработки html2epub"
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/__init__.py:170
msgid "Extract the contents of the produced EPUB file to the specified directory."
msgid ""
"Extract the contents of the produced EPUB file to the specified directory."
msgstr "Извлечь содержимое созданного файла EPUB в специальную дерикторию."
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/from_any.py:43
@ -342,8 +344,10 @@ msgid "%s format books are not supported"
msgstr "%s формат книг не поддерживается"
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:30
msgid "Could not find reasonable point at which to split: %s Sub-tree size: %d KB"
msgstr "Не могу найти приемлимое место разделения: %s Размер поддерева: %d КБ"
msgid ""
"Could not find reasonable point at which to split: %s Sub-tree size: %d KB"
msgstr ""
"Не могу найти приемлимое место разделения: %s Размер поддерева: %d КБ"
#: /home/kovid/work/calibre/src/calibre/ebooks/epub/split.py:109
msgid ""
@ -739,7 +743,8 @@ msgstr ""
"нескольких элементов."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:180
msgid "Force a page break before tags whose names match this regular expression."
msgid ""
"Force a page break before tags whose names match this regular expression."
msgstr ""
"Устанавить разрывы страниц перед тегами, имена которых соответствуют этому "
"регулярному выражению."
@ -877,7 +882,8 @@ msgstr ""
"%s"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:282
msgid "Options to control the conversion of comics (CBR, CBZ) files into ebooks"
msgid ""
"Options to control the conversion of comics (CBR, CBZ) files into ebooks"
msgstr ""
"Опции контроля преобразования файлов комиксов (CBR, CBZ) в электронную книгу"
@ -886,7 +892,8 @@ msgid "Title for generated ebook. Default is to use the filename."
msgstr "Заголовок для созданной книги. По умолчанию используется имя файла."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/comic/convert_from.py:290
msgid "Set the author in the metadata of the generated ebook. Default is %default"
msgid ""
"Set the author in the metadata of the generated ebook. Default is %default"
msgstr ""
"Ввести автора в метаданные создаваемые электронной книгой. По умолчанию "
"%default"
@ -1098,8 +1105,10 @@ msgstr ""
"%s"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1765
msgid "An error occurred while processing a table: %s. Ignoring table markup."
msgstr "Призошла ошибка при обработке таблицы: %s. Пропустить разметку таблицы."
msgid ""
"An error occurred while processing a table: %s. Ignoring table markup."
msgstr ""
"Призошла ошибка при обработке таблицы: %s. Пропустить разметку таблицы."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/html/convert_from.py:1767
msgid ""
@ -1254,11 +1263,14 @@ msgstr "Катигория этой книги. Например: История
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:598
msgid "Path to a graphic that will be set as this files' thumbnail"
msgstr "Путь к картинке, которая будет использоваться в этом файле как миниатюра"
msgstr ""
"Путь к картинке, которая будет использоваться в этом файле как миниатюра"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:601
msgid "Path to a txt file containing the comment to be stored in the lrf file."
msgstr "Путь к текстовому файлу содержащему комментарии сохраняемые в файл lrf."
msgid ""
"Path to a txt file containing the comment to be stored in the lrf file."
msgstr ""
"Путь к текстовому файлу содержащему комментарии сохраняемые в файл lrf."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/meta.py:605
msgid "Extract thumbnail from LRF file"
@ -1297,7 +1309,8 @@ msgid "Could not find pdftohtml, check it is in your PATH"
msgstr "Не могу найти pdftohtml, проверьте наличе по PATH"
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/pdf/convert_from.py:61
msgid " is an image based PDF. Only conversion of text based PDFs is supported."
msgid ""
" is an image based PDF. Only conversion of text based PDFs is supported."
msgstr ""
" PDF содержит картинки. Поддерживается преобразование только текстовых PDF."
@ -1802,49 +1815,49 @@ msgstr ""
"Сервер\n"
"Контента"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr "Лог ошибок:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr "Лог доступа:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr "Сбой запуска контент сервера"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Неправильное расположение базы данных"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr "<br>Должна быть дирректория."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Неправильное расположение базы данных "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Неправильное расположение базы данных.<br>Немогу записать "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr "Сжатие базы данных. Это займет некоторое время."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr "Сжатие..."
@ -1868,7 +1881,7 @@ msgstr "Просмотреть расположение новой базы да
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -1981,7 +1994,8 @@ msgstr "Использовать &Римские цифры для нумера
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:391
msgid "&Number of covers to show in browse mode (after restart):"
msgstr "&Количество обложек показываемых в режиме просмотра (после перезагрузки):"
msgstr ""
"&Количество обложек показываемых в режиме просмотра (после перезагрузки):"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:392
msgid "Toolbar"
@ -2265,22 +2279,22 @@ msgid "Book Cover"
msgstr "Обложка книги"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Использовать обложку из &исходного файла"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr "Заменено изображение &обложки:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr "Просматреть изображения для обложки этой книги."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Использовать обложку из &исходного файла"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2536,7 +2550,8 @@ msgid "No metadata found"
msgstr "Нет метаданных"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:144
msgid "No metadata found, try adjusting the title and author or the ISBN key."
msgid ""
"No metadata found, try adjusting the title and author or the ISBN key."
msgstr ""
"Нет метаданных, попробуйте откорректировать заглавие и автора или ISBN ключ."
@ -2569,7 +2584,8 @@ msgid "Matches"
msgstr "Совпадения"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata_ui.py:83
msgid "Select the book that most closely matches your copy from the list below"
msgid ""
"Select the book that most closely matches your copy from the list below"
msgstr "Из списка выберете книгу, которая более соответствует вашей."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/job_view_ui.py:33
@ -2745,7 +2761,8 @@ msgstr " пикс."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:557
msgid "&Convert tables to images (good for large/complex tables)"
msgstr "Преобразовать таблицы в картинки (полезно для больших/сложных таблиц)"
msgstr ""
"Преобразовать таблицы в картинки (полезно для больших/сложных таблиц)"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:558
msgid "&Multiplier for text size in rendered tables:"
@ -2805,19 +2822,9 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" "
"\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style "
"type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
msgid "Edit Meta information"
@ -2956,7 +2963,8 @@ msgid "Fetch cover image from server"
msgstr "Получить изображение обложки с сервера"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:322
msgid "Change the username and/or password for your account at LibraryThing.com"
msgid ""
"Change the username and/or password for your account at LibraryThing.com"
msgstr ""
"Сменить имя пользователя и/или пароль для ваших данных на LibraryThing.com"
@ -3019,7 +3027,7 @@ msgid "News"
msgstr "Новости"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr "Состав"
@ -3236,25 +3244,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -3266,7 +3274,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3420,11 +3428,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -3836,7 +3844,8 @@ msgid "No space on device"
msgstr "Нет места на устройстве"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:635
msgid "<p>Cannot upload books to device there is no more free space available "
msgid ""
"<p>Cannot upload books to device there is no more free space available "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:665
@ -4465,43 +4474,41 @@ msgstr "Справочный режим"
msgid "Bookmark"
msgstr "Закладка"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr "Неправильное регулярное выражение"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr "Неправильное регулярное выражение: %s"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
"Ридер\n"
"%s доступен"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
"Карта\n"
"%s доступна"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4856,13 +4863,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr "Неизвестная заготовка"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""
@ -4879,7 +4886,8 @@ msgstr ""
msgid ""
"Timeout in seconds to wait for a response from the server. Default: %default "
"s"
msgstr "Максимальное время ожидания ответа от сервера. По умолчанию: %default с"
msgstr ""
"Максимальное время ожидания ответа от сервера. По умолчанию: %default с"
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:22
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:450
@ -5035,7 +5043,8 @@ msgstr ""
"%s\n"
#: /home/kovid/work/calibre/src/calibre/web/feeds/main.py:85
msgid "Options to control web2disk (used to fetch websites linked from feeds)"
msgid ""
"Options to control web2disk (used to fetch websites linked from feeds)"
msgstr ""
"Опции контроля web2disk (обычно вызываются линки сайтов переводных страниц )"
@ -5143,7 +5152,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:439
msgid "Base directory into which URL is saved. Default is %default"
msgstr "Основная директория, в которую сохранятся URL. По умолчанию: %default"
msgstr ""
"Основная директория, в которую сохранятся URL. По умолчанию: %default"
#: /home/kovid/work/calibre/src/calibre/web/fetch/simple.py:445
msgid ""
@ -5168,6 +5178,20 @@ msgstr "Показать детальную информацию. Использ
#~ msgid "&Priority for conversion jobs:"
#~ msgstr "&Очередность работ преобразования:"
#~ msgid ""
#~ "Reader\n"
#~ "%s available"
#~ msgstr ""
#~ "Ридер\n"
#~ "%s доступен"
#~ msgid ""
#~ "Card\n"
#~ "%s available"
#~ msgstr ""
#~ "Карта\n"
#~ "%s доступна"
#~ msgid ""
#~ "Detect a chapter beginning at an element having the specified attribute. The "
#~ "format for this option is tagname regexp,attribute name,attribute value "
@ -5182,4 +5206,3 @@ msgstr "Показать детальную информацию. Использ
#~ msgid "Enable system &tray icon"
#~ msgstr "Использовать иконку в панели задач"

File diff suppressed because it is too large Load Diff

View File

@ -6,14 +6,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre 0.4.17\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-09-19 19:17+0000\n"
"Last-Translator: Kovid Goyal <Unknown>\n"
"Language-Team: sl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:42+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:49+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n"
@ -1703,49 +1703,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr "Napačna lokacija podatkovne baze"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr "<br>Mora biti direktorij."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr "Napačna lokacija podatkovne baze "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr "Napačna lokacija podatkovne baze. <br>Ne morem pisati v "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr "Krčenje podatkovne baze. To lahko traja nekaj časa."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr "Krčenje ..."
@ -1771,7 +1771,7 @@ msgstr "Prebrskaj za novo lokacijo podatkovne baze"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -2154,22 +2154,22 @@ msgid "Book Cover"
msgstr "Naslovna Stran"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Uporabi na&slovnico iz izvorne datoteke"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr "Spremeni &sliko naslovne strani:"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr "Izberi sliko, ki bo uporabljena za naslovnico te knjige."
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr "Uporabi na&slovnico iz izvorne datoteke"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2679,8 +2679,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2882,7 +2882,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr "Recepti"
@ -3092,25 +3092,25 @@ msgstr "Ta feed je že bil dodan v recept"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr "Nepravilen vnos"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr "<p>Kreiranje recepta ni bilo mogoče. Napaka:<br>%s"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr "Zamenjam recept?"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr "Vir novic po meri z imenom %s že obstaja. Ga želite zamenjati?"
@ -3122,7 +3122,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr "Izberite recept"
@ -3279,11 +3279,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr "Brez zadetka"
@ -4372,45 +4372,43 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr "Neveljaven regularni izraz"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr "Neveljaven regularni izraz: %s"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr "Knjižnica"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Reader\n"
"%s je na voljo"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s available"
"%s\n"
"available"
msgstr ""
"Kartica\n"
"%s je na voljo"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr "Kliknite za seznam knjig, ki so na voljo na vašem računalniku"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
"Kliknite za seznam knjig, ki so na voljo v glavnem pomnilniku vašega reader-"
"ja"
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
"Kliknite za seznam knjig, ki so na voljo v spominski kartici v vašem reader-"
@ -4825,13 +4823,13 @@ msgstr "Avtentikacija SSH seje ni uspela: "
msgid "Failed to authenticate with server: %s"
msgstr "Avtentikacija s strežnikom ni uspela: %s"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr "Neznani feed"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr "Neznan članek"
@ -5175,6 +5173,20 @@ msgstr "Podrobneje prikaži izhodne informacije. Koristno za razhroščevanje."
#~ msgid "Custom news sources"
#~ msgstr "Viri novic po meri"
#~ msgid ""
#~ "Reader\n"
#~ "%s available"
#~ msgstr ""
#~ "Reader\n"
#~ "%s je na voljo"
#~ msgid ""
#~ "Card\n"
#~ "%s available"
#~ msgstr ""
#~ "Kartica\n"
#~ "%s je na voljo"
#~ msgid " does not allow copying of text."
#~ msgstr " ne omogoča kopiranje teksta."

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-09-14 18:45+0000\n"
"Last-Translator: Linus C Unneback <linus@folkdatorn.se>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:41+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1546,49 +1546,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1612,7 +1612,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -1993,22 +1993,22 @@ msgid "Book Cover"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2503,8 +2503,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2700,7 +2700,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -2904,25 +2904,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -2934,7 +2934,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3088,11 +3088,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4134,39 +4134,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4521,13 +4523,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""

View File

@ -7,14 +7,14 @@ msgid ""
msgstr ""
"Project-Id-Version: calibre\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2008-12-06 07:37+0000\n"
"POT-Creation-Date: 2008-12-09 02:03+0000\n"
"PO-Revision-Date: 2008-06-24 13:22+0000\n"
"Last-Translator: వీవెన్ (Veeven) <Unknown>\n"
"Language-Team: Telugu <te@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-12-07 21:41+0000\n"
"X-Launchpad-Export-Date: 2008-12-10 21:48+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:135
@ -1546,49 +1546,49 @@ msgid ""
"Server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:162
msgid "Error log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:166
msgid "Access log:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:187
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:188
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:339
msgid "Failed to start content server"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "Invalid size"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:227
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:228
msgid "The size %s is invalid. must be of the form widthxheight"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:269
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:273
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
msgid "Invalid database location"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "<br>Must be a directory."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:270
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:271
msgid "Invalid database location "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:274
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:275
msgid "Invalid database location.<br>Cannot write to "
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting database. This may take a while."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:286
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config.py:287
msgid "Compacting..."
msgstr ""
@ -1612,7 +1612,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:389
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:399
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:400
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:509
#: /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:288
@ -1993,22 +1993,22 @@ msgid "Book Cover"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:371
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:507
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:316
msgid "Change &cover image:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:373
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:372
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:508
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_single_ui.py:317
msgid "Browse for an image to use as the cover of this book."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:374
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/lrf_single_ui.py:510
msgid "Use cover from &source file"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/epub_ui.py:375
#: /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:279
@ -2503,8 +2503,8 @@ msgid ""
"</style></head><body style=\" font-family:'DejaVu Sans'; font-size:10pt; "
"font-weight:400; font-style:normal;\">\n"
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; "
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-"
"family:'Sans Serif'; font-size:9pt;\"></p></body></html>"
"margin-left:0px; margin-right:0px; -qt-block-indent:0; text-"
"indent:0px;\"></p></body></html>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/metadata_bulk_ui.py:122
@ -2700,7 +2700,7 @@ msgid "News"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Recipes"
msgstr ""
@ -2904,25 +2904,25 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:163
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:172
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:228
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
msgid "Invalid input"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:164
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:173
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:230
msgid "<p>Could not create recipe. Error:<br>%s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:210
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:234
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
msgid "Replace recipe?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:180
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:211
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:235
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:236
msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr ""
@ -2934,7 +2934,7 @@ msgstr ""
msgid "Pick the recipe to customize"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:221
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:222
msgid "Choose a recipe file"
msgstr ""
@ -3088,11 +3088,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:116
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:119
#: /home/kovid/work/calibre/src/calibre/gui2/filename_pattern_ui.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:54
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:70
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:55
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:59
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:64
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:69
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:71
msgid "No match"
msgstr ""
@ -4134,39 +4134,41 @@ msgstr ""
msgid "Bookmark"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
msgid "Invalid regular expression"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:48
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:49
msgid "Invalid regular expression: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:178
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:183
msgid "Library"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:179
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid ""
"Reader\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:180
msgid ""
"Card\n"
"%s available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:184
msgid "Click to see the list of books available on your computer"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:185
msgid ""
"Card\n"
"%s\n"
"available"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:189
msgid "Click to see the list of books available on your computer"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:190
msgid "Click to see the list of books in the main memory of your reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:186
#: /home/kovid/work/calibre/src/calibre/gui2/widgets.py:191
msgid "Click to see the list of books on the storage card in your reader"
msgstr ""
@ -4521,13 +4523,13 @@ msgstr ""
msgid "Failed to authenticate with server: %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:63
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:84
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:75
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:96
msgid "Unknown feed"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:102
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:124
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:114
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:136
msgid "Untitled article"
msgstr ""

View File

@ -0,0 +1,37 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
'''
telegraph.co.uk
'''
from calibre.web.feeds.news import BasicNewsRecipe
class TelegraphUK(BasicNewsRecipe):
title = u'Telegraph.co.uk'
__author__ = 'Darko Miletic'
description = 'News from United Kingdom'
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
keep_only_tags = [
dict(name='div', attrs={'class':'storyHead'})
,dict(name='div', attrs={'class':'story' })
]
remove_tags = [dict(name='div', attrs={'class':'slideshow'})]
feeds = [
(u'UK News' , u'http://www.telegraph.co.uk/news/uknews/rss' )
,(u'World News' , u'http://www.telegraph.co.uk/news/worldnews/rss' )
,(u'Politics' , u'http://www.telegraph.co.uk/news/newstopics/politics/rss' )
,(u'Technology News', u'http://www.telegraph.co.uk/scienceandtechnology/technology/technologynews/rss' )
,(u'UK News' , u'http://www.telegraph.co.uk/scienceandtechnology/technology/technologyreviews/rss')
,(u'Science News' , u'http://www.telegraph.co.uk/scienceandtechnology/science/sciencenews/rss' )
,(u'Sport' , u'http://www.telegraph.co.uk/sport/rss' )
,(u'Earth News' , u'http://www.telegraph.co.uk/earth/earthnews/rss' )
,(u'Comment' , u'http://www.telegraph.co.uk/comment/rss' )
,(u'How about that?', u'http://www.telegraph.co.uk/news/newstopics/howaboutthat/rss' )
]

View File

@ -102,15 +102,12 @@ def build_osx(shutdown=True):
return os.path.basename(installer)
def build_linux(shutdown=True):
def build_linux(*args, **kwargs):
installer = installer_name('tar.bz2')
vm = '/vmware/linux/libprs500-gentoo.vmx'
start_vm(vm, 'linux', (BUILD_SCRIPT%('sudo python setup.py develop', 'python','installer/linux/freeze.py')).replace('rm ', 'sudo rm '), sleep=120)
subprocess.check_call(('scp', 'linux:/tmp/%s'%os.path.basename(installer), 'dist'))
exec open('installer/linux/freeze.py')
freeze()
if not os.path.exists(installer):
raise Exception('Failed to build installer '+installer)
if shutdown:
subprocess.Popen(('ssh', 'linux', 'sudo', '/sbin/poweroff'))
return os.path.basename(installer)
def build_installers():