Preliminary msi support
Added a proper icon Fix output directory for packaged builds Added a button to open the ouput directory, and a button to open documentation for packaged builds.
This commit is contained in:
parent
91c7fdaf2d
commit
0de4a5857c
|
@ -3,4 +3,7 @@ dist
|
||||||
build
|
build
|
||||||
.idea
|
.idea
|
||||||
*.sfc
|
*.sfc
|
||||||
*_Spoiler.txt
|
*_Spoiler.txt
|
||||||
|
bundle/components.wxs
|
||||||
|
*.wixobj
|
||||||
|
README.html
|
||||||
|
|
41
Gui.py
41
Gui.py
|
@ -1,14 +1,18 @@
|
||||||
from Main import main, __version__ as ESVersion
|
from Main import main, __version__ as ESVersion, get_output_path
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
import random
|
import random
|
||||||
|
import subprocess
|
||||||
from tkinter import Checkbutton, OptionMenu, Tk, LEFT, RIGHT, BOTTOM, TOP, StringVar, IntVar, Frame, Label, W, E, Entry, Spinbox, Button, filedialog, messagebox
|
import os
|
||||||
|
import sys
|
||||||
|
from tkinter import Checkbutton, OptionMenu, Tk, LEFT, RIGHT, BOTTOM, TOP, StringVar, IntVar, Frame, Label, W, E, X, Entry, Spinbox, Button, filedialog, messagebox, PhotoImage
|
||||||
|
|
||||||
|
|
||||||
def guiMain(args=None):
|
def guiMain(args=None):
|
||||||
mainWindow = Tk()
|
mainWindow = Tk()
|
||||||
mainWindow.wm_title("Entrance Shuffle %s" % ESVersion)
|
mainWindow.wm_title("Entrance Shuffle %s" % ESVersion)
|
||||||
|
|
||||||
|
set_icon(mainWindow)
|
||||||
|
|
||||||
topFrame = Frame(mainWindow)
|
topFrame = Frame(mainWindow)
|
||||||
rightHalfFrame = Frame(topFrame)
|
rightHalfFrame = Frame(topFrame)
|
||||||
checkBoxFrame = Frame(rightHalfFrame)
|
checkBoxFrame = Frame(rightHalfFrame)
|
||||||
|
@ -164,6 +168,7 @@ def guiMain(args=None):
|
||||||
heartbeepFrame.pack(expand=True, anchor=E)
|
heartbeepFrame.pack(expand=True, anchor=E)
|
||||||
|
|
||||||
bottomFrame = Frame(mainWindow)
|
bottomFrame = Frame(mainWindow)
|
||||||
|
farBottomFrame = Frame(mainWindow)
|
||||||
|
|
||||||
seedLabel = Label(bottomFrame, text='Seed #')
|
seedLabel = Label(bottomFrame, text='Seed #')
|
||||||
seedVar = StringVar()
|
seedVar = StringVar()
|
||||||
|
@ -212,15 +217,29 @@ def guiMain(args=None):
|
||||||
|
|
||||||
generateButton = Button(bottomFrame, text='Generate Patched Rom', command=generateRom)
|
generateButton = Button(bottomFrame, text='Generate Patched Rom', command=generateRom)
|
||||||
|
|
||||||
|
def open_output():
|
||||||
|
open_file(get_output_path())
|
||||||
|
|
||||||
|
openOutputButton = Button(farBottomFrame, text='Open Output Directory', command=open_output)
|
||||||
|
|
||||||
|
if os.path.exists('README.html'):
|
||||||
|
def open_readme():
|
||||||
|
open_file('README.html')
|
||||||
|
openReadmeButton = Button(farBottomFrame, text='Open Documentation', command=open_readme)
|
||||||
|
openReadmeButton.pack(side=LEFT)
|
||||||
|
|
||||||
seedLabel.pack(side=LEFT)
|
seedLabel.pack(side=LEFT)
|
||||||
seedEntry.pack(side=LEFT)
|
seedEntry.pack(side=LEFT)
|
||||||
countLabel.pack(side=LEFT)
|
countLabel.pack(side=LEFT, padx=(5,0))
|
||||||
countSpinbox.pack(side=LEFT)
|
countSpinbox.pack(side=LEFT)
|
||||||
generateButton.pack(side=LEFT)
|
generateButton.pack(side=LEFT, padx=(5,0))
|
||||||
|
|
||||||
|
openOutputButton.pack(side=RIGHT)
|
||||||
|
|
||||||
drowDownFrame.pack(side=LEFT)
|
drowDownFrame.pack(side=LEFT)
|
||||||
rightHalfFrame.pack(side=RIGHT)
|
rightHalfFrame.pack(side=RIGHT)
|
||||||
topFrame.pack(side=TOP)
|
topFrame.pack(side=TOP)
|
||||||
|
farBottomFrame.pack(side=BOTTOM, fill=X, padx=5, pady=5)
|
||||||
bottomFrame.pack(side=BOTTOM)
|
bottomFrame.pack(side=BOTTOM)
|
||||||
|
|
||||||
if args is not None:
|
if args is not None:
|
||||||
|
@ -254,6 +273,18 @@ def guiMain(args=None):
|
||||||
|
|
||||||
mainWindow.mainloop()
|
mainWindow.mainloop()
|
||||||
|
|
||||||
|
def open_file(filename):
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
os.startfile(filename)
|
||||||
|
else:
|
||||||
|
open_Command = 'open' if sys.plaform == 'darwin' else 'xdg-open'
|
||||||
|
subprocess.call([open_command, filename])
|
||||||
|
|
||||||
|
def set_icon(window):
|
||||||
|
er16 = PhotoImage(file='data/ER16.gif')
|
||||||
|
er32 = PhotoImage(file='data/ER32.gif')
|
||||||
|
er48 = PhotoImage(file='data/ER32.gif')
|
||||||
|
window.tk.call('wm', 'iconphoto', window._w, er16, er32, er48)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
guiMain()
|
guiMain()
|
||||||
|
|
43
Main.py
43
Main.py
|
@ -12,6 +12,8 @@ import random
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
__version__ = '0.5.0-dev'
|
__version__ = '0.5.0-dev'
|
||||||
|
|
||||||
|
@ -105,16 +107,53 @@ def main(args, seed=None):
|
||||||
if args.jsonout:
|
if args.jsonout:
|
||||||
print(json.dumps({'patch': rom.patches, 'spoiler': world.spoiler.to_json()}))
|
print(json.dumps({'patch': rom.patches, 'spoiler': world.spoiler.to_json()}))
|
||||||
else:
|
else:
|
||||||
rom.write_to_file(args.jsonout or '%s.sfc' % outfilebase)
|
rom.write_to_file(args.jsonout or os.path.join(get_output_path(),'%s.sfc' % outfilebase))
|
||||||
|
|
||||||
if args.create_spoiler and not args.jsonout:
|
if args.create_spoiler and not args.jsonout:
|
||||||
world.spoiler.to_file('%s_Spoiler.txt' % outfilebase)
|
world.spoiler.to_file(os.path.join(get_output_path(),'%s_Spoiler.txt' % outfilebase))
|
||||||
|
|
||||||
logger.info('Done. Enjoy.')
|
logger.info('Done. Enjoy.')
|
||||||
logger.debug('Total Time: %s' % (time.clock() - start))
|
logger.debug('Total Time: %s' % (time.clock() - start))
|
||||||
|
|
||||||
return world
|
return world
|
||||||
|
|
||||||
|
def get_output_path():
|
||||||
|
if get_output_path.cached_path is not None:
|
||||||
|
return get_output_path.cached_path
|
||||||
|
|
||||||
|
if not hasattr(sys, 'frozen'):
|
||||||
|
get_output_path.cached_path = '.'
|
||||||
|
return get_output_path.cached_path
|
||||||
|
else:
|
||||||
|
# has been packaged, so cannot use CWD for output.
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
#windows
|
||||||
|
import ctypes.wintypes
|
||||||
|
CSIDL_PERSONAL = 5 # My Documents
|
||||||
|
SHGFP_TYPE_CURRENT = 0 # Get current, not default value
|
||||||
|
|
||||||
|
buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
|
||||||
|
ctypes.windll.shell32.SHGetFolderPathW(None, CSIDL_PERSONAL, None, SHGFP_TYPE_CURRENT, buf)
|
||||||
|
|
||||||
|
documents = buf.value
|
||||||
|
|
||||||
|
elif sys.platform == 'darwin':
|
||||||
|
from AppKit import NSSearchPathForDirectoriesInDomains
|
||||||
|
# http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains
|
||||||
|
NSDocumentDirectory = 9
|
||||||
|
NSUserDomainMask = 1
|
||||||
|
# True for expanding the tilde into a fully qualified path
|
||||||
|
documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, True)[0]
|
||||||
|
else:
|
||||||
|
raise NotImplementedError('Not supported yet')
|
||||||
|
|
||||||
|
get_output_path.cached_path = os.path.join(documents, 'ALttPEntranceRandomizer')
|
||||||
|
if not os.path.exists(get_output_path.cached_path):
|
||||||
|
os.mkdir(get_output_path.cached_path)
|
||||||
|
return get_output_path.cached_path
|
||||||
|
|
||||||
|
get_output_path.cached_path = None
|
||||||
|
|
||||||
def copy_world(world):
|
def copy_world(world):
|
||||||
# ToDo: Not good yet
|
# ToDo: Not good yet
|
||||||
ret = World(world.shuffle, world.logic, world.mode, world.difficulty, world.timer, world.progressive, world.goal, world.algorithm, world.place_dungeon_items, world.check_beatable_only, world.shuffle_ganon, world.quickswap, world.fastmenu, world.disable_music, world.keysanity)
|
ret = World(world.shuffle, world.logic, world.mode, world.difficulty, world.timer, world.progressive, world.goal, world.algorithm, world.place_dungeon_items, world.check_beatable_only, world.shuffle_ganon, world.quickswap, world.fastmenu, world.disable_music, world.keysanity)
|
||||||
|
|
10
appveyor.yml
10
appveyor.yml
|
@ -11,22 +11,24 @@ install:
|
||||||
- '%PYTHON%\Scripts\pip install pyinstaller'
|
- '%PYTHON%\Scripts\pip install pyinstaller'
|
||||||
- '%PYTHON%\Scripts\pip install markdown'
|
- '%PYTHON%\Scripts\pip install markdown'
|
||||||
- '%PYTHON%\python.exe -m markdown README.md > README.html'
|
- '%PYTHON%\python.exe -m markdown README.md > README.html'
|
||||||
- 'copy LICENSE LICENSE.txt'
|
|
||||||
- '%PYTHON%\Scripts\pyinstaller bundle\EntranceRandomizer.spec'
|
- '%PYTHON%\Scripts\pyinstaller bundle\EntranceRandomizer.spec'
|
||||||
- 'mkdir dist\EntranceRandomizer\ext'
|
- 'mkdir dist\EntranceRandomizer\ext'
|
||||||
- 'move dist\EntranceRandomizer\*.pyd dist\EntranceRandomizer\ext'
|
- 'move dist\EntranceRandomizer\*.pyd dist\EntranceRandomizer\ext'
|
||||||
- 'move dist\EntranceRandomizer\tcl*.dll dist\EntranceRandomizer\ext'
|
- 'move dist\EntranceRandomizer\tcl*.dll dist\EntranceRandomizer\ext'
|
||||||
- 'move dist\EntranceRandomizer\tk*.dll dist\EntranceRandomizer\ext'
|
- 'move dist\EntranceRandomizer\tk*.dll dist\EntranceRandomizer\ext'
|
||||||
|
- '"%WIX%\bin\heat.exe" dir "dist\EntranceRandomizer" -sfrag -srd -suid -dr INSTALLDIR -cg ERFiles -ag -template fragment -t bundle\components.xslt -out build\components.wxs'
|
||||||
|
- '"%WIX%\bin\candle.exe" -out build\ bundle\*.wxs build\*.wxs'
|
||||||
|
- '"%WIX%\bin\light.exe" -ext WixUIExtension build\*.wixobj -o dist\EntranceRandomizer.msi -b dist\EntranceRandomizer'
|
||||||
build: off
|
build: off
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: dist/EntranceRandomizer/
|
- path: dist/EntranceRandomizer.msi
|
||||||
name: EntranceRandomizer-$(ProjectVersion)-win32
|
name: EntranceRandomizer-$(ProjectVersion)-win32.msi
|
||||||
deploy:
|
deploy:
|
||||||
- provider: GitHub
|
- provider: GitHub
|
||||||
tag: $(APPVEYOR_REPO_TAG_NAME)
|
tag: $(APPVEYOR_REPO_TAG_NAME)
|
||||||
auth_token:
|
auth_token:
|
||||||
secure: wQH+KnogyjYcDdo/srOQeoYEVIbH1uoYA5Iajdy/sR0Tbme7gOt15u2FBIkTg9/x
|
secure: wQH+KnogyjYcDdo/srOQeoYEVIbH1uoYA5Iajdy/sR0Tbme7gOt15u2FBIkTg9/x
|
||||||
artifact: /.*-win32.zip/
|
artifact: /.*-win32.*/
|
||||||
force_update: false
|
force_update: false
|
||||||
on:
|
on:
|
||||||
appveyor_repo_tag: true
|
appveyor_repo_tag: true
|
||||||
|
|
|
@ -6,7 +6,7 @@ block_cipher = None
|
||||||
a = Analysis(['../EntranceRandomizer.py'],
|
a = Analysis(['../EntranceRandomizer.py'],
|
||||||
pathex=['bundle'],
|
pathex=['bundle'],
|
||||||
binaries=[],
|
binaries=[],
|
||||||
datas=[('../data/', 'data/'), ('../README.html', '.'), ('../LICENSE.txt', '.')],
|
datas=[('../data/', 'data/'), ('../README.html', '.')],
|
||||||
hiddenimports=[],
|
hiddenimports=[],
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
runtime_hooks=['bundle/_rt_hook.py'],
|
runtime_hooks=['bundle/_rt_hook.py'],
|
||||||
|
@ -24,6 +24,7 @@ exe = EXE(pyz,
|
||||||
debug=False,
|
debug=False,
|
||||||
strip=False,
|
strip=False,
|
||||||
upx=False,
|
upx=False,
|
||||||
|
icon='data/ER.ico',
|
||||||
console=is_win )
|
console=is_win )
|
||||||
coll = COLLECT(exe,
|
coll = COLLECT(exe,
|
||||||
a.binaries,
|
a.binaries,
|
||||||
|
@ -34,5 +35,5 @@ coll = COLLECT(exe,
|
||||||
name='EntranceRandomizer')
|
name='EntranceRandomizer')
|
||||||
app = BUNDLE(coll,
|
app = BUNDLE(coll,
|
||||||
name ='EntranceRandomizer.app',
|
name ='EntranceRandomizer.app',
|
||||||
icon = None,
|
icon = 'data/ER.icns',
|
||||||
bundle_identifier = None)
|
bundle_identifier = None)
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<xsl:stylesheet version="1.0"
|
||||||
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||||
|
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
|
||||||
|
exclude-result-prefixes="msxsl"
|
||||||
|
xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">
|
||||||
|
|
||||||
|
<xsl:output method="xml" indent="no"/>
|
||||||
|
|
||||||
|
<xsl:strip-space elements="*"/>
|
||||||
|
|
||||||
|
<xsl:template match="@*|node()">
|
||||||
|
<xsl:copy>
|
||||||
|
<xsl:apply-templates select="@*|node()"/>
|
||||||
|
</xsl:copy>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="wix:File[@Source='SourceDir\EntranceRandomizer.exe']">
|
||||||
|
<xsl:copy-of select="." />
|
||||||
|
<wix:Shortcut Id="ProgramShortcut"
|
||||||
|
Name="ALttP Entrance Randomizer"
|
||||||
|
Advertise="yes"
|
||||||
|
Description="ALttP Entrance Randomizer"
|
||||||
|
Directory="ApplicationProgramsFolder" />
|
||||||
|
</xsl:template>
|
||||||
|
<xsl:template match="wix:File[@Source='SourceDir\README.hmtl']">
|
||||||
|
<xsl:copy-of select="." />
|
||||||
|
<wix:Shortcut Id="ReadmeShortcut"
|
||||||
|
Name="ALttP Entrance Randomizer README"
|
||||||
|
Advertise="yes"
|
||||||
|
Description="ALttP Entrance Randomizer README"
|
||||||
|
Directory="ApplicationProgramsFolder" />
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||||
|
<Product Id="*" Name="ALttP Entrance Randomizer" Language="1033" Version="0.5.0" Manufacturer="Randomizer Community" UpgradeCode="0229C621-5F8A-4D59-962A-5826C58B93DD" >
|
||||||
|
<Package Id="*" InstallerVersion="400" Compressed="yes" InstallScope="perMachine" />
|
||||||
|
<MajorUpgrade AllowDowngrades="yes"/>
|
||||||
|
<Media Id="1" Cabinet="contents.cab" EmbedCab="yes" CompressionLevel="high"/>
|
||||||
|
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||||
|
<Directory Id='ProgramFilesFolder' Name='PFiles'>
|
||||||
|
<Directory Id='INSTALLDIR' Name='ALttP Entrance Randomizer'/>
|
||||||
|
</Directory>
|
||||||
|
<Directory Id="ProgramMenuFolder">
|
||||||
|
<Directory Id="ApplicationProgramsFolder" Name="ALttP Entrance Randomizer"/>
|
||||||
|
</Directory>
|
||||||
|
</Directory>
|
||||||
|
<DirectoryRef Id="ApplicationProgramsFolder">
|
||||||
|
<Component Id="ApplicationShortcut" Guid="0054698A-5A56-4B36-8176-8FEC1762EF2D">
|
||||||
|
<RemoveFolder Id="CleanUpShortCut" Directory="ApplicationProgramsFolder" On="uninstall"/>
|
||||||
|
<RegistryValue Root="HKCU" Key="Software\ALttPEntranceRandomizer" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
|
||||||
|
</Component>
|
||||||
|
</DirectoryRef>
|
||||||
|
<Feature Id="Complete"
|
||||||
|
Title="ALttP Entrance Randomizer"
|
||||||
|
Description="ALttP Entrance Randomizer"
|
||||||
|
Level="1">
|
||||||
|
<ComponentGroupRef Id="ERFiles"/>
|
||||||
|
<ComponentRef Id="ApplicationShortcut"/>
|
||||||
|
</Feature>
|
||||||
|
|
||||||
|
<Icon Id="ER.ico" SourceFile="Data/ER.ico" />
|
||||||
|
<Property Id="DISABLEADVTSHORTCUTS" Secure="yes">1</Property>
|
||||||
|
<Property Id="ARPPRODUCTICON" Value="ER.ico" />
|
||||||
|
<Property Id="WIXUI_INSTALLDIR">INSTALLDIR</Property>
|
||||||
|
<UI>
|
||||||
|
<UIRef Id="WixUI_InstallDir" />
|
||||||
|
<UIRef Id="WixUI_ErrorProgressText" />
|
||||||
|
<!-- Skip license page -->
|
||||||
|
<Publish Dialog="WelcomeDlg"
|
||||||
|
Control="Next"
|
||||||
|
Event="NewDialog"
|
||||||
|
Value="InstallDirDlg"
|
||||||
|
Order="2">1</Publish>
|
||||||
|
<Publish Dialog="InstallDirDlg"
|
||||||
|
Control="Back"
|
||||||
|
Event="NewDialog"
|
||||||
|
Value="WelcomeDlg"
|
||||||
|
Order="2">1</Publish>
|
||||||
|
</UI>
|
||||||
|
</Product>
|
||||||
|
</Wix>
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
After Width: | Height: | Size: 123 B |
Binary file not shown.
After Width: | Height: | Size: 370 B |
Binary file not shown.
After Width: | Height: | Size: 882 B |
Loading…
Reference in New Issue