Added list event function
Also refactored the code a little bit more and updated the README file according.
This commit is contained in:
parent
0c78434919
commit
9db6136e86
18
README.md
18
README.md
@ -27,15 +27,17 @@ To interact with rooms, the [Matrix Python SDK](http://matrix-org.github.io/matr
|
|||||||
#### Mandatory files
|
#### Mandatory files
|
||||||
To create a plugin, a few mandatory files must be present. The tree below shows the general structure of a plugin. A new plugin must be placed in a directory with the same name. The main class (more on that later) of the plugin must be defined in a Python file with the same name within that directory. The event may not use bot's main configuration file. All configuration must be placed in a separate `config.json`.
|
To create a plugin, a few mandatory files must be present. The tree below shows the general structure of a plugin. A new plugin must be placed in a directory with the same name. The main class (more on that later) of the plugin must be defined in a Python file with the same name within that directory. The event may not use bot's main configuration file. All configuration must be placed in a separate `config.json`.
|
||||||
|
|
||||||
A subdirectory `messages` is used to store messages. Within this directory, a file `help` must be present. The content of this file must be returned with a method of the plugin class (more on that later).
|
A subdirectory `messages` is used to store messages. Within this directory, a file `help` must be present. The content of this file must be returned with a method of the plugin class (more on that later). Furthermore, for every language a file `messages.<language>.json` with all messages should exist.
|
||||||
```
|
```
|
||||||
.
|
.
|
||||||
└── plugins
|
└── plugins
|
||||||
├── <plugin1>
|
├── <plugin1>
|
||||||
│ ├── __init__.py
|
│ ├── __init__.py
|
||||||
│ ├── <plugin1>.py
|
│ ├── <plugin1>.py
|
||||||
|
│ ├── README.md
|
||||||
│ ├── config.json
|
│ ├── config.json
|
||||||
│ └── messages
|
│ └── messages
|
||||||
|
│ ├── messages.<language>.json
|
||||||
│ └── help
|
│ └── help
|
||||||
├── <plugin2>
|
├── <plugin2>
|
||||||
╎
|
╎
|
||||||
@ -80,6 +82,8 @@ The code below shows the template for a simple plugin with a few features. The n
|
|||||||
```python
|
```python
|
||||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.json')
|
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||||
HELP_LOCATION = os.path.join(os.path.dirname(__file__), 'help')
|
HELP_LOCATION = os.path.join(os.path.dirname(__file__), 'help')
|
||||||
|
MESSAGES_LOCATION = os.path.join(os.path.dirname(__file__),
|
||||||
|
'messages/messages.dutch.json')
|
||||||
|
|
||||||
class Plugin:
|
class Plugin:
|
||||||
""" Description of event plugin """
|
""" Description of event plugin """
|
||||||
@ -89,9 +93,17 @@ class Plugin:
|
|||||||
with open(CONFIG_LOCATION) as json_data:
|
with open(CONFIG_LOCATION) as json_data:
|
||||||
self.config = json.load(json_data)
|
self.config = json.load(json_data)
|
||||||
|
|
||||||
|
# Load all messages for this plugin
|
||||||
|
with open(MESSAGES_LOCATION) as json_data:
|
||||||
|
self.messages = json.load(json_data)
|
||||||
|
|
||||||
# Define sensitivity
|
# Define sensitivity
|
||||||
self.handler = MRegexHandler("Peter <plugin1> <feature1>", self.callback1)
|
self.handler = []
|
||||||
self.handler = MRegexHandler("Peter <plugin1> <feature2>", self.callback2)
|
|
||||||
|
self.handler.append(MRegexHandler("Peter <plugin1> <feature1>",
|
||||||
|
self.callback1))
|
||||||
|
self.handler.append(MRegexHandler("Peter <plugin1> <feature2>",
|
||||||
|
self.callback2))
|
||||||
|
|
||||||
# Save parent bot
|
# Save parent bot
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -164,11 +164,17 @@ class MatrixBotAPI:
|
|||||||
self.send_message_private_public(room, event, help_text)
|
self.send_message_private_public(room, event, help_text)
|
||||||
|
|
||||||
def add_handler(self, handler):
|
def add_handler(self, handler):
|
||||||
self.handlers.append(handler)
|
try:
|
||||||
|
# Assume it's a list and not a single handler
|
||||||
|
for handler_obj in handler:
|
||||||
|
self.handlers.append(handler_obj)
|
||||||
|
except TypeError:
|
||||||
|
# If it is not a list, TypeError: not iterable will occur
|
||||||
|
self.handlers.append(handler)
|
||||||
|
|
||||||
def handle_message(self, room, event):
|
def handle_message(self, room, event):
|
||||||
# Make sure we didn't send this message
|
# Make sure we didn't send this message
|
||||||
if re.match("@" + self.username, event['sender']):
|
if re.match(self.username, event['sender']):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Loop through all installed handlers and see if they need to be called
|
# Loop through all installed handlers and see if they need to be called
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
__author__ = "Dennis Potter"
|
||||||
|
__copyright__ = "Copyright 2019, Dennis Potter"
|
||||||
|
__credits__ = ["Dennis Potter"]
|
||||||
|
__license__ = "GPL-3.0"
|
||||||
|
__version__ = "1.0.1"
|
||||||
|
__maintainer__ = "Dennis Potter"
|
||||||
|
__email__ = "dennis@dennispotter.eu"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
@ -9,8 +17,9 @@ import MySQLdb as mysql
|
|||||||
from matrix_bot_api.mregex_handler import MRegexHandler
|
from matrix_bot_api.mregex_handler import MRegexHandler
|
||||||
|
|
||||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.json')
|
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||||
HELP_LOCATION = os.path.join(os.path.dirname(__file__), 'help')
|
HELP_LOCATION = os.path.join(os.path.dirname(__file__), 'messages/help')
|
||||||
NEW_EVENT_LOCATION = os.path.join(os.path.dirname(__file__), 'new_event')
|
MESSAGES_LOCATION = os.path.join(os.path.dirname(__file__),
|
||||||
|
'messages/messages.dutch.json')
|
||||||
|
|
||||||
class Plugin:
|
class Plugin:
|
||||||
""" Description of event plugin """
|
""" Description of event plugin """
|
||||||
@ -20,30 +29,47 @@ class Plugin:
|
|||||||
with open(CONFIG_LOCATION) as json_data:
|
with open(CONFIG_LOCATION) as json_data:
|
||||||
self.config = json.load(json_data)
|
self.config = json.load(json_data)
|
||||||
|
|
||||||
|
# Load all messages for this plugin
|
||||||
|
with open(MESSAGES_LOCATION) as json_data:
|
||||||
|
self.messages = json.load(json_data)
|
||||||
|
|
||||||
# Define sensitivity
|
# Define sensitivity
|
||||||
self.handler = MRegexHandler("Peter evenementen", self.callback)
|
self.handler = []
|
||||||
|
|
||||||
|
self.handler.append(MRegexHandler("Peter evenementen lijst",
|
||||||
|
self.list_callback))
|
||||||
|
self.handler.append(MRegexHandler("Peter evenementen info",
|
||||||
|
self.info_callback))
|
||||||
|
self.handler.append(MRegexHandler("Peter evenementen chat",
|
||||||
|
self.chat_callback))
|
||||||
|
self.handler.append(MRegexHandler("Peter evenementen deelnemers",
|
||||||
|
self.participants_callback))
|
||||||
|
|
||||||
# Save parent bot
|
# Save parent bot
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
|
# Run one time setup
|
||||||
|
self.setup()
|
||||||
|
|
||||||
# Start thread to check events
|
# Start thread to check events
|
||||||
self.event_thread = threading.Thread(target=self.check_new_event_thread)
|
self.event_thread = threading.Thread(target=self.check_new_event_thread)
|
||||||
self.event_thread.start()
|
self.event_thread.start()
|
||||||
|
|
||||||
self.setup()
|
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
"""This function only runs once, ever. It initializes the necessary
|
"""This function only runs once, ever. It initializes the necessary
|
||||||
SQLite tables."""
|
SQLite tables."""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Try to make a new directory
|
||||||
|
os.mkdir("data/events")
|
||||||
|
|
||||||
# Define query to INSERT event table to SQLite DB
|
# Define query to INSERT event table to SQLite DB
|
||||||
sql = """CREATE TABLE 'events' (
|
sql = """CREATE TABLE 'events' (
|
||||||
'dat_id' integer,
|
'dat_id' integer,
|
||||||
'datetime_posted' datetime);"""
|
'datetime_posted' datetime);"""
|
||||||
|
|
||||||
# Open, execute, commit, and close SQLite database
|
# Open, execute, commit, and close SQLite database
|
||||||
sqlite_db = sqlite3.connect('data/bot.db')
|
sqlite_db = sqlite3.connect('data/events/data.db')
|
||||||
sqlite_cursor = sqlite_db.cursor()
|
sqlite_cursor = sqlite_db.cursor()
|
||||||
sqlite_cursor.execute(sql)
|
sqlite_cursor.execute(sql)
|
||||||
sqlite_db.commit()
|
sqlite_db.commit()
|
||||||
@ -52,6 +78,17 @@ class Plugin:
|
|||||||
except sqlite3.OperationalError:
|
except sqlite3.OperationalError:
|
||||||
# Table already exists, do nothing
|
# Table already exists, do nothing
|
||||||
pass
|
pass
|
||||||
|
except FileExistsError:
|
||||||
|
# Directory already exists, do nothing
|
||||||
|
pass
|
||||||
|
|
||||||
|
def connect_database(self):
|
||||||
|
# Connect to database
|
||||||
|
return mysql.connect(
|
||||||
|
user = self.config['database_credentials']['username'],
|
||||||
|
password = self.config['database_credentials']['password'],
|
||||||
|
database = self.config['database_credentials']['database'])
|
||||||
|
|
||||||
|
|
||||||
def check_new_event_thread(self):
|
def check_new_event_thread(self):
|
||||||
while not self.bot.cancel:
|
while not self.bot.cancel:
|
||||||
@ -67,12 +104,7 @@ class Plugin:
|
|||||||
saved in an SQLite database.
|
saved in an SQLite database.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Connect to database
|
mysql_db = self.connect_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()
|
mysql_cursor = mysql_db.cursor()
|
||||||
|
|
||||||
# Grab all events from database that start in the future
|
# Grab all events from database that start in the future
|
||||||
@ -87,10 +119,8 @@ class Plugin:
|
|||||||
# Fetch events
|
# Fetch events
|
||||||
results = mysql_cursor.fetchall()
|
results = mysql_cursor.fetchall()
|
||||||
|
|
||||||
mysql_db.close()
|
|
||||||
|
|
||||||
# Open SQLite database
|
# Open SQLite database
|
||||||
sqlite_db = sqlite3.connect('data/bot.db')
|
sqlite_db = sqlite3.connect('data/events/data.db')
|
||||||
|
|
||||||
sqlite_cursor = sqlite_db.cursor()
|
sqlite_cursor = sqlite_db.cursor()
|
||||||
|
|
||||||
@ -128,8 +158,6 @@ class Plugin:
|
|||||||
maybe_link = function_link.format(base_date_url, '7', row[0])
|
maybe_link = function_link.format(base_date_url, '7', row[0])
|
||||||
cancel_link = function_link.format(base_date_url, '4', 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
|
# First, write to SQLite database that it is processed
|
||||||
sqlite_cursor.execute(
|
sqlite_cursor.execute(
|
||||||
insert_sql, {
|
insert_sql, {
|
||||||
@ -146,7 +174,7 @@ class Plugin:
|
|||||||
for i, room in self.bot.client.get_rooms().items():
|
for i, room in self.bot.client.get_rooms().items():
|
||||||
if room.display_name in mapping[1]:
|
if room.display_name in mapping[1]:
|
||||||
room.send_html(
|
room.send_html(
|
||||||
new_event.format(
|
self.messages["new_event"].format(
|
||||||
row[3].strftime("%d-%m-%Y"),
|
row[3].strftime("%d-%m-%Y"),
|
||||||
row[3].strftime("%H:%M"),
|
row[3].strftime("%H:%M"),
|
||||||
row[2],
|
row[2],
|
||||||
@ -159,12 +187,82 @@ class Plugin:
|
|||||||
sqlite_db.commit()
|
sqlite_db.commit()
|
||||||
sqlite_db.close()
|
sqlite_db.close()
|
||||||
|
|
||||||
# Sleep
|
# Close MySQL
|
||||||
#time.sleep(self.config['update_time_span'] * 60)
|
mysql_db.close()
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
def callback(self, room, event):
|
# Sleep
|
||||||
room.send_text("Information ")
|
time.sleep(self.config['update_time_span'] * 60)
|
||||||
|
|
||||||
|
def list_callback(self, room, event):
|
||||||
|
number_events = False
|
||||||
|
|
||||||
|
for word in event['content']['body'].split():
|
||||||
|
try:
|
||||||
|
number_events = int(word)
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not number_events:
|
||||||
|
number_events = 10
|
||||||
|
if number_events <= 0 or number_events > 100:
|
||||||
|
room.send_text(self.messages['list_event_num_err'])
|
||||||
|
number_events = 10
|
||||||
|
|
||||||
|
datetime_now = dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
|
mysql_cursor = self.mysql_db.cursor()
|
||||||
|
|
||||||
|
select_sql = f"""SELECT dat_id, dat_cat_id,
|
||||||
|
dat_headline, dat_begin, dat_end
|
||||||
|
FROM adm_dates
|
||||||
|
WHERE dat_begin >'{datetime_now}'
|
||||||
|
ORDER BY dat_begin
|
||||||
|
LIMIT {number_events}"""
|
||||||
|
|
||||||
|
mysql_cursor.execute(select_sql)
|
||||||
|
|
||||||
|
# Fetch events
|
||||||
|
results = mysql_cursor.fetchall()
|
||||||
|
|
||||||
|
# Set header
|
||||||
|
html_message = self.messages['list_events_head'].format(number_events)
|
||||||
|
|
||||||
|
# Loop through fetched events
|
||||||
|
html_message += "<br /><ul>"
|
||||||
|
for row in results:
|
||||||
|
base_date_url = "{}{}".format(
|
||||||
|
self.config['base_url_adm'],
|
||||||
|
"/adm_program/modules/dates/")
|
||||||
|
|
||||||
|
function_link = "{}dates_function.php?mode={}&dat_id={}&"
|
||||||
|
|
||||||
|
attend_link = function_link.format(base_date_url, '3', row[0])
|
||||||
|
|
||||||
|
html_message += "<li>"
|
||||||
|
html_message += self.messages['list_event_item'].format(
|
||||||
|
row[3].strftime("%d-%m-%Y"),
|
||||||
|
row[3].strftime("%H:%M"),
|
||||||
|
row[2],
|
||||||
|
attend_link)
|
||||||
|
html_message += "</li>"
|
||||||
|
|
||||||
|
html_message += "</ul>"
|
||||||
|
|
||||||
|
# Send message
|
||||||
|
room.send_html(html_message)
|
||||||
|
|
||||||
|
# Close DB connection
|
||||||
|
mysql_db.close()
|
||||||
|
|
||||||
|
def info_callback(self, room, event):
|
||||||
|
room.send_text("Info")
|
||||||
|
|
||||||
|
def chat_callback(self, room, event):
|
||||||
|
room.send_text("Chat")
|
||||||
|
|
||||||
|
def participants_callback(self, room, event):
|
||||||
|
room.send_text("Deelnemers")
|
||||||
|
|
||||||
def help(self):
|
def help(self):
|
||||||
return open(HELP_LOCATION, mode="r").read()
|
return open(HELP_LOCATION, mode="r").read()
|
||||||
|
6
plugins/events/messages/messages.dutch.json
Normal file
6
plugins/events/messages/messages.dutch.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"new_event": "<strong>@room er is zojuist een nieuw evenement aangemaakt! Op {} om {} zal \"{}\" plaatsvinden.</strong><br /><br />Ben je aangemeld op de leden database in je favoriete browser? Klik dan hier:<ul><li> <a href='{}'>om het evenement te bekijken</a> 👀<li> <a href='{}'>om je op aanwezig te zetten</a> ✅<li> <a href='{}'>om je op misschien te zetten</a> 🤷<li> <a href='{}'>om je op afwezig te zetten</a> ⛔</ul>",
|
||||||
|
"list_events_head": "De aankomende {} evenementen zijn:",
|
||||||
|
"list_event_item": "{} om {}: <strong>{}</strong> (<a href='{}'>aanmelden</a>)",
|
||||||
|
"list_event_num_err": "Let op: alleen de getallen [1,100] zijn toegestaan! Ik pak de standaard waarde 10."
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user