diff --git a/BUILD.md b/BUILD.md
index 87274958..05122859 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -62,9 +62,15 @@ brew install python3 pyqt5 qt5
Install some dependencies using pip3:
```sh
-sudo pip3 install pyinstaller flask stem
+sudo pip3 install flask stem
```
+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`
+
Get the source code:
```sh
@@ -83,7 +89,7 @@ Now you should have `dist/OnionShare.app`.
To codesign and build a .pkg for distribution:
```sh
-install/build_osx.sh --sign
+install/build_osx.sh --release
```
Now you should have `dist/OnionShare.pkg`.
diff --git a/install/Info.plist b/install/Info.plist
new file mode 100644
index 00000000..0125c1d5
--- /dev/null
+++ b/install/Info.plist
@@ -0,0 +1,18 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleExecutable
+ onionshare-gui
+ CFBundleIdentifier
+ com.micahflee.onionshare
+ NSHighResolutionCapable
+
+ CFBundleShortVersionString
+ {VERSION}
+ CFBundleIconFile
+ icon.icns
+
+
diff --git a/install/build_osx.sh b/install/build_osx.sh
index 22d6cc4d..2f2314f5 100755
--- a/install/build_osx.sh
+++ b/install/build_osx.sh
@@ -5,19 +5,27 @@ cd $ROOT
# deleting dist
echo Deleting dist folder
-rm -rf $ROOT/dist &>/dev/null 2>&1
+rm -rf $ROOT/build $ROOT/dist &>/dev/null 2>&1
# build the .app
echo Building OnionShare.app
-pyinstaller install/pyinstaller.spec
+python3 setup.py bdist_mac
-if [ "$1" = "--sign" ]; then
- SIGNING_IDENTITY_APP="3rd Party Mac Developer Application: Micah Lee"
- SIGNING_IDENTITY_INSTALLER="3rd Party Mac Developer Installer: Micah Lee"
+if [ "$1" = "--release" ]; then
+ mkdir -p dist
+ APP_PATH="build/OnionShare.app"
+ PKG_PATH="dist/OnionShare.pkg"
+ IDENTITY_NAME_APPLICATION="Developer ID Application: Micah Lee"
+ IDENTITY_NAME_INSTALLER="Developer ID Installer: Micah Lee"
- # codesign the .app
- codesign -vvvv --deep -s "$SIGNING_IDENTITY_APP" dist/OnionShare.app
+ echo "Codesigning the app bundle"
+ codesign --deep -s "$IDENTITY_NAME_APPLICATION" "$APP_PATH"
- # build .pkg
- productbuild --component dist/OnionShare.app /Applications dist/OnionShare.pkg --sign "$SIGNING_IDENTITY_INSTALLER"
+ echo "Creating an installer"
+ productbuild --sign "$IDENTITY_NAME_INSTALLER" --component "$APP_PATH" /Applications "$PKG_PATH"
+
+ echo "Cleaning up"
+ rm -rf "$APP_PATH"
+
+ echo "All done, your installer is in: $PKG_PATH"
fi
diff --git a/install/pyinstaller.spec b/install/pyinstaller.spec
deleted file mode 100644
index 817c22c2..00000000
--- a/install/pyinstaller.spec
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- mode: python -*-
-
-import platform
-system = platform.system()
-
-version = open('resources/version.txt').read().strip()
-
-block_cipher = None
-
-a = Analysis(
- ['scripts/onionshare-gui'],
- pathex=['.'],
- binaries=None,
- datas=[
- ('../resources/images/*', 'images'),
- ('../resources/locale/*', 'locale'),
- ('../resources/html/*', 'html'),
- ('../resources/version.txt', '.'),
- ('../resources/wordlist.txt', '.')
- ],
- hiddenimports=[],
- hookspath=[],
- runtime_hooks=[],
- excludes=[],
- win_no_prefer_redirects=False,
- win_private_assemblies=False,
- cipher=block_cipher)
-
-pyz = PYZ(
- a.pure, a.zipped_data,
- cipher=block_cipher)
-
-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 system == 'Darwin':
- app = BUNDLE(
- coll,
- name='OnionShare.app',
- icon='install/onionshare.icns',
- bundle_identifier='com.micahflee.onionshare',
- info_plist={
- 'CFBundleShortVersionString': version,
- 'NSHighResolutionCapable': 'True'
- }
- )
diff --git a/onionshare/helpers.py b/onionshare/helpers.py
index d80122df..aaa1c999 100644
--- a/onionshare/helpers.py
+++ b/onionshare/helpers.py
@@ -37,15 +37,9 @@ def get_resource_path(filename):
if p == 'Linux' and sys.argv and sys.argv[0].startswith('/usr/bin/onionshare'):
# 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 pyinstaller, cx_Freeze
- # https://pythonhosted.org/PyInstaller/#run-time-information
+ 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
- if p == 'Windows':
- # Windows is using cx_Freeze
- resources_dir = os.path.join(os.path.dirname(sys.executable), 'resources')
- else:
- # OS X is using PyInstaller
- resources_dir = sys._MEIPASS
+ resources_dir = os.path.join(os.path.dirname(sys.executable), 'resources')
else: # 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')
diff --git a/setup.py b/setup.py
index a3516a88..b37f3598 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, platform, tempfile
def file_list(path):
files = []
@@ -42,84 +42,69 @@ long_description = description + " " + (
author = 'Micah Lee'
author_email = 'micah@micahflee.com'
url = 'https://github.com/micahflee/onionshare'
-license = "GPL v3"
+license = 'GPL v3'
keywords = 'onion, share, onionshare, tor, anonymous, web server'
os = platform.system()
-if os == 'Windows':
+# Windows and Mac
+if os == 'Windows' or os == 'Darwin':
from cx_Freeze import setup, Executable
+
+ if os == '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 os == '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,
+ 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": [],
- "excludes": [],
- "include_files": ['resources']
+ '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=[
- 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")
- ]
+ executables=executables
)
-
+
+# Linux
else:
- 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'
- ]
-
- 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'
- ]
-
- html = [
- 'resources/html/index.html',
- 'resources/html/denied.html',
- 'resources/html/404.html'
- ]
-
from setuptools import setup
setup(
- name='onionshare',
- version=version,
- description=description,
- long_description=long_description,
- author=author,
- author_email=author_email,
- url=url,
- license=license,
- keywords=keywords,
+ name='onionshare', version=version,
+ description=description, long_description=long_description,
+ author=author, author_email=author_email,
+ url=url, license=license, keywords=keywords,
packages=['onionshare', 'onionshare_gui'],
include_package_data=True,
scripts=['install/scripts/onionshare', 'install/scripts/onionshare-gui'],
@@ -131,9 +116,33 @@ else:
'resources/version.txt',
'resources/wordlist.txt'
]),
- (os.path.join(sys.prefix, 'share/onionshare/images'), images),
- (os.path.join(sys.prefix, 'share/onionshare/locale'), locale),
- (os.path.join(sys.prefix, 'share/onionshare/html'), html),
+ (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']),
]
)