init
This commit is contained in:
commit
21c7f71971
3 changed files with 111 additions and 0 deletions
BIN
__pycache__/bot.cpython-310.pyc
Normal file
BIN
__pycache__/bot.cpython-310.pyc
Normal file
Binary file not shown.
101
bot.py
Normal file
101
bot.py
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
import os, time
|
||||||
|
import RNS
|
||||||
|
from LXMF import LXMRouter, LXMessage
|
||||||
|
from appdirs import AppDirs
|
||||||
|
from queue import Queue
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
# Core class influenced by https://github.com/chengtripp/lxmf_messageboard
|
||||||
|
# Bot syntax inspired by Discord.py and Telethon
|
||||||
|
|
||||||
|
class LXMFBot:
|
||||||
|
|
||||||
|
delivery_callbacks = []
|
||||||
|
queue = Queue(maxsize = 5)
|
||||||
|
|
||||||
|
def __init__(self, name='LXMFBot'):
|
||||||
|
|
||||||
|
# initialize identiy
|
||||||
|
self.name = name
|
||||||
|
dirs = AppDirs("LXMFBot", "randogoth")
|
||||||
|
idpath = os.path.join(dirs.user_data_dir, "identity")
|
||||||
|
self.announce_path = os.path.join(dirs.user_data_dir, "announce")
|
||||||
|
if not os.path.isfile(idpath):
|
||||||
|
RNS.log('No Primary Identity file found, creating new...', RNS.LOG_INFO)
|
||||||
|
id = RNS.Identity()
|
||||||
|
id.to_file(idpath)
|
||||||
|
self.id = RNS.Identity.from_file(idpath)
|
||||||
|
RNS.log('Loaded identity from file', RNS.LOG_INFO)
|
||||||
|
|
||||||
|
# start RNS and LXMFRouter
|
||||||
|
RNS.Reticulum(loglevel=RNS.LOG_VERBOSE)
|
||||||
|
self.router = LXMRouter(identity = self.id, storagepath = dirs.user_data_dir)
|
||||||
|
self.local = self.router.register_delivery_identity(self.id, display_name=name)
|
||||||
|
self.router.register_delivery_callback(self._message_received)
|
||||||
|
RNS.log('LXMF Router ready to receive on: {}'.format(RNS.prettyhexrep(self.local.hash)), RNS.LOG_INFO)
|
||||||
|
self._announce()
|
||||||
|
|
||||||
|
def _announce(self):
|
||||||
|
if os.path.isfile(self.announce_path):
|
||||||
|
with open(self.announce_path, "r") as f:
|
||||||
|
announce = int(f.readline())
|
||||||
|
else:
|
||||||
|
RNS.log('failed to open announcepath', RNS.LOG_DEBUG)
|
||||||
|
announce = 1
|
||||||
|
if announce > int(time.time()):
|
||||||
|
RNS.log('Recent announcement', RNS.LOG_DEBUG)
|
||||||
|
else:
|
||||||
|
with open(self.announce_path, "w") as af:
|
||||||
|
next_announce = int(time.time()) + 1800
|
||||||
|
af.write(str(next_announce))
|
||||||
|
self.local.announce()
|
||||||
|
RNS.log('Announcement sent, expr set 1800 seconds', RNS.LOG_INFO)
|
||||||
|
|
||||||
|
def received(self, function):
|
||||||
|
self.delivery_callbacks.append(function)
|
||||||
|
return function
|
||||||
|
|
||||||
|
def _message_received(self, message):
|
||||||
|
sender = RNS.hexrep(message.source_hash, delimit=False)
|
||||||
|
def reply(msg):
|
||||||
|
self.send(sender, msg)
|
||||||
|
for callback in self.delivery_callbacks:
|
||||||
|
obj = {
|
||||||
|
'lxmf' : message,
|
||||||
|
'reply' : reply,
|
||||||
|
'sender' : sender,
|
||||||
|
'content' : message.content.decode('utf-8')
|
||||||
|
}
|
||||||
|
msg = SimpleNamespace(**obj)
|
||||||
|
callback(msg)
|
||||||
|
|
||||||
|
def send(self, destination, message, title='Reply'):
|
||||||
|
try:
|
||||||
|
hash = bytes.fromhex(destination)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Invalid destination hash", RNS.LOG_ERROR)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not len(hash) == RNS.Reticulum.TRUNCATED_HASHLENGTH//8:
|
||||||
|
RNS.log("Invalid destination hash length", RNS.LOG_ERROR)
|
||||||
|
else:
|
||||||
|
id = RNS.Identity.recall(hash)
|
||||||
|
|
||||||
|
if id == None:
|
||||||
|
RNS.log("Could not recall an Identity for the requested address. You have probably never received an announce from it. Try requesting a path from the network first. In fact, let's do this now :)", RNS.LOG_ERROR)
|
||||||
|
RNS.Transport.request_path(hash)
|
||||||
|
RNS.log("OK, a path was requested. If the network knows a path, you will receive an announce with the Identity data shortly.", RNS.LOG_INFO)
|
||||||
|
else:
|
||||||
|
lxmf_destination = RNS.Destination(id, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery")
|
||||||
|
lxm = LXMessage(lxmf_destination, self.local, message, title=title, desired_method=LXMessage.DIRECT)
|
||||||
|
lxm.try_propagation_on_fail = True
|
||||||
|
self.queue.put(lxm)
|
||||||
|
|
||||||
|
def run(self, delay=10):
|
||||||
|
RNS.log(f'LXMF Bot `{self.name}` reporting for duty and awaiting messages...', RNS.LOG_INFO)
|
||||||
|
while True:
|
||||||
|
for i in list(self.queue.queue):
|
||||||
|
lxm = self.queue.get()
|
||||||
|
self.router.handle_outbound(lxm)
|
||||||
|
self._announce
|
||||||
|
time.sleep(delay)
|
||||||
10
randobot.py
Normal file
10
randobot.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
from bot import LXMFBot
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
bot = LXMFBot("Randobot")
|
||||||
|
|
||||||
|
@bot.received
|
||||||
|
def echo_msg(msg):
|
||||||
|
msg.reply(msg.content)
|
||||||
|
|
||||||
|
bot.run()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue