onionr/static-data/default-plugins/circles/main.py

177 lines
6.0 KiB
Python
Raw Normal View History

2020-01-15 06:25:16 +00:00
"""Onionr - Private P2P Communication.
2018-07-11 07:35:22 +00:00
2020-01-15 06:25:16 +00:00
This default plugin handles "flow" messages
(global chatroom style communication)
"""
import sys
import os
import deadsimplekv as simplekv
from utils import identifyhome, reconstructhash
from coredb import blockmetadb
import threading
import time
import locale
from onionrblocks.onionrblockapi import Block
import logger
import onionrblocks
from onionrutils import escapeansi, epoch, bytesconverter
locale.setlocale(locale.LC_ALL, '')
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
# import after path insert
import flowapi # noqa
"""
2018-07-11 07:35:22 +00:00
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/>.
2020-01-15 06:25:16 +00:00
"""
2018-07-11 07:35:22 +00:00
2019-04-27 15:43:16 +00:00
flask_blueprint = flowapi.flask_blueprint
security_whitelist = ['circles.circlesstatic', 'circles.circlesindex']
2018-07-11 07:35:22 +00:00
2020-03-28 05:16:42 +00:00
plugin_name = 'circles'
PLUGIN_VERSION = '0.1.0'
2018-07-11 07:35:22 +00:00
EXPIRE_TIME = 43200
2020-01-15 06:25:16 +00:00
2018-07-11 07:35:22 +00:00
class OnionrFlow:
def __init__(self):
self.alreadyOutputed = []
self.flowRunning = False
2019-07-29 03:00:38 +00:00
self.channel = ""
2018-07-11 07:35:22 +00:00
return
def start(self):
2020-01-15 06:25:16 +00:00
logger.warn(
"Please note: everything said here is public, " +
"even if a random channel name is used.", terminal=True)
message = ""
self.flowRunning = True
2018-12-09 17:29:39 +00:00
try:
2020-01-15 06:25:16 +00:00
self.channel = logger.readline(
"Enter a channel name or none for default:").strip()
except (KeyboardInterrupt, EOFError):
2018-12-09 17:29:39 +00:00
self.flowRunning = False
2019-07-29 03:00:38 +00:00
newThread = threading.Thread(target=self.showOutput, daemon=True)
newThread.start()
while self.flowRunning:
2019-07-29 03:00:38 +00:00
if self.channel == "":
self.channel = "global"
try:
2020-03-28 05:16:42 +00:00
message = logger.readline(f'\nInsert message into {plugin_name}:').strip().replace(
2020-01-15 06:25:16 +00:00
'\n', '\\n').replace('\r', '\\r')
except EOFError:
pass
except KeyboardInterrupt:
self.flowRunning = False
2018-12-09 17:29:39 +00:00
else:
if message == "q":
self.flowRunning = False
expireTime = epoch.get_epoch() + EXPIRE_TIME
2018-12-09 17:29:39 +00:00
if len(message) > 0:
logger.info('Inserting message as block...', terminal=True)
2020-01-15 06:25:16 +00:00
onionrblocks.insert(message, header='brd',
expire=expireTime,
meta = {
'ch': self.channel})
2020-03-28 05:16:42 +00:00
logger.info(f"{plugin_name} is exiting, goodbye", terminal=True)
return
def showOutput(self):
2020-09-07 03:18:23 +00:00
while isinstance(self.channel, type(None)) and self.flowRunning:
2018-12-09 17:29:39 +00:00
time.sleep(1)
try:
while self.flowRunning:
2019-07-29 03:00:38 +00:00
for block in blockmetadb.get_blocks_by_type('brd'):
2019-07-20 21:21:03 +00:00
if block in self.alreadyOutputed:
continue
2019-04-27 15:43:16 +00:00
block = Block(block)
2019-07-20 21:21:03 +00:00
b_hash = bytesconverter.bytes_to_str(block.getHash())
2019-04-27 15:43:16 +00:00
if block.getMetadata('ch') != self.channel:
continue
if not self.flowRunning:
break
2020-01-15 06:25:16 +00:00
logger.info('\n------------------------',
prompt=False, terminal=True)
2019-04-27 15:43:16 +00:00
content = block.getContent()
# Escape new lines, remove trailing whitespace, and escape ansi sequences
2020-01-15 06:25:16 +00:00
content = escapeansi.escape_ANSI(content.replace(
b'\n', b'\\n').replace(b'\r', b'\\r').strip().decode('utf-8'))
2020-01-15 06:25:16 +00:00
logger.info(block.getDate().strftime(
2020-09-07 03:18:23 +00:00
"%m/%d %H:%M") + ' - ' +
logger.colors.reset + content,
prompt=False, terminal=True)
2019-07-20 21:21:03 +00:00
self.alreadyOutputed.append(b_hash)
2019-04-27 15:43:16 +00:00
time.sleep(5)
2018-12-09 17:29:39 +00:00
except KeyboardInterrupt:
self.flowRunning = False
2018-07-11 07:35:22 +00:00
2020-01-15 06:25:16 +00:00
2020-03-28 05:16:42 +00:00
def on_circles_cmd(api, data=None):
2019-08-05 00:34:57 +00:00
OnionrFlow().start()
2020-01-15 06:25:16 +00:00
2020-03-28 05:16:42 +00:00
def on_circlesend_cmd(api, data=None):
err_msg = "Second arg is board name, third is quoted message"
try:
sys.argv[2]
except IndexError:
logger.error(err_msg, terminal=True)
try:
sys.argv[3]
except IndexError:
logger.error(err_msg, terminal=True)
bl = onionrblocks.insert(sys.argv[3], header='brd',
expire=(EXPIRE_TIME + epoch.get_epoch()),
meta={'ch': sys.argv[2]})
print(bl)
def on_softreset(api, data=None):
try:
os.remove(identifyhome.identify_home() + '/board-index.cache.json')
logger.info('Cleared Circles board cache')
except FileNotFoundError:
pass
2019-07-29 03:00:38 +00:00
2020-01-15 06:25:16 +00:00
2019-07-29 03:00:38 +00:00
def on_processblocks(api, data=None):
2020-01-15 06:25:16 +00:00
metadata = data['block'].bmetadata # Get the block metadata
2019-08-06 05:49:31 +00:00
if data['type'] != 'brd':
2019-08-05 23:09:04 +00:00
return
2019-07-29 03:00:38 +00:00
2020-01-15 06:25:16 +00:00
b_hash = reconstructhash.deconstruct_hash(
data['block'].hash) # Get the 0-truncated block hash
board_cache = simplekv.DeadSimpleKV(identifyhome.identify_home(
) + '/board-index.cache.json', flush_on_exit=False) # get the board index cache
2019-08-26 02:18:09 +00:00
board_cache.refresh()
2019-07-29 03:00:38 +00:00
# Validate the channel name is sane for caching
try:
ch = metadata['ch']
except KeyError:
ch = 'global'
ch_len = len(ch)
2019-08-05 23:09:04 +00:00
if ch_len == 0:
2019-07-29 03:00:38 +00:00
ch = 'global'
2019-08-05 23:09:04 +00:00
elif ch_len > 12:
2019-07-29 03:00:38 +00:00
return
2020-01-15 06:25:16 +00:00
2019-07-29 03:00:38 +00:00
existing_posts = board_cache.get(ch)
if existing_posts is None:
2019-08-26 02:18:09 +00:00
existing_posts = []
existing_posts.append(data['block'].hash)
board_cache.put(ch, existing_posts)
board_cache.flush()