work on ui
This commit is contained in:
parent
47ee28f74f
commit
1b22a993a0
@ -26,7 +26,7 @@ import core
|
||||
from onionrblockapi import Block
|
||||
import onionrutils, onionrexceptions, onionrcrypto, blockimporter, onionrevents as events, logger, config
|
||||
import httpapi
|
||||
from httpapi import friendsapi, simplecache, profilesapi
|
||||
from httpapi import friendsapi, simplecache, profilesapi, configapi
|
||||
from onionrservices import httpheaders
|
||||
import onionr
|
||||
|
||||
@ -259,7 +259,7 @@ class API:
|
||||
self.bindPort = bindPort
|
||||
|
||||
# Be extremely mindful of this. These are endpoints available without a password
|
||||
self.whitelistEndpoints = ('site', 'www', 'onionrhome', 'board', 'profiles', 'profilesindex',
|
||||
self.whitelistEndpoints = ('site', 'www', 'onionrhome', 'homedata', 'board', 'profiles', 'profilesindex',
|
||||
'boardContent', 'sharedContent', 'mail', 'mailindex', 'friends', 'friendsindex')
|
||||
|
||||
self.clientToken = config.get('client.webpassword')
|
||||
@ -276,6 +276,7 @@ class API:
|
||||
app.register_blueprint(friendsapi.friends)
|
||||
app.register_blueprint(simplecache.simplecache)
|
||||
app.register_blueprint(profilesapi.profile_BP)
|
||||
app.register_blueprint(configapi.config_BP)
|
||||
httpapi.load_plugin_blueprints(app)
|
||||
|
||||
@app.before_request
|
||||
@ -347,6 +348,15 @@ class API:
|
||||
def sharedContent(path):
|
||||
return send_from_directory('static-data/www/shared/', path)
|
||||
|
||||
@app.route('/', endpoint='onionrhome')
|
||||
def hello():
|
||||
# ui home
|
||||
return send_from_directory('static-data/www/private/', 'index.html')
|
||||
|
||||
@app.route('/private/<path:path>', endpoint='homedata')
|
||||
def homedata(path):
|
||||
return send_from_directory('static-data/www/private/', path)
|
||||
|
||||
@app.route('/www/<path:path>', endpoint='www')
|
||||
def wwwPublic(path):
|
||||
if not config.get("www.private.run", True):
|
||||
@ -378,11 +388,6 @@ class API:
|
||||
def ping():
|
||||
# Used to check if client api is working
|
||||
return Response("pong!")
|
||||
|
||||
@app.route('/', endpoint='onionrhome')
|
||||
def hello():
|
||||
# ui home
|
||||
return send_from_directory('static-data/www/private/', 'index.html')
|
||||
|
||||
@app.route('/getblocksbytype/<name>')
|
||||
def getBlocksByType(name):
|
||||
|
@ -115,7 +115,7 @@ def save():
|
||||
try:
|
||||
with open(get_config_file(), 'w', encoding="utf8") as configfile:
|
||||
json.dump(get_config(), configfile, indent=2)
|
||||
except:
|
||||
except json.JSONDecodeError:
|
||||
logger.warn('Failed to write to configuration file.')
|
||||
|
||||
def reload():
|
||||
|
62
onionr/httpapi/configapi/__init__.py
Normal file
62
onionr/httpapi/configapi/__init__.py
Normal file
@ -0,0 +1,62 @@
|
||||
'''
|
||||
Onionr - P2P Anonymous Storage Network
|
||||
|
||||
This file handles configuration setting and getting from the HTTP API
|
||||
'''
|
||||
'''
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
'''
|
||||
import json
|
||||
from flask import Blueprint, request, Response, abort
|
||||
import config, onionrutils
|
||||
config.reload()
|
||||
|
||||
config_BP = Blueprint('config_BP', __name__)
|
||||
|
||||
@config_BP.route('/config/get')
|
||||
def get_all_config():
|
||||
'''Simply return all configuration as JSON string'''
|
||||
return Response(json.dumps(config.get_config()))
|
||||
|
||||
@config_BP.route('/config/get/<key>')
|
||||
def get_by_key(key):
|
||||
'''Return a config setting by key'''
|
||||
return Response(json.dumps(config.get(key)))
|
||||
|
||||
@config_BP.route('/config/setall', methods=['POST'])
|
||||
def set_all_config():
|
||||
'''Overwrite existing JSON config with new JSON string'''
|
||||
new_config = request.get_json(force=True)
|
||||
try:
|
||||
new_config = json.loads(new_config)
|
||||
except json.JSONDecodeError:
|
||||
abort(400)
|
||||
else:
|
||||
config.set_config(new_config)
|
||||
return Response('success')
|
||||
|
||||
@config_BP.route('/config/set/<key>', methods=['POST'])
|
||||
def set_by_key(key):
|
||||
'''Overwrite/set only 1 config key'''
|
||||
'''
|
||||
{
|
||||
'data': data
|
||||
}
|
||||
'''
|
||||
try:
|
||||
data = json.loads(onionrutils.OnionrUtils.bytesToStr(request.data))['data']
|
||||
except (json.JSONDecodeError, KeyError):
|
||||
abort(400)
|
||||
config.set(key, data, True)
|
||||
return Response('success')
|
@ -530,13 +530,15 @@ class OnionrUtils:
|
||||
else:
|
||||
return retData
|
||||
|
||||
def strToBytes(self, data):
|
||||
@staticmethod
|
||||
def strToBytes(data):
|
||||
try:
|
||||
data = data.encode()
|
||||
except AttributeError:
|
||||
pass
|
||||
return data
|
||||
def bytesToStr(self, data):
|
||||
@staticmethod
|
||||
def bytesToStr(data):
|
||||
try:
|
||||
data = data.decode()
|
||||
except AttributeError:
|
||||
|
27
onionr/static-data/default-plugins/flow/flowapi.py
Normal file
27
onionr/static-data/default-plugins/flow/flowapi.py
Normal file
@ -0,0 +1,27 @@
|
||||
'''
|
||||
Onionr - P2P Microblogging Platform & Social network
|
||||
|
||||
This file primarily serves to allow specific fetching of flow board messages
|
||||
'''
|
||||
'''
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
'''
|
||||
|
||||
from flask import Response, request, redirect, Blueprint, abort
|
||||
|
||||
flask_blueprint = Blueprint('flow', __name__)
|
||||
|
||||
@flask_blueprint.route('/flow/getpostsbyboard/<board>')
|
||||
def get_post_by_board(board):
|
||||
return Response('WIP')
|
@ -19,10 +19,17 @@
|
||||
'''
|
||||
|
||||
# Imports some useful libraries
|
||||
import logger, config, threading, time
|
||||
import threading, time, locale, sys, os
|
||||
from onionrblockapi import Block
|
||||
import logger, config
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
||||
import flowapi # import after path insert
|
||||
flask_blueprint = flowapi.flask_blueprint
|
||||
|
||||
plugin_name = 'flow'
|
||||
PLUGIN_VERSION = '0.0.1'
|
||||
|
||||
class OnionrFlow:
|
||||
def __init__(self):
|
||||
@ -64,23 +71,23 @@ class OnionrFlow:
|
||||
time.sleep(1)
|
||||
try:
|
||||
while self.flowRunning:
|
||||
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
|
||||
logger.info('\n------------------------', prompt = False)
|
||||
content = block.getContent()
|
||||
# Escape new lines, remove trailing whitespace, and escape ansi sequences
|
||||
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)
|
||||
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
|
||||
logger.info('\n------------------------', prompt = False)
|
||||
content = block.getContent()
|
||||
# Escape new lines, remove trailing whitespace, and escape ansi sequences
|
||||
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)
|
||||
except KeyboardInterrupt:
|
||||
self.flowRunning = False
|
||||
|
||||
|
@ -61,20 +61,3 @@ def list_sentbox():
|
||||
if x['hash'] in deleted:
|
||||
sentbox_list.remove(x)
|
||||
return json.dumps(sentbox_list)
|
||||
'''
|
||||
@flask_blueprint.route('/mail/getsentbox')
|
||||
def list_sentbox():
|
||||
sentbox_list = sentboxdb.SentBox(c).listSent()
|
||||
sentbox_list_copy = list(sentbox_list)
|
||||
kv.refresh()
|
||||
deleted = kv.get('deleted_mail')
|
||||
if deleted is None:
|
||||
deleted = []
|
||||
for x in range(len(sentbox_list_copy)):
|
||||
if sentbox_list_copy[x]['hash'] in deleted:
|
||||
sentbox_list.remove(sentbox_list_copy[x]['hash'])
|
||||
else:
|
||||
sentbox_list[x]['name'] = contactmanager.ContactManager(c, sentbox_list_copy[x]['peer'], saveUser=False).get_info('name')
|
||||
|
||||
return json.dumps(sentbox_list)
|
||||
'''
|
@ -35,7 +35,7 @@ import sentboxdb, mailapi, loadinbox # import after path insert
|
||||
flask_blueprint = mailapi.flask_blueprint
|
||||
|
||||
def draw_border(text):
|
||||
#https://stackoverflow.com/a/20757491
|
||||
# This function taken from https://stackoverflow.com/a/20757491 by https://stackoverflow.com/users/816449/bunyk, under https://creativecommons.org/licenses/by-sa/3.0/
|
||||
lines = text.splitlines()
|
||||
width = max(len(s) for s in lines)
|
||||
res = ['┌' + '─' * width + '┐']
|
||||
|
@ -10,7 +10,7 @@
|
||||
<link rel='stylesheet' href='/shared/main/style.css'>
|
||||
<link rel='stylesheet' href='/mail/mail.css'>
|
||||
</head>
|
||||
<body>
|
||||
<body>
|
||||
<div id="infoOverlay" class='overlay'>
|
||||
</div>
|
||||
<div class='content'>
|
||||
|
@ -327,12 +327,6 @@ fetch('/friends/list', {
|
||||
}
|
||||
friendSelectParent.appendChild(option)
|
||||
}
|
||||
|
||||
for (var i = 0; i < keys.length; i++){
|
||||
|
||||
//friendSelectParent
|
||||
//alert(resp[keys[i]]['name'])
|
||||
}
|
||||
})
|
||||
setActiveTab('inbox')
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
8
onionr/static-data/www/private/main.css
Normal file
8
onionr/static-data/www/private/main.css
Normal file
@ -0,0 +1,8 @@
|
||||
.configEditor{
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.saveConfig{
|
||||
margin-top: 1em;
|
||||
}
|
18
onionr/static-data/www/shared/configeditor.js
Normal file
18
onionr/static-data/www/shared/configeditor.js
Normal file
@ -0,0 +1,18 @@
|
||||
var saveBtns = document.getElementsByClassName('saveConfig')
|
||||
var saveBtn = document.getElementsByClassName('saveConfig')[0]
|
||||
var configEditor = document.getElementsByClassName('configEditor')[0]
|
||||
var config = {}
|
||||
|
||||
fetch('/config/get', {
|
||||
headers: {
|
||||
"token": webpass
|
||||
}})
|
||||
.then((resp) => resp.json()) // Transform the data into json
|
||||
.then(function(resp) {
|
||||
config = resp
|
||||
configEditor.value = JSON.stringify(config)
|
||||
})
|
||||
|
||||
saveBtn.onclick = function(){
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user