Added persistent user data and installer generator for windows.
This commit is contained in:
parent
57a2a2f3a0
commit
a6f8ab247c
5 changed files with 202 additions and 21 deletions
137
Web2Exe.nsi
Normal file
137
Web2Exe.nsi
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
; Script generated by the HM NIS Edit Script Wizard.
|
||||
|
||||
; HM NIS Edit Wizard helper defines
|
||||
!define PRODUCT_NAME "Web2Executable"
|
||||
!define PRODUCT_VERSION "0.2.4b"
|
||||
!define PRODUCT_PUBLISHER "SimplyPixelated"
|
||||
!define PRODUCT_WEB_SITE "http://www.simplypixelated.com"
|
||||
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${PRODUCT_NAME}.exe"
|
||||
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
|
||||
!define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir"
|
||||
|
||||
SetCompressor lzma
|
||||
|
||||
; MUI 1.67 compatible ------
|
||||
!include "MUI.nsh"
|
||||
|
||||
; MUI Settings
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
|
||||
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
|
||||
|
||||
; Welcome page
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
; License page
|
||||
!insertmacro MUI_PAGE_LICENSE "license.rtf"
|
||||
; Components page
|
||||
!insertmacro MUI_PAGE_COMPONENTS
|
||||
; Directory page
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
; Start menu page
|
||||
var ICONS_GROUP
|
||||
!define MUI_STARTMENUPAGE_NODISABLE
|
||||
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "${PRODUCT_NAME}"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}"
|
||||
!insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP
|
||||
; Instfiles page
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
; Finish page
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
; Uninstaller pages
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
; Language files
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
; Reserve files
|
||||
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
|
||||
|
||||
; MUI end ------
|
||||
|
||||
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
|
||||
OutFile "Web2Exe-Setup.exe"
|
||||
|
||||
RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on)
|
||||
|
||||
!include LogicLib.nsh
|
||||
|
||||
Function .onInit
|
||||
UserInfo::GetAccountType
|
||||
pop $0
|
||||
${If} $0 != "admin" ;Require admin rights on NT4+
|
||||
MessageBox mb_iconstop "Administrator rights required!"
|
||||
SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
|
||||
Quit
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
InstallDir "$PROGRAMFILES\${PRODUCT_NAME}"
|
||||
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
|
||||
ShowInstDetails show
|
||||
ShowUnInstDetails show
|
||||
|
||||
Section "Web2Executable" SEC01
|
||||
SectionIn RO
|
||||
SetOutPath "$INSTDIR"
|
||||
SetOverwrite try
|
||||
File /r "Web2ExeWin\"
|
||||
|
||||
; Shortcuts
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||
CreateDirectory "$SMPROGRAMS\$ICONS_GROUP"
|
||||
CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe"
|
||||
CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe"
|
||||
!insertmacro MUI_STARTMENU_WRITE_END
|
||||
SectionEnd
|
||||
|
||||
LangString DESC_SEC01 ${LANG_ENGLISH} "A tool to convert web applications to exe's."
|
||||
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC01} $(DESC_SEC01)
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
|
||||
Section -AdditionalIcons
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||
WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
|
||||
CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
|
||||
CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninst.exe"
|
||||
!insertmacro MUI_STARTMENU_WRITE_END
|
||||
SectionEnd
|
||||
|
||||
Section -Post
|
||||
WriteUninstaller "$INSTDIR\uninst.exe"
|
||||
WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\${PRODUCT_NAME}.exe"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_NAME}.exe"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
|
||||
WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
|
||||
SectionEnd
|
||||
|
||||
|
||||
Function un.onUninstSuccess
|
||||
HideWindow
|
||||
MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer."
|
||||
FunctionEnd
|
||||
|
||||
Function un.onInit
|
||||
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2
|
||||
Abort
|
||||
FunctionEnd
|
||||
|
||||
Section Uninstall
|
||||
RMDir /r "$INSTDIR"
|
||||
Delete "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk"
|
||||
Delete "$SMPROGRAMS\${PRODUCT_NAME}\Website.lnk"
|
||||
Delete "$DESKTOP\${PRODUCT_NAME}.lnk"
|
||||
Delete "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk"
|
||||
|
||||
DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
|
||||
DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
|
||||
SetAutoClose true
|
||||
SectionEnd
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
'''Command line module for web2exe.'''
|
||||
|
||||
__version__ = "v0.2.4b"
|
||||
|
||||
from utils import zip_files, join_files, log, get_temp_dir
|
||||
from pycns import save_icns
|
||||
from pepy.pe import PEFile
|
||||
|
||||
import argparse
|
||||
import urllib2
|
||||
import platform
|
||||
import re
|
||||
|
|
@ -23,6 +26,8 @@ import logging.handlers as lh
|
|||
import plistlib
|
||||
import codecs
|
||||
|
||||
from utils import get_data_path, get_data_file_path
|
||||
|
||||
from semantic_version import Version
|
||||
|
||||
from zipfile import ZipFile
|
||||
|
|
@ -45,15 +50,13 @@ def get_file(path):
|
|||
return independent_path
|
||||
|
||||
TEMP_DIR = get_temp_dir()
|
||||
DEFAULT_DOWNLOAD_PATH = os.path.join(CWD,
|
||||
'files',
|
||||
'downloads').replace('\\',
|
||||
'\\\\')
|
||||
DEFAULT_DOWNLOAD_PATH = get_data_path('files/downloads')
|
||||
|
||||
logger = logging.getLogger('W2E logger')
|
||||
LOG_FILENAME = os.path.join(CWD, 'files', 'error.log')
|
||||
LOG_FILENAME = get_data_file_path('files/error.log')
|
||||
if __name__ != '__main__':
|
||||
logging.basicConfig(
|
||||
filename=os.path.join(CWD, 'files', 'error.log'),
|
||||
filename=LOG_FILENAME,
|
||||
format=("%(levelname) -10s %(asctime)s %(module)s.py: "
|
||||
"%(lineno)s %(funcName)s - %(message)s"),
|
||||
level=logging.DEBUG
|
||||
|
|
@ -80,7 +83,7 @@ except:
|
|||
def get_base_url():
|
||||
url = None
|
||||
try:
|
||||
url = codecs.open(os.path.join(CWD, 'files', 'base_url.txt'), encoding='utf-8').read().strip()
|
||||
url = codecs.open(get_file('files', 'base_url.txt'), encoding='utf-8').read().strip()
|
||||
except (OSError, IOError):
|
||||
url = 'http://dl.node-webkit.org/v{}/'
|
||||
return url
|
||||
|
|
@ -283,8 +286,9 @@ class CommandBase(object):
|
|||
|
||||
def setup_nw_versions(self):
|
||||
nw_version = self.get_setting('nw_version')
|
||||
nw_version.values = []
|
||||
try:
|
||||
f = codecs.open(os.path.join(CWD, 'files', 'nw-versions.txt'), encoding='utf-8')
|
||||
f = codecs.open(get_data_file_path('files/nw-versions.txt'), encoding='utf-8')
|
||||
for line in f:
|
||||
nw_version.values.append(line.strip())
|
||||
f.close()
|
||||
|
|
@ -296,7 +300,7 @@ class CommandBase(object):
|
|||
return nw_version.values[:]
|
||||
|
||||
def get_settings(self):
|
||||
config_file = os.path.join(CWD, 'files', 'settings.cfg')
|
||||
config_file = get_file('files/settings.cfg')
|
||||
contents = codecs.open(config_file, encoding='utf-8').read()
|
||||
contents = contents.replace(u'{DEFAULT_DOWNLOAD_PATH}',
|
||||
DEFAULT_DOWNLOAD_PATH)
|
||||
|
|
@ -375,7 +379,7 @@ class CommandBase(object):
|
|||
nw_version.values = versions
|
||||
f = None
|
||||
try:
|
||||
f = codecs.open(os.path.join(CWD, 'files', 'nw-versions.txt'), 'w', encoding='utf-8')
|
||||
f = codecs.open(get_data_file_path('files/nw-versions.txt'), 'w', encoding='utf-8')
|
||||
for v in nw_version.values:
|
||||
f.write(v+os.linesep)
|
||||
f.close()
|
||||
|
|
@ -939,10 +943,16 @@ class CommandBase(object):
|
|||
os.remove(f_path)
|
||||
|
||||
|
||||
class ArgParser(argparse.ArgumentParser):
|
||||
def error(self, message):
|
||||
sys.stderr.write('error: {}\n'.format(message))
|
||||
self.print_help()
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description=('Command line interface '
|
||||
'to web2exe'),
|
||||
parser = ArgParser(description=('Command line interface '
|
||||
'to web2exe. {}'.format(__version__)),
|
||||
prog='web2execmd')
|
||||
command_base = CommandBase()
|
||||
command_base.init()
|
||||
|
|
@ -965,6 +975,7 @@ if __name__ == '__main__':
|
|||
help=('Loads the package.json '
|
||||
'file in the project directory. '
|
||||
'Ignores other command line arguments.'))
|
||||
parser.add_argument('--cmd-version', action='version', version='%(prog)s {}'.format(__version__))
|
||||
|
||||
for setting_group_dict in command_base.settings['setting_groups']:
|
||||
for setting_name, setting in setting_group_dict.items():
|
||||
|
|
@ -1014,7 +1025,7 @@ if __name__ == '__main__':
|
|||
)
|
||||
else:
|
||||
logging.basicConfig(
|
||||
filename=os.path.join(CWD, 'files', 'error.log'),
|
||||
filename=LOG_FILENAME,
|
||||
format=("%(levelname) -10s %(asctime)s %(module)s.py: "
|
||||
"%(lineno)s %(funcName)s - %(message)s"),
|
||||
level=logging.DEBUG
|
||||
|
|
|
|||
18
license.rtf
Normal file
18
license.rtf
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210
|
||||
{\fonttbl\f0\fnil\fcharset0 Verdana;}
|
||||
{\colortbl;\red255\green255\blue255;\red57\green57\blue57;\red255\green255\blue255;}
|
||||
\margl1440\margr1440\vieww10800\viewh8400\viewkind0
|
||||
\deftab720
|
||||
\pard\pardeftab720\sl400\sa291\qc
|
||||
|
||||
\f0\b\fs28 \cf2 \cb3 The MIT License (MIT)
|
||||
\b0\fs24 \
|
||||
\pard\pardeftab720\sl400\sa291
|
||||
|
||||
\b \cf2 Copyright (c)
|
||||
\b0 2015 SimplyPixelated\
|
||||
\pard\pardeftab720\sl400\sa291
|
||||
\cf2 Permission is hereby granted, free of charge, to any person obtaining a copy\uc0\u8232 of this software and associated documentation files (the "Software"), to deal\u8232 in the Software without restriction, including without limitation the rights\u8232 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\u8232 copies of the Software, and to permit persons to whom the Software is\u8232 furnished to do so, subject to the following conditions:\
|
||||
The above copyright notice and this permission notice shall be included in\uc0\u8232 all copies or substantial portions of the Software.\
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\
|
||||
}
|
||||
15
main.py
15
main.py
|
|
@ -1,7 +1,5 @@
|
|||
from utils import log, open_folder_in_explorer
|
||||
|
||||
__gui_version__ = "v0.2.3b"
|
||||
|
||||
import os
|
||||
import re
|
||||
import glob
|
||||
|
|
@ -16,6 +14,9 @@ from PySide.QtCore import QUrl, QFile, QIODevice, QCoreApplication
|
|||
|
||||
from pycns import pngs_from_icns
|
||||
from command_line import CommandBase, logger, get_file
|
||||
from command_line import __version__ as __gui_version__
|
||||
|
||||
from utils import get_data_path, get_data_file_path
|
||||
|
||||
MAX_RECENT = 10
|
||||
|
||||
|
|
@ -56,7 +57,7 @@ class MainWindow(QtGui.QMainWindow, CommandBase):
|
|||
|
||||
def load_recent_projects(self):
|
||||
files = []
|
||||
history_file = get_file('files/recent_files.txt')
|
||||
history_file = get_data_file_path('files/recent_files.txt')
|
||||
if not os.path.exists(history_file):
|
||||
return files
|
||||
with codecs.open(history_file, encoding='utf-8') as f:
|
||||
|
|
@ -69,7 +70,7 @@ class MainWindow(QtGui.QMainWindow, CommandBase):
|
|||
|
||||
def load_last_project_path(self):
|
||||
proj_path = ''
|
||||
proj_file = get_file('files/last_project_path.txt')
|
||||
proj_file = get_data_file_path('files/last_project_path.txt')
|
||||
if os.path.exists(proj_file):
|
||||
with codecs.open(proj_file, encoding='utf-8') as f:
|
||||
proj_path = f.read().strip()
|
||||
|
|
@ -80,12 +81,12 @@ class MainWindow(QtGui.QMainWindow, CommandBase):
|
|||
return proj_path
|
||||
|
||||
def save_project_path(self, path):
|
||||
proj_file = get_file('files/last_project_path.txt')
|
||||
proj_file = get_data_file_path('files/last_project_path.txt')
|
||||
with codecs.open(proj_file, 'w+', encoding='utf-8') as f:
|
||||
f.write(path)
|
||||
|
||||
def save_recent_project(self, proj):
|
||||
recent_file_path = get_file('files/recent_files.txt')
|
||||
recent_file_path = get_data_file_path('files/recent_files.txt')
|
||||
max_length = MAX_RECENT
|
||||
recent_files = []
|
||||
if os.path.exists(recent_file_path):
|
||||
|
|
@ -427,7 +428,7 @@ class MainWindow(QtGui.QMainWindow, CommandBase):
|
|||
|
||||
open_export_button = QtGui.QPushButton()
|
||||
open_export_button.setEnabled(False)
|
||||
open_export_button.setIcon(QtGui.QIcon(os.path.join('files', 'images', 'folder_open.png')))
|
||||
open_export_button.setIcon(QtGui.QIcon(get_file('files/images/folder_open.png')))
|
||||
open_export_button.setToolTip('Open Export Folder')
|
||||
open_export_button.setStatusTip('Open Export Folder')
|
||||
open_export_button.setMaximumWidth(30)
|
||||
|
|
|
|||
14
utils.py
14
utils.py
|
|
@ -2,6 +2,7 @@ from __future__ import print_function
|
|||
import os, zipfile, io, platform
|
||||
import sys, tempfile
|
||||
import subprocess
|
||||
from appdirs import AppDirs
|
||||
|
||||
#try:
|
||||
# import zlib
|
||||
|
|
@ -17,6 +18,19 @@ def is_windows():
|
|||
def get_temp_dir():
|
||||
return tempfile.gettempdir()
|
||||
|
||||
def get_data_path(dir_path):
|
||||
parts = dir_path.split('/')
|
||||
dirs = AppDirs('Web2Executable', 'Web2Executable')
|
||||
data_path = os.path.join(dirs.user_data_dir, *parts)
|
||||
if not os.path.exists(data_path):
|
||||
os.makedirs(data_path)
|
||||
return data_path
|
||||
|
||||
def get_data_file_path(file_path):
|
||||
parts = file_path.split('/')
|
||||
data_path = get_data_path('/'.join(parts[:-1]))
|
||||
return os.path.join(data_path, parts[-1])
|
||||
|
||||
def log(*args):
|
||||
if DEBUG:
|
||||
print(*args)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue