plugable-matrix-bot/plugins/events/events.py

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()