chr-1x / ananas Goto Github PK
View Code? Open in Web Editor NEWThe Python Bot Framework for Mastodon
License: MIT License
The Python Bot Framework for Mastodon
License: MIT License
I run a number of bots and when they error out, which happens pretty regularly due to network flakiness etc, they keep sending DMs that I cannot even delete without logging in as the bot and removing them.
Would be great if that could be redirected into a logfile or even as email and I can filter it there. I am not sure just because it is a mastodon bot that DMing error messages is the best thing.
If you have a fork of this repo, heads up that the history was rewritten to remove my deadname; this roughly corresponded with a move from master
to main
for the default branch of the repo so hopefully it should be easy to update. Thank you for contributing!
In true cron, to schedule something bi-hourly, you'd set the hours column to "*/2"
As far as I can tell, in ananas, the only way to do it is by setting
@schedule(hour=2)
@schedule(hour=4)
@schedule(hour=6)
@schedule(hour=8)
# etc...
or by using an interval of 3600*2
It'd be nice if ananas could support either */2
syntax, or at least passing lists so you could supply the hours in one statement like:
@schedule(hour=[hour for hour in range(0, 24, 2)])
After running a bot or bots for a while (on a scale of days) this (extremely long, so pastebinned) error is thrown and the bots no longer respond to @replies. @shutdown functions are still called, however. May be related to psf/requests#4248 . Seems to show up when people are making GET requests with the Requests library. Might be caused by poor behavior by the mastodon server? Could be worked-around by catching this error (seems to be about a failure of a persistent connection) and reopening that connection as a result.
The ananas version currently in PyPI doesn't include the "async->run_async" fix (b33bba8) yet, while the current version of Mastodon.py already does, resulting in errors like this:
Traceback (most recent call last):
File "/home/lordminx/.local/share/virtualenvs/glitch_art-cmsPNbAw/lib/python3.6/site-packages/ananas/run.py", line 44, in main
.format(module, botclass, args.config, bot, args.interactive, args.verbose))
File "", line 1, in
File "/home/lordminx/.local/share/virtualenvs/glitch_art-cmsPNbAw/lib/python3.6/site-packages/ananas/ananas.py", line 269, in init
self.startup()
File "/home/lordminx/.local/share/virtualenvs/glitch_art-cmsPNbAw/lib/python3.6/site-packages/ananas/ananas.py", line 332, in startup
self.stream = self.mastodon.stream_user(self, async=True)
TypeError: stream_user() got an unexpected keyword argument 'async'
see above, thankfully i had a copy of it elsewhere
EOI
What it says on the tin
I've been running a bot with ananas for years now and occasionally it gets stucks and stops running its interval functions anymore, I could not figure out why for the longest time, but I think I've got it: it's when an error occurs during normal function and subsequent error reporting fails.
I have an admin
set in the bot's config, the bot encounters an error (say, the server is down), the default error handler tries to report the error by sending a DM to the admin, which also doesn't work because the server is down, and it goes completely silent until I restart ananas.
[2023-08-08 01:53:01] apod.accept_one_page_of_follow_requests: Exception encountered in @interval function: MastodonInternalServerError('Mastodon API returned error', 500, 'Internal Server Error', None)
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/ananas/ananas.py", line 377, in interval_threadproc
f()
File "/usr/local/lib/python3.10/site-packages/apod/__init__.py", line 360, in accept_one_page_of_follow_requests
follow_requests = self.mastodon.follow_requests()
File "/usr/local/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/usr/local/lib/python3.10/site-packages/mastodon/utility.py", line 49, in wrapper
return function(self, *args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/mastodon/relationships.py", line 71, in follow_requests
return self.__api_request('GET', '/api/v1/follow_requests', params)
File "/usr/local/lib/python3.10/site-packages/mastodon/internals.py", line 297, in __api_request
raise ex_type('Mastodon API returned error', response_object.status_code, response_object.reason, error_msg)
mastodon.errors.MastodonInternalServerError: ('Mastodon API returned error', 500, 'Internal Server Error', None)
Exception in thread Thread-1 (interval_threadproc):
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/ananas/ananas.py", line 377, in interval_threadproc
f()
File "/usr/local/lib/python3.10/site-packages/apod/__init__.py", line 360, in accept_one_page_of_follow_requests
follow_requests = self.mastodon.follow_requests()
File "/usr/local/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/usr/local/lib/python3.10/site-packages/mastodon/utility.py", line 49, in wrapper
return function(self, *args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/mastodon/relationships.py", line 71, in follow_requests
return self.__api_request('GET', '/api/v1/follow_requests', params)
File "/usr/local/lib/python3.10/site-packages/mastodon/internals.py", line 297, in __api_request
raise ex_type('Mastodon API returned error', response_object.status_code, response_object.reason, error_msg)
mastodon.errors.MastodonInternalServerError: ('Mastodon API returned error', 500, 'Internal Server Error', None)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/threading.py", line 1009, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.10/threading.py", line 946, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.10/site-packages/ananas/ananas.py", line 380, in interval_threadproc
self.report_error(error, f.__name__)
File "/usr/local/lib/python3.10/site-packages/ananas/ananas.py", line 509, in report_error
f(error)
File "/usr/local/lib/python3.10/site-packages/ananas/ananas.py", line 498, in default_report_handler
self.mastodon.status_post(("@{} ERROR REPORT from {}:\n{}"
File "/usr/local/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/usr/local/lib/python3.10/site-packages/mastodon/utility.py", line 49, in wrapper
return function(self, *args, **kwargs)
File "/usr/local/lib/python3.10/site-packages/mastodon/statuses.py", line 248, in status_post
return self.__status_internal(
File "/usr/local/lib/python3.10/site-packages/mastodon/statuses.py", line 182, in __status_internal
return self.__api_request('POST', '/api/v1/statuses', params, headers=headers, use_json=use_json)
File "/usr/local/lib/python3.10/site-packages/mastodon/internals.py", line 297, in __api_request
raise ex_type('Mastodon API returned error', response_object.status_code, response_object.reason, error_msg)
mastodon.errors.MastodonInternalServerError: ('Mastodon API returned error', 500, 'Internal Server Error', None)
Note the second exception that happens within the default error handler
Line 43 in e4625a3
I've had an issue with this line, and had to change it to the following one in order to make my project working:
exec("from {0}.{1} import {1}; bots.append({1}('{2}', name='{3}', interactive={4}, verbose={5}))"
I've got a bot python file in custom/ArchiveBot.py
and my config.cfg
contains the following class: class = custom.ArchiveBot
With the current line exec("from {0} import {1}
, it return the following error:
/home/alx/.local/bin/ananas: fatal exception loading bot archive_bot: TypeError("'module' object is not callable",)
Traceback (most recent call last):
File "/home/alx/.local/lib/python3.6/site-packages/ananas/run.py", line 44, in main
.format(module, botclass, args.config, bot, args.interactive, args.verbose))
File "<string>", line 3, in <module>
TypeError: 'module' object is not callable
looks like this repo is one release behind pypi
When ananas closes, it writes the running bots' current configuration information into the indicated config file. However, this appears to have the undesired result of removing any comments that were in the original configuration file.
This means, among other things, that you can't simply comment out the configuration of a bot you temporarily don't want to run.
Is there a way to change this so that configparser.ConfigParser preserves the comments in the original file?
Seems like deleted config keys and values still get written to the config file
$ cat ananas.cfg
[test]
class = test.TestBot
domain = chitter.xyz
client_id = xxxxxxxxxxxx
client_secret = yyyyyyyyyyyy
access_token = zzzzzzzzzzzz
$ cat test.py
import ananas
class TestBot(ananas.PineappleBot):
def start(self):
self.config["secret"] = "my brain IBM"
self.config.save()
del self.config["secret"]
self.config.save()
$ ananas ananas.cfg
range(0, 60, 2)
range(0, 60, 2)
range(0, 60, 1)
range(0, 60, 1)
[2022-04-22 10:25:16] test.config: Loading configuration from ananas.cfg
[2022-04-22 10:25:16] test: Starting TestBot test
[2022-04-22 10:25:16] test.config: Saving configuration to ananas.cfg...
[2022-04-22 10:25:16] test.config: Done.
[2022-04-22 10:25:16] test.config: Saving configuration to ananas.cfg...
[2022-04-22 10:25:16] test.config: Done.
[2022-04-22 10:25:16] test: Startup complete.
^C[2022-04-22 10:25:31] test: Stopping TestBot test
[2022-04-22 10:25:31] test.config: Saving configuration to ananas.cfg...
[2022-04-22 10:25:31] test.config: Done.
Shutdown complete
$ cat ananas.cfg
[test]
class = test.TestBot
domain = chitter.xyz
client_id = xxxxxxxxxxxx
client_secret = yyyyyyyyyyyy
access_token = zzzzzzzzzzzz
secret = my brain IBM
Currently if a config.cfg file has no DEFAULT section an ugly error is thrown. This should be handled more gracefully.
In particular the four-line config.cfg in the README fails because there is no DEFAULT section.
Gah! just discovered that this has already been fixed in 5c8a191 but apparently not pushed downstream far enough (yet).
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.