IGN:Rationalize automated build process

This commit is contained in:
Kovid Goyal 2008-06-15 16:30:44 -07:00
parent 30a01e4484
commit 908e31a80c
15 changed files with 282 additions and 211 deletions

View File

@ -1,8 +1,10 @@
PYTHON = python PYTHON = python
all : plugins pictureflow gui2 translations resources all : plugins gui2 translations resources
plugins: plugins : src/calibre/plugins pictureflow
src/calibre/plugins:
mkdir -p src/calibre/plugins mkdir -p src/calibre/plugins
clean : clean :

153
linux_installer.py Normal file
View File

@ -0,0 +1,153 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
'''
Create linux binary.
'''
import glob, sys, subprocess, tarfile, os, re
HOME = '/home/kovid'
PYINSTALLER = os.path.expanduser('~/build/pyinstaller')
CALIBREPREFIX = '___'
CLIT = '/usr/bin/clit'
PDFTOHTML = '/usr/bin/pdftohtml'
LIBUNRAR = '/usr/lib/libunrar.so'
QTDIR = '/usr/lib/qt4'
QTDLLS = ('QtCore', 'QtGui', 'QtNetwork', 'QtSvg', 'QtXml')
EXTRAS = ('/usr/lib/python2.5/site-packages/PIL', os.path.expanduser('~/ipython/IPython'))
CALIBRESRC = os.path.join(CALIBREPREFIX, 'src')
CALIBREPLUGINS = os.path.join(CALIBRESRC, 'calibre', 'plugins')
sys.path.insert(0, CALIBRESRC)
from calibre import __version__
def run_pyinstaller(args=sys.argv):
subprocess.check_call(('/usr/bin/sudo', 'chown', '-R', 'kovid:users', glob.glob('/usr/lib/python*/site-packages/')[-1]))
subprocess.check_call('rm -rf %(py)s/dist/* %(py)s/build/*'%dict(py=PYINSTALLER), shell=True)
subprocess.check_call('make plugins', shell=True)
cp = HOME+'/build/'+os.path.basename(os.getcwd())
spec = open(os.path.join(PYINSTALLER, 'calibre', 'calibre.spec'), 'wb')
raw = re.sub(r'CALIBREPREFIX\s+=\s+\'___\'', 'CALIBREPREFIX = '+repr(cp),
open(__file__).read())
spec.write(raw)
spec.close()
os.chdir(PYINSTALLER)
subprocess.check_call('python -OO Build.py calibre/calibre.spec', shell=True)
return 0
if __name__ == '__main__' and 'linux_installer.py' in __file__:
sys.exit(run_pyinstaller())
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, "plugins")])
''')
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']
temp = ['keyword', 'codeop']
recipes = ['calibre', 'web', 'feeds', 'recipes']
prefix = '.'.join(recipes)+'.'
for f in glob.glob(os.path.join(CALIBRESRC, *(recipes+['*.py']))):
temp.append(prefix + os.path.basename(f).partition('.')[0])
hook = os.path.expanduser('~/temp/hook-calibre.py')
f = open(hook, 'wb')
hook_script = 'hiddenimports = %s'%repr(temp)
f.write(hook_script)
sys.path.insert(0, CALIBRESRC)
from calibre.linux import entry_points
executables, scripts = ['calibre_postinstall', 'parallel'], \
[os.path.join(CALIBRESRC, 'calibre', 'linux.py'), os.path.join(CALIBRESRC, 'calibre', 'parallel.py')]
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')
recipes = Analysis(glob.glob(os.path.join(CALIBRESRC, 'calibre', 'web', 'feeds', 'recipes', '*.py')),
pathex=[CALIBRESRC], hookspath=[os.path.dirname(hook)], excludes=excludes)
analyses = [Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), loader, script],
pathex=[PYINSTALLER, CALIBRESRC, CALIBREPLUGINS], excludes=excludes) for script in scripts]
pyz = TOC()
binaries = TOC()
for a in analyses:
pyz = a.pure + pyz
binaries = a.binaries + binaries
pyz = PYZ(pyz + recipes.pure, name='library.pyz')
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))
print 'Adding plugins...'
for f in glob.glob(os.path.join(CALIBREPLUGINS, '*.so')):
binaries += [(os.path.basename(f), f, 'BINARY')]
print 'Adding external programs...'
binaries += [('clit', CLIT, 'BINARY'), ('pdftohtml', PDFTOHTML, 'BINARY'),
('libunrar.so', LIBUNRAR, 'BINARY')]
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 = []
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
f = os.path.join(dirpath, f)
plugins.append(('plugins/'+f.replace(plugdir, ''), f, 'BINARY'))
binaries += plugins
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'))
os.chdir(os.path.join(HOMEPATH, 'calibre', 'dist'))
for folder in EXTRAS:
subprocess.check_call('cp -rf %s .'%folder, shell=True)
print 'Building tarball...'
tbz2 = 'calibre-%s-i686.tar.bz2'%__version__
tf = tarfile.open(os.path.join('/tmp', tbz2), 'w:bz2')
for f in os.listdir('.'):
tf.add(f)

View File

@ -99,8 +99,7 @@ _check_symlinks_prescript()
includes=list(self.includes) + main_modules['console'], includes=list(self.includes) + main_modules['console'],
packages=self.packages, packages=self.packages,
excludes=self.excludes, excludes=self.excludes,
debug=debug debug=debug)
)
@classmethod @classmethod
def makedmg(cls, d, volname, def makedmg(cls, d, volname,
@ -249,6 +248,11 @@ _check_symlinks_prescript()
else: else:
os.link(src, os.path.join(module_dir, dest)) os.link(src, os.path.join(module_dir, dest))
print print
print 'Adding IPython'
dst = os.path.join(resource_dir, 'lib', 'python2.5', 'IPython')
if os.path.exists(dst): shutil.rmtree(dst)
shutil.copytree(os.path.expanduser('~/build/ipython/IPython'), dst)
print
print 'Installing prescipt' print 'Installing prescipt'
sf = [os.path.basename(s) for s in all_names] sf = [os.path.basename(s) for s in all_names]
cs = BuildAPP.CHECK_SYMLINKS_PRESCRIPT % dict(dest_path=repr('/usr/bin'), cs = BuildAPP.CHECK_SYMLINKS_PRESCRIPT % dict(dest_path=repr('/usr/bin'),
@ -294,12 +298,12 @@ def main():
'PyQt4.QtSvg', 'PyQt4.QtSvg',
'mechanize', 'ClientForm', 'usbobserver', 'mechanize', 'ClientForm', 'usbobserver',
'genshi', 'calibre.web.feeds.recipes.*', 'genshi', 'calibre.web.feeds.recipes.*',
'IPython.Extensions.*', 'pydoc'], 'keyword', 'codeop', 'pydoc'],
'packages' : ['PIL', 'Authorization', 'rtf2xml', 'lxml'], 'packages' : ['PIL', 'Authorization', 'rtf2xml', 'lxml'],
'excludes' : [], 'excludes' : ['IPython'],
'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.''' 'plist' : { 'CFBundleGetInfoString' : '''calibre, an E-book management application.'''
''' Visit http://calibre.kovidgoyal.net for details.''', ''' Visit http://calibre.kovidgoyal.net for details.''',
'CFBundleIdentifier':'net.kovidgoyal.librs500', 'CFBundleIdentifier':'net.kovidgoyal.calibre',
'CFBundleShortVersionString':VERSION, 'CFBundleShortVersionString':VERSION,
'CFBundleVersion':APPNAME + ' ' + VERSION, 'CFBundleVersion':APPNAME + ' ' + VERSION,
'LSMinimumSystemVersion':'10.4.3', 'LSMinimumSystemVersion':'10.4.3',

View File

@ -7,9 +7,9 @@ import re, os
from PyQt4.QtGui import QListView, QIcon, QFont, QLabel, QListWidget, \ from PyQt4.QtGui import QListView, QIcon, QFont, QLabel, QListWidget, \
QListWidgetItem, QTextCharFormat, QApplication, \ QListWidgetItem, QTextCharFormat, QApplication, \
QSyntaxHighlighter, QCursor, QColor, QWidget, \ QSyntaxHighlighter, QCursor, QColor, QWidget, \
QAbstractItemDelegate, QPixmap, QStyle QAbstractItemDelegate, QPixmap, QStyle, QFontMetrics
from PyQt4.QtCore import QAbstractListModel, QVariant, Qt, SIGNAL, \ from PyQt4.QtCore import QAbstractListModel, QVariant, Qt, SIGNAL, \
QObject, QRegExp, QRectF, QString QObject, QRegExp, QString
from calibre.gui2.jobs import DetailView from calibre.gui2.jobs import DetailView
from calibre.gui2 import human_readable, NONE, TableView, qstring_to_unicode, error_dialog from calibre.gui2 import human_readable, NONE, TableView, qstring_to_unicode, error_dialog
@ -128,8 +128,10 @@ class LocationDelegate(QAbstractItemDelegate):
def rects(self, option): def rects(self, option):
style = QApplication.style() style = QApplication.style()
font = QFont(option.font)
font.setBold(True)
irect = style.itemPixmapRect(option.rect, Qt.AlignHCenter|Qt.AlignTop, self.pixmap) irect = style.itemPixmapRect(option.rect, Qt.AlignHCenter|Qt.AlignTop, self.pixmap)
trect = style.itemTextRect(option.fontMetrics, option.rect, trect = style.itemTextRect(QFontMetrics(font), option.rect,
Qt.AlignHCenter|Qt.AlignTop, True, self.text) Qt.AlignHCenter|Qt.AlignTop, True, self.text)
trect.moveTop(irect.bottom()) trect.moveTop(irect.bottom())
return irect, trect return irect, trect

View File

@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"

View File

@ -17,7 +17,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#~ msgid "" #~ msgid ""

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"

View File

@ -11,13 +11,13 @@ msgstr ""
"Project-Id-Version: es\n" "Project-Id-Version: es\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-12 20:18+0000\n" "POT-Creation-Date: 2008-06-12 20:18+0000\n"
"PO-Revision-Date: 2008-06-12 22:40+0000\n" "PO-Revision-Date: 2008-06-15 08:31+0000\n"
"Last-Translator: S. Dorscht <Unknown>\n" "Last-Translator: S. Dorscht <Unknown>\n"
"Language-Team: Spanish\n" "Language-Team: Spanish\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#~ msgid "" #~ msgid ""
@ -151,7 +151,7 @@ msgstr "Creado por "
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:146 #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:146
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:174 #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:174
msgid "Unable to detect the %s disk drive. Try rebooting." msgid "Unable to detect the %s disk drive. Try rebooting."
msgstr "" msgstr "No se ha podido detectar la unidad de disco %s. Trate de reiniciar."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/__init__.py:73
msgid "Set the title. Default: filename." msgid "Set the title. Default: filename."
@ -671,7 +671,6 @@ msgid "Creating XML..."
msgstr "Creando XML..." msgstr "Creando XML..."
#: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156 #: /home/kovid/work/calibre/src/calibre/ebooks/lrf/lrfparser.py:156
#, fuzzy
msgid "LRS written to " msgid "LRS written to "
msgstr "LRS escrito en " msgstr "LRS escrito en "
@ -1130,7 +1129,6 @@ msgid "Show &text in toolbar buttons"
msgstr "Mostrar &texto en los botones de la barra de herramientas" msgstr "Mostrar &texto en los botones de la barra de herramientas"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/config_ui.py:219
#, fuzzy
msgid "Free unused diskspace from the database" msgid "Free unused diskspace from the database"
msgstr "Espacio de disco disponible de la base de datos" msgstr "Espacio de disco disponible de la base de datos"
@ -1896,18 +1894,16 @@ msgstr ""
"actual" "actual"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:63 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:63
#, fuzzy
msgid "No recipe selected" msgid "No recipe selected"
msgstr "No hay ninguna receta seleccionada" msgstr "No hay ninguna receta seleccionada"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:69 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:69
#, fuzzy
msgid "The attached file: %s is a recipe to download %s." msgid "The attached file: %s is a recipe to download %s."
msgstr "el archivo adjunto: %s es una receta para descargar %s" msgstr "El archivo adjunto: %s es una receta para descargar %s"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:70 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:70
msgid "Recipe for " msgid "Recipe for "
msgstr "" msgstr "Receta para "
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:86 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:86
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:96 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:96
@ -1941,9 +1937,8 @@ msgid "Already exists"
msgstr "Ya existe" msgstr "Ya existe"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:121 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:121
#, fuzzy
msgid "This feed has already been added to the recipe" msgid "This feed has already been added to the recipe"
msgstr "el Feed ya se ha añadido a la receta" msgstr "Este Feed ya se ha añadido a la receta"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:162 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:162
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:171 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:171
@ -1968,9 +1963,8 @@ msgid "A custom recipe named %s already exists. Do you want to replace it?"
msgstr "una receta personalizada llamada %s ya existe. Quiere reemplazarla?" msgstr "una receta personalizada llamada %s ya existe. Quiere reemplazarla?"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:187 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:187
#, fuzzy
msgid "Choose a recipe file" msgid "Choose a recipe file"
msgstr "Seleccionarr un archivo de receta" msgstr "Seleccionar un archivo de receta"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:187 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/user_profiles.py:187
msgid "Recipes" msgid "Recipes"
@ -2651,6 +2645,9 @@ msgid ""
"href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. " "href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">new features</a>. "
"Visit the download page?" "Visit the download page?"
msgstr "" msgstr ""
"%s se ha actualizado a la versión %s. Ver las <a "
"href=\"http://calibre.kovidgoyal.net/wiki/Changelog\">nuevas "
"características</a>. Visita la página de descarga?"
#: /home/kovid/work/calibre/src/calibre/gui2/main.py:1155 #: /home/kovid/work/calibre/src/calibre/gui2/main.py:1155
msgid "Update available" msgid "Update available"
@ -2833,6 +2830,8 @@ msgid ""
"Path to the calibre database. Default is to use the path stored in the " "Path to the calibre database. Default is to use the path stored in the "
"settings." "settings."
msgstr "" msgstr ""
"Camino a la base de datos calibre. El valor predeterminado es a usar la ruta "
"almacenada en la configuración."
#: /home/kovid/work/calibre/src/calibre/library/cli.py:80 #: /home/kovid/work/calibre/src/calibre/library/cli.py:80
msgid "" msgid ""
@ -2840,6 +2839,9 @@ msgid ""
"\n" "\n"
"List the books available in the calibre database. \n" "List the books available in the calibre database. \n"
msgstr "" msgstr ""
"%prog list [options]\n"
"\n"
"Mostrar los libros disponibles en la base de datos calibre. \n"
#: /home/kovid/work/calibre/src/calibre/library/cli.py:88 #: /home/kovid/work/calibre/src/calibre/library/cli.py:88
msgid "" msgid ""
@ -2866,6 +2868,9 @@ msgid ""
"please see the search related documentation in the User Manual. Default is " "please see the search related documentation in the User Manual. Default is "
"to do no filtering." "to do no filtering."
msgstr "" msgstr ""
"Filtrar los resultados de la consulta de búsqueda. Para el formato de la "
"consulta de búsqueda consulte la documentación relacionada con la búsqueda "
"en el Manual del usuario. El valor predeterminado es a no hacer el filtrado."
#: /home/kovid/work/calibre/src/calibre/library/cli.py:101 #: /home/kovid/work/calibre/src/calibre/library/cli.py:101
msgid "Invalid fields. Available fields:" msgid "Invalid fields. Available fields:"
@ -2891,12 +2896,20 @@ msgid ""
"directories, see\n" "directories, see\n"
"the directory related options below. \n" "the directory related options below. \n"
msgstr "" msgstr ""
"%prog add [options] file1 file2 file3 ...\n"
"\n"
"Añadir los archivos especificados como libros a la base de datos. También "
"puede especificar\n"
"directorios, consulte las opciones relacionadas a los directorios más abajo. "
"\n"
#: /home/kovid/work/calibre/src/calibre/library/cli.py:204 #: /home/kovid/work/calibre/src/calibre/library/cli.py:204
msgid "" msgid ""
"Assume that each directory has only a single logical book and that all files " "Assume that each directory has only a single logical book and that all files "
"in it are different e-book formats of that book" "in it are different e-book formats of that book"
msgstr "" msgstr ""
"Supongamos que cada directorio tiene un solo libro lógico y que todos los "
"archivos en este directorio son diferentes formatos de este libro"
#: /home/kovid/work/calibre/src/calibre/library/cli.py:206 #: /home/kovid/work/calibre/src/calibre/library/cli.py:206
msgid "Process directories recursively" msgid "Process directories recursively"
@ -2922,6 +2935,12 @@ msgid ""
"separated list of id numbers (you can get id numbers by using the list " "separated list of id numbers (you can get id numbers by using the list "
"command). For example, 23,34,57-85\n" "command). For example, 23,34,57-85\n"
msgstr "" msgstr ""
"%prog remove ids\n"
"\n"
"Eliminar los libros identificados por ID de la base de datos. ID debe ser "
"una lista separada por comas de números de identificación (se puede obtener "
"números de identificación utilizando el commando \"list\"). Por ejemplo, "
"23,34,57-85\n"
#: /home/kovid/work/calibre/src/calibre/library/cli.py:243 #: /home/kovid/work/calibre/src/calibre/library/cli.py:243
msgid "You must specify at least one book to remove" msgid "You must specify at least one book to remove"
@ -2953,6 +2972,13 @@ msgid ""
"by using the list command. fmt should be a file extension like LRF or TXT or " "by using the list command. fmt should be a file extension like LRF or TXT or "
"EPUB. If the logical book does not have fmt available, do nothing.\n" "EPUB. If the logical book does not have fmt available, do nothing.\n"
msgstr "" msgstr ""
"\n"
"%prog remove_format [options] id fmt\n"
"\n"
"Eliminar el formato fmt del libro lógico identificado por id. Usted puede "
"obtener id utilizando el comando \"list\". fmt debe ser una extensión de "
"archivo como LRF o TXT o EPUB. Si el libro lógico no tiene fmt disponible, "
"no hacer nada.\n"
#: /home/kovid/work/calibre/src/calibre/library/cli.py:300 #: /home/kovid/work/calibre/src/calibre/library/cli.py:300
msgid "You must specify an id and a format" msgid "You must specify an id and a format"
@ -2976,11 +3002,11 @@ msgstr "Trabajo detenido por el usuario"
#: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:124 #: /home/kovid/work/calibre/src/calibre/utils/fontconfig.py:124
msgid "Could not initialize the fontconfig library" msgid "Could not initialize the fontconfig library"
msgstr "" msgstr "No se ha podido inicializar la biblioteca fontconfig"
#: /home/kovid/work/calibre/src/calibre/utils/sftp.py:53 #: /home/kovid/work/calibre/src/calibre/utils/sftp.py:53
msgid "URL must have the scheme sftp" msgid "URL must have the scheme sftp"
msgstr "" msgstr "La URL debe tener el régimen de sftp"
#: /home/kovid/work/calibre/src/calibre/utils/sftp.py:57 #: /home/kovid/work/calibre/src/calibre/utils/sftp.py:57
msgid "host must be of the form user@hostname" msgid "host must be of the form user@hostname"
@ -2988,11 +3014,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/utils/sftp.py:68 #: /home/kovid/work/calibre/src/calibre/utils/sftp.py:68
msgid "Failed to negotiate SSH session: " msgid "Failed to negotiate SSH session: "
msgstr "" msgstr "No se ha podido negociar período de sesiones SSH: "
#: /home/kovid/work/calibre/src/calibre/utils/sftp.py:71 #: /home/kovid/work/calibre/src/calibre/utils/sftp.py:71
msgid "Failed to authenticate with server: %s" msgid "Failed to authenticate with server: %s"
msgstr "" msgstr "No se ha podido autenticar con el servidor: %s"
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:56 #: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:56
#: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:77 #: /home/kovid/work/calibre/src/calibre/web/feeds/__init__.py:77

View File

@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"

View File

@ -15,7 +15,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"

View File

@ -14,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
#~ msgid "" #~ msgid ""

View File

@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"

View File

@ -13,7 +13,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2008-06-14 07:16+0000\n" "X-Launchpad-Export-Date: 2008-06-15 22:20+0000\n"
"X-Generator: Launchpad (build Unknown)\n" "X-Generator: Launchpad (build Unknown)\n"
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"

220
upload.py
View File

@ -1,13 +1,19 @@
#!/usr/bin/python #!/usr/bin/python
import sys, os, shutil, time, tempfile, socket import sys, os, shutil, time, tempfile, socket, fcntl, struct
sys.path.append('src') sys.path.append('src')
import subprocess import subprocess
from subprocess import check_call as _check_call from subprocess import check_call as _check_call
from functools import partial from functools import partial
#from pyvix.vix import Host, VIX_SERVICEPROVIDER_VMWARE_WORKSTATION #from pyvix.vix import Host, VIX_SERVICEPROVIDER_VMWARE_WORKSTATION
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) def get_ip_address(ifname):
s.connect(('google.com', 0)) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
HOST=s.getsockname()[0] return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
HOST=get_ip_address('eth0')
PROJECT=os.path.basename(os.getcwd()) PROJECT=os.path.basename(os.getcwd())
from calibre import __version__, __appname__ from calibre import __version__, __appname__
@ -21,11 +27,12 @@ TXT2LRF = "src/calibre/ebooks/lrf/txt/demo"
BUILD_SCRIPT ='''\ BUILD_SCRIPT ='''\
#!/bin/bash #!/bin/bash
cd ~/build && \ cd ~/build && \
rsync -avz --exclude docs --exclude .bzr --exclude .build --exclude build --exclude dist --exclude "*.pyc" --exclude "*.pyo" rsync://%(host)s/work/%(project)s . && \ rsync -avz --exclude src/calibre/plugins --exclude docs --exclude .bzr --exclude .build --exclude build --exclude dist --exclude "*.pyc" --exclude "*.pyo" rsync://%(host)s/work/%(project)s . && \
cd %(project)s && \ cd %(project)s && \
mkdir -p build dist && \ mkdir -p build dist src/calibre/plugins && \
%%s && \
rm -rf build/* dist/* && \ rm -rf build/* dist/* && \
python %%s %%s %%s
'''%dict(host=HOST, project=PROJECT) '''%dict(host=HOST, project=PROJECT)
check_call = partial(_check_call, shell=True) check_call = partial(_check_call, shell=True)
#h = Host(hostType=VIX_SERVICEPROVIDER_VMWARE_WORKSTATION) #h = Host(hostType=VIX_SERVICEPROVIDER_VMWARE_WORKSTATION)
@ -41,22 +48,24 @@ def installer_name(ext):
return 'dist/%s-%s.%s'%(__appname__, __version__, ext) return 'dist/%s-%s.%s'%(__appname__, __version__, ext)
return 'dist/%s-%s-i686.%s'%(__appname__, __version__, ext) return 'dist/%s-%s-i686.%s'%(__appname__, __version__, ext)
def start_vm(vm, ssh_host, build_script, sleep): def start_vm(vm, ssh_host, build_script, sleep=75):
vmware = ('vmware', '-q', '-x', '-n', vm) vmware = ('vmware', '-q', '-x', '-n', vm)
subprocess.Popen(vmware) subprocess.Popen(vmware)
t = tempfile.NamedTemporaryFile(suffix='.sh') t = tempfile.NamedTemporaryFile(suffix='.sh')
t.write(build_script) t.write(build_script)
t.flush() t.flush()
print 'Waiting for VM to startup' print 'Waiting for VM to startup'
time.sleep(sleep) while subprocess.call('ping -q -c1 '+ssh_host, shell=True, stdout=open('/dev/null', 'w')) != 0:
time.sleep(5)
time.sleep(20)
print 'Trying to SSH into VM' print 'Trying to SSH into VM'
subprocess.check_call(('scp', t.name, ssh_host+':build-'+PROJECT)) subprocess.check_call(('scp', t.name, ssh_host+':build-'+PROJECT))
subprocess.check_call('ssh -t %s bash build-%s'%(ssh_host, PROJECT), shell=True)
def build_windows(): def build_windows():
installer = installer_name('exe') installer = installer_name('exe')
vm = '/vmware/Windows XP/Windows XP Professional.vmx' vm = '/vmware/Windows XP/Windows XP Professional.vmx'
start_vm(vm, 'windows', BUILD_SCRIPT%'windows_installer.py', 75) start_vm(vm, 'windows', BUILD_SCRIPT%('python setup.py develop', 'python','windows_installer.py'))
subprocess.check_call(('ssh', 'windows', '/bin/bash', '~/build-'+PROJECT))
subprocess.check_call(('scp', 'windows:build/%s/dist/*.exe'%PROJECT, 'dist')) subprocess.check_call(('scp', 'windows:build/%s/dist/*.exe'%PROJECT, 'dist'))
if not os.path.exists(installer): if not os.path.exists(installer):
raise Exception('Failed to build installer '+installer) raise Exception('Failed to build installer '+installer)
@ -66,160 +75,24 @@ def build_windows():
def build_osx(): def build_osx():
installer = installer_name('dmg') installer = installer_name('dmg')
vm = '/vmware/Mac OSX/Mac OSX.vmx' vm = '/vmware/Mac OSX/Mac OSX.vmx'
vmware = ('vmware', '-q', '-x', '-n', vm) python = '/Library/Frameworks/Python.framework/Versions/Current/bin/python'
start_vm(vm, 'osx', BUILD_SCRIPT%'osx_installer.py', 120) start_vm(vm, 'osx', BUILD_SCRIPT%('sudo %s setup.py develop'%python, python, 'osx_installer.py'))
subprocess.check_call(('ssh', 'osx', '/bin/bash', '~/build-'+PROJECT)) subprocess.check_call(('scp', 'osx:build/%s/dist/*.dmg'%PROJECT, 'dist'))
subprocess.check_call(('scp', 'windows:build/%s/dist/*.dmg'%PROJECT, 'dist'))
if not os.path.exists(installer): if not os.path.exists(installer):
raise Exception('Failed to build installer '+installer) raise Exception('Failed to build installer '+installer)
subprocess.Popen(('ssh', 'osx', 'sudo', '/sbin/shutdown', '-h', 'now')) subprocess.Popen(('ssh', 'osx', 'sudo', '/sbin/shutdown', '-h', 'now'))
return os.path.basename(installer) return os.path.basename(installer)
def _build_linux():
cwd = os.getcwd()
tbz2 = os.path.join(cwd, installer_name('tar.bz2'))
SPEC="""\
import os
HOME = '%(home)s'
PYINSTALLER = os.path.expanduser('~/build/pyinstaller')
CALIBREPREFIX = HOME+'/work/%(project)s'
CLIT = '/usr/bin/clit'
PDFTOHTML = '/usr/bin/pdftohtml'
LIBUNRAR = '/usr/lib/libunrar.so'
QTDIR = '/usr/lib/qt4'
QTDLLS = ('QtCore', 'QtGui', 'QtNetwork', 'QtSvg', 'QtXml')
EXTRAS = ('/usr/lib/python2.5/site-packages/PIL', os.path.expanduser('~/ipython/IPython'))
import glob, sys, subprocess, tarfile
CALIBRESRC = os.path.join(CALIBREPREFIX, 'src')
CALIBREPLUGINS = os.path.join(CALIBRESRC, 'calibre', 'plugins')
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)
loader = os.path.join('/tmp', '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, "plugins")])
''')
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']
temp = ['keyword', 'codeop']
recipes = ['calibre', 'web', 'feeds', 'recipes']
prefix = '.'.join(recipes)+'.'
for f in glob.glob(os.path.join(CALIBRESRC, *(recipes+['*.py']))):
temp.append(prefix + os.path.basename(f).partition('.')[0])
hook = '/tmp/hook-calibre.py'
open(hook, 'wb').write('hiddenimports = %%s'%%repr(temp) + '\\n')
sys.path.insert(0, CALIBRESRC)
from calibre.linux import entry_points
executables, scripts = ['calibre_postinstall', 'parallel'], \
[os.path.join(CALIBRESRC, 'calibre', 'linux.py'), os.path.join(CALIBRESRC, 'calibre', 'parallel.py')]
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')
recipes = Analysis(glob.glob(os.path.join(CALIBRESRC, 'calibre', 'web', 'feeds', 'recipes', '*.py')),
pathex=[CALIBRESRC], hookspath=[os.path.dirname(hook)], excludes=excludes)
analyses = [Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), loader, script],
pathex=[PYINSTALLER, CALIBRESRC, CALIBREPLUGINS], excludes=excludes) for script in scripts]
pyz = TOC()
binaries = TOC()
for a in analyses:
pyz = a.pure + pyz
binaries = a.binaries + binaries
pyz = PYZ(pyz + recipes.pure, name='library.pyz')
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))
print 'Adding plugins...'
for f in glob.glob(os.path.join(CALIBREPLUGINS, '*.so')):
binaries += [(os.path.basename(f), f, 'BINARY')]
print 'Adding external programs...'
binaries += [('clit', CLIT, 'BINARY'), ('pdftohtml', PDFTOHTML, 'BINARY'),
('libunrar.so', LIBUNRAR, 'BINARY')]
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 = []
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
f = os.path.join(dirpath, f)
plugins.append(('plugins/'+f.replace(plugdir, ''), f, 'BINARY'))
binaries += plugins
manifest = '/tmp/manifest'
open(manifest, 'wb').write('\\n'.join(executables))
from calibre import __version__
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'))
os.chdir(os.path.join(HOMEPATH, 'calibre', 'dist'))
for folder in EXTRAS:
subprocess.check_call('cp -rf %%s .'%%folder, shell=True)
print 'Building tarball...'
tf = tarfile.open('%(tarfile)s', 'w:bz2')
for f in os.listdir('.'):
tf.add(f)
"""%dict(home='/mnt/hgfs/giskard/', tarfile=tbz2, project=PROJECT)
os.chdir(os.path.expanduser('~/build/pyinstaller'))
open('calibre/calibre.spec', 'wb').write(SPEC)
try:
subprocess.check_call(('/usr/bin/python', '-O', 'Build.py', 'calibre/calibre.spec'))
finally:
os.chdir(cwd)
return os.path.basename(tbz2)
def build_linux(): def build_linux():
installer = installer_name('tar.bz2')
vm = '/vmware/linux/libprs500-gentoo.vmx' vm = '/vmware/linux/libprs500-gentoo.vmx'
vmware = ('vmware', '-q', '-x', '-n', vm) start_vm(vm, 'linux', BUILD_SCRIPT%('sudo python setup.py develop', 'python','linux_installer.py'))
subprocess.Popen(vmware) subprocess.check_call(('scp', 'linux:/tmp/%s'%os.path.basename(installer), 'dist'))
print 'Waiting for linux to boot up...' if not os.path.exists(installer):
time.sleep(75) raise Exception('Failed to build installer '+installer)
check_call('ssh linux make -C /mnt/hgfs/giskard/work/%s all egg linux_binary'%PROJECT) subprocess.Popen(('ssh', 'linux', 'sudo', '/sbin/poweroff'))
check_call('ssh linux sudo poweroff') return os.path.basename(installer)
def build_installers(): def build_installers():
return build_linux(), build_windows(), build_osx() return build_linux(), build_windows(), build_osx()
@ -267,18 +140,14 @@ def upload_user_manual():
finally: finally:
os.chdir(cwd) os.chdir(cwd)
def build_tarball(): def build_src_tarball():
cwd = os.getcwd()
check_call('bzr export dist/calibre-%s.tar.bz2'%__version__) check_call('bzr export dist/calibre-%s.tar.bz2'%__version__)
def upload_tarball(): def upload_src_tarball():
check_call('ssh divok rm -f %s/calibre-\*.tar.bz2'%DOWNLOADS) check_call('ssh divok rm -f %s/calibre-\*.tar.bz2'%DOWNLOADS)
check_call('scp dist/calibre-*.tar.bz2 divok:%s/'%DOWNLOADS) check_call('scp dist/calibre-*.tar.bz2 divok:%s/'%DOWNLOADS)
def stage_one():
def main():
upload = len(sys.argv) < 2
shutil.rmtree('build') shutil.rmtree('build')
os.mkdir('build') os.mkdir('build')
shutil.rmtree('docs') shutil.rmtree('docs')
@ -288,17 +157,32 @@ def main():
check_call('make', shell=True) check_call('make', shell=True)
tag_release() tag_release()
upload_demo() upload_demo()
def stage_two():
subprocess.check_call('rm -rf dist/*', shell=True)
build_installers() build_installers()
build_tarball() build_src_tarball()
if upload:
def stage_three():
print 'Uploading installers...' print 'Uploading installers...'
upload_installers() upload_installers()
print 'Uploading to PyPI' print 'Uploading to PyPI'
upload_tarball() upload_src_tarball()
upload_docs() upload_docs()
upload_user_manual() upload_user_manual()
check_call('python setup.py register bdist_egg --exclude-source-files upload') check_call('python setup.py register bdist_egg --exclude-source-files upload')
check_call('''rm -rf dist/* build/*''') check_call('''rm -rf dist/* build/*''')
def main(args=sys.argv):
print 'Starting stage one...'
stage_one()
print 'Starting stage two...'
stage_two()
print 'Starting stage three...'
stage_three()
print 'Finished'
return 0
if __name__ == '__main__': if __name__ == '__main__':
main() sys.exit(main())