Merge master branch and fix conflicts

This commit is contained in:
Miguel Jacq 2017-12-03 17:06:33 +11:00
commit 2eb7bca242
No known key found for this signature in database
GPG Key ID: EEA4341C6D97A0B6
15 changed files with 128 additions and 39 deletions

1
.gitignore vendored
View File

@ -27,6 +27,7 @@ pip-log.txt
.coverage
.tox
nosetests.xml
.cache
# Translations
*.mo

View File

@ -1,11 +1,12 @@
include LICENSE
include README.md
include BUILD.md
include resources/*
include resources/images/*
include resources/locale/*
include resources/html/*
include share/*
include share/images/*
include share/locale/*
include share/html/*
include install/onionshare.desktop
include install/onionshare.appdata.xml
include install/onionshare80.xpm
include install/scripts/onionshare-nautilus.py
include test/*.py

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python
import os
import sys
import json
import locale
import subprocess
import urllib
import gi
@ -12,7 +13,55 @@ from gi.repository import GObject
# Put me in /usr/share/nautilus-python/extensions/
class OnionShareExtension(GObject.GObject, Nautilus.MenuProvider):
def __init__(self):
pass
# Get the localized string for "Share via OnionShare" label
self.label = None
default_label = 'Share via OnionShare'
try:
# Re-implement localization in python2
default_locale = 'en'
locale_dir = os.path.join(sys.prefix, 'share/onionshare/locale')
if os.path.exists(locale_dir):
# Load all translations
strings = {}
translations = {}
for filename in os.listdir(locale_dir):
abs_filename = os.path.join(locale_dir, filename)
lang, ext = os.path.splitext(filename)
if ext == '.json':
with open(abs_filename) as f:
translations[lang] = json.load(f)
strings = translations[default_locale]
lc, enc = locale.getdefaultlocale()
if lc:
lang = lc[:2]
if lang in translations:
# if a string doesn't exist, fallback to English
for key in translations[default_locale]:
if key in translations[lang]:
strings[key] = translations[lang][key]
self.label = strings['share_via_onionshare']
except:
self.label = default_label
if not self.label:
self.label = default_label
"""
# This more elegant solution will only work if nautilus is using python3, and onionshare is installed system-wide.
# But nautilus is using python2, so this is commented out.
try:
import onionshare
onionshare.strings.load_strings(onionshare.common)
self.label = onionshare.strings._('share_via_onionshare')
except:
import sys
print('python version: {}').format(sys.version)
self.label = 'Share via OnionShare'
"""
def url2path(self,url):
file_uri = url.get_activation_uri()
@ -31,7 +80,7 @@ class OnionShareExtension(GObject.GObject, Nautilus.MenuProvider):
def get_file_items(self, window, files):
menuitem = Nautilus.MenuItem(name='OnionShare::Nautilus',
label='Share via OnionShare',
label=self.label,
tip='',
icon='')
menu = Nautilus.Menu()

View File

@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import base64
import hashlib
import inspect
import math
import os
import platform
import random
@ -70,9 +69,12 @@ def get_resource_path(filename):
if getattr(sys, 'onionshare_dev_mode', False):
# Look for resources directory relative to python file
prefix = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))), 'share')
if not os.path.exists(prefix):
# While running tests during stdeb bdist_deb, look 3 directories up for the share folder
prefix = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(prefix)))), 'share')
elif p == 'Linux' and sys.argv and sys.argv[0].startswith(sys.prefix):
# OnionShare is installed systemwide in Linux
elif p == 'Linux':
# Assume OnionShare is installed systemwide in Linux, since we're not running in dev mode
prefix = os.path.join(sys.prefix, 'share/onionshare')
elif getattr(sys, 'frozen', False):
@ -144,14 +146,14 @@ def human_readable_filesize(b):
"""
thresh = 1024.0
if b < thresh:
return '{0:.1f} B'.format(b)
units = ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
return '{:.1f} B'.format(b)
units = ('KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB')
u = 0
b /= thresh
while b >= thresh:
b /= thresh
u += 1
return '{0:.1f} {1:s}'.format(round(b, 1), units[u])
return '{:.1f} {}'.format(b, units[u])
def format_seconds(seconds):

View File

@ -433,6 +433,13 @@ class Onion(object):
self.stealth = False
self.service_id = None
try:
# Delete the temporary tor data directory
self.tor_data_directory.cleanup()
except AttributeError:
# Skip if cleanup was somehow run before connect
pass
def get_tor_socks_port(self):
"""
Returns a (address, port) tuple for the Tor SOCKS port

View File

@ -18,10 +18,13 @@ 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 platform, os, json
import json
import os
import platform
from . import strings, common
class Settings(object):
"""
This class stores all of the settings for OnionShare, specifically for how
@ -95,7 +98,7 @@ class Settings(object):
try:
common.log('Settings', 'load', 'Trying to load {}'.format(self.filename))
with open(self.filename, 'r') as f:
self._settings = json.loads(f.read())
self._settings = json.load(f)
self.fill_in_defaults()
except:
pass

View File

@ -17,17 +17,19 @@ 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, os
import json
import locale
import os
strings = {}
def load_strings(common, default="en"):
"""
Loads translated strings and fallback to English
if the translation does not exist.
"""
global strings
p = common.get_platform()
# find locale dir
locale_dir = common.get_resource_path('locale')
@ -37,10 +39,9 @@ def load_strings(common, default="en"):
for filename in os.listdir(locale_dir):
abs_filename = os.path.join(locale_dir, filename)
lang, ext = os.path.splitext(filename)
if abs_filename.endswith('.json'):
if ext == '.json':
with open(abs_filename, encoding='utf-8') as f:
lang_json = f.read()
translations[lang] = json.loads(lang_json)
translations[lang] = json.load(f)
strings = translations[default]
lc, enc = locale.getdefaultlocale()

View File

@ -17,12 +17,22 @@ 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/>.
"""
from distutils.version import StrictVersion as Version
import queue, mimetypes, platform, os, sys, socket, logging, hmac
import hmac
import logging
import mimetypes
import os
import queue
import socket
import sys
import tempfile
from distutils.version import LooseVersion as Version
from urllib.request import urlopen
from flask import Flask, Response, request, render_template_string, abort, make_response
from flask import __version__ as flask_version
from flask import (
Flask, Response, request, render_template_string, abort, make_response,
__version__ as flask_version
)
from . import strings, common
@ -56,6 +66,7 @@ security_headers = [
('Server', 'OnionShare')
]
def set_file_info(filenames, processed_size_callback=None):
"""
Using the list of filenames being shared, fill in details that the web
@ -115,6 +126,8 @@ def add_request(request_type, path, data=None):
slug = None
def generate_slug():
global slug
slug = common.build_slug()
@ -123,12 +136,16 @@ download_count = 0
error404_count = 0
stay_open = False
def set_stay_open(new_stay_open):
"""
Set stay_open variable.
"""
global stay_open
stay_open = new_stay_open
def get_stay_open():
"""
Get stay_open variable.
@ -138,6 +155,8 @@ def get_stay_open():
# Are we running in GUI mode?
gui_mode = False
def set_gui_mode():
"""
Tell the web service that we're running in GUI mode
@ -145,21 +164,19 @@ def set_gui_mode():
global gui_mode
gui_mode = True
def debug_mode():
"""
Turn on debugging mode, which will log flask errors to a debug file.
"""
if platform.system() == 'Windows':
temp_dir = os.environ['Temp'].replace('\\', '/')
else:
temp_dir = '/tmp/'
log_handler = logging.FileHandler('{0:s}/onionshare_server.log'.format(temp_dir))
temp_dir = tempfile.gettempdir()
log_handler = logging.FileHandler(
os.path.join(temp_dir, 'onionshare_server.log'))
log_handler.setLevel(logging.WARNING)
app.logger.addHandler(log_handler)
def check_slug_candidate(slug_candidate, slug_compare=None):
global slug
if not slug_compare:
slug_compare = slug
if not hmac.compare_digest(slug_compare, slug_candidate):
@ -170,6 +187,7 @@ def check_slug_candidate(slug_candidate, slug_compare = None):
# one download at a time.
download_in_progress = False
@app.route("/<slug_candidate>")
def index(slug_candidate):
"""
@ -202,11 +220,13 @@ def index(slug_candidate):
r.headers.set(header, value)
return r
# If the client closes the OnionShare window while a download is in progress,
# it should immediately stop serving the file. The client_cancel global is
# used to tell the download function that the client is canceling the download.
client_cancel = False
@app.route("/<slug_candidate>/download")
def download(slug_candidate):
"""
@ -331,11 +351,12 @@ def page_not_found(e):
force_shutdown()
print(strings._('error_rate_limit'))
r = make_response(render_template_string(open(common.get_resource_path('html/404.html')).read()))
r = make_response(render_template_string(open(common.get_resource_path('html/404.html')).read()), 404)
for header, value in security_headers:
r.headers.set(header, value)
return r
# shutting down the server only works within the context of flask, so the easiest way to do it is over http
shutdown_slug = common.random_string(16)

View File

@ -434,6 +434,9 @@ class OnionShareGui(QtWidgets.QMainWindow):
if not web.get_stay_open():
self.server_status.stop_server()
self.server_status.shutdown_timeout_reset()
else:
if self.server_status.status == self.server_status.STATUS_STOPPED:
self.downloads.cancel_download(event["data"]["id"])
elif event["type"] == web.REQUEST_CANCELED:
download_in_progress = False

View File

@ -125,7 +125,7 @@ class TorConnectionThread(QtCore.QThread):
# Connect to the Onion
try:
self.onion.connect(self.settings, self._tor_status_update)
self.onion.connect(self.settings, False, self._tor_status_update)
if self.onion.connected_to_tor:
self.connected_to_tor.emit()
else:

View File

@ -118,5 +118,6 @@
"gui_tor_connection_ask_quit": "Quit",
"gui_tor_connection_error_settings": "Try adjusting how OnionShare connects to the Tor network in Settings.",
"gui_server_started_after_timeout": "The server started after your chosen auto-timeout.\nPlease start a new share.",
"gui_server_timeout_expired": "The chosen timeout has already expired.\nPlease update the timeout and then you may start sharing."
"gui_server_timeout_expired": "The chosen timeout has already expired.\nPlease update the timeout and then you may start sharing.",
"share_via_onionshare": "Share via OnionShare"
}