arkanemoose / botbot Goto Github PK
View Code? Open in Web Editor NEWA meta-bot for Euphoria.
License: MIT License
A meta-bot for Euphoria.
License: MIT License
Could this project benefit from a wiki? We could have some proper documentation, good practices, in-depth tutorials and some example code from the community. There could even be a roadmap, showing where this project was going to go in the future.
Is there any way to set a bot to only reply to a certain sender (or set of senders)? If not, could this, or something that enables this to be accomplished, be added?
BotBot should be able to use regexes to match the sender of a message.
Here's what I'm thinking:
The snapshot system should be incremental.
I think the system should be something like this:
That way, no data is lost on a crash, and everything is easier.
The snapshot system doesn't have to "incremental" per se, but it should autosave in the way I described, i.e. it should write a new autosave file whenever a bot is created or killed.
Although the computation feature is powerful, an error-resilient bot must assume that any command may be the first one to be received by the bot, and initialize variables in every one. Workarounds (such as self-modifying commands that are invoked by update helper bots) exists, but are necessarily hacky. I propose some special syntax (say, (??INIT)
, which is not a valid regular expression) for a "pattern" whose corresponding replies are executed exactly once at the initialization of the bot.
Because of Euphoria's limit on message length, BotBot cannot show the whole list of bots in a single message. The message must be split up before being sent.
Snapshots do not currently work in the "redesign" branch.
With accounts rolled out now, it is technically possible to maintain a per-account "bot stash", where bots can be stored safely for later use. Would remove the need to have multiple active copies as backups of each other, and also mitigate "kill griefing".
The title should explain it quite well.
Feature suggestion: Assign each bot an UUID, and ensure bots with the same one aren't loaded twice.
!createbot @TestBot test -> normal reply -| inline reply
would do this:
[person] test
[TestBot] normal reply
[TestBot] inline reply
totallyhuman was looking for this feature and I think it would be easy to add similar to (sender) I found the place in botparser.py where this is done but I was having trouble knowing what to replicate.... it would just be a case of passing self.nickname to the parser and duplicating existing code but changing these three lines:
search_string = content.replace(EuphUtils.mention(sender), '(@sender)')
search_string = content.replace(sender, '(sender)')
search_string = content.replace(EuphUtils.mention(sender), '(@sender)').replace(sender, '(sender)')
to use the value sent to the parser from the botbotbots self.nickname (or the bot.nickname if it's sent from a botbotbot collection not the bot itself)
this was just a bit too complex for me without having access to a test environment.
-Etchy (now called Kaze Brightside on euphoria, my github changed too)
!sendbot and !to have a different syntax from !createbot. This should be updated so both syntaxes work.
Add some kind of way to retrieve the code if you are the creator. Will be especially useful when accounts are supported.
This is most likely because BotBot has not updated its list of botlings before the botling calls (+init)
[c+1] !createbot @testbot
│ (+init) -> !createbot @testbot2
│ [BotBot] Created @testbot.
[testbot] !createbot @testbot2
│ [BotBot] Created @testbot2.
This also lets botlings access the !load
, !save
, and !killall
commands.
I've noticed that you utilize a BotCollection in the code. This is good, but could it be inherited from the ExecGroup in my code? Here's a link showing what it can do: army.py.
Thanks for the suggestions, @CylonicRaider. I've put them here for reference.
uptimeutc
should be aliased/renamed to starttimeutc
BotBot complies with a significant portion of the bot standards, but we should aim for full compliance. Of course, bots created with BotBot can choose to ignore the standards (by setting an empty response), but by default, they should all comply.
Here's what we have so far:
(When a missing command is implemented, please check its corresponding box and provide the commit and issue that implements it, if any.)
(This issue should be closed once everything is checked.)
For some botlings, it might be benefitial to know the ID of the message currently being processed as well as the one of its parent in order to be able to make deductions about the tree structure. Therefore, I propose the addition of msgid
and parentid
variables, which are just that.
Certain approved users should be able to create bots that can surpass the spam detection limit, or the no-interaction rule, for projects that demand it. I'll make a PR implementing that.
If a botling is created with an certain type of invalid regular expression (^*$
was observed), it enters a bad state that renders it nonfunctional (thus making removal impossible (at least via the widely-known means)), and prevents shutdown of the entire BotBot.
Scrubbed stacktraces attached.
Stacktrace 1: Botling crashing
Exception in thread Thread-XXX:
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/usr/lib/python3.4/threading.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "$EUPY/euphoria/room.py", line 120, in run
if self.connection.receive_data():
File "$EUPY/euphoria/connection.py", line 142, in receive_data
self.handle_packet(json.loads(raw))
File "$EUPY/euphoria/connection.py", line 186, in handle_packet
i(packet)
File "$EUPY/euphoria/chat_room.py", line 22, in handle_message
self.handle_chat(message["data"])
File "$BOTBOT/botbot/botbotbot.py", line 72, in handle_chat
self.recv_message(message['content'], message['parent'], message['id'], message['sender']['name'], message['sender']['id'], message['time'], self.room_name)
File "$BOTBOT/botbot/botbotbot.py", line 171, in recv_message
for message in messages:
File "$BOTBOT/botbot/botparser.py", line 71, in get_messages
regex = re.compile(regex_string, re.IGNORECASE)
File "/usr/lib/python3.4/re.py", line 223, in compile
return _compile(pattern, flags)
File "/usr/lib/python3.4/re.py", line 294, in _compile
p = sre_compile.compile(pattern, flags)
File "/usr/lib/python3.4/sre_compile.py", line 568, in compile
p = sre_parse.parse(p, flags)
File "/usr/lib/python3.4/sre_parse.py", line 760, in parse
p = _parse_sub(source, pattern, 0)
File "/usr/lib/python3.4/sre_parse.py", line 370, in _parse_sub
itemsappend(_parse(source, state))
File "/usr/lib/python3.4/sre_parse.py", line 579, in _parse
raise error("nothing to repeat")
sre_constants.error: nothing to repeat
Stacktrace 2: BotBot not shutting down
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/usr/lib/python3.4/threading.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "$EUPY/euphoria/execgroup.py", line 50, in run
self.execs[i].thread.join()
File "/usr/lib/python3.4/threading.py", line 1055, in join
raise RuntimeError("cannot join thread before it is started")
RuntimeError: cannot join thread before it is started
A bot should be able to respond with !suppress
to have no response. This is different from syntax like []
because []
is evaluated at compile-time to become no response, so commands like !ping
and !help
use their autogenerated values. !suppress
would be evaluated at runtime, causing no response to !ping
or !help
.
This is a variant of #30 that now occurs due to 53a8678.
Logs contain many copies of the following:
Traceback (most recent call last):
File "/home/user/.local/lib/python3.4/site-packages/botbot-0.2.0-py3.4.egg/botbot/snapshot.py", line 150, in load_current
uuid=packed_bot.get('uuid', None)
File "/home/user/.local/lib/python3.4/site-packages/botbot-0.2.0-py3.4.egg/botbot/botcollection.py", line 44, in create
raise ValueError('bot with specified UUID already exists')
ValueError: bot with specified UUID already exists
BotBot (presumably) then outputs: Successfully loaded 0 of x bots from snapshot.
The following also shows up sometimes, but less frequently and with no apparent correlation to the above error:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/usr/lib/python3.4/threading.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "/home/user/.local/lib/python3.4/site-packages/eupy-1.0-py3.4.egg/euphoria/execgroup.py", line 50, in run
self.execs[i].thread.join()
File "/usr/lib/python3.4/threading.py", line 1055, in join
raise RuntimeError("cannot join thread before it is started")
RuntimeError: cannot join thread before it is started
I am not sure this error is related to the previous error, but I am including it for completeness.
A !restart @BotBot
fixes this issue until the next disruptive event.
Someone mentioned this at some point. The lack of variables is a little annoying, as state cannot be stored.
This could be a really useful addition in the future, capable of being able to take BotBot to the next level.
Could/should this be implemented? The current syntax might make storing of vars quite complex. It could be done though. And would definitely be worth it.
Sometimes bots will get stuck on a different name, or several versions will end up in one room.
Having a syntax like !ukill <uuid>
would allow easier management of such accidents.
When a custom nickname is passed to the bottom via command line arguments, the nickname in the help text does not change. This is a consequence of #7.
When creating a bot using a git repo, @BotBot should create a bot from the code there.
For example,
!createbot @GitBot GIT_URL
!ping
with an @-mention triggers reponses from bots that are not mentioned.
Can't believe I just noticed this, but notice this line where the !sendbot code should be.
It is generally seen as bad practice to inherit from a thread. It is better to write the bot and then run it from the thread.
Something like this:
import threading
def foo():
for i in range(2000):
print(i)
t = threading.Thread(target=foo)
t.start()
t.join()
Also, you don't need to worry about threads really at all if you're planning to use my bot lib. You can in fact have a group of bots which manages the threads and everything. You just write the bot as normal and then the ExecutableGroup manages it.
Cause is still unknown. Some botlings remain, fully functional, but the majority do not return.
Things I know:
Possible causes:
quit()
is being called prematurelyTo do this, the BotBot class should be an ExecGroup managing multiple BotBots in different rooms.
The state of the codebase at the moment is a little bit messy. So, it must be cleaned up a bit.
I suggest that the best way to do this is to try to seperate some objects and functions into seperate modules and to try to make a class that wraps the whole BotBot.
@BotBot responds to !help randomstring @Anotherbotname
or !help randomstring
!help @BotBot
-> long help message
!help
-> short help message
!help randomstring @AnotherBot
-> no help message
!help randomstring
-> no help message
!help @BotBot
-> long help message
!help
-> short help message
!help randomstring @AnotherBot
-> short help message
!help randomstring
-> short help message
!help randomstring
or !help randomstring @anotherbot
Require !help
to be only contents of message for @BotBot to give short help message. I'll make the fix in my fork and lodge a PR.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.