Source code for sas.sasview.installer_generator

"""
This module generates .iss file according to the local config of
the current application. Please make sure a file named "local_config.py"
exists in the current directory. Edit local_config.py according to your needs.
"""
import local_config
import os 
import string

REG_PROGRAM = """{app}\MYPROG.EXE"" ""%1"""
APPLICATION = str(local_config.__appname__ )+ '.exe'
AppName = str(local_config.__appname__ )
AppVerName = str(local_config.__appname__ )+'-'+ str(local_config.__version__)
Dev = ''
if AppVerName.lower().count('dev') > 0:
    Dev = '-Dev'
AppPublisher = local_config._copyright
AppPublisherURL = local_config._homepage
AppSupportURL = local_config._homepage
AppUpdatesURL = local_config._homepage
ChangesEnvironment = 'true'
DefaultDirName = os.path.join("{pf}" , AppName+Dev) 
DefaultGroupName = os.path.join(local_config.DefaultGroupName, AppVerName)
                                
OutputBaseFilename = local_config.OutputBaseFilename
SetupIconFile = "images\\ball.ico"
LicenseFile = 'license.txt'
DisableProgramGroupPage = 'yes'
Compression = 'lzma'
SolidCompression = 'yes'
PrivilegesRequired = 'none'
INSTALLER_FILE = 'installer'

icon_path =  local_config.icon_path
media_path = local_config.media_path
test_path = local_config.test_path

