From ef5665b050bb948f43d399efbc0fd33945949da7 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Mon, 11 Apr 2016 23:25:40 -0700 Subject: [PATCH] Switched from py2app to PyInstaller for Windows. Renamed version to version.txt, to avoid Windows namespace collision with version.dll. --- BUILD.md | 4 +- MANIFEST.in | 2 +- install/build_deb.sh | 2 +- install/build_exe.bat | 4 +- install/build_osx.sh | 2 +- install/build_rpm.sh | 2 +- install/osx_scripts/onionshare | 30 -------- install/osx_scripts/onionshare-gui | 22 ------ ...{pyinstaller-osx.spec => pyinstaller.spec} | 37 +++++---- install/windows_scripts/onionshare.py | 37 --------- onionshare/helpers.py | 31 ++++---- onionshare/strings.py | 6 +- onionshare_gui/common.py | 6 +- setup.py | 75 ++++++------------- version => version.txt | 0 15 files changed, 73 insertions(+), 187 deletions(-) delete mode 100755 install/osx_scripts/onionshare delete mode 100755 install/osx_scripts/onionshare-gui rename install/{pyinstaller-osx.spec => pyinstaller.spec} (50%) delete mode 100644 install/windows_scripts/onionshare.py rename version => version.txt (100%) diff --git a/BUILD.md b/BUILD.md index e33b975d..69b8905c 100644 --- a/BUILD.md +++ b/BUILD.md @@ -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. -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 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). If you want to build the installer: diff --git a/MANIFEST.in b/MANIFEST.in index 09f1cf04..c9326602 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,7 +1,7 @@ include LICENSE include README.md include BUILD.md -include version +include version.txt include onionshare/index.html include onionshare/404.html include onionshare/strings.json diff --git a/install/build_deb.sh b/install/build_deb.sh index cd4ec427..1c4678d8 100755 --- a/install/build_deb.sh +++ b/install/build_deb.sh @@ -3,7 +3,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" cd $DIR -VERSION=`cat version` +VERSION=`cat version.txt` # clean up from last build rm -r deb_dist >/dev/null 2>&1 diff --git a/install/build_exe.bat b/install/build_exe.bat index b68566f4..da8719e1 100644 --- a/install/build_exe.bat +++ b/install/build_exe.bat @@ -1,5 +1,5 @@ -REM use py2exe to builder a folder with onionshare.exe -python setup.py py2exe +REM use PyInstaller to builder a folder with onionshare.exe +pyinstaller install/pyinstaller.spec REM sign onionshare.exe signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 dist\onionshare.exe diff --git a/install/build_osx.sh b/install/build_osx.sh index 460dc11b..22d6cc4d 100755 --- a/install/build_osx.sh +++ b/install/build_osx.sh @@ -9,7 +9,7 @@ rm -rf $ROOT/dist &>/dev/null 2>&1 # build the .app echo Building OnionShare.app -pyinstaller install/pyinstaller-osx.spec +pyinstaller install/pyinstaller.spec if [ "$1" = "--sign" ]; then SIGNING_IDENTITY_APP="3rd Party Mac Developer Application: Micah Lee" diff --git a/install/build_rpm.sh b/install/build_rpm.sh index 954197b7..f00d4fdb 100755 --- a/install/build_rpm.sh +++ b/install/build_rpm.sh @@ -3,7 +3,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" cd $DIR -VERSION=`cat version` +VERSION=`cat version.txt` # clean up from last build rm -r build dist >/dev/null 2>&1 diff --git a/install/osx_scripts/onionshare b/install/osx_scripts/onionshare deleted file mode 100755 index dd13d198..00000000 --- a/install/osx_scripts/onionshare +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -OnionShare | https://onionshare.org/ - -Copyright (C) 2016 Micah Lee - -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 . -""" -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) diff --git a/install/osx_scripts/onionshare-gui b/install/osx_scripts/onionshare-gui deleted file mode 100755 index 6ccdd00b..00000000 --- a/install/osx_scripts/onionshare-gui +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -OnionShare | https://onionshare.org/ - -Copyright (C) 2016 Micah Lee - -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 . -""" -import onionshare_gui -onionshare_gui.main() diff --git a/install/pyinstaller-osx.spec b/install/pyinstaller.spec similarity index 50% rename from install/pyinstaller-osx.spec rename to install/pyinstaller.spec index 1cd75557..1dbec3b9 100644 --- a/install/pyinstaller-osx.spec +++ b/install/pyinstaller.spec @@ -1,16 +1,19 @@ # -*- mode: python -*- +import platform +system = platform.system() + block_cipher = None a = Analysis( - ['osx_scripts/onionshare-gui'], + ['linux_scripts/onionshare-gui'], pathex=['.'], binaries=None, datas=[ - ('../images/*', 'images'), - ('../locale/*', 'locale'), - ('../onionshare/*.html', 'html'), - ('../version', '.') + ('../images/*', 'images'), + ('../locale/*', 'locale'), + ('../onionshare/*.html', 'html'), + ('../version.txt', '.') ], hiddenimports=[], hookspath=[], @@ -28,11 +31,11 @@ exe = EXE( pyz, a.scripts, exclude_binaries=True, - name='onionshare-gui', + name='onionshare', debug=False, strip=False, upx=True, - console=False) + console=True) coll = COLLECT( exe, @@ -41,13 +44,15 @@ coll = COLLECT( a.datas, strip=False, upx=True, - name='onionshare-gui') + name='onionshare') -app = BUNDLE( - coll, - name='OnionShare.app', - icon='install/onionshare.icns', - bundle_identifier='com.micahflee.onionshare', - info_plist={ - 'NSHighResolutionCapable': 'True' - }) +if system == 'Darwin': + app = BUNDLE( + coll, + name='OnionShare.app', + icon='install/onionshare.icns', + bundle_identifier='com.micahflee.onionshare', + info_plist={ + 'NSHighResolutionCapable': 'True' + } + ) diff --git a/install/windows_scripts/onionshare.py b/install/windows_scripts/onionshare.py deleted file mode 100644 index 4d6f066e..00000000 --- a/install/windows_scripts/onionshare.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -""" -OnionShare | https://onionshare.org/ - -Copyright (C) 2016 Micah Lee - -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 . -""" -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() diff --git a/onionshare/helpers.py b/onionshare/helpers.py index cc89b6a5..cb77dd43 100644 --- a/onionshare/helpers.py +++ b/onionshare/helpers.py @@ -30,30 +30,29 @@ def get_onionshare_dir(): """ Returns the OnionShare directory. """ - if get_platform() == 'Darwin': - onionshare_dir = os.path.dirname(__file__) - else: - onionshare_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) - return onionshare_dir + return os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) -def get_osx_resource_path(filename): +def get_pyinstaller_resource_path(filename): """ Returns the path a resource file in a frozen PyInstall app """ - if get_platform() == 'Darwin': - # Resource path from frozen PyInstaller app - # https://pythonhosted.org/PyInstaller/#run-time-information + # Resource path from frozen PyInstaller app + # 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) + elif p == 'Windows': + return os.path.join(sys._MEIPASS, filename) def get_html_path(filename): """ Returns the path of the html files. """ p = get_platform() - if p == 'Darwin': - prefix = get_osx_resource_path('html') + if p == 'Darwin' or p == 'Windows': + prefix = get_pyinstaller_resource_path('html') else: - prefix = get_onionshare_dir() + prefix = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) return os.path.join(prefix, filename) @@ -63,11 +62,11 @@ def get_version(): """ p = get_platform() if p == 'Linux': - version_filename = os.path.join(sys.prefix, 'share/onionshare/version') - elif p == 'Darwin': - version_filename = get_osx_resource_path('version') + version_filename = os.path.join(sys.prefix, 'share/onionshare/version.txt') + elif p == 'Darwin' or p == 'Windows': + version_filename = get_pyinstaller_resource_path('version.txt') else: - version_filename = os.path.join(os.path.dirname(get_onionshare_dir()), 'version') + return None return open(version_filename).read().strip() diff --git a/onionshare/strings.py b/onionshare/strings.py index 50e5835f..71f0b79a 100644 --- a/onionshare/strings.py +++ b/onionshare/strings.py @@ -35,10 +35,10 @@ def load_strings(default="en"): # find locale dir if p == 'Linux': locale_dir = os.path.join(sys.prefix, 'share/onionshare/locale') - elif p == 'Darwin': - locale_dir = helpers.get_osx_resource_path('locale') + elif p == 'Darwin' or p == 'Windows': + locale_dir = helpers.get_pyinstaller_resource_path('locale') else: - locale_dir = os.path.join(os.path.dirname(helpers.get_onionshare_dir()), 'locale') + locale_dir = '' # load all translations translations = {} diff --git a/onionshare_gui/common.py b/onionshare_gui/common.py index 4b3c7cf7..6c531d9b 100644 --- a/onionshare_gui/common.py +++ b/onionshare_gui/common.py @@ -43,8 +43,8 @@ def get_image_path(filename): p = helpers.get_platform() if p == 'Linux': prefix = os.path.join(sys.prefix, 'share/onionshare/images') - elif p == 'Darwin': - prefix = locale_dir = helpers.get_osx_resource_path('images') + elif p == 'Darwin' or p == 'Windows': + prefix = locale_dir = helpers.get_pyinstaller_resource_path('images') else: - prefix = os.path.join(os.path.dirname(get_onionshare_gui_dir()), 'images') + return None return os.path.join(prefix, filename) diff --git a/setup.py b/setup.py index 3d59f5f1..414b060d 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -import os, sys, platform +import os, sys try: from setuptools import setup @@ -33,8 +33,7 @@ def file_list(path): files.append(os.path.join(path, filename)) return files -system = platform.system() -version = open('version').read().strip() +version = open('version.txt').read().strip() description = ( """OnionShare lets you securely and anonymously share a file of any size with someone. """ @@ -72,51 +71,25 @@ locale = [ 'locale/tr.json' ] -if system == 'Linux': - setup( - name='onionshare', - version=version, - description=description, - long_description=long_description, - author='Micah Lee', - author_email='micah@micahflee.com', - url='https://github.com/micahflee/onionshare', - license="GPL v3", - keywords='onion, share, onionshare, tor, anonymous, web server', - packages=['onionshare', 'onionshare_gui'], - include_package_data=True, - scripts=['install/linux_scripts/onionshare', 'install/linux_scripts/onionshare-gui'], - data_files=[ - (os.path.join(sys.prefix, 'share/applications'), ['install/onionshare.desktop']), - (os.path.join(sys.prefix, 'share/appdata'), ['install/onionshare.appdata.xml']), - (os.path.join(sys.prefix, 'share/pixmaps'), ['install/onionshare80.xpm']), - (os.path.join(sys.prefix, 'share/onionshare'), ['version']), - (os.path.join(sys.prefix, 'share/onionshare/images'), images), - (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'], - ) +setup( + name='onionshare', + version=version, + description=description, + long_description=long_description, + author='Micah Lee', + author_email='micah@micahflee.com', + url='https://github.com/micahflee/onionshare', + license="GPL v3", + keywords='onion, share, onionshare, tor, anonymous, web server', + packages=['onionshare', 'onionshare_gui'], + include_package_data=True, + scripts=['install/linux_scripts/onionshare', 'install/linux_scripts/onionshare-gui'], + data_files=[ + (os.path.join(sys.prefix, 'share/applications'), ['install/onionshare.desktop']), + (os.path.join(sys.prefix, 'share/appdata'), ['install/onionshare.appdata.xml']), + (os.path.join(sys.prefix, 'share/pixmaps'), ['install/onionshare80.xpm']), + (os.path.join(sys.prefix, 'share/onionshare'), ['version']), + (os.path.join(sys.prefix, 'share/onionshare/images'), images), + (os.path.join(sys.prefix, 'share/onionshare/locale'), locale) + ] +) diff --git a/version b/version.txt similarity index 100% rename from version rename to version.txt