2019-07-25 01:30:54 -04:00

140 lines
5.7 KiB
Python

#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import (unicode_literals, division, absolute_import,
print_function)
from itertools import count
import os
import shutil
from bypy.constants import is64bit
from bypy.utils import run
WIXP = r'C:\Program Files (x86)\WiX Toolset v3.11'
if is64bit:
UPGRADE_CODE = '5DD881FF-756B-4097-9D82-8C0F11D521EA'
else:
UPGRADE_CODE = 'BEB2A80D-E902-4DAD-ADF9-8BD2DA42CFE1'
MINVERHUMAN = 'Windows 7'
calibre_constants = globals()['calibre_constants']
CANDLE = WIXP + r'\bin\candle.exe'
LIGHT = WIXP + r'\bin\light.exe'
j, d, a, b = os.path.join, os.path.dirname, os.path.abspath, os.path.basename
def create_installer(env):
if os.path.exists(env.installer_dir):
shutil.rmtree(env.installer_dir)
os.makedirs(env.installer_dir)
with open(j(d(__file__), 'wix-template.xml'), 'rb') as f:
template = f.read().decode('utf-8')
components, smap = get_components_from_files(env)
wxs = template.format(
app=calibre_constants['appname'],
appfolder='Calibre2' if is64bit else 'Calibre',
version=calibre_constants['version'],
upgrade_code=UPGRADE_CODE,
ProgramFilesFolder='ProgramFiles64Folder' if is64bit else 'ProgramFilesFolder',
x64=' 64bit' if is64bit else '',
minverhuman=MINVERHUMAN,
minver='601',
fix_wix='<Custom Action="OverwriteWixSetDefaultPerMachineFolder" After="WixSetDefaultPerMachineFolder" />' if is64bit else '',
compression='high',
app_components=components,
exe_map=smap,
main_icon=j(env.src_root, 'icons', 'library.ico'),
viewer_icon=j(env.src_root, 'icons', 'viewer.ico'),
editor_icon=j(env.src_root, 'icons', 'ebook-edit.ico'),
web_icon=j(env.src_root, 'icons', 'web.ico'),
)
with open(j(d(__file__), 'en-us.xml'), 'rb') as f:
template = f.read().decode('utf-8')
enus = template.format(app=calibre_constants['appname'])
enusf = j(env.installer_dir, 'en-us.wxl')
wxsf = j(env.installer_dir, calibre_constants['appname'] + '.wxs')
with open(wxsf, 'wb') as f:
f.write(wxs.encode('utf-8'))
with open(enusf, 'wb') as f:
f.write(enus.encode('utf-8'))
wixobj = j(env.installer_dir, calibre_constants['appname'] + '.wixobj')
arch = 'x64' if is64bit else 'x86'
cmd = [CANDLE, '-nologo', '-arch', arch, '-ext', 'WiXUtilExtension', '-o', wixobj, wxsf]
run(*cmd)
installer = j(env.dist, '%s%s-%s.msi' % (
calibre_constants['appname'], ('-64bit' if is64bit else ''), calibre_constants['version']))
license = j(env.src_root, 'LICENSE.rtf')
banner = j(env.src_root, 'icons', 'wix-banner.bmp')
dialog = j(env.src_root, 'icons', 'wix-dialog.bmp')
cmd = [LIGHT, '-nologo', '-ext', 'WixUIExtension',
'-cultures:en-us', '-loc', enusf, wixobj,
'-ext', 'WixUtilExtension',
'-o', installer,
'-dWixUILicenseRtf=' + license,
'-dWixUIBannerBmp=' + banner,
'-dWixUIDialogBmp=' + dialog]
cmd.extend([
'-sice:ICE60', # No language in dlls warning
'-sice:ICE61', # Allow upgrading with same version number
'-sice:ICE40', # Re-install mode overriden
'-sice:ICE69', # Shortcut components are part of a different feature than the files they point to
])
cmd.append('-sval') # Disable all checks since they fail when running under ssh
run(*cmd)
def get_components_from_files(env):
file_idc = count()
file_id_map = {}
def process_dir(path):
components = []
for x in os.listdir(path):
f = os.path.join(path, x)
file_id_map[f] = fid = next(file_idc)
if os.path.isdir(f):
components.append(
'<Directory Id="file_%s" FileSource="%s" Name="%s">' %
(file_id_map[f], f, x))
c = process_dir(f)
components.extend(c)
components.append('</Directory>')
else:
checksum = 'Checksum="yes"' if x.endswith('.exe') else ''
c = [
('<Component Id="component_%s" Feature="MainApplication" '
'Guid="*">') % (fid,),
('<File Id="file_%s" Source="%s" Name="%s" ReadOnly="yes" '
'KeyPath="yes" %s/>') %
(fid, f, x, checksum),
'</Component>'
]
if x.endswith('.exe') and not x.startswith('pdf'):
# Add the executable to app paths so that users can
# launch it from the run dialog even if it is not on
# the path. See http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx
c[-1:-1] = [
('<RegistryValue Root="HKLM" '
r'Key="SOFTWARE\Microsoft\Windows\CurrentVersion\App '
r'Paths\%s" Value="[#file_%d]" Type="string" />' % (x, fid)),
('<RegistryValue Root="HKLM" '
r'Key="SOFTWARE\Microsoft\Windows\CurrentVersion\App '
r'Paths\{0}" Name="Path" Value="[APPLICATIONFOLDER]" '
'Type="string" />'.format(x)),
]
components.append('\n'.join(c))
return components
components = process_dir(a(env.base))
smap = {}
for x in calibre_constants['basenames']['gui']:
smap[x] = 'file_%d' % file_id_map[a(j(env.base, x + '.exe'))]
return '\t\t\t\t' + '\n\t\t\t\t'.join(components), smap