2023-11-13 19:21:35 +05:30

124 lines
4.9 KiB
Python

#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
from itertools import count
import os
import shutil
from bypy.constants import is64bit
from bypy.utils import run
WIX = os.path.expanduser('~/.dotnet/tools/wix.exe')
if is64bit:
UPGRADE_CODE = '5DD881FF-756B-4097-9D82-8C0F11D521EA'
else:
UPGRADE_CODE = 'BEB2A80D-E902-4DAD-ADF9-8BD2DA42CFE1'
calibre_constants = globals()['calibre_constants']
j, d, a, b = os.path.join, os.path.dirname, os.path.abspath, os.path.basename
def create_installer(env, compression_level='9'):
cl = int(compression_level)
if cl > 4:
dcl = 'high'
else:
dcl = {1: 'none', 2: 'low', 3: 'medium', 4: 'mszip'}[cl]
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'],
version=calibre_constants['version'],
upgrade_code=UPGRADE_CODE,
x64=' 64bit' 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'))
arch = 'x64' if is64bit else 'x86'
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')
run(WIX, 'extension', 'add', '-g', 'WixToolset.Util.wixext')
run(WIX, 'extension', 'add', '-g', 'WixToolset.UI.wixext')
cmd = [WIX, 'build', '-arch', arch, '-culture', 'en-us', '-loc', enusf, '-dcl', dcl,
'-ext', 'WixToolset.Util.wixext', '-ext', 'WixToolset.UI.wixext',
'-d', 'WixUILicenseRtf=' + license, '-d', 'WixUIBannerBmp=' + banner, '-d', 'WixUIDialogBmp=' + dialog,
'-o', installer, wxsf]
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