2014-06-26 14:22:32 -04:00
|
|
|
import os, sys, subprocess, inspect, platform, argparse
|
2014-06-19 16:19:46 -04:00
|
|
|
from PyQt4.QtCore import *
|
|
|
|
from PyQt4.QtGui import *
|
|
|
|
from PyQt4.QtWebKit import *
|
|
|
|
|
2014-06-25 17:42:39 -04:00
|
|
|
if platform.system() == 'Darwin':
|
|
|
|
onionshare_gui_dir = os.path.dirname(__file__)
|
|
|
|
else:
|
|
|
|
onionshare_gui_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
2014-06-22 00:54:44 -04:00
|
|
|
|
|
|
|
try:
|
|
|
|
import onionshare
|
|
|
|
except ImportError:
|
|
|
|
sys.path.append(os.path.abspath(onionshare_gui_dir+"/.."))
|
|
|
|
import onionshare
|
|
|
|
|
|
|
|
import webapp
|
|
|
|
|
2014-06-20 21:15:46 -04:00
|
|
|
window_icon = None
|
|
|
|
|
2014-06-19 23:00:36 -04:00
|
|
|
class Application(QApplication):
|
|
|
|
def __init__(self):
|
|
|
|
platform = onionshare.get_platform()
|
|
|
|
if platform == 'Tails' or platform == 'Linux':
|
|
|
|
self.setAttribute(Qt.AA_X11InitThreads, True)
|
|
|
|
|
|
|
|
QApplication.__init__(self, sys.argv)
|
|
|
|
|
2014-06-19 21:16:22 -04:00
|
|
|
class WebAppThread(QThread):
|
2014-06-19 21:46:22 -04:00
|
|
|
def __init__(self, webapp_port):
|
2014-06-19 21:16:22 -04:00
|
|
|
QThread.__init__(self)
|
|
|
|
self.webapp_port = webapp_port
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
webapp.app.run(port=self.webapp_port)
|
|
|
|
|
2014-06-19 21:46:22 -04:00
|
|
|
class Window(QWebView):
|
|
|
|
def __init__(self, basename, webapp_port):
|
2014-06-20 21:15:46 -04:00
|
|
|
global window_icon
|
2014-06-19 21:46:22 -04:00
|
|
|
QWebView.__init__(self)
|
|
|
|
self.setWindowTitle("{0} | OnionShare".format(basename))
|
2014-06-19 22:39:48 -04:00
|
|
|
self.resize(580, 400)
|
|
|
|
self.setMinimumSize(580, 400)
|
|
|
|
self.setMaximumSize(580, 400)
|
2014-06-20 21:15:46 -04:00
|
|
|
self.setWindowIcon(window_icon)
|
2014-06-19 21:46:22 -04:00
|
|
|
self.load(QUrl("http://127.0.0.1:{0}".format(webapp_port)))
|
|
|
|
|
2014-06-19 16:51:40 -04:00
|
|
|
def alert(msg, icon=QMessageBox.NoIcon):
|
2014-06-20 21:15:46 -04:00
|
|
|
global window_icon
|
2014-06-19 16:51:40 -04:00
|
|
|
dialog = QMessageBox()
|
2014-06-19 20:28:55 -04:00
|
|
|
dialog.setWindowTitle("OnionShare")
|
2014-06-20 21:15:46 -04:00
|
|
|
dialog.setWindowIcon(window_icon)
|
2014-06-19 16:51:40 -04:00
|
|
|
dialog.setText(msg)
|
|
|
|
dialog.setIcon(icon)
|
|
|
|
dialog.exec_()
|
2014-05-30 20:46:24 -04:00
|
|
|
|
2014-06-26 14:22:32 -04:00
|
|
|
def select_file(strings, filename=None):
|
2014-05-30 20:46:24 -04:00
|
|
|
# get filename, either from argument or file chooser dialog
|
2014-06-26 14:22:32 -04:00
|
|
|
if not filename:
|
2014-06-19 16:36:49 -04:00
|
|
|
args = {}
|
2014-06-10 18:07:53 -04:00
|
|
|
if onionshare.get_platform() == 'Tails':
|
2014-06-19 16:36:49 -04:00
|
|
|
args['directory'] = '/home/amnesia'
|
|
|
|
|
|
|
|
filename = QFileDialog.getOpenFileName(caption=strings['choose_file'], options=QFileDialog.ReadOnly, **args)
|
|
|
|
if not filename:
|
2014-05-30 20:46:24 -04:00
|
|
|
return False, False
|
|
|
|
|
2014-06-19 16:36:49 -04:00
|
|
|
filename = str(filename)
|
|
|
|
|
2014-05-30 20:46:24 -04:00
|
|
|
# validate filename
|
|
|
|
if not os.path.isfile(filename):
|
2014-06-19 16:51:40 -04:00
|
|
|
alert(strings["not_a_file"].format(filename), QMessageBox.Warning)
|
2014-05-30 20:46:24 -04:00
|
|
|
return False, False
|
|
|
|
|
|
|
|
filename = os.path.abspath(filename)
|
|
|
|
basename = os.path.basename(filename)
|
|
|
|
return filename, basename
|
|
|
|
|
2014-05-29 21:05:30 -04:00
|
|
|
def main():
|
2014-06-06 21:20:57 -04:00
|
|
|
onionshare.strings = onionshare.load_strings()
|
2014-05-30 20:46:24 -04:00
|
|
|
|
2014-06-20 00:13:55 -04:00
|
|
|
# start the Qt app
|
|
|
|
app = Application()
|
|
|
|
|
2014-06-10 18:07:53 -04:00
|
|
|
# check for root in Tails
|
|
|
|
if onionshare.get_platform() == 'Tails' and not onionshare.is_root():
|
|
|
|
subprocess.call(['/usr/bin/gksudo']+sys.argv)
|
|
|
|
return
|
|
|
|
|
2014-06-26 14:22:32 -04:00
|
|
|
# parse arguments
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument('--local-only', action='store_true', dest='local_only', help='Do not attempt to use tor: for development only')
|
|
|
|
parser.add_argument('--stay-open', action='store_true', dest='stay_open', help='Keep hidden service running after download has finished')
|
|
|
|
parser.add_argument('--debug', action='store_true', dest='debug', help='Log errors to disk')
|
|
|
|
parser.add_argument('filename', nargs='?', help='File to share')
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
filename = args.filename
|
|
|
|
local_only = args.local_only
|
|
|
|
stay_open = args.stay_open
|
|
|
|
debug = args.debug
|
|
|
|
|
2014-06-20 21:15:46 -04:00
|
|
|
# create the onionshare icon
|
2014-06-22 00:54:44 -04:00
|
|
|
global window_icon, onionshare_gui_dir
|
2014-06-20 21:15:46 -04:00
|
|
|
window_icon = QIcon("{0}/onionshare-icon.png".format(onionshare_gui_dir))
|
|
|
|
|
2014-05-30 21:03:53 -04:00
|
|
|
# try starting hidden service
|
2014-06-06 21:20:57 -04:00
|
|
|
onionshare_port = onionshare.choose_port()
|
2014-06-26 14:26:41 -04:00
|
|
|
local_host = "127.0.0.1:{0}".format(onionshare_port)
|
|
|
|
if not local_only:
|
|
|
|
try:
|
|
|
|
onion_host = onionshare.start_hidden_service(onionshare_port)
|
|
|
|
except onionshare.NoTor as e:
|
|
|
|
alert(e.args[0], QMessageBox.Warning)
|
|
|
|
return
|
2014-06-06 21:20:57 -04:00
|
|
|
onionshare.tails_open_port(onionshare_port)
|
2014-05-30 21:03:53 -04:00
|
|
|
|
2014-05-30 20:46:24 -04:00
|
|
|
# select file to share
|
2014-06-26 14:22:32 -04:00
|
|
|
filename, basename = select_file(onionshare.strings, filename)
|
2014-05-29 22:31:28 -04:00
|
|
|
if not filename:
|
2014-05-29 21:05:30 -04:00
|
|
|
return
|
|
|
|
|
2014-06-19 21:46:22 -04:00
|
|
|
# initialize the web app
|
|
|
|
webapp.onionshare = onionshare
|
|
|
|
webapp.onionshare_port = onionshare_port
|
|
|
|
webapp.filename = filename
|
2014-06-26 14:26:41 -04:00
|
|
|
if not local_only:
|
|
|
|
webapp.onion_host = onion_host
|
|
|
|
else:
|
|
|
|
webapp.onion_host = local_host
|
2014-06-19 21:46:22 -04:00
|
|
|
webapp.qtapp = app
|
|
|
|
webapp.clipboard = app.clipboard()
|
|
|
|
|
|
|
|
# run the web app in a new thread
|
2014-06-06 21:20:57 -04:00
|
|
|
webapp_port = onionshare.choose_port()
|
2014-06-10 18:10:40 -04:00
|
|
|
onionshare.tails_open_port(webapp_port)
|
2014-06-19 21:46:22 -04:00
|
|
|
webapp_thread = WebAppThread(webapp_port)
|
|
|
|
webapp_thread.start()
|
2014-06-06 21:20:57 -04:00
|
|
|
|
2014-06-20 00:13:55 -04:00
|
|
|
# clean up when app quits
|
|
|
|
def shutdown():
|
|
|
|
onionshare.tails_close_port(onionshare_port)
|
|
|
|
onionshare.tails_close_port(webapp_port)
|
|
|
|
app.connect(app, SIGNAL("aboutToQuit()"), shutdown)
|
|
|
|
|
2014-06-06 21:20:57 -04:00
|
|
|
# launch the window
|
2014-06-19 21:46:22 -04:00
|
|
|
web = Window(basename, webapp_port)
|
|
|
|
web.show()
|
|
|
|
|
|
|
|
# all done
|
|
|
|
sys.exit(app.exec_())
|
2014-05-29 21:05:30 -04:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|