Switched from py2app to PyInstaller for Windows. Renamed version to version.txt, to avoid Windows namespace collision with version.dll.

This commit is contained in:
Micah Lee 2016-04-11 23:25:40 -07:00
parent 229603eb7d
commit ef5665b050
15 changed files with 73 additions and 187 deletions

View File

@ -83,14 +83,12 @@ These instructions include adding folders to the path in Windows. To do this, go
First, download and install the 32-bit (x86) version of Python 3.4.x from https://www.python.org/downloads/windows/. You need 3.4 instead of 3.5 because PyQt5 was built with 3.4. Add `C:\Python34` and `C:\Python34\Scripts` to the path. First, download and install the 32-bit (x86) version of Python 3.4.x from https://www.python.org/downloads/windows/. You need 3.4 instead of 3.5 because PyQt5 was built with 3.4. Add `C:\Python34` and `C:\Python34\Scripts` to the path.
Open a command prompt and install some dependencies with pip: `pip install flask stem py2exe` Open a command prompt and install some dependencies with pip: `pip3 install pyinstaller pypiwin32 flask stem`
Download and install Qt5 from https://www.qt.io/download-open-source/. I downloaded `qt-unified-windows-x86-2.0.2-2-online.exe`. There's no need to login to a Qt account during installation. Make sure you install the latest Qt 5.x. Download and install Qt5 from https://www.qt.io/download-open-source/. I downloaded `qt-unified-windows-x86-2.0.2-2-online.exe`. There's no need to login to a Qt account during installation. Make sure you install the latest Qt 5.x.
Download and install the latest PyQt5 for 32-bit Windows from https://www.riverbankcomputing.com/software/pyqt/download5. I downloaded `PyQt5-5.5.1-gpl-Py3.4-Qt5.5.1-x32.exe`. Download and install the latest PyQt5 for 32-bit Windows from https://www.riverbankcomputing.com/software/pyqt/download5. I downloaded `PyQt5-5.5.1-gpl-Py3.4-Qt5.5.1-x32.exe`.
Download and install the latest 32-bit pywin32 binary for Python 3.4 from http://sourceforge.net/projects/pywin32/. I downloaded `pywin32-220.win32-py3.4.exe`.
Download and install the [Microsoft Visual C++ 2008 Redistributable Package (x86)](http://www.microsoft.com/en-us/download/details.aspx?id=29). Download and install the [Microsoft Visual C++ 2008 Redistributable Package (x86)](http://www.microsoft.com/en-us/download/details.aspx?id=29).
If you want to build the installer: If you want to build the installer:

View File

@ -1,7 +1,7 @@
include LICENSE include LICENSE
include README.md include README.md
include BUILD.md include BUILD.md
include version include version.txt
include onionshare/index.html include onionshare/index.html
include onionshare/404.html include onionshare/404.html
include onionshare/strings.json include onionshare/strings.json

View File

@ -3,7 +3,7 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
cd $DIR cd $DIR
VERSION=`cat version` VERSION=`cat version.txt`
# clean up from last build # clean up from last build
rm -r deb_dist >/dev/null 2>&1 rm -r deb_dist >/dev/null 2>&1

View File

@ -1,5 +1,5 @@
REM use py2exe to builder a folder with onionshare.exe REM use PyInstaller to builder a folder with onionshare.exe
python setup.py py2exe pyinstaller install/pyinstaller.spec
REM sign onionshare.exe REM sign onionshare.exe
signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 dist\onionshare.exe signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 dist\onionshare.exe

View File

@ -9,7 +9,7 @@ rm -rf $ROOT/dist &>/dev/null 2>&1
# build the .app # build the .app
echo Building OnionShare.app echo Building OnionShare.app
pyinstaller install/pyinstaller-osx.spec pyinstaller install/pyinstaller.spec
if [ "$1" = "--sign" ]; then if [ "$1" = "--sign" ]; then
SIGNING_IDENTITY_APP="3rd Party Mac Developer Application: Micah Lee" SIGNING_IDENTITY_APP="3rd Party Mac Developer Application: Micah Lee"

View File

@ -3,7 +3,7 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
cd $DIR cd $DIR
VERSION=`cat version` VERSION=`cat version.txt`
# clean up from last build # clean up from last build
rm -r build dist >/dev/null 2>&1 rm -r build dist >/dev/null 2>&1

View File

@ -1,30 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
OnionShare | https://onionshare.org/
Copyright (C) 2016 Micah Lee <micah@micahflee.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import zipimport, os, inspect
original_cwd = os.getcwd()
new_cwd = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
os.chdir(new_cwd)
zi = zipimport.zipimporter('lib/python2.7/site-packages.zip')
onionshare = zi.load_module('onionshare')
onionshare.main(original_cwd)

View File

@ -1,22 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
OnionShare | https://onionshare.org/
Copyright (C) 2016 Micah Lee <micah@micahflee.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import onionshare_gui
onionshare_gui.main()

View File

@ -1,16 +1,19 @@
# -*- mode: python -*- # -*- mode: python -*-
import platform
system = platform.system()
block_cipher = None block_cipher = None
a = Analysis( a = Analysis(
['osx_scripts/onionshare-gui'], ['linux_scripts/onionshare-gui'],
pathex=['.'], pathex=['.'],
binaries=None, binaries=None,
datas=[ datas=[
('../images/*', 'images'), ('../images/*', 'images'),
('../locale/*', 'locale'), ('../locale/*', 'locale'),
('../onionshare/*.html', 'html'), ('../onionshare/*.html', 'html'),
('../version', '.') ('../version.txt', '.')
], ],
hiddenimports=[], hiddenimports=[],
hookspath=[], hookspath=[],
@ -28,11 +31,11 @@ exe = EXE(
pyz, pyz,
a.scripts, a.scripts,
exclude_binaries=True, exclude_binaries=True,
name='onionshare-gui', name='onionshare',
debug=False, debug=False,
strip=False, strip=False,
upx=True, upx=True,
console=False) console=True)
coll = COLLECT( coll = COLLECT(
exe, exe,
@ -41,8 +44,9 @@ coll = COLLECT(
a.datas, a.datas,
strip=False, strip=False,
upx=True, upx=True,
name='onionshare-gui') name='onionshare')
if system == 'Darwin':
app = BUNDLE( app = BUNDLE(
coll, coll,
name='OnionShare.app', name='OnionShare.app',
@ -50,4 +54,5 @@ app = BUNDLE(
bundle_identifier='com.micahflee.onionshare', bundle_identifier='com.micahflee.onionshare',
info_plist={ info_plist={
'NSHighResolutionCapable': 'True' 'NSHighResolutionCapable': 'True'
}) }
)

View File

@ -1,37 +0,0 @@
# -*- coding: utf-8 -*-
"""
OnionShare | https://onionshare.org/
Copyright (C) 2016 Micah Lee <micah@micahflee.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from __future__ import division
import os, subprocess, time, hashlib, platform, json, locale, socket
import argparse, queue, inspect, base64, random, functools, logging, ctypes
import hmac, shutil
import stem, stem.control, flask
from PyQt5 import QtCore, QtWidgets, QtGui
import onionshare, onionshare_gui
# Disable py2exe logging in Windows. Comment these if you need logs. See:
# http://www.py2exe.org/index.cgi/StderrLog
# http://stackoverflow.com/questions/20549843/py2exe-generate-log-file
import sys
f = open(os.devnull, 'w')
sys.stdout = f
sys.stderr = f
onionshare_gui.main()

View File

@ -30,30 +30,29 @@ def get_onionshare_dir():
""" """
Returns the OnionShare directory. Returns the OnionShare directory.
""" """
if get_platform() == 'Darwin': return os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
onionshare_dir = os.path.dirname(__file__)
else:
onionshare_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
return onionshare_dir
def get_osx_resource_path(filename): def get_pyinstaller_resource_path(filename):
""" """
Returns the path a resource file in a frozen PyInstall app Returns the path a resource file in a frozen PyInstall app
""" """
if get_platform() == 'Darwin':
# Resource path from frozen PyInstaller app # Resource path from frozen PyInstaller app
# https://pythonhosted.org/PyInstaller/#run-time-information # https://pythonhosted.org/PyInstaller/#run-time-information
p = get_platform()
if p == 'Darwin':
return os.path.join(os.path.join(os.path.dirname(sys._MEIPASS), 'Resources'), filename) return os.path.join(os.path.join(os.path.dirname(sys._MEIPASS), 'Resources'), filename)
elif p == 'Windows':
return os.path.join(sys._MEIPASS, filename)
def get_html_path(filename): def get_html_path(filename):
""" """
Returns the path of the html files. Returns the path of the html files.
""" """
p = get_platform() p = get_platform()
if p == 'Darwin': if p == 'Darwin' or p == 'Windows':
prefix = get_osx_resource_path('html') prefix = get_pyinstaller_resource_path('html')
else: else:
prefix = get_onionshare_dir() prefix = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
return os.path.join(prefix, filename) return os.path.join(prefix, filename)
@ -63,11 +62,11 @@ def get_version():
""" """
p = get_platform() p = get_platform()
if p == 'Linux': if p == 'Linux':
version_filename = os.path.join(sys.prefix, 'share/onionshare/version') version_filename = os.path.join(sys.prefix, 'share/onionshare/version.txt')
elif p == 'Darwin': elif p == 'Darwin' or p == 'Windows':
version_filename = get_osx_resource_path('version') version_filename = get_pyinstaller_resource_path('version.txt')
else: else:
version_filename = os.path.join(os.path.dirname(get_onionshare_dir()), 'version') return None
return open(version_filename).read().strip() return open(version_filename).read().strip()

View File

@ -35,10 +35,10 @@ def load_strings(default="en"):
# find locale dir # find locale dir
if p == 'Linux': if p == 'Linux':
locale_dir = os.path.join(sys.prefix, 'share/onionshare/locale') locale_dir = os.path.join(sys.prefix, 'share/onionshare/locale')
elif p == 'Darwin': elif p == 'Darwin' or p == 'Windows':
locale_dir = helpers.get_osx_resource_path('locale') locale_dir = helpers.get_pyinstaller_resource_path('locale')
else: else:
locale_dir = os.path.join(os.path.dirname(helpers.get_onionshare_dir()), 'locale') locale_dir = ''
# load all translations # load all translations
translations = {} translations = {}

View File

@ -43,8 +43,8 @@ def get_image_path(filename):
p = helpers.get_platform() p = helpers.get_platform()
if p == 'Linux': if p == 'Linux':
prefix = os.path.join(sys.prefix, 'share/onionshare/images') prefix = os.path.join(sys.prefix, 'share/onionshare/images')
elif p == 'Darwin': elif p == 'Darwin' or p == 'Windows':
prefix = locale_dir = helpers.get_osx_resource_path('images') prefix = locale_dir = helpers.get_pyinstaller_resource_path('images')
else: else:
prefix = os.path.join(os.path.dirname(get_onionshare_gui_dir()), 'images') return None
return os.path.join(prefix, filename) return os.path.join(prefix, filename)

View File

@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import os, sys, platform import os, sys
try: try:
from setuptools import setup from setuptools import setup
@ -33,8 +33,7 @@ def file_list(path):
files.append(os.path.join(path, filename)) files.append(os.path.join(path, filename))
return files return files
system = platform.system() version = open('version.txt').read().strip()
version = open('version').read().strip()
description = ( description = (
"""OnionShare lets you securely and anonymously share a file of any size with someone. """ """OnionShare lets you securely and anonymously share a file of any size with someone. """
@ -72,7 +71,6 @@ locale = [
'locale/tr.json' 'locale/tr.json'
] ]
if system == 'Linux':
setup( setup(
name='onionshare', name='onionshare',
version=version, version=version,
@ -95,28 +93,3 @@ if system == 'Linux':
(os.path.join(sys.prefix, 'share/onionshare/locale'), locale) (os.path.join(sys.prefix, 'share/onionshare/locale'), locale)
] ]
) )
elif system == 'Windows':
import py2exe
setup(
name='OnionShare',
version=version,
description=description,
long_description=long_description,
data_files=[
('images', images),
('locale', locale),
('html', ['onionshare/index.html', 'onionshare/404.html']),
('', ['version', 'install/license.txt', 'install/onionshare.ico']),
('platforms', ['C:\\Python34\\Lib\\site-packages\\PyQt5\\plugins\\platforms\\qwindows.dll'])
],
windows=['install/windows_scripts/onionshare.py'],
options={
'py2exe': {
'includes': [
'PyQt5', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWidgets',
'jinja2', 'jinja2.ext', 'sip']
}
},
setup_requires=['py2exe', 'flask', 'stem'],
)