[docs]def find_extension(): """ Describe the extensions that can be read by the current application """ list_data = [] list_app =[] try: #(ext, type, name, flags) from sas.dataloader.loader import Loader wild_cards = Loader().get_wildcards() for item in wild_cards: #['All (*.*)|*.*'] file_type, ext = string.split(item, "|*", 1) if ext.strip() not in ['.*', ''] and ext.strip() not in list_data: list_data.append((ext, 'string', file_type)) except: pass try: file_type, ext = string.split(local_config.APPLICATION_WLIST, "|*", 1) if ext.strip() not in ['.', ''] and ext.strip() not in list_app: list_app.append((ext, 'string', file_type)) except: pass try: for item in local_config.PLUGINS_WLIST: file_type, ext = string.split(item, "|*", 1) if ext.strip() not in ['.', ''] and ext.strip() not in list_app: list_app.append((ext, 'string', file_type)) except: pass return list_data, list_app
DATA_EXTENSION, APP_EXTENSION = find_extension()
[docs]def write_registry(data_extension=None, app_extension=None): """ create file association for windows. Allow open file on double click """ msg = "" if data_extension is not None and data_extension: openwithlist = "OpenWithList\%s" % str(APPLICATION) msg = "\n\n[Registry]\n" for (ext, type, _) in data_extension: list = os.path.join(ext, openwithlist) msg += """Root: HKCR;\tSubkey: "%s";\t""" % str(list) msg += """ Flags: %s""" % str('uninsdeletekey noerror') msg += "\n" #list the file on right-click msg += """Root: HKCR; Subkey: "applications\%s\shell\open\command";\t"""\ % str(APPLICATION) msg += """ValueType: %s; """ % str('string') msg += """ValueName: "%s";\t""" %str('') msg += """ValueData: \"""{app}\%s"" ""%s1\"""; \t"""% (str(APPLICATION), str('%')) msg += """ Flags: %s""" % str('uninsdeletevalue noerror') msg += "\n" user_list = "Software\Classes" for (ext, type, _) in data_extension: list = os.path.join(user_list, ext, openwithlist) msg += """Root: HKCU;\tSubkey: "%s";\t""" % str(list) msg += """ Flags: %s""" % str('uninsdeletekey noerror') msg += "\n" #list the file on right-click user_list = os.path.join("Software", "Classes", "applications") msg += """Root: HKCU; Subkey: "%s\%s\shell\open\command";\t"""\ % (str(user_list), str(APPLICATION)) msg += """ValueType: %s; """ % str('string') msg += """ValueName: "%s";\t""" %str('') msg += """ValueData: \"""{app}\%s"" ""%s1\"""; \t"""% (str(APPLICATION), str('%')) msg += """ Flags: %s""" % str('uninsdeletevalue noerror') msg += "\n" if app_extension is not None and app_extension: for (ext, type, _) in app_extension: msg += """Root: HKCR;\tSubkey: "%s";\t""" % str(ext) msg += """ValueType: %s;\t""" % str(type) #file type empty set the current application as the default #reader for this file. change the value of file_type to another #string modify the default reader file_type = '' msg += """ValueName: "%s";\t""" % str('') msg += """ValueData: "{app}\%s";\t""" % str(APPLICATION) msg += """ Flags: %s""" % str('uninsdeletevalue noerror') msg += "\n" msg += """Root: HKCR; Subkey: "{app}\%s";\t""" % str(APPLICATION) msg += """ValueType: %s; """ % str('string') msg += """ValueName: "%s";\t""" % str('') msg += """ValueData: "{app}\%s";\t""" % str("SasView File") msg += """ Flags: %s \t""" % str("uninsdeletekey noerror") msg += "\n" #execute the file on double-click msg += """Root: HKCR; Subkey: "{app}\%s\shell\open\command";\t""" % str(APPLICATION) msg += """ValueType: %s; """ % str('string') msg += """ValueName: "%s";\t""" %str('') msg += """ValueData: \"""{app}\%s"" ""%s1\""";\t"""% (str(APPLICATION), str('%')) msg += """ Flags: %s \t""" % str("uninsdeletevalue noerror") msg += "\n" #create default icon msg += """Root: HKCR; Subkey: "{app}\%s";\t""" % str(SetupIconFile) msg += """ValueType: %s; """ % str('string') msg += """ValueName: "%s";\t""" % str('') msg += """ValueData: "{app}\%s,0";\t""" % str(APPLICATION) msg += """ Flags: %s \t""" % str("uninsdeletevalue noerror") msg += "\n" #SASVIEWPATH msg += """Root: HKLM; Subkey: "%s";\t""" % str('SYSTEM\CurrentControlSet\Control\Session Manager\Environment') msg += """ValueType: %s; """ % str('expandsz') msg += """ValueName: "%s";\t""" % str('SASVIEWPATH') msg += """ValueData: "{app}";\t""" msg += """ Flags: %s""" % str('uninsdeletevalue noerror') msg += "\n" #PATH msg += """; Write to PATH (below) is disabled; need more tests\n""" msg += """;Root: HKCU; Subkey: "%s";\t""" % str('Environment') msg += """ValueType: %s; """ % str('expandsz') msg += """ValueName: "%s";\t""" % str('PATH') msg += """ValueData: "%s;{olddata}";\t""" % str('%SASVIEWPATH%') msg += """ Check: %s""" % str('NeedsAddPath()') msg += "\n" return msg
[docs]def write_language(language=['english'], msfile="compiler:Default.isl"): """ define the language of the application """ msg = '' if language: msg = "\n\n[Languages]\n" for lang in language: msg += """Name: "%s";\tMessagesFile: "%s"\n""" % (str(lang), str(msfile)) return msg
[docs]def write_tasks(): """ create desktop icon """ msg = """\n\n[Tasks]\n""" msg += """Name: "desktopicon";\tDescription: "{cm:CreateDesktopIcon}";\t""" msg += """GroupDescription: "{cm:AdditionalIcons}";\tFlags: unchecked\n""" msg += """Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}";\t""" msg += """GroupDescription: "{cm:AdditionalIcons}";\n""" return msg
dist_path = "dist"
[docs]def write_file(): """ copy some data files """ msg = "\n\n[Files]\n" msg += """Source: "%s\%s";\t""" % (dist_path, str(APPLICATION)) msg += """DestDir: "{app}";\tFlags: ignoreversion\n""" msg += """Source: "dist\*";\tDestDir: "{app}";\t""" msg += """Flags: ignoreversion recursesubdirs createallsubdirs\n""" msg += """Source: "dist\plugin_models\*";\tDestDir: "{userdesktop}\..\.sasview\plugin_models";\t""" msg += """Flags: recursesubdirs createallsubdirs\n""" msg += """Source: "dist\config\custom_config.py";\tDestDir: "{userdesktop}\..\.sasview\config";\t""" msg += """Flags: recursesubdirs createallsubdirs\n""" msg += """Source: "dist\default_categories.json"; DestDir: "{userdesktop}\..\.sasview";\t""" msg += """DestName: "serialized_cat.json";\n""" msg += """;\tNOTE: Don't use "Flags: ignoreversion" on any shared system files""" return msg
[docs]def write_icon(): """ Create application icon """ msg = """\n\n[Icons]\n""" msg += """Name: "{group}\%s";\t""" % str(AppName) msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) msg += """WorkingDir: "{app}"; IconFilename: "{app}\images\\ball.ico" \n""" msg += """Name: "{group}\{cm:UninstallProgram, %s}";\t""" % str(AppName) msg += """ Filename: "{uninstallexe}" \n""" msg += """Name: "{commondesktop}\%s";\t""" % str(AppVerName) msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) msg += """Tasks: desktopicon; WorkingDir: "{app}" ; IconFilename: "{app}\images\\ball.ico" \n""" msg += """Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\%s";\t""" % str(AppVerName) msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) msg += """Tasks: quicklaunchicon; WorkingDir: "{app}"; IconFilename: "{app}\images\\ball.ico" \n""" return msg
[docs]def write_run(): """ execute some file """ msg = """\n\n[Run]\n""" msg += """Filename: "{app}\%s";\t""" % str(APPLICATION) msg += """Description: "{cm:LaunchProgram, %s}";\t""" %str(AppName) msg += """Flags: nowait postinstall skipifsilent\n""" msg += """; Install the Microsoft C++ DLL redistributable package if it is """ msg += """provided and the DLLs are not present on the target system.\n""" msg += """; Note that the redistributable package is included if the app was """ msg += """built using Python 2.6 or 2.7, but not with 2.5.\n""" msg += """; Parameter options:\n""" msg += """; - for silent install use: "/q"\n""" msg += """; - for silent install with progress bar use: "/qb"\n""" msg += """; - for silent install with progress bar but disallow """ msg += """cancellation of operation use: "/qb!"\n""" msg += """; Note that we do not use the postinstall flag as this would """ msg += """display a checkbox and thus require the user to decide what to do.\n""" msg += """;Filename: "{app}\\vcredist_x86.exe"; Parameters: "/qb!"; """ msg += """WorkingDir: "{tmp}"; StatusMsg: "Installing Microsoft Visual """ msg += """C++ 2008 Redistributable Package ..."; Check: InstallVC90CRT(); """ msg += """Flags: skipifdoesntexist waituntilterminated\n""" return msg
[docs]def write_dirs(): """ Define Dir permission """ msg = """\n\n[Dirs]\n""" msg += """Name: "{app}\%s";\t""" % str('') msg += """Permissions: everyone-modify\t""" msg += """\n""" return msg
[docs]def write_code(): """ Code that checks the existing path and snaviewpath in the environmental viriables/PATH """ msg = """\n\n[Code]\n""" msg += """function InstallVC90CRT(): Boolean;\n""" msg += """begin\n""" msg += """ Result := not DirExists('C:\WINDOWS\WinSxS\\x86_Microsoft.VC90.""" msg += """CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375');\n""" msg += """end;\n\n""" msg += """function NeedsAddPath(): boolean;\n""" msg += """var\n""" msg += """ oldpath: string;\n""" msg += """ newpath: string;\n""" msg += """ pathArr: TArrayOfString;\n""" msg += """ i: Integer;\n""" msg += """begin\n""" msg += """ RegQueryStringValue(HKEY_CURRENT_USER,'Environment',""" msg += """'PATH', oldpath)\n""" msg += """ oldpath := oldpath + ';';\n""" msg += """ newpath := '%SASVIEWPATH%';\n""" msg += """ i := 0;\n""" msg += """ while (Pos(';', oldpath) > 0) do begin\n""" msg += """ SetArrayLength(pathArr, i+1);\n""" msg += """ pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);\n""" msg += """ oldpath := Copy(oldpath, Pos(';', oldpath)+1,""" msg += """ Length(oldpath));\n""" msg += """ i := i + 1;\n""" msg += """ // Check if current directory matches app dir\n""" msg += """ if newpath = pathArr[i-1] \n""" msg += """ then begin\n""" msg += """ Result := False;\n""" msg += """ exit;\n""" msg += """ end;\n""" msg += """ end;\n""" msg += """ Result := True;\n""" msg += """end;\n""" msg += """\n""" return msg
[docs]def write_uninstalldelete(): """ Define uninstalldelete """ msg = """\n[UninstallDelete]\n""" msg += """; Delete directories and files that are dynamically created by """ msg += """the application (i.e. at runtime).\n""" msg += """Type: filesandordirs; Name: "{app}\.matplotlib"\n""" msg += """Type: files; Name: "{app}\*.*"\n""" msg += """; The following is a workaround for the case where the """ msg += """application is installed and uninstalled but the\n""" msg += """;{app} directory is not deleted because it has user files. """ msg += """Then the application is installed into the\n""" msg += """; existing directory, user files are deleted, and the """ msg += """application is un-installed again. Without the\n""" msg += """; directive below, {app} will not be deleted because Inno Setup """ msg += """did not create it during the previous\n""" msg += """; installation.\n""" msg += """Type: dirifempty; Name: "{app}"\n""" msg += """\n""" return msg
[docs]def generate_installer(): """ """ TEMPLATE = "\n; Script generated by the Inno Setup Script Wizard\n" TEMPLATE += "\n; and local_config.py located in this directory.\n " TEMPLATE += "; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!" TEMPLATE += "\n[Setup]\n\n" TEMPLATE += "ChangesAssociations=%s\n" %str('yes') TEMPLATE += "AppName=%s\n" % str(AppName) TEMPLATE += "AppVerName=%s\n" % str(AppVerName) TEMPLATE += "AppPublisher=%s\n" % str(AppPublisher) TEMPLATE += "AppPublisherURL=%s\n" % str(AppPublisherURL) TEMPLATE += "AppSupportURL=%s\n" % str(AppSupportURL) TEMPLATE += "AppUpdatesURL=%s \n" % str(AppUpdatesURL) TEMPLATE += "ChangesEnvironment=%s \n" % str(ChangesEnvironment) TEMPLATE += "DefaultDirName=%s\n" % str(DefaultDirName) TEMPLATE += "DefaultGroupName=%s\n" % str(DefaultGroupName) TEMPLATE += "DisableProgramGroupPage=%s\n" % str(DisableProgramGroupPage) TEMPLATE += "LicenseFile=%s\n" % str(LicenseFile) TEMPLATE += "OutputBaseFilename=%s\n" % str(OutputBaseFilename) TEMPLATE += "SetupIconFile=%s\n" % str(SetupIconFile) TEMPLATE += "Compression=%s\n" % str(Compression) TEMPLATE += "SolidCompression=%s\n" % str(SolidCompression) TEMPLATE += "PrivilegesRequired=%s\n" % str(PrivilegesRequired) TEMPLATE += "UsePreviousAppDir=no\n" TEMPLATE += write_registry(data_extension=DATA_EXTENSION, app_extension=APP_EXTENSION) TEMPLATE += write_language() TEMPLATE += write_tasks() TEMPLATE += write_file() TEMPLATE += write_icon() TEMPLATE += write_run() TEMPLATE += write_dirs() TEMPLATE += write_code() TEMPLATE += write_uninstalldelete() path = '%s.iss' % str(INSTALLER_FILE) f = open(path,'w') f.write(TEMPLATE) f.close() print "Generate Inno setup installer script complete" print "A new file %s.iss should be created.Please refresh your directory" % str(INSTALLER_FILE)
if __name__ == "__main__": generate_installer()