Compare commits

...

2 Commits

Author SHA1 Message Date
Nathan Schneider
2207f0add2 added placeholder for Mastodon interactions override 2024-07-19 15:11:32 -06:00
Nathan Schneider
aed1d708c4 Masto govbot basics running 2024-07-19 15:08:19 -06:00
5 changed files with 151 additions and 10 deletions

5
.gitignore vendored
View File

@ -1,2 +1,5 @@
*/data/* */data/*
!*/data/placeholder !*/data/placeholder
# ignore Mastodon credentials
modpol_mastodon/creds/

View File

@ -1,25 +1,43 @@
# Modpol for Minetest # Modpol
![](lib/empire-modpol.png) ![](lib/empire-modpol.png)
Modpol, short for "modular politics," enables diverse governance processes on multi-user platforms. It offers a library with which users can choose, modify, and create modules that add specific governance functionalities. Modpol, short for "modular politics," enables diverse governance processes on multi-user platforms. It offers a library with which users can choose, modify, and create modules that add specific governance functionalities.
This implementation is a mod for [Minetest](https://minetest.net), a free/open-source voxel game. It is designed to be adapted to other multi-user platforms that also employ Lua as an extension language.
**Learn more at [modpol.net](https://modpol.net).** **Learn more at [modpol.net](https://modpol.net).**
## Installation in Minetest ## Modpol for Minetest
To use this in Minetest, simply install it in your `mods/` or `worldmods/` folder. Minetest will load `init.lua`. This implementation is a mod for [Minetest](https://minetest.net), a free/open-source voxel game. To use in Minetest, simply install the full codebase in your `mods/` or `worldmods/` folder. Minetest will load `init.lua`.
In the game, open the Modpol dashboard with the command `/mp`. In the game, open the Modpol dashboard with the command `/mp`.
For testing purposes, players with the `privs` privilege (generally admins) can use the `/mptest` command, which resets all the orgs and opens a dashboard.\ For testing purposes, players with the `privs` privilege (generally admins) can use the `/mptest` command, which resets all the orgs and opens a dashboard.
## Mastodon Govbot
## Standalone Version on the Command Line Modpol can operate a governance-supporting bot for communities on [Mastodon](https://joinmastodon.org), an open social network.
Modpol can also be used independently of Minetest as a command-line tool. Currently command-line use of modpol requires a Unix-style system, but it is intended to become more fully platform independent. This version utilizes and requires the installation of [lupa](https://github.com/scoder/lupa), which integrates Lua into Python, and [Mastodon.py](https://pypi.org/project/Mastodon.py/), a Python library for interacting with the Mastodon API.
*To do: explain how to set up the bot on the server.*
* Install Python on your system and the two required libraries:
- `pip install lupa`
- `pip install Mastodon.py`
* Set up files `clientcred.secret` and `usercred.secret` in the `modpol_mastodon/creds/` directory, using the account settings in Mastodon
Once it is configured, to initialize the bot, run from Modpol's base directory:
```
python govbot.py
```
This in turn calls login-mastodon.py, which initializes Modpol and the bot.
## Command Line
Modpol can also be used as a command-line tool. Currently command-line use of modpol requires a Unix-style system, but it is intended to become more fully platform independent.
The command-line version is in the `modpol` subdirectory. To run the program on Unix systems in CLI mode, install lua or luajit and execute the following in this directory: The command-line version is in the `modpol` subdirectory. To run the program on Unix systems in CLI mode, install lua or luajit and execute the following in this directory:
@ -38,7 +56,11 @@ In the interpreter, for a list of global functions and tables, use `modpol.menu(
## Storage ## Storage
The persistent storage method may be chosen in `modpol.lua`. If available, Modpol uses Minetest's built-in StorageRef system for Minetest 5.*. If that is not available, or in CLI mode, data will be stored in a data directory at `modpol_core/data/`. This will contain a log file and serialized program data files. The persistent storage method may be chosen in `modpol.lua`.
By default, data will be stored in a data directory at `modpol_core/data/`. This will contain a log file and serialized program data files.
For Minetest: If available, Modpol uses Minetest's built-in StorageRef system for Minetest 5.*.
## Documentation ## Documentation

113
govbot.py Normal file
View File

@ -0,0 +1,113 @@
# MODPOL GOVBOT
# A Python bridge between Modpol and Mastodon
## Initialize Modpol ##
import lupa
# Create a Lua runtime
lua = lupa.LuaRuntime(unpack_returned_tuples=True)
# Load your Lua script
script_path = 'login_mastodon.lua'
with open(script_path, 'r') as f:
lua.execute(f.read())
print("Loaded Modpol into Govbot")
# To do: load all override files
# If your Lua script defines functions, you can call them from Python
#result = lua.globals().your_function_name() # Replace with your actual function name
#print("Result from Lua:", result)
## Initialize Mastodon ##
from mastodon import Mastodon
# ^ https://mastodonpy.readthedocs.io/en/stable/#
import time
import datetime
# ^ https://github.com/HikaruSama233/mastodon_autoreply_bot_template/blob/main/bot_template.py
# Variables
## Character maximum for the server
char_max = 500
# Connect to Mastodon
govbot = Mastodon(
client_id='modpol_mastodon/creds/clientcred.secret',
access_token = 'modpol_mastodon/creds/usercred.secret')
print("Signed in to Mastodon")
# Handle notification events
def handle_event(event):
print("{} Handling notification ".format(datetime.datetime.now())
+ str(event['id']))
if 'mention' in event['type']:
mention_username = event['account']['username']
print(str(event['id']) + ": mention from @"
+ mention_username)
# Command handling
# perhaps move this to a separate Interfaces file
if "!dashboard" in event['status']['content']:
govbot.status_reply(event['status'],
"[dashboard here]")
print("{} Replied to ".format(datetime.datetime.now())
+ str(event['id']))
# To do: if DM
else:
govbot.status_reply(event['status'],
"Thanks for mentioning me!")
print("{} Replied to ".format(datetime.datetime.now())
+ str(event['id']))
## ADD OTHER IF STATEMENTS HERE
else:
govbot.status_reply(event['status'],
"I'm not sure how to parse that.")
print("{} Posted error message ".format(datetime.datetime.now())
+ str(event['id']))
# Check notifications
events_queue = {}
def check_events():
notifications = govbot.notifications(mentions_only=True)
current_time = datetime.datetime.now()
if len(notifications) > 0:
print("{} Total notifications {}".format(current_time, len(notifications)))
events_queue = notifications
while len(events_queue) > 0:
id = events_queue[0]['id']
handle_event(events_queue.pop(0)) # removes event from queue
govbot.notifications_dismiss(id)
elif str(current_time.minute) == '0':
print("{} No notifications".format(current_time))
# Initialization
# Delete past posts (while we are testing)
## Get account information
account_info = govbot.account_verify_credentials()
## Extract and print account ID
acc_id = account_info['id']
## Fetch the bot's posts
old_posts = govbot.account_statuses(id=acc_id)
## Delete
for post in old_posts:
govbot.status_delete(id=post.id)
# Delete past notifications
govbot.notifications_clear()
print("{} Initialized".format(datetime.datetime.now()))
first_post = "Commands:"
first_post += "\n!dashboard: View dashboard"
govbot.status_post(first_post[:char_max])
while 1:
# Check every 5 seconds
time.sleep(5)
if len(events_queue) == 0:
check_events()

2
login_mastodon.lua Normal file
View File

@ -0,0 +1,2 @@
dofile("modpol_core/modpol.lua")

View File

@ -0,0 +1 @@
(placeholder)