work on gui, dbstorage, daemon queue responses
This commit is contained in:
parent
84fdb23b1c
commit
aeb9a6e775
@ -109,7 +109,7 @@ class PublicAPI:
|
||||
data = name
|
||||
if clientAPI._utils.validateHash(data):
|
||||
if data not in self.hideBlocks:
|
||||
if os.path.exists(clientAPI._core.dataDir + 'blocks/' + data + '.dat'):
|
||||
if data in clientAPI._core.getBlockList():
|
||||
block = Block(hash=data.encode(), core=clientAPI._core)
|
||||
resp = base64.b64encode(block.getRaw().encode()).decode()
|
||||
if len(resp) == 0:
|
||||
@ -244,6 +244,8 @@ class API:
|
||||
self.host = setBindIP(self._core.privateApiHostFile)
|
||||
logger.info('Running api on %s:%s' % (self.host, self.bindPort))
|
||||
self.httpServer = ''
|
||||
|
||||
self.queueResponse = {}
|
||||
onionrInst.setClientAPIInst(self)
|
||||
|
||||
@app.before_request
|
||||
@ -287,6 +289,19 @@ class API:
|
||||
abort(403)
|
||||
return send_from_directory(config.get('www.private.path', 'static-data/www/private/'), path)
|
||||
|
||||
@app.route('/queueResponseAdd/<name>', methods=['post'])
|
||||
def queueResponseAdd(name):
|
||||
self.queueResponse[name] = request.form['data']
|
||||
return Response('success')
|
||||
|
||||
@app.route('/queueResponse/<name>')
|
||||
def queueResponse(name):
|
||||
try:
|
||||
res = self.queueResponse[name]
|
||||
except KeyError:
|
||||
resp = ''
|
||||
return Response(resp)
|
||||
|
||||
@app.route('/ping')
|
||||
def ping():
|
||||
return Response("pong!")
|
||||
|
@ -472,7 +472,7 @@ class OnionrCommunicatorDaemon:
|
||||
Process daemon commands from daemonQueue
|
||||
'''
|
||||
cmd = self._core.daemonQueue()
|
||||
|
||||
response = ''
|
||||
if cmd is not False:
|
||||
events.event('daemon_command', onionr = None, data = {'cmd' : cmd})
|
||||
if cmd[0] == 'shutdown':
|
||||
@ -486,7 +486,7 @@ class OnionrCommunicatorDaemon:
|
||||
logger.debug('Status check; looks good.')
|
||||
open(self._core.dataDir + '.runcheck', 'w+').close()
|
||||
elif cmd[0] == 'connectedPeers':
|
||||
self.printOnlinePeers()
|
||||
response = '\n'.join(list(self.onlinePeers)).strip()
|
||||
elif cmd[0] == 'pex':
|
||||
for i in self.timers:
|
||||
if i.timerFunction.__name__ == 'lookupAdders':
|
||||
@ -507,6 +507,10 @@ class OnionrCommunicatorDaemon:
|
||||
else:
|
||||
logger.info('Recieved daemonQueue command:' + cmd[0])
|
||||
|
||||
if cmd[4] != '':
|
||||
if response != '':
|
||||
self._core._utils.localCommand('queueResponseAdd', data='/' + cmd[4], post=True, postData=response)
|
||||
|
||||
self.decrementThreadCount('daemonCommands')
|
||||
|
||||
def uploadBlock(self):
|
||||
|
@ -129,7 +129,7 @@ def reload():
|
||||
with open(get_config_file(), 'r', encoding="utf8") as configfile:
|
||||
set_config(json.loads(configfile.read()))
|
||||
except:
|
||||
logger.warn('Failed to parse configuration file.')
|
||||
logger.debug('Failed to parse configuration file.')
|
||||
|
||||
def get_config():
|
||||
'''
|
||||
|
@ -17,7 +17,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
'''
|
||||
import sqlite3, os, sys, time, math, base64, tarfile, nacl, logger, json, netcontroller, math, config
|
||||
import sqlite3, os, sys, time, math, base64, tarfile, nacl, logger, json, netcontroller, math, config, uuid
|
||||
from onionrblockapi import Block
|
||||
|
||||
import onionrutils, onionrcrypto, onionrproofs, onionrevents as events, onionrexceptions, onionrvalues
|
||||
@ -342,7 +342,7 @@ class Core:
|
||||
conn = sqlite3.connect(self.queueDB, timeout=10)
|
||||
c = conn.cursor()
|
||||
try:
|
||||
for row in c.execute('SELECT command, data, date, min(ID) FROM commands group by id'):
|
||||
for row in c.execute('SELECT command, data, date, min(ID), responseID FROM commands group by id'):
|
||||
retData = row
|
||||
break
|
||||
except sqlite3.OperationalError:
|
||||
@ -357,21 +357,20 @@ class Core:
|
||||
|
||||
return retData
|
||||
|
||||
def daemonQueueAdd(self, command, data=''):
|
||||
def daemonQueueAdd(self, command, data='', responseID=''):
|
||||
'''
|
||||
Add a command to the daemon queue, used by the communication daemon (communicator.py)
|
||||
'''
|
||||
|
||||
retData = True
|
||||
# Intended to be used by the web server
|
||||
|
||||
date = self._utils.getEpoch()
|
||||
conn = sqlite3.connect(self.queueDB, timeout=10)
|
||||
c = conn.cursor()
|
||||
t = (command, data, date)
|
||||
t = (command, data, date, responseID)
|
||||
|
||||
try:
|
||||
c.execute('INSERT INTO commands (command, data, date) VALUES(?, ?, ?)', t)
|
||||
c.execute('INSERT INTO commands (command, data, date, responseID) VALUES(?, ?, ?, ?)', t)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
except sqlite3.OperationalError:
|
||||
@ -379,6 +378,13 @@ class Core:
|
||||
self.daemonQueue()
|
||||
events.event('queue_push', data = {'command': command, 'data': data}, onionr = None)
|
||||
return retData
|
||||
|
||||
def daemonQueueGetResponse(self, responseID=''):
|
||||
'''
|
||||
Get a response sent by communicator to the API, by requesting to the API
|
||||
'''
|
||||
assert len(responseID) > 0
|
||||
resp = self._utils.localCommand('queueResponse', data='/' + responseID, post=True)
|
||||
|
||||
def clearDaemonQueue(self):
|
||||
'''
|
||||
|
@ -152,7 +152,6 @@ class DBCreator:
|
||||
conn = sqlite3.connect(self.core.queueDB, timeout=10)
|
||||
c = conn.cursor()
|
||||
# Create table
|
||||
c.execute('''CREATE TABLE commands
|
||||
(id integer primary key autoincrement, command text, data text, date text)''')
|
||||
c.execute('''CREATE TABLE commands (id integer primary key autoincrement, command text, data text, date text, responseID text)''')
|
||||
conn.commit()
|
||||
conn.close()
|
@ -25,7 +25,7 @@ if sys.version_info[0] == 2 or sys.version_info[1] < 5:
|
||||
print('Error, Onionr requires Python 3.5+')
|
||||
sys.exit(1)
|
||||
import os, base64, random, getpass, shutil, subprocess, requests, time, platform, datetime, re, json, getpass, sqlite3
|
||||
import webbrowser
|
||||
import webbrowser, uuid
|
||||
from threading import Thread
|
||||
import api, core, config, logger, onionrplugins as plugins, onionrevents as events
|
||||
import onionrutils
|
||||
@ -394,7 +394,14 @@ class Onionr:
|
||||
return
|
||||
|
||||
def listConn(self):
|
||||
self.onionrCore.daemonQueueAdd('connectedPeers')
|
||||
randID = str(uuid.uuid4())
|
||||
self.onionrCore.daemonQueueAdd('connectedPeers', responseID=randID)
|
||||
while True:
|
||||
time.sleep(1)
|
||||
peers = self.onionrCore.daemonQueueGetResponse(randID)
|
||||
if peers not in ('', None):
|
||||
print(peers)
|
||||
break
|
||||
|
||||
def listPeers(self):
|
||||
logger.info('Peer transport address list:')
|
||||
|
@ -240,12 +240,14 @@ class Block:
|
||||
|
||||
try:
|
||||
if self.isValid() is True:
|
||||
'''
|
||||
if (not self.getBlockFile() is None) and (recreate is True):
|
||||
onionrstorage.store(self.core, self.getRaw().encode())
|
||||
#with open(self.getBlockFile(), 'wb') as blockFile:
|
||||
# blockFile.write(self.getRaw().encode())
|
||||
else:
|
||||
self.hash = self.getCore().insertBlock(self.getContent(), header = self.getType(), sign = sign, meta = self.getMetadata(), expire = self.getExpire())
|
||||
'''
|
||||
self.hash = self.getCore().insertBlock(self.getRaw(), header = self.getType(), sign = sign, meta = self.getMetadata(), expire = self.getExpire())
|
||||
if self.hash != False:
|
||||
self.update()
|
||||
|
||||
@ -751,13 +753,16 @@ class Block:
|
||||
# no input data? scrap it.
|
||||
if hash is None:
|
||||
return False
|
||||
|
||||
'''
|
||||
if type(hash) == Block:
|
||||
blockfile = hash.getBlockFile()
|
||||
else:
|
||||
blockfile = onionrcore.Core().dataDir + 'blocks/%s.dat' % hash
|
||||
'''
|
||||
|
||||
return os.path.exists(blockfile) and os.path.isfile(blockfile)
|
||||
ret = isinstance(onionrstorage.getData(onionrcore.Core(), hash.getHash()), type(None))
|
||||
|
||||
return not ret
|
||||
|
||||
def getCache(hash = None):
|
||||
# give a list of the hashes of the cached blocks
|
||||
|
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
import threading, time
|
||||
from tkinter import *
|
||||
import core
|
||||
class OnionrGUI:
|
||||
@ -11,8 +12,7 @@ class OnionrGUI:
|
||||
|
||||
# create a pulldown menu, and add it to the menu bar
|
||||
filemenu = Menu(menubar, tearoff=0)
|
||||
filemenu.add_command(label="Open", command=None)
|
||||
filemenu.add_command(label="Save", command=None)
|
||||
#filemenu.add_command(label="Open", command=None)
|
||||
filemenu.add_separator()
|
||||
filemenu.add_command(label="Exit", command=self.root.quit)
|
||||
menubar.add_cascade(label="File", menu=filemenu)
|
||||
@ -26,16 +26,13 @@ class OnionrGUI:
|
||||
self.root.config(menu=menubar)
|
||||
|
||||
self.menuFrame = Frame(self.root)
|
||||
self.mainButton = Button(self.menuFrame, text="Main View")
|
||||
self.mainButton.grid(row=0, column=0, padx=0, pady=2, sticky=N+W)
|
||||
self.tabButton1 = Button(self.menuFrame, text="Mail")
|
||||
self.tabButton1 = Button(self.menuFrame, text="Mail", command=self.openMail)
|
||||
self.tabButton1.grid(row=0, column=1, padx=0, pady=2, sticky=N+W)
|
||||
self.tabButton2 = Button(self.menuFrame, text="Message Flow")
|
||||
self.tabButton2.grid(row=0, column=3, padx=0, pady=2, sticky=N+W)
|
||||
|
||||
self.menuFrame.grid(row=0, column=0, padx=2, pady=0, sticky=N+W)
|
||||
|
||||
|
||||
self.idFrame = Frame(self.root)
|
||||
|
||||
self.ourIDLabel = Label(self.idFrame, text="ID: ")
|
||||
@ -48,11 +45,34 @@ class OnionrGUI:
|
||||
|
||||
self.syncStatus = Label(self.root, text="Sync Status: 15/100")
|
||||
self.syncStatus.place(relx=1.0, rely=1.0, anchor=S+E)
|
||||
self.peerCount = Label(self.root, text="Connected Peers: 3")
|
||||
self.peerCount = Label(self.root, text="Connected Peers: ")
|
||||
self.peerCount.place(relx=0.0, rely=1.0, anchor='sw')
|
||||
|
||||
self.root.wm_title("Onionr")
|
||||
threading.Thread(target=self.updateStats)
|
||||
self.root.mainloop()
|
||||
return
|
||||
|
||||
def updateStats(self):
|
||||
#self.core._utils.localCommand()
|
||||
self.peerCount.config(text='Connected Peers: %s' % ())
|
||||
time.sleep(1)
|
||||
return
|
||||
def openMail(self):
|
||||
MailWindow(self)
|
||||
|
||||
|
||||
class MailWindow:
|
||||
def __init__(self, mainGUI):
|
||||
assert isinstance(mainGUI, OnionrGUI)
|
||||
self.core = mainGUI.core
|
||||
self.mailRoot = Toplevel()
|
||||
|
||||
self.inboxFrame = Frame(self.mailRoot)
|
||||
self.sentboxFrame = Frame(self.mailRoot)
|
||||
self.composeFrame = Frame(self.mailRoot)
|
||||
|
||||
|
||||
self.mailRoot.mainloop()
|
||||
|
||||
OnionrGUI()
|
@ -67,10 +67,12 @@ def getData(coreInst, bHash):
|
||||
assert isinstance(coreInst, core.Core)
|
||||
assert coreInst._utils.validateHash(bHash)
|
||||
|
||||
bHash = coreInst._utils.bytesToStr(bHash)
|
||||
|
||||
# First check DB for data entry by hash
|
||||
# if no entry, check disk
|
||||
# If no entry in either, raise an exception
|
||||
retData = ''
|
||||
retData = None
|
||||
fileLocation = '%s/%s.dat' % (coreInst.blockDataLocation, bHash)
|
||||
if os.path.exists(fileLocation):
|
||||
with open(fileLocation, 'rb') as block:
|
||||
|
@ -151,7 +151,7 @@ class OnionrUtils:
|
||||
logger.error('Failed to read my address.', error = error)
|
||||
return None
|
||||
|
||||
def localCommand(self, command, data='', silent = True):
|
||||
def localCommand(self, command, data='', silent = True, post=False, postData = {}):
|
||||
'''
|
||||
Send a command to the local http API server, securely. Intended for local clients, DO NOT USE for remote peers.
|
||||
'''
|
||||
@ -173,8 +173,12 @@ class OnionrUtils:
|
||||
if data != '':
|
||||
data = '&data=' + urllib.parse.quote_plus(data)
|
||||
payload = 'http://%s:%s/%s%s' % (hostname, config.get('client.client.port'), command, data)
|
||||
|
||||
try:
|
||||
retData = requests.get(payload, headers={'token': config.get('client.webpassword')}).text
|
||||
if post:
|
||||
retData = requests.post(payload, data=postData, headers={'token': config.get('client.webpassword')}).text
|
||||
else:
|
||||
retData = requests.get(payload, headers={'token': config.get('client.webpassword')}).text
|
||||
except Exception as error:
|
||||
if not silent:
|
||||
logger.error('Failed to make local request (command: %s):%s' % (command, error))
|
||||
|
@ -54,7 +54,7 @@ class OnionrFlow:
|
||||
self.flowRunning = False
|
||||
expireTime = self.myCore._utils.getEpoch() + 43200
|
||||
if len(message) > 0:
|
||||
self.myCore.insertBlock(message, header='txt', expire=expireTime)
|
||||
self.myCore.insertBlock(message, header='txt', expire=expireTime, meta={'ch': self.channel})
|
||||
#insertBL = Block(content = message, type = 'txt', expire=expireTime, core = self.myCore)
|
||||
#insertBL.setMetadata('ch', self.channel)
|
||||
#insertBL.save()
|
||||
@ -67,10 +67,13 @@ class OnionrFlow:
|
||||
time.sleep(1)
|
||||
try:
|
||||
while self.flowRunning:
|
||||
for block in Block.getBlocks(type = 'txt', core = self.myCore):
|
||||
for block in self.myCore.getBlocksByType('txt'):
|
||||
block = Block(block)
|
||||
if block.getMetadata('ch') != self.channel:
|
||||
#print('not chan', block.getMetadata('ch'))
|
||||
continue
|
||||
if block.getHash() in self.alreadyOutputed:
|
||||
#print('already')
|
||||
continue
|
||||
if not self.flowRunning:
|
||||
break
|
||||
@ -80,7 +83,7 @@ class OnionrFlow:
|
||||
content = self.myCore._utils.escapeAnsi(content.replace('\n', '\\n').replace('\r', '\\r').strip())
|
||||
logger.info(block.getDate().strftime("%m/%d %H:%M") + ' - ' + logger.colors.reset + content, prompt = False)
|
||||
self.alreadyOutputed.append(block.getHash())
|
||||
time.sleep(5)
|
||||
time.sleep(5)
|
||||
except KeyboardInterrupt:
|
||||
self.flowRunning = False
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user