Merge branch 'pyinstaller'
57
BUILD.md
|
@ -34,35 +34,23 @@ For ArchLinux: There is a PKBUILD available [here](https://aur.archlinux.org/pac
|
|||
|
||||
Install Xcode from the Mac App Store. Once it's installed, run it for the first time to set it up.
|
||||
|
||||
If you don't already have it installed, install [Homebrew](http://brew.sh/).
|
||||
Download and install Python 3.5.2 from https://www.python.org/downloads/release/python-352/ (note that a pyinstaller bug prevents you from using Python 3.6). I downloaded `python-3.5.2-macosx10.6.pkg`.
|
||||
|
||||
Install some dependencies using Homebrew:
|
||||
Download and install Qt 5.7.1 for macOS offline installer from https://www.qt.io/download-open-source/. I downloaded `qt-opensource-mac-x64-clang-5.7.1.dmg`. (You can skip making an account in the installer.)
|
||||
|
||||
Now install some python dependencies with pip (note, there's issues building a .app if you install this in a virtualenv):
|
||||
|
||||
```sh
|
||||
brew install python3 pyqt5 qt5
|
||||
sudo pip3 install -r install/requirements.txt
|
||||
```
|
||||
|
||||
Install some dependencies using pip3:
|
||||
|
||||
```sh
|
||||
sudo pip3 install flask stem
|
||||
```
|
||||
|
||||
After that you can try both the CLI and the GUI version of OnionShare:
|
||||
You can run both the CLI and GUI versions of OnionShare without building an bundle:
|
||||
|
||||
```sh
|
||||
./dev_scripts/onionshare
|
||||
./dev_scripts/onionshare-gui
|
||||
```
|
||||
|
||||
If you want to build a Mac OS X app bundle:
|
||||
|
||||
Install the latest development version of cx_Freeze:
|
||||
|
||||
* Download a [snapshot](https://bitbucket.org/anthony_tuininga/cx_freeze/downloads) of the latest development version of cx_Freeze, extract it, and cd into the folder you extracted it to
|
||||
* Build the package: `python3 setup.py bdist_wheel`
|
||||
* Install it with pip: `sudo pip3 install dist/cx_Freeze-5.0-cp35-cp35m-macosx_10_11_x86_64.whl`
|
||||
|
||||
To build the app bundle:
|
||||
|
||||
```sh
|
||||
|
@ -83,9 +71,13 @@ Now you should have `dist/OnionShare.pkg`.
|
|||
|
||||
### Setting up your dev environment
|
||||
|
||||
Download the latest Python 3.6.x, 32-bit (x86) from https://www.python.org/downloads/. I downloaded `python-3.6.0.exe`. When installing it, make sure to check the "Add Python 3.6 to PATH" checkbox on the first page of the installer.
|
||||
Download the latest Python 3.5.2, 32-bit (x86) from https://www.python.org/downloads/release/python-352/ (note that there's a pyinstaller/pywin32 bug that prevents 3.6.x from working). I downloaded `python-3.5.2.exe`. When installing it, make sure to check the "Add Python 3.5 to PATH" checkbox on the first page of the installer.
|
||||
|
||||
Open a command prompt and install dependencies with pip: `pip install flask stem PyQt5`
|
||||
Open a command prompt, cd to the onionshare folder, and install dependencies with pip:
|
||||
|
||||
```cmd
|
||||
pip3 install -r install\requirements-windows.txt
|
||||
```
|
||||
|
||||
Download and install Qt5 from https://www.qt.io/download-open-source/. I downloaded `qt-unified-windows-x86-2.0.4-online.exe`. There's no need to login to a Qt account during installation. Make sure you install the latest Qt 5.x. I installed Qt 5.7.
|
||||
|
||||
|
@ -96,19 +88,17 @@ python dev_scripts\onionshare
|
|||
python dev_scripts\onionshare-gui
|
||||
```
|
||||
|
||||
If you want to build an .exe:
|
||||
If you want to build a .exe:
|
||||
|
||||
These instructions include adding folders to the path in Windows. To do this, go to Start and type "advanced system settings", and open "View advanced system settings" in the Control Panel. Click Environment Variables. Under "System variables" double-click on Path. From there you can add and remove folders that are available in the PATH.
|
||||
|
||||
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 32-bit [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-US/download/details.aspx?id=48145). I downloaded `vc_redist.x86.exe`.
|
||||
|
||||
Installing cx_Freeze with support for Python 3.5 is annoying. Here are the steps (thanks https://github.com/sekrause/cx_Freeze-Wheels):
|
||||
Download and install the standalone [Windows 10 SDK](https://dev.windows.com/en-us/downloads/windows-10-sdk). Note that you may not need this if you already have Visual Studio. Add the following directories to the path:
|
||||
|
||||
* Download and install the Visual C++ Build Tools 2005 from http://go.microsoft.com/fwlink/?LinkId=691126. I downloaded `visualcppbuildtools_full.exe`.
|
||||
* Install the python wheel package: `pip install wheel`
|
||||
* Download a [snapshot](https://bitbucket.org/anthony_tuininga/cx_freeze/downloads) of the latest development version of cx_Freeze, extract it, and cd into the folder you extracted it to
|
||||
* Build the package: `python setup.py bdist_wheel`
|
||||
* Install it with pip: `pip install dist\cx_Freeze-5.0-cp35-cp35m-win32.whl`
|
||||
* `C:\Program Files (x86)\Windows Kits\10\bin\x86`
|
||||
* `C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86`
|
||||
* `C:\Users\user\AppData\Local\Programs\Python\Python35-32\Lib\site-packages\PyQt5\Qt\bin`
|
||||
|
||||
If you want to build the installer:
|
||||
|
||||
|
@ -119,17 +109,12 @@ If you want to sign binaries with Authenticode:
|
|||
|
||||
* You'll need a code signing certificate. I roughly followed [this guide](http://blog.assarbad.net/20110513/startssl-code-signing-certificate/) to make one using my StartSSL account.
|
||||
* Once you get a code signing key and certificate and covert it to a pfx file, import it into your certificate store.
|
||||
* Windows 7:
|
||||
* Go to http://msdn.microsoft.com/en-us/vstudio/aa496123 and install the latest .NET Framework. I installed `.NET Framework 4.6`.
|
||||
* Go to http://www.microsoft.com/en-us/download/confirmation.aspx?id=8279 and install the Windows SDK.
|
||||
* Add `C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin` to the path.
|
||||
* Windows 10:
|
||||
* Go to https://dev.windows.com/en-us/downloads/windows-10-sdk and install the standalone Windows 10 SDK. Note that you may not need this if you already have Visual Studio.
|
||||
* Add `C:\Program Files (x86)\Windows Kits\10\bin\x86` to the path.
|
||||
|
||||
### To make a .exe:
|
||||
|
||||
* Open a command prompt, cd into the onionshare directory, and type: `python setup.py build`. `onionshare.exe`, `onionshare-gui.exe`, and all of their supporting files will get created inside the `build\exe.win32-3.5` folder.
|
||||
For PyInstaller to work, you might need to edit `Scripts\pyinstaller-script.py` in your Python 3.5 folder, to work around [this bug](https://stackoverflow.com/questions/31808180/installing-pyinstaller-via-pip-leads-to-failed-to-create-process) in pip.
|
||||
|
||||
* Open a command prompt, cd into the onionshare directory, and type: `pyinstaller install\pyinstaller.spec`. `onionshare.exe`, `onionshare-gui.exe`, and all of their supporting files will get created inside the `build` folder.
|
||||
|
||||
### To build the installer:
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
|
||||
cd $DIR
|
||||
|
||||
VERSION=`cat resources/version.txt`
|
||||
VERSION=`cat share/version.txt`
|
||||
|
||||
# clean up from last build
|
||||
rm -r deb_dist >/dev/null 2>&1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
REM build onionshare.exe, onionshare-gui.exe
|
||||
python setup.py build
|
||||
pyinstaller install\pyinstaller.spec -y
|
||||
|
||||
REM sign onionshare.exe, onionshare-gui.exe
|
||||
signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 build\exe.win32-3.5\onionshare.exe
|
||||
|
|
|
@ -9,7 +9,7 @@ rm -rf $ROOT/build $ROOT/dist &>/dev/null 2>&1
|
|||
|
||||
# build the .app
|
||||
echo Building OnionShare.app
|
||||
python3 setup.py bdist_mac
|
||||
pyinstaller install/pyinstaller.spec
|
||||
|
||||
if [ "$1" = "--release" ]; then
|
||||
mkdir -p dist
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
|
||||
cd $DIR
|
||||
|
||||
VERSION=`cat resources/version.txt`
|
||||
VERSION=`cat share/version.txt`
|
||||
|
||||
# clean up from last build
|
||||
rm -r build dist >/dev/null 2>&1
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
|
||||
cd $DIR
|
||||
|
||||
VERSION=`cat resources/version.txt`
|
||||
VERSION=`cat share/version.txt`
|
||||
|
||||
rm -rf deb_dist >/dev/null 2>&1
|
||||
python3 setup.py --command-packages=stdeb.command sdist_dsc
|
||||
|
|
61
install/pyinstaller.spec
Normal file
|
@ -0,0 +1,61 @@
|
|||
# -*- mode: python -*-
|
||||
|
||||
import platform
|
||||
p = platform.system()
|
||||
|
||||
version = open('share/version.txt').read().strip()
|
||||
|
||||
a = Analysis(
|
||||
['scripts/onionshare-gui'],
|
||||
pathex=['.'],
|
||||
binaries=None,
|
||||
datas=[
|
||||
('../share/license.txt', 'share'),
|
||||
('../share/version.txt', 'share'),
|
||||
('../share/wordlist.txt', 'share'),
|
||||
('../share/images/*', 'share/images'),
|
||||
('../share/locale/*', 'share/locale'),
|
||||
('../share/html/*', 'share/html')
|
||||
],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
runtime_hooks=[],
|
||||
excludes=['jinja2.asyncsupport'],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=None)
|
||||
|
||||
pyz = PYZ(
|
||||
a.pure, a.zipped_data,
|
||||
cipher=None)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
exclude_binaries=True,
|
||||
name='onionshare',
|
||||
debug=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
console=False)
|
||||
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
name='onionshare')
|
||||
|
||||
if p == 'Darwin':
|
||||
app = BUNDLE(
|
||||
coll,
|
||||
name='OnionShare.app',
|
||||
icon='install/onionshare.icns',
|
||||
bundle_identifier='com.micahflee.onionshare',
|
||||
info_plist={
|
||||
'CFBundleShortVersionString': version,
|
||||
'NSHighResolutionCapable': 'True'
|
||||
}
|
||||
)
|
13
install/requirements-windows.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
click==6.7
|
||||
Flask==0.12
|
||||
future==0.16.0
|
||||
itsdangerous==0.24
|
||||
Jinja2==2.9.5
|
||||
MarkupSafe==0.23
|
||||
pefile==2016.3.28
|
||||
PyInstaller==3.2.1
|
||||
pypiwin32==219
|
||||
PyQt5==5.8
|
||||
sip==4.19.1
|
||||
stem==1.5.4
|
||||
Werkzeug==0.11.15
|
10
install/requirements.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
click==6.7
|
||||
Flask==0.12
|
||||
itsdangerous==0.24
|
||||
Jinja2==2.9.5
|
||||
MarkupSafe==0.23
|
||||
PyInstaller==3.2.1
|
||||
PyQt5==5.7.1
|
||||
sip==4.19
|
||||
stem==1.5.4
|
||||
Werkzeug==0.11.15
|
|
@ -37,16 +37,21 @@ def get_resource_path(filename):
|
|||
|
||||
if getattr(sys, 'onionshare_dev_mode', False):
|
||||
# Look for resources directory relative to python file
|
||||
resources_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))), 'resources')
|
||||
prefix = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))), 'share')
|
||||
|
||||
elif p == 'Linux' and sys.argv and sys.argv[0].startswith(sys.prefix):
|
||||
# OnionShare is installed systemwide in Linux
|
||||
resources_dir = os.path.join(sys.prefix, 'share/onionshare')
|
||||
elif getattr(sys, 'frozen', False): # Check if app is "frozen" with cx_Freeze
|
||||
# http://cx-freeze.readthedocs.io/en/latest/faq.html#using-data-files
|
||||
resources_dir = os.path.join(os.path.dirname(sys.executable), 'resources')
|
||||
prefix = os.path.join(sys.prefix, 'share/onionshare')
|
||||
|
||||
return os.path.join(resources_dir, filename)
|
||||
elif getattr(sys, 'frozen', False):
|
||||
# Check if app is "frozen"
|
||||
# https://pythonhosted.org/PyInstaller/#run-time-information
|
||||
if p == 'Darwin':
|
||||
prefix = os.path.join(sys._MEIPASS, 'share')
|
||||
elif p == 'Windows':
|
||||
prefix = os.path.join(os.path.dirname(sys.executable), 'share')
|
||||
|
||||
return os.path.join(prefix, filename)
|
||||
|
||||
|
||||
def get_version():
|
||||
|
|
95
setup.py
|
@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
"""
|
||||
|
||||
import os, sys, platform, tempfile
|
||||
from distutils.core import setup
|
||||
|
||||
def file_list(path):
|
||||
files = []
|
||||
|
@ -28,7 +29,7 @@ def file_list(path):
|
|||
files.append(os.path.join(path, filename))
|
||||
return files
|
||||
|
||||
version = open('resources/version.txt').read().strip()
|
||||
version = open('share/version.txt').read().strip()
|
||||
description = (
|
||||
"""OnionShare lets you securely and anonymously share a file of any size with someone. """
|
||||
"""It works by starting a web server, making it accessible as a Tor hidden service, """
|
||||
|
@ -45,61 +46,6 @@ url = 'https://github.com/micahflee/onionshare'
|
|||
license = 'GPL v3'
|
||||
keywords = 'onion, share, onionshare, tor, anonymous, web server'
|
||||
|
||||
p = platform.system()
|
||||
|
||||
# Windows and Mac
|
||||
if p == 'Windows' or p == 'Darwin':
|
||||
from cx_Freeze import setup, Executable
|
||||
|
||||
if p == 'Windows':
|
||||
executables = [
|
||||
Executable('install/scripts/onionshare',
|
||||
icon='install/onionshare.ico',
|
||||
base=None),
|
||||
Executable('install/scripts/onionshare-gui',
|
||||
icon='install/onionshare.ico',
|
||||
shortcutName='OnionShare',
|
||||
shortcutDir='ProgramMenuFolder',
|
||||
base='Win32GUI')
|
||||
]
|
||||
custom_info_plist = ''
|
||||
|
||||
elif p == 'Darwin':
|
||||
executables = [
|
||||
Executable('install/scripts/onionshare-gui'),
|
||||
Executable('install/scripts/onionshare')
|
||||
]
|
||||
|
||||
# Write the correct version into Info.plist
|
||||
f = tempfile.NamedTemporaryFile(mode='w')
|
||||
custom_info_plist = f.name
|
||||
f.write(open('install/Info.plist').read().replace('{VERSION}', str(version)))
|
||||
f.flush()
|
||||
|
||||
setup(
|
||||
name='OnionShare', version=version,
|
||||
description=description, long_description=long_description,
|
||||
author=author, author_email=author_email,
|
||||
url=url, license=license, keywords=keywords,
|
||||
options={
|
||||
'build_exe': {
|
||||
'packages': ['jinja2.ext'],
|
||||
'excludes': [],
|
||||
'include_files': ['resources']
|
||||
},
|
||||
'bdist_mac': {
|
||||
'iconfile': 'install/onionshare.icns',
|
||||
'bundle_name': 'OnionShare',
|
||||
'qt_menu_nib': '/usr/local/Cellar/qt5/5.6.1-1/plugins/platforms',
|
||||
'custom_info_plist': custom_info_plist
|
||||
}
|
||||
},
|
||||
executables=executables
|
||||
)
|
||||
|
||||
# Linux
|
||||
else:
|
||||
from setuptools import setup
|
||||
setup(
|
||||
name='onionshare', version=version,
|
||||
description=description, long_description=long_description,
|
||||
|
@ -112,37 +58,10 @@ else:
|
|||
(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'), [
|
||||
'resources/version.txt',
|
||||
'resources/wordlist.txt'
|
||||
]),
|
||||
(os.path.join(sys.prefix, 'share/onionshare/images'), [
|
||||
'resources/images/logo.png',
|
||||
'resources/images/drop_files.png',
|
||||
'resources/images/server_stopped.png',
|
||||
'resources/images/server_started.png',
|
||||
'resources/images/server_working.png'
|
||||
]),
|
||||
(os.path.join(sys.prefix, 'share/onionshare/locale'), [
|
||||
'resources/locale/cs.json',
|
||||
'resources/locale/de.json',
|
||||
'resources/locale/en.json',
|
||||
'resources/locale/eo.json',
|
||||
'resources/locale/es.json',
|
||||
'resources/locale/fi.json',
|
||||
'resources/locale/fr.json',
|
||||
'resources/locale/it.json',
|
||||
'resources/locale/nl.json',
|
||||
'resources/locale/no.json',
|
||||
'resources/locale/pt.json',
|
||||
'resources/locale/ru.json',
|
||||
'resources/locale/tr.json'
|
||||
]),
|
||||
(os.path.join(sys.prefix, 'share/onionshare/html'), [
|
||||
'resources/html/index.html',
|
||||
'resources/html/denied.html',
|
||||
'resources/html/404.html'
|
||||
]),
|
||||
('/usr/share/nautilus-python/extensions/', ['install/scripts/onionshare-nautilus.py']),
|
||||
(os.path.join(sys.prefix, 'share/onionshare'), file_list('share')),
|
||||
(os.path.join(sys.prefix, 'share/onionshare/images'), file_list('share/images')),
|
||||
(os.path.join(sys.prefix, 'share/onionshare/locale'), file_list('share/locale')),
|
||||
(os.path.join(sys.prefix, 'share/onionshare/html'), file_list('share/html')),
|
||||
('/usr/share/nautilus-python/extensions/', ['install/scripts/onionshare-nautilus.py'])
|
||||
]
|
||||
)
|
||||
|
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 346 B |
Before Width: | Height: | Size: 286 B After Width: | Height: | Size: 286 B |
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 338 B |
|
@ -22,7 +22,7 @@ from onionshare import helpers, strings
|
|||
|
||||
# Stub get_resource_path so it finds the correct path while running tests
|
||||
def get_resource_path(filename):
|
||||
resources_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'resources')
|
||||
resources_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'share')
|
||||
path = os.path.join(resources_dir, filename)
|
||||
return path
|
||||
helpers.get_resource_path = get_resource_path
|
||||
|
|