Onionr/onionr/static-data/default-plugins/flow/main.py
2019-08-06 00:49:31 -05:00

136 lines
5.2 KiB
Python
Executable File

'''
Onionr - Private P2P Communication
This default plugin handles "flow" messages (global chatroom style communication)
'''
'''
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/>.
'''
# Imports some useful libraries
import threading, time, locale, sys, os
from onionrblockapi import Block
import logger, config, onionrblocks
from onionrutils import escapeansi, epoch, bytesconverter
locale.setlocale(locale.LC_ALL, '')
from coredb import blockmetadb
from utils import identifyhome, reconstructhash
import deadsimplekv as simplekv
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):
self.alreadyOutputed = []
self.flowRunning = False
self.channel = ""
return
def start(self):
logger.warn("Please note: everything said here is public, even if a random channel name is used.", terminal=True)
message = ""
self.flowRunning = True
try:
self.channel = logger.readline("Enter a channel name or none for default:").strip()
except (KeyboardInterrupt, EOFError) as e:
self.flowRunning = False
newThread = threading.Thread(target=self.showOutput, daemon=True)
newThread.start()
while self.flowRunning:
if self.channel == "":
self.channel = "global"
try:
message = logger.readline('\nInsert message into flow:').strip().replace('\n', '\\n').replace('\r', '\\r')
except EOFError:
pass
except KeyboardInterrupt:
self.flowRunning = False
else:
if message == "q":
self.flowRunning = False
expireTime = epoch.get_epoch() + 43200
if len(message) > 0:
logger.info('Inserting message as block...', terminal=True)
onionrblocks.insert(message, header='brd', expire=expireTime, meta={'ch': self.channel})
logger.info("Flow is exiting, goodbye", terminal=True)
return
def showOutput(self):
while type(self.channel) is type(None) and self.flowRunning:
time.sleep(1)
try:
while self.flowRunning:
for block in blockmetadb.get_blocks_by_type('brd'):
if block in self.alreadyOutputed:
continue
block = Block(block)
b_hash = bytesconverter.bytes_to_str(block.getHash())
if block.getMetadata('ch') != self.channel:
continue
if not self.flowRunning:
break
logger.info('\n------------------------', prompt = False, terminal=True)
content = block.getContent()
# Escape new lines, remove trailing whitespace, and escape ansi sequences
content = escapeansi.escape_ANSI(content.replace('\n', '\\n').replace('\r', '\\r').strip())
logger.info(block.getDate().strftime("%m/%d %H:%M") + ' - ' + logger.colors.reset + content, prompt = False, terminal=True)
self.alreadyOutputed.append(b_hash)
time.sleep(5)
except KeyboardInterrupt:
self.flowRunning = False
def on_flow_cmd(api, data=None):
OnionrFlow().start()
def on_init(api, data = None):
'''
This event is called after Onionr is initialized, but before the command
inputted is executed. Could be called when daemon is starting or when
just the client is running.
'''
return
def on_processblocks(api, data=None):
metadata = data['block'].bmetadata # Get the block metadata
if data['type'] != 'brd':
return
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') # get the board index cache
# Validate the channel name is sane for caching
try:
ch = metadata['ch']
except KeyError:
ch = 'global'
ch_len = len(ch)
if ch_len == 0:
ch = 'global'
elif ch_len > 12:
return
existing_posts = board_cache.get(ch)
if existing_posts is None:
existing_posts = ''
check_list = existing_posts.split(',')
if len(check_list) > 30:
check_list.pop(0)
existing_posts = ','.join(check_list)
board_cache.put(ch, '%s,%s' % (existing_posts, b_hash))
board_cache.flush()