Ripping out dmg code, replacing pyinstaller with py2app for OSX -- still in progress (#151)

This commit is contained in:
Micah Lee 2015-05-15 16:56:22 -07:00
parent aae9995c5f
commit a86cda4549
11 changed files with 105 additions and 175 deletions

View File

@ -39,33 +39,24 @@ cd onionshare
echo export PYTHONPATH=\$PYTHONPATH:/usr/local/lib/python2.7/site-packages/ >> ~/.profile
source ~/.profile
brew install qt4 pyqt
sudo pip install virtualenv
virtualenv env
. env/bin/activate
pip install flask stem pyinstaller
```
Each time you start work:
```sh
. env/bin/activate
sudo pip install py2app flask stem
```
To build the .app:
```sh
pyinstaller -w -y install/onionshare-osx.spec
python setup.py py2app
```
Now you should have `dist/OnionShare.app`.
To build a .dmg (this script builds the .app for you):
To codesign and build a .pkg for distribution:
```sh
./install/build_dmg.sh
./install/build_osx.sh
```
Now you should have `dist/OnionShare.dmg`.
Now you should have `dist/OnionShare.pkg`.
## Windows

View File

@ -1,61 +0,0 @@
#!/bin/bash
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
DMG_DIR=$ROOT/dist/dmg
DMG_TMP_NAME=$ROOT/dist/tmp.dmg
DMG_NAME=$ROOT/dist/OnionShare.dmg
TITLE=OnionShare
VOLUME=/Volumes/$TITLE
cd $ROOT
# deleting dist
echo Deleting dist folder
rm -rf $ROOT/dist &>/dev/null 2>&1
# build the .app
echo Building OnionShare.app
pyinstaller -w -y $ROOT/install/onionshare-osx.spec
# create the .dmg
echo Creating DMG
mkdir -p $DMG_DIR
hdiutil create -srcfolder $DMG_DIR -volname $TITLE -fs HFS+ -fsargs "-c c=64,a=16,e=16" -format UDRW -size 100mb $DMG_TMP_NAME
DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen $DMG_TMP_NAME | egrep '^/dev/' | sed 1q | awk '{print $1}')
sleep 10
# set up the dmg
echo Setting up DMG
cp -r $ROOT/dist/OnionShare.app $VOLUME
ln -s /Applications $VOLUME/Applications
mkdir $VOLUME/.background
cp $ROOT/install/dmg_background.png $VOLUME/.background/background.png
echo '
tell application "Finder"
tell disk "'${TITLE}'"
open
set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set the bounds of container window to {100, 100, 400, 480}
set theViewOptions to the icon view options of container window
set arrangement of theViewOptions to not arranged
set icon size of theViewOptions to 72
set background picture of theViewOptions to file ".background:background.png"
set position of item "'${TITLE}.app'" of container window to {60, 288}
set position of item "Applications" of container window to {268, 288}
update without registering applications
delay 10
eject
end tell
end tell
' | osascript
# finalize the DMG
echo Finalizing DMG
hdiutil convert $DMG_TMP_NAME -format UDZO -imagekey zlib-level=9 -o $DMG_NAME
rm -r $DMG_DIR
rm -f $DMG_TMP_NAME
# all done
echo DMG created: $DMG_NAME

14
install/build_osx.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
cd $ROOT
# deleting dist
echo Deleting dist folder
rm -rf $ROOT/dist &>/dev/null 2>&1
# build the .app
echo Building OnionShare.app
python setup.py py2app
# codesign the .app

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

View File

@ -1,52 +0,0 @@
# -*- mode: python -*-
a = Analysis(['install/onionshare-launcher.py'],
pathex=['.'],
hiddenimports=['onionshare', 'onionshare_gui'],
hookspath=None,
runtime_hooks=None)
a.datas += [
('onionshare/index.html', 'onionshare/index.html', 'DATA'),
('onionshare/404.html', 'onionshare/404.html', 'DATA'),
('images/logo.png', 'images/logo.png', 'DATA'),
('images/drop_files.png', 'images/drop_files.png', 'DATA'),
('images/server_stopped.png', 'images/server_stopped.png', 'DATA'),
('images/server_started.png', 'images/server_started.png', 'DATA'),
('images/server_working.png', 'images/server_working.png', 'DATA'),
('locale/de.json', 'locale/de.json', 'DATA'),
('locale/en.json', 'locale/en.json', 'DATA'),
('locale/es.json', 'locale/es.json', 'DATA'),
('locale/fi.json', 'locale/fi.json', 'DATA'),
('locale/fr.json', 'locale/fr.json', 'DATA'),
('locale/it.json', 'locale/it.json', 'DATA'),
('locale/nl.json', 'locale/nl.json', 'DATA'),
('locale/no.json', 'locale/no.json', 'DATA'),
('locale/pt.json', 'locale/pt.json', 'DATA'),
('locale/ru.json', 'locale/ru.json', 'DATA'),
('locale/tr.json', 'locale/tr.json', 'DATA'),
]
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='onionshare-launcher',
debug=False,
strip=False,
upx=True,
console=False )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='onionshare')
app = BUNDLE(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='OnionShare.app',
appname='OnionShare',
icon='install/onionshare.icns',
version=open('version').read().strip())

View File

@ -41,6 +41,12 @@ def get_onionshare_dir():
return onionshare_dir
def get_osx_resources_dir():
# this is hacky, but in it ultimate ends up returning the absolute path to
# OnionShare.app/Contents/Resources
return os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
def constant_time_compare(val1, val2):
_builtin_constant_time_compare = getattr(hmac, 'compare_digest', None)
if _builtin_constant_time_compare is not None:

View File

@ -286,7 +286,7 @@ def main():
try:
app = OnionShare(debug, local_only, stay_open)
app.choose_port()
print strings._("connecting_ctrlport").format(app.port)
print strings._("connecting_ctrlport").format(int(app.port))
app.start_hidden_service()
except NoTor as e:
sys.exit(e.args[0])

View File

@ -17,7 +17,7 @@ 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 json, locale, sys, platform, os
import json, locale, sys, os, inspect
import helpers
strings = {}
@ -25,10 +25,13 @@ strings = {}
def load_strings(default="en"):
global strings
p = helpers.get_platform()
# find locale dir
if platform.system() == 'Linux':
if p == 'Linux' or p == 'Tails':
locale_dir = os.path.join(sys.prefix, 'share/onionshare/locale')
elif p == 'Darwin':
locale_dir = os.path.join(helpers.get_osx_resources_dir(), 'locale')
else:
locale_dir = os.path.join(os.path.dirname(helpers.get_onionshare_dir()), 'locale')

View File

@ -18,10 +18,11 @@ 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 os, sys, inspect, platform
from onionshare import helpers
def get_onionshare_gui_dir():
if platform.system() == 'Darwin':
p = helpers.get_platform()
if p == 'Darwin':
onionshare_gui_dir = os.path.dirname(__file__)
else:
onionshare_gui_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
@ -31,8 +32,11 @@ onionshare_gui_dir = get_onionshare_gui_dir()
def get_image_path(filename):
if platform.system() == 'Linux':
p = helpers.get_platform()
if p == 'Linux' or p == 'Tails':
prefix = os.path.join(sys.prefix, 'share/onionshare/images')
elif p == 'Darwin':
prefix = os.path.join(helpers.get_osx_resources_dir(), 'images')
else:
prefix = os.path.join(os.path.dirname(get_onionshare_gui_dir()), 'images')
return os.path.join(prefix, filename)

View File

@ -121,7 +121,7 @@ class OnionShareGui(QtGui.QWidget):
self.status_bar.showMessage(strings._('gui_starting_server1', True))
try:
self.app.choose_port()
print strings._("connecting_ctrlport").format(self.app.port)
print strings._("connecting_ctrlport").format(int(self.app.port))
self.app.start_hidden_service(gui=True)
except onionshare.NoTor as e:
alert(e.args[0], QtGui.QMessageBox.Warning)

107
setup.py
View File

@ -20,14 +20,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import os, sys, platform
from glob import glob
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
def file_list(path):
files = []
for filename in os.listdir(path):
@ -35,7 +33,7 @@ def file_list(path):
files.append(path+'/'+filename)
return files
system = platform.system()
version = open('version').read().strip()
description = (
@ -50,41 +48,68 @@ long_description = description + " " + (
"""just needs to use Tor Browser to download the file from you."""
)
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=['bin/onionshare', 'bin/onionshare-gui'],
data_files=[
(os.path.join(sys.prefix, 'share/applications'), ['install/onionshare.desktop']),
(os.path.join(sys.prefix, 'share/pixmaps'), ['install/onionshare80.xpm']),
(os.path.join(sys.prefix, 'share/onionshare/images'), [
'images/logo.png',
'images/drop_files.png',
'images/server_stopped.png',
'images/server_started.png',
'images/server_working.png'
]),
(os.path.join(sys.prefix, 'share/onionshare/locale'), [
'locale/de.json',
'locale/en.json',
'locale/es.json',
'locale/fi.json',
'locale/fr.json',
'locale/it.json',
'locale/nl.json',
'locale/no.json',
'locale/pt.json',
'locale/ru.json',
'locale/tr.json'
])
]
)
images = [
'images/logo.png',
'images/drop_files.png',
'images/server_stopped.png',
'images/server_started.png',
'images/server_working.png'
]
locale = [
'locale/de.json',
'locale/en.json',
'locale/es.json',
'locale/fi.json',
'locale/fr.json',
'locale/it.json',
'locale/nl.json',
'locale/no.json',
'locale/pt.json',
'locale/ru.json',
'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=['bin/onionshare', 'bin/onionshare-gui'],
data_files=[
(os.path.join(sys.prefix, 'share/applications'), ['install/onionshare.desktop']),
(os.path.join(sys.prefix, 'share/pixmaps'), ['install/onionshare80.xpm']),
(os.path.join(sys.prefix, 'share/onionshare/images'), images),
(os.path.join(sys.prefix, 'share/onionshare/locale'), locale)
]
)
elif system == 'Darwin':
setup(
name='OnionShare',
version=version,
description=description,
long_description=long_description,
app=['install/onionshare-launcher.py'],
data_files=[
('images', images),
('locale', locale)
],
options={
'py2app': {
'argv_emulation': True,
'iconfile':'install/onionshare.icns',
'includes': ['pip', 'PyQt4', 'PyQt4.QtCore', 'PyQt4.QtGui'],
'excludes': ['PyQt4.QtDesigner', 'PyQt4.QtNetwork', 'PyQt4.QtOpenGL', 'PyQt4.QtScript', 'PyQt4.QtSql', 'PyQt4.QtTest', 'PyQt4.QtWebKit', 'PyQt4.QtXml', 'PyQt4.phonon']
}
},
setup_requires=['py2app'],
)