initial commit
This commit is contained in:
parent
dc52922587
commit
c85485f8f3
10
README.md
10
README.md
|
@ -1,2 +1,12 @@
|
|||
# cstate-pusher
|
||||
Simple script to send status notifications to CSTATE, XMPP and Fediverse. Script requires slixmpp python package and perhaps other that aren't included by default (note: need to check what is needed to be loaded and either list it or create requirenments file)
|
||||
|
||||
To configure, you need to add example.conf to `~/.config/cstate-pusher.conf` and fill in needed credentials. If you use pleroma/akkoma there is no straight forward way to obtain token. Follow those steps:
|
||||
`curl -s -S -i -X POST -F client_name="Cstate pusher" -F redirect_uris="urn:ietf:wg:oauth:2.0:oob" -F scopes="read write" https://social.example.com/api/v1/apps`
|
||||
This will give you response with `client_id and` `client_secret`.
|
||||
Now run this:
|
||||
`curl -s -S -i -X POST -F client_id="<client_id>" -F client_secret="<secret>" redirect_uri="urn:ietf:wg:oauth:2.0:oob" -F scope="read,write" -F grant_type="password" -F username="<account_username>" -F password="<account_password>" https://social.example.com/oauth/token`
|
||||
|
||||
Copy `access_token` to your `cstate-pusher.conf` file under `[Fedi][token]` section.
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
[Fedi]
|
||||
fediurl = 'http://social.example.com'
|
||||
token = changeme
|
||||
|
||||
|
||||
[XMPP]
|
||||
userjid = 'usee@example.com'
|
||||
nickname = 'User'
|
||||
password = 'changeme'
|
||||
roomjid = 'test@chat.example.com'
|
||||
|
||||
[GIT]
|
||||
repo_path = "/path/to/your/local/repository"
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
# Simple script to send status information to cstate, xmpp and fediverse
|
||||
|
||||
#Load libs
|
||||
import questionary
|
||||
from datetime import datetime
|
||||
import asyncio
|
||||
import time
|
||||
import requests
|
||||
import slixmpp
|
||||
import os
|
||||
import configparser
|
||||
import signal
|
||||
import sys
|
||||
import git
|
||||
from getpass import getpass
|
||||
|
||||
# Load configuration from the file
|
||||
home = os.path.expanduser("~")
|
||||
config_file = os.path.join(home, ".config", "cstate-pusher.conf")
|
||||
config = configparser.ConfigParser()
|
||||
config.read(config_file)
|
||||
|
||||
tempalte = "default"
|
||||
post_tpl = "default"
|
||||
ftitle = ""
|
||||
fdate = ""
|
||||
|
||||
### Wizard
|
||||
def multiline_input(prompt_message):
|
||||
print(prompt_message)
|
||||
result = []
|
||||
while True:
|
||||
line = input()
|
||||
if line == "" and (len(result) == 0 or result[-1] == ""):
|
||||
break
|
||||
result.append(line)
|
||||
return "\n ".join(result)
|
||||
|
||||
def generate_questions(informational):
|
||||
default_title = "Maintenance window" if informational else "Issue -"
|
||||
now = datetime.now()
|
||||
default_time = "21:00" if informational else now.strftime('%H:%M')
|
||||
current_date = datetime.now().strftime('%Y-%m-%d')
|
||||
|
||||
questions = [
|
||||
{
|
||||
'type': 'input',
|
||||
'name': 'title',
|
||||
'message': 'Enter the title:',
|
||||
'default': default_title
|
||||
},
|
||||
{
|
||||
'type': 'input',
|
||||
'name': 'time',
|
||||
'message': 'Enter the time (HH:MM):',
|
||||
'default': default_time
|
||||
},
|
||||
{
|
||||
'type': 'input',
|
||||
'name': 'date',
|
||||
'message': 'Enter the date (YYYY-MM-DD):',
|
||||
'default': current_date
|
||||
},
|
||||
{
|
||||
'type': 'confirm',
|
||||
'name': 'pin',
|
||||
'message': 'Do you want to pin it?',
|
||||
'default': True
|
||||
}
|
||||
]
|
||||
|
||||
if informational:
|
||||
questions.append(
|
||||
{
|
||||
'type': 'checkbox',
|
||||
'name': 'service_list',
|
||||
'message': 'Choose services',
|
||||
'choices': ['Email Server - (IMAP/POP3/SMTP)', 'Webmail (https://webmail.disroot.org)', 'Nextcloud - (https://cloud.disroot.org)', 'XMPP Chat Server - (XMPP)', 'XMPP Webchat - (https://webchat.disroot.org)', 'Etherpad (https://pad.disroot.org)', 'PrivateBin - (https://bin.disroot.org)', 'Lufi - (https://upload.disroot.org)', 'SearX - (https://search.disroot.org)', 'Jitsi - (https://calls.disroot.org)', 'Forgejo - (https://git.disroot.org)', 'Mumble - (https://mumble.disroot.org)', 'Cryptpad - (https://cryptpad.disroot.org)', 'Akkoma - (https://fe.disroot.org)', 'LibreTranslate - (https://translate.disroot.org)']
|
||||
}
|
||||
)
|
||||
else:
|
||||
questions.extend([
|
||||
{
|
||||
'type': 'list',
|
||||
'name': 'severity',
|
||||
'message': 'Choose an option:',
|
||||
'choices': [
|
||||
"down",
|
||||
"disrupted",
|
||||
"notice"
|
||||
],
|
||||
},
|
||||
{
|
||||
'type': 'checkbox',
|
||||
'name': 'service_list',
|
||||
'message': 'Choose services',
|
||||
'choices': ['Calls', 'Mail', 'Server', 'Webmail', 'Cloud', 'XMPP Chat server', 'XMPP Webchat', 'Pad', 'Bin', 'Upload', 'Searx', 'Git', 'Cryptpad', 'User Password management', 'Disroot.org', 'Website', 'Files', 'Gallery', 'Calendar', 'Contacts', 'Tasks', 'Notes', 'Talk', 'Bookmarks', 'Circles', 'Deck', 'Cospend', 'Forms', 'Appointments']
|
||||
},
|
||||
{
|
||||
'type': 'input',
|
||||
'name': 'content',
|
||||
'message': 'Add your content:',
|
||||
},
|
||||
])
|
||||
|
||||
return questions
|
||||
|
||||
def launch_wizard():
|
||||
global post_tpl, template, ftitle, fdate
|
||||
informational = questionary.confirm("Is it a Maintenance entry?").ask()
|
||||
|
||||
questions = generate_questions(informational)
|
||||
|
||||
answers = questionary.prompt(questions)
|
||||
ftitle = answers['title']
|
||||
fdate = answers['date']
|
||||
date_obj = datetime.strptime(fdate, '%Y-%m-%d')
|
||||
day = date_obj.strftime('%A')
|
||||
|
||||
if informational:
|
||||
services = "".join([f" - {service}\n" for service in answers['service_list']])
|
||||
template = f"""---
|
||||
title: 🔧️ {answers['title']} 🔧️
|
||||
date: {answers['date']} {answers['time']}:00
|
||||
informational: {informational}
|
||||
section: issue
|
||||
pin: {answers['pin']}
|
||||
---
|
||||
On {day} starting from {answers['time']} CET we are going to do some maintenance work. We will make sure to keep as minimal downtime as possible. Following services will not be affected by this migration:
|
||||
{services}
|
||||
"""
|
||||
post_tpl = f"""🔧️ {answers['title']} 🔧️
|
||||
On {day} starting from {answers['time']} CET we are going to do some maintenance work. We will make sure to keep as minimal downtime as possible. Following services will not be affected by this migration:
|
||||
{services}
|
||||
_.~"~._.~"~._.~"~._.~"~.__.~"~._.~"~._.~"~._.~"~.__.~"~._.~"~._.~"~.__
|
||||
"""
|
||||
else:
|
||||
services = "".join([f" - {service}\n" for service in answers['service_list']])
|
||||
template = f"""---
|
||||
title: 🔥️ {answers['title']} 🔥️
|
||||
date: {answers['date']} {answers['time']}:00
|
||||
informational: {informational}
|
||||
section: issue
|
||||
severity: {answers['severity']}
|
||||
resolved: False
|
||||
pin: {answers['pin']}
|
||||
affected:
|
||||
{services}
|
||||
---
|
||||
{answers['content']}
|
||||
"""
|
||||
post_tpl = f"""🔥️ {answers['title']} 🔥️
|
||||
date: {answers['date']} {answers['time']}:00
|
||||
|
||||
{answers['content']}
|
||||
_.~"~._.~"~._.~"~._.~"~.__.~"~._.~"~._.~"~._.~"~.__.~"~._.~"~._.~"~._.~"~._
|
||||
"""
|
||||
|
||||
print(template)
|
||||
is_correct = questionary.confirm("Is the information correct?").ask()
|
||||
|
||||
if not is_correct:
|
||||
launch_wizard()
|
||||
|
||||
launch_wizard()
|
||||
|
||||
### POST to FEDIVERSE
|
||||
# Define the instance URL and user credentials
|
||||
instance_url = config['Fedi']['fediurl']
|
||||
username = config['Fedi']['username']
|
||||
password = config['Fedi']['password']
|
||||
token = config['Fedi']['token']
|
||||
|
||||
headers = {
|
||||
'Authorization': f'Bearer {token}',
|
||||
}
|
||||
|
||||
data = {
|
||||
"status": post_tpl
|
||||
}
|
||||
# Print the request details for inspection
|
||||
print(f"FEDI - Sending a POST request to: {instance_url}")
|
||||
|
||||
try:
|
||||
response = requests.post(f"{instance_url}/api/v1/statuses", headers=headers, data=data, verify=False)
|
||||
print("FEDI - Message successfully posted.")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"An error occurred: {e}")
|
||||
|
||||
### POST to XMPP
|
||||
# Get XMPP credentials from the user
|
||||
jid = config['XMPP']['userjid']
|
||||
password = config['XMPP']['password']
|
||||
room = config['XMPP']['roomjid']
|
||||
nickname = config['XMPP']['nickname']
|
||||
message = post_tpl
|
||||
|
||||
class MUCBot(slixmpp.ClientXMPP):
|
||||
def __init__(self, jid, password, room, nickname, message):
|
||||
slixmpp.ClientXMPP.__init__(self, jid, password)
|
||||
self.room = room
|
||||
self.nick = nickname
|
||||
self.msg = message
|
||||
self.add_event_handler("session_start", self.start)
|
||||
self.add_event_handler("muc::%s::got_online" % self.room, self.muc_online)
|
||||
|
||||
async def start(self, event):
|
||||
self.send_presence()
|
||||
await self.get_roster()
|
||||
self.plugin['xep_0045'].join_muc(self.room, self.nick)
|
||||
|
||||
def muc_online(self, presence):
|
||||
if presence['muc']['nick'] != self.nick:
|
||||
self.send_message(mto=self.room, mbody=self.msg, mtype='groupchat')
|
||||
self.disconnect()
|
||||
|
||||
|
||||
# Create an instance of the XMPP client and connect to the XMPP server
|
||||
xmpp = MUCBot(jid, password, room, nickname, message)
|
||||
xmpp.register_plugin('xep_0030') # Service Discovery
|
||||
xmpp.register_plugin('xep_0045') # Load the MUC plugin
|
||||
xmpp.register_plugin('xep_0199') # XMPP Ping
|
||||
xmpp.connect()
|
||||
xmpp.process(forever=False)
|
||||
|
||||
# Run the event loop until the XMPP client is disconnected
|
||||
print("XMPP - Message sent and disconnected.")
|
||||
|
||||
### POST to GIT
|
||||
# Set the path to your local repository
|
||||
repo_path = config['GIT']['repo_path']
|
||||
ftitle = ftitle.replace(" ", "-")
|
||||
|
||||
# Modify the template file
|
||||
print("GIT - Saving to file")
|
||||
file_path = f"{repo_path}/{fdate}-{ftitle}.md"
|
||||
with open(file_path, "w") as file:
|
||||
file.write(template)
|
||||
|
||||
# Initialize the repository and add the file
|
||||
repo = git.Repo(repo_path)
|
||||
repo.git.add(file_path)
|
||||
|
||||
# Commit the changes
|
||||
print("GIT - Commit to the repo")
|
||||
commit_message = f"Added a {ftitle}"
|
||||
repo.index.commit(commit_message)
|
||||
|
||||
# Push the changes to the branch
|
||||
print("GIT - Push to the repo")
|
||||
origin = repo.remote(name='origin')
|
||||
origin.push()
|
||||
|
||||
# Exit the program
|
||||
sys.exit()
|
||||
|
Loading…
Reference in New Issue