work on serialization and communication, misc work on web, run files

This commit is contained in:
Kevin Froman 2019-01-13 16:20:10 -06:00
parent f82e7bfb59
commit 22cece2b2c
12 changed files with 86 additions and 28 deletions

View File

@ -27,7 +27,7 @@ And most importantly, please be patient. Onionr is an open source project done b
## Asking Questions ## Asking Questions
If you need help with Onionr, you can ask in our If you need help with Onionr, you can contact the devs (be polite and remember this is a volunteer-driven non-profit project).
## Contributing Code ## Contributing Code

View File

@ -18,7 +18,7 @@ uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/onionr rm -f $(DESTDIR)$(PREFIX)/bin/onionr
test: test:
@./run-linux stop @./onionr.sh stop
@sleep 1 @sleep 1
@rm -rf onionr/data-backup @rm -rf onionr/data-backup
@mv onionr/data onionr/data-backup | true > /dev/null 2>&1 @mv onionr/data onionr/data-backup | true > /dev/null 2>&1
@ -29,15 +29,15 @@ test:
soft-reset: soft-reset:
@echo "Soft-resetting Onionr..." @echo "Soft-resetting Onionr..."
rm -f onionr/data/blocks/*.dat onionr/data/*.db onionr/data/block-nonces.dat | true > /dev/null 2>&1 rm -f onionr/data/blocks/*.dat onionr/data/*.db onionr/data/block-nonces.dat | true > /dev/null 2>&1
@./run-linux version | grep -v "Failed" --color=always @./onionr.sh version | grep -v "Failed" --color=always
reset: reset:
@echo "Hard-resetting Onionr..." @echo "Hard-resetting Onionr..."
rm -rf onionr/data/ | true > /dev/null 2>&1 rm -rf onionr/data/ | true > /dev/null 2>&1
cd onionr/static-data/www/ui/; rm -rf ./dist; python compile.py cd onionr/static-data/www/ui/; rm -rf ./dist; python compile.py
#@./RUN-LINUX.sh version | grep -v "Failed" --color=always #@./onionr.sh.sh version | grep -v "Failed" --color=always
plugins-reset: plugins-reset:
@echo "Resetting plugins..." @echo "Resetting plugins..."
rm -rf onionr/data/plugins/ | true > /dev/null 2>&1 rm -rf onionr/data/plugins/ | true > /dev/null 2>&1
@./run-linux version | grep -v "Failed" --color=always @./onionr.sh version | grep -v "Failed" --color=always

View File

@ -1,2 +0,0 @@
#!/usr/bin/sh
nohup ./run-linux start & disown

View File

@ -17,9 +17,11 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
from gevent.pywsgi import WSGIServer
import gevent.monkey
gevent.monkey.patch_socket()
import flask, cgi import flask, cgi
from flask import request, Response, abort, send_from_directory from flask import request, Response, abort, send_from_directory
from gevent.pywsgi import WSGIServer
import sys, random, threading, hmac, hashlib, base64, time, math, os, json, socket import sys, random, threading, hmac, hashlib, base64, time, math, os, json, socket
import core import core
from onionrblockapi import Block from onionrblockapi import Block
@ -238,6 +240,7 @@ class API:
self.debug = debug self.debug = debug
self._privateDelayTime = 3 self._privateDelayTime = 3
self._core = core.Core() self._core = core.Core()
self.startTime = self._core._utils.getEpoch()
self._crypto = onionrcrypto.OnionrCrypto(self._core) self._crypto = onionrcrypto.OnionrCrypto(self._core)
self._utils = onionrutils.OnionrUtils(self._core) self._utils = onionrutils.OnionrUtils(self._core)
app = flask.Flask(__name__) app = flask.Flask(__name__)
@ -301,18 +304,20 @@ class API:
@app.route('/queueResponseAdd/<name>', methods=['post']) @app.route('/queueResponseAdd/<name>', methods=['post'])
def queueResponseAdd(name): def queueResponseAdd(name):
print('added',name)
self.queueResponse[name] = request.form['data'] self.queueResponse[name] = request.form['data']
return Response('success') return Response('success')
@app.route('/queueResponse/<name>') @app.route('/queueResponse/<name>')
def queueResponse(name): def queueResponse(name):
resp = '' resp = 'failure'
try: try:
resp = self.queueResponse[name] resp = self.queueResponse[name]
except KeyError: except KeyError:
pass pass
else: else:
del self.queueResponse[name] del self.queueResponse[name]
print(name, resp)
return Response(resp) return Response(resp)
@app.route('/ping') @app.route('/ping')
@ -321,7 +326,7 @@ class API:
@app.route('/', endpoint='onionrhome') @app.route('/', endpoint='onionrhome')
def hello(): def hello():
return Response("Welcome to Onionr") return send_from_directory('static-data/www/private/', 'index.html')
@app.route('/getblocksbytype/<name>') @app.route('/getblocksbytype/<name>')
def getBlocksByType(name): def getBlocksByType(name):
@ -375,6 +380,14 @@ class API:
except AttributeError: except AttributeError:
pass pass
return Response("bye") return Response("bye")
@app.route('/getstats')
def getStats():
return Response(self._core.serializer.getStats())
@app.route('/getuptime')
def showUptime():
return Response(str(self.getUptime()))
self.httpServer = WSGIServer((self.host, bindPort), app, log=None) self.httpServer = WSGIServer((self.host, bindPort), app, log=None)
self.httpServer.serve_forever() self.httpServer.serve_forever()
@ -397,3 +410,6 @@ class API:
return True return True
except TypeError: except TypeError:
return False return False
def getUptime(self):
return self._utils.getEpoch() - self.startTime

View File

@ -486,7 +486,10 @@ class OnionrCommunicatorDaemon:
logger.debug('Status check; looks good.') logger.debug('Status check; looks good.')
open(self._core.dataDir + '.runcheck', 'w+').close() open(self._core.dataDir + '.runcheck', 'w+').close()
elif cmd[0] == 'connectedPeers': elif cmd[0] == 'connectedPeers':
print('yup')
response = '\n'.join(list(self.onlinePeers)).strip() response = '\n'.join(list(self.onlinePeers)).strip()
if response == '':
response = 'none'
elif cmd[0] == 'pex': elif cmd[0] == 'pex':
for i in self.timers: for i in self.timers:
if i.timerFunction.__name__ == 'lookupAdders': if i.timerFunction.__name__ == 'lookupAdders':
@ -507,7 +510,7 @@ class OnionrCommunicatorDaemon:
else: else:
logger.info('Recieved daemonQueue command:' + cmd[0]) logger.info('Recieved daemonQueue command:' + cmd[0])
if cmd[4] != '' and cmd[0] not in ('', None): if cmd[0] not in ('', None):
if response != '': if response != '':
self._core._utils.localCommand('queueResponseAdd/' + cmd[4], post=True, postData={'data': response}) self._core._utils.localCommand('queueResponseAdd/' + cmd[4], post=True, postData={'data': response})
response = '' response = ''

View File

@ -22,7 +22,7 @@ from onionrblockapi import Block
import onionrutils, onionrcrypto, onionrproofs, onionrevents as events, onionrexceptions, onionrvalues import onionrutils, onionrcrypto, onionrproofs, onionrevents as events, onionrexceptions, onionrvalues
import onionrblacklist, onionrchat, onionrusers import onionrblacklist, onionrchat, onionrusers
import dbcreator, onionrstorage import dbcreator, onionrstorage, serializeddata
if sys.version_info < (3, 6): if sys.version_info < (3, 6):
try: try:
@ -101,6 +101,7 @@ class Core:
# Initialize the crypto object # Initialize the crypto object
self._crypto = onionrcrypto.OnionrCrypto(self) self._crypto = onionrcrypto.OnionrCrypto(self)
self._blacklist = onionrblacklist.OnionrBlackList(self) self._blacklist = onionrblacklist.OnionrBlackList(self)
self.serializer = serializeddata.SerializedData(self)
except Exception as error: except Exception as error:
logger.error('Failed to initialize core Onionr library.', error=error) logger.error('Failed to initialize core Onionr library.', error=error)
@ -386,6 +387,24 @@ class Core:
assert len(responseID) > 0 assert len(responseID) > 0
resp = self._utils.localCommand('queueResponse/' + responseID) resp = self._utils.localCommand('queueResponse/' + responseID)
return resp return resp
def daemonQueueWaitForResponse(self, responseID='', checkFreqSecs=1):
resp = 'failure'
while resp == 'failure':
resp = self.daemonQueueGetResponse(responseID)
time.sleep(1)
print(resp)
return resp
def daemonQueueSimple(self, command, data='', checkFreqSecs=1):
'''
A simplified way to use the daemon queue. Will register a command (with optional data) and wait, return the data
Not always useful, but saves time + LOC in some cases.
This is a blocking function, so be careful.
'''
responseID = str(uuid.uuid4()) # generate unique response ID
self.daemonQueueAdd(command, data=data, responseID=responseID)
return self.daemonQueueWaitForResponse(responseID, checkFreqSecs)
def clearDaemonQueue(self): def clearDaemonQueue(self):
''' '''

View File

@ -180,6 +180,9 @@ class Onionr:
'add-site': self.addWebpage, 'add-site': self.addWebpage,
'addsite': self.addWebpage, 'addsite': self.addWebpage,
'openhome': self.openHome,
'open-home': self.openHome,
'get-file': self.getFile, 'get-file': self.getFile,
'getfile': self.getFile, 'getfile': self.getFile,
@ -240,7 +243,8 @@ class Onionr:
'introduce': 'Introduce your node to the public Onionr network', 'introduce': 'Introduce your node to the public Onionr network',
'friend': '[add|remove] [public key/id]', 'friend': '[add|remove] [public key/id]',
'add-id': 'Generate a new ID (key pair)', 'add-id': 'Generate a new ID (key pair)',
'change-id': 'Change active ID' 'change-id': 'Change active ID',
'open-home': 'Open your node\'s home/info screen'
} }
# initialize plugins # initialize plugins
@ -274,6 +278,14 @@ class Onionr:
for detail in details: for detail in details:
logger.info('%s%s: \n%s%s\n' % (logger.colors.fg.lightgreen, detail, logger.colors.fg.green, details[detail]), sensitive = True) logger.info('%s%s: \n%s%s\n' % (logger.colors.fg.lightgreen, detail, logger.colors.fg.green, details[detail]), sensitive = True)
def openHome(self):
try:
url = self.onionrUtils.getClientAPIServer()
except FileNotFoundError:
logger.error('Onionr seems to not be running (could not get api host)')
else:
webbrowser.open_new_tab('http://%s/#%s' % (url, config.get('client.webpassword')))
def addID(self): def addID(self):
try: try:
sys.argv[2] sys.argv[2]
@ -409,8 +421,11 @@ class Onionr:
except KeyboardInterrupt: except KeyboardInterrupt:
break break
if not type(peers) is None: if not type(peers) is None:
if peers not in ('', None): if peers not in ('', 'failure', None):
print(peers) if peers != False:
print(peers)
else:
print('Daemon probably not running. Unable to list connected peers.')
break break
def listPeers(self): def listPeers(self):

View File

@ -49,8 +49,8 @@ class PeerProfiles:
def getConnectTime(self): def getConnectTime(self):
try: try:
self.connectTime = self.coreInst.getAddressInfo(self.address, 'lastConnect') self.connectTime = int(self.coreInst.getAddressInfo(self.address, 'lastConnect'))
except KeyError: except (KeyError, ValueError, TypeError) as e:
pass pass
def saveScore(self): def saveScore(self):
@ -83,7 +83,6 @@ def getScoreSortedPeerList(coreInst):
# Sort peers by their score, greatest to least, and then last connected time # Sort peers by their score, greatest to least, and then last connected time
peerList = sorted(peerScores, key=peerScores.get, reverse=True) peerList = sorted(peerScores, key=peerScores.get, reverse=True)
peerList = sorted(peerTimes, key=peerTimes.get, reverse=True) peerList = sorted(peerTimes, key=peerTimes.get, reverse=True)
print(peerList)
return peerList return peerList
def peerCleanup(coreInst): def peerCleanup(coreInst):

View File

@ -150,6 +150,17 @@ class OnionrUtils:
except Exception as error: except Exception as error:
logger.error('Failed to read my address.', error = error) logger.error('Failed to read my address.', error = error)
return None return None
def getClientAPIServer(self):
retData = ''
try:
with open(self._core.privateApiHostFile, 'r') as host:
hostname = host.read()
except FileNotFoundError:
raise FileNotFoundError
else:
retData += '%s:%s' % (hostname, config.get('client.client.port'))
return retData
def localCommand(self, command, data='', silent = True, post=False, postData = {}): def localCommand(self, command, data='', silent = True, post=False, postData = {}):
''' '''
@ -163,8 +174,7 @@ class OnionrUtils:
waited = 0 waited = 0
while hostname == '': while hostname == '':
try: try:
with open(self._core.privateApiHostFile, 'r') as host: hostname = self.getClientAPIServer()
hostname = host.read()
except FileNotFoundError: except FileNotFoundError:
time.sleep(1) time.sleep(1)
waited += 1 waited += 1
@ -172,12 +182,13 @@ class OnionrUtils:
return False return False
if data != '': if data != '':
data = '&data=' + urllib.parse.quote_plus(data) data = '&data=' + urllib.parse.quote_plus(data)
payload = 'http://%s:%s/%s%s' % (hostname, config.get('client.client.port'), command, data) payload = 'http://%s/%s%s' % (hostname, command, data)
print(payload,config.get('client.webpassword'))
try: try:
if post: if post:
retData = requests.post(payload, data=postData, headers={'token': config.get('client.webpassword')}).text retData = requests.post(payload, data=postData, headers={'token': config.get('client.webpassword')}, timeout=(15, 30)).text
else: else:
retData = requests.get(payload, headers={'token': config.get('client.webpassword')}).text retData = requests.get(payload, headers={'token': config.get('client.webpassword')}, timeout=(15, 30)).text
except Exception as error: except Exception as error:
if not silent: if not silent:
logger.error('Failed to make local request (command: %s):%s' % (command, error)) logger.error('Failed to make local request (command: %s):%s' % (command, error))

View File

@ -19,7 +19,7 @@
''' '''
# Imports some useful libraries # Imports some useful libraries
import logger, config, threading, time, uuid, subprocess import logger, config, threading, time, uuid, subprocess, sys
from onionrblockapi import Block from onionrblockapi import Block
plugin_name = 'cliui' plugin_name = 'cliui'

View File

@ -2,6 +2,7 @@
<html> <html>
<head> <head>
<meta charset='utf-8'> <meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title> <title>
OnionrBoard OnionrBoard
</title> </title>

View File

@ -1,4 +0,0 @@
#!/bin/sh
cd "$(dirname "$0")"
cd onionr/
./onionr.py "$@"