Dennis
57499db3f5
This commit includes the matrix bot API (https://github.com/shawnanastasio/python-matrix-bot-api/) and the first proof of concept that the plugin API works. Furthermore, it includes the first version of a plugin that acquires event from an Admidio setup (https://admidio.org).
171 lines
5.9 KiB
Python
171 lines
5.9 KiB
Python
import os
|
|
import json
|
|
import time
|
|
import sqlite3
|
|
import threading
|
|
import datetime as dt
|
|
import MySQLdb as mysql
|
|
|
|
from matrix_bot_api.mregex_handler import MRegexHandler
|
|
|
|
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.json')
|
|
HELP_LOCATION = os.path.join(os.path.dirname(__file__), 'help')
|
|
NEW_EVENT_LOCATION = os.path.join(os.path.dirname(__file__), 'new_event')
|
|
|
|
class Plugin:
|
|
""" Description of event plugin """
|
|
|
|
def __init__(self, bot):
|
|
# Load the configuration
|
|
with open(CONFIG_LOCATION) as json_data:
|
|
self.config = json.load(json_data)
|
|
|
|
# Define sensitivity
|
|
self.handler = MRegexHandler("Peter evenementen", self.callback)
|
|
|
|
# Save parent bot
|
|
self.bot = bot
|
|
|
|
# Start thread to check events
|
|
self.event_thread = threading.Thread(target=self.check_new_event_thread)
|
|
self.event_thread.start()
|
|
|
|
self.setup()
|
|
|
|
def setup(self):
|
|
"""This function only runs once, ever. It initializes the necessary
|
|
SQLite tables."""
|
|
|
|
try:
|
|
# Define query to INSERT event table to SQLite DB
|
|
sql = """CREATE TABLE 'events' (
|
|
'dat_id' integer,
|
|
'datetime_posted' datetime);"""
|
|
|
|
# Open, execute, commit, and close SQLite database
|
|
sqlite_db = sqlite3.connect('data/bot.db')
|
|
sqlite_cursor = sqlite_db.cursor()
|
|
sqlite_cursor.execute(sql)
|
|
sqlite_db.commit()
|
|
sqlite_db.close()
|
|
|
|
except sqlite3.OperationalError:
|
|
# Table already exists, do nothing
|
|
pass
|
|
|
|
def check_new_event_thread(self):
|
|
while not self.bot.cancel:
|
|
self.check_new_event()
|
|
|
|
def check_new_event(self):
|
|
""" Check every <X> minutes for new events in the database.
|
|
|
|
Since the check will only be performed every <X> minutes, the
|
|
connection to the database will not be kept open.
|
|
|
|
As soon as an event is posted to the defined room, its ID is
|
|
saved in an SQLite database.
|
|
"""
|
|
|
|
# Connect to database
|
|
mysql_db = mysql.connect(
|
|
user = self.config['database_credentials']['username'],
|
|
password = self.config['database_credentials']['password'],
|
|
database = self.config['database_credentials']['database'])
|
|
|
|
mysql_cursor = mysql_db.cursor()
|
|
|
|
# Grab all events from database that start in the future
|
|
select_sql = """SELECT dat_id, dat_cat_id,
|
|
dat_headline, dat_begin, dat_end
|
|
FROM adm_dates
|
|
WHERE dat_begin >'{}'""".format(
|
|
dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
|
|
|
|
mysql_cursor.execute(select_sql)
|
|
|
|
# Fetch events
|
|
results = mysql_cursor.fetchall()
|
|
|
|
mysql_db.close()
|
|
|
|
# Open SQLite database
|
|
sqlite_db = sqlite3.connect('data/bot.db')
|
|
|
|
sqlite_cursor = sqlite_db.cursor()
|
|
|
|
# Define query to SELECT event from SQLite DB
|
|
select_sql = """SELECT dat_id
|
|
FROM events
|
|
WHERE dat_id = {}"""
|
|
|
|
insert_sql = """INSERT INTO events(dat_id, datetime_posted)
|
|
VALUES(:dat_id, :datetime_posted)"""
|
|
|
|
# Loop through event
|
|
for row in results:
|
|
# First, check if a message on this event was already sent
|
|
sqlite_cursor.execute(select_sql.format(row[0]))
|
|
|
|
if sqlite_cursor.fetchall():
|
|
# Do nothing. This event was already processed
|
|
pass
|
|
else:
|
|
# This appears to be a new event. Process it!
|
|
|
|
# Generate links
|
|
base_date_url = "{}{}".format(
|
|
self.config['base_url_adm'],
|
|
"/adm_program/modules/dates/")
|
|
|
|
view_link = "{}dates.php?id={}&view_mode=html&"
|
|
view_link += "view=detail&headline={}"
|
|
view_link = view_link.format(base_date_url, row[0], row[2])
|
|
|
|
function_link = "{}dates_function.php?mode={}&dat_id={}&"
|
|
|
|
attend_link = function_link.format(base_date_url, '3', row[0])
|
|
maybe_link = function_link.format(base_date_url, '7', row[0])
|
|
cancel_link = function_link.format(base_date_url, '4', row[0])
|
|
|
|
new_event = open(NEW_EVENT_LOCATION, mode="r").read()
|
|
|
|
# First, write to SQLite database that it is processed
|
|
sqlite_cursor.execute(
|
|
insert_sql, {
|
|
'dat_id':row[0],
|
|
'datetime_posted':
|
|
dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
|
|
|
|
# Check role ID of event and check if config defines
|
|
# where it should be shared.
|
|
for mapping in self.config['cat_id_room_mapping']:
|
|
if row[1] in mapping[0]:
|
|
# We got a winner!
|
|
|
|
for i, room in self.bot.client.get_rooms().items():
|
|
if room.display_name in mapping[1]:
|
|
room.send_html(
|
|
new_event.format(
|
|
row[3].strftime("%d-%m-%Y"),
|
|
row[3].strftime("%H:%M"),
|
|
row[2],
|
|
view_link,
|
|
attend_link,
|
|
maybe_link,
|
|
cancel_link))
|
|
|
|
# Commit and close queries
|
|
sqlite_db.commit()
|
|
sqlite_db.close()
|
|
|
|
# Sleep
|
|
#time.sleep(self.config['update_time_span'] * 60)
|
|
time.sleep(1)
|
|
|
|
def callback(self, room, event):
|
|
room.send_text("Information ")
|
|
|
|
def help(self):
|
|
return open(HELP_LOCATION, mode="r").read()
|