diff --git a/onionr/api.py b/onionr/api.py index a77e95aa..bf42348a 100755 --- a/onionr/api.py +++ b/onionr/api.py @@ -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/', endpoint='homedata') + def homedata(path): + return send_from_directory('static-data/www/private/', path) + @app.route('/www/', 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/') def getBlocksByType(name): diff --git a/onionr/config.py b/onionr/config.py index fe093b57..11319b85 100755 --- a/onionr/config.py +++ b/onionr/config.py @@ -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(): diff --git a/onionr/httpapi/configapi/__init__.py b/onionr/httpapi/configapi/__init__.py new file mode 100644 index 00000000..5f5588af --- /dev/null +++ b/onionr/httpapi/configapi/__init__.py @@ -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 . +''' +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/') +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/', 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') \ No newline at end of file diff --git a/onionr/onionrutils.py b/onionr/onionrutils.py index 27c7fa2b..e3b9e49e 100755 --- a/onionr/onionrutils.py +++ b/onionr/onionrutils.py @@ -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: diff --git a/onionr/static-data/default-plugins/flow/flowapi.py b/onionr/static-data/default-plugins/flow/flowapi.py new file mode 100644 index 00000000..95d5fb4f --- /dev/null +++ b/onionr/static-data/default-plugins/flow/flowapi.py @@ -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 . +''' + +from flask import Response, request, redirect, Blueprint, abort + +flask_blueprint = Blueprint('flow', __name__) + +@flask_blueprint.route('/flow/getpostsbyboard/') +def get_post_by_board(board): + return Response('WIP') \ No newline at end of file diff --git a/onionr/static-data/default-plugins/flow/main.py b/onionr/static-data/default-plugins/flow/main.py index 2587df93..de406207 100755 --- a/onionr/static-data/default-plugins/flow/main.py +++ b/onionr/static-data/default-plugins/flow/main.py @@ -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 diff --git a/onionr/static-data/default-plugins/pms/mailapi.py b/onionr/static-data/default-plugins/pms/mailapi.py index 0a60e67c..c9df3a52 100644 --- a/onionr/static-data/default-plugins/pms/mailapi.py +++ b/onionr/static-data/default-plugins/pms/mailapi.py @@ -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) -''' \ No newline at end of file diff --git a/onionr/static-data/default-plugins/pms/main.py b/onionr/static-data/default-plugins/pms/main.py index 2a4c15a5..ce58c58e 100755 --- a/onionr/static-data/default-plugins/pms/main.py +++ b/onionr/static-data/default-plugins/pms/main.py @@ -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 + '┐'] diff --git a/onionr/static-data/www/mail/index.html b/onionr/static-data/www/mail/index.html index 08441075..81a0128e 100644 --- a/onionr/static-data/www/mail/index.html +++ b/onionr/static-data/www/mail/index.html @@ -10,7 +10,7 @@ - +
diff --git a/onionr/static-data/www/mail/mail.js b/onionr/static-data/www/mail/mail.js index cdc013e1..8c9b13d1 100644 --- a/onionr/static-data/www/mail/mail.js +++ b/onionr/static-data/www/mail/mail.js @@ -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') diff --git a/onionr/static-data/www/private/index.html b/onionr/static-data/www/private/index.html index 60ce3804..2b54cc99 100644 --- a/onionr/static-data/www/private/index.html +++ b/onionr/static-data/www/private/index.html @@ -6,8 +6,8 @@ Onionr - +
@@ -28,6 +28,13 @@


Mail - Friend Manager - Boards


+
+ Edit Configuration +
+ + +
+

Stats

🕰️ Uptime:

🖇️ Last Received Connection: Unknown

@@ -39,6 +46,7 @@ + \ No newline at end of file diff --git a/onionr/static-data/www/private/main.css b/onionr/static-data/www/private/main.css new file mode 100644 index 00000000..91a7b588 --- /dev/null +++ b/onionr/static-data/www/private/main.css @@ -0,0 +1,8 @@ +.configEditor{ + width: 100%; + height: 300px; +} + +.saveConfig{ + margin-top: 1em; +} \ No newline at end of file diff --git a/onionr/static-data/www/shared/configeditor.js b/onionr/static-data/www/shared/configeditor.js new file mode 100644 index 00000000..45a97d46 --- /dev/null +++ b/onionr/static-data/www/shared/configeditor.js @@ -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(){ + +} \ No newline at end of file