Transitioned from JSON to Hjson. Closes #3
All configuration files and all messages files should now preferrable be done in Hjson. This format supports, i.a. features, multi line strings and commenting. This greatly improves readability. All installation and documentation files are also updated in this commit.
This commit is contained in:
parent
8e746674c4
commit
eb2b887c0a
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,7 +1,13 @@
|
||||
# Config
|
||||
config.json
|
||||
config.hjson
|
||||
*.db
|
||||
|
||||
# Generated directories
|
||||
data/
|
||||
bin/
|
||||
include/
|
||||
|
||||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
|
30
README.md
30
README.md
@ -24,7 +24,7 @@ In order for the bot framework to work, Python 3, [virtualenv](https://virtualen
|
||||
### Automatic installation (Linux)
|
||||
On Linux, the bash script `install.sh` can be used to install the bot.
|
||||
```
|
||||
install.sh : Creates a virtualenv, an initial config.json, and installs
|
||||
install.sh : Creates a virtualenv, an initial config.hjson, and installs
|
||||
all required packages
|
||||
install.sh service: Runs ./install and additionally adds a systemd service.
|
||||
This command will ask you for root credentials!
|
||||
@ -43,7 +43,7 @@ and install all required packages
|
||||
```
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
Now, you need to create a configuration file `config.json`. The template `config.json.template` can be used for this purpose.
|
||||
Now, you need to create a configuration file `config.hjson`. The template `config.hjson.template` can be used for this purpose.
|
||||
|
||||
Finally, the bot can be started by executing the following command within the virtual environment:
|
||||
|
||||
@ -52,7 +52,7 @@ Finally, the bot can be started by executing the following command within the vi
|
||||
```
|
||||
|
||||
## Plugins
|
||||
The bot has different plugins that can be activated by sending `[Keyword in bot's config.json] [Keyword(s) in plugin's config.json]` to a room in which the bot is present. Below, under [List of available plugins](list-of-available-plugins), you can first find a list of already available plugins. Then, under [API](#api), you can find a description on how to develop a new plugin.
|
||||
The bot has different plugins that can be activated by sending `[Keyword in bot's config.hjson] [Keyword(s) in plugin's config.hjson]` to a room in which the bot is present. Below, under [List of available plugins](list-of-available-plugins), you can first find a list of already available plugins. Then, under [API](#api), you can find a description on how to develop a new plugin.
|
||||
|
||||
### List of available plugins:
|
||||
* [Hello plugin](src/branch/master/plugins/events): An example plugin that interacts with users that send "Hello bot" to the bot.
|
||||
@ -63,9 +63,9 @@ The bot has different plugins that can be activated by sending `[Keyword in bot'
|
||||
To interact with rooms, the [Matrix Python SDK](http://matrix-org.github.io/matrix-python-sdk/<Paste>) can be used.
|
||||
|
||||
#### Mandatory/recommended files
|
||||
To create a plugin, a few files must or can be present. The tree below shows the general structure of a plugin. A new plugin must be placed in a directory that has the name of that plugin. The main class (more on that later) of the plugin must be defined in a Python file with that same name. The plugin may not use bot's main configuration file. All configuration must be placed in a separate `config.json`.
|
||||
To create a plugin, a few files must or can be present. The tree below shows the general structure of a plugin. A new plugin must be placed in a directory that has the name of that plugin. The main class (more on that later) of the plugin must be defined in a Python file with that same name. The plugin may not use bot's main configuration file. All configuration must be placed in a separate `config.hjson`. More information on Hjson can be found on [their website](https://hjson.org).
|
||||
|
||||
A subdirectory `messages` is used to store messages. Within this directory, a file `help` may 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.
|
||||
A subdirectory `messages` is used to store messages. Within this directory, a file `help` may 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>.hjson` with all messages should exist.
|
||||
|
||||
The optional file `requirements.txt` is used to define all dependencies. The framework will automatically install them before the first time the plugin is used. This happens even *before* the `setup()` function is invoked (more on that later).
|
||||
|
||||
@ -77,10 +77,10 @@ Although recommended, the help file is also not mandatory. If no help message fo
|
||||
│ ├── __init__.py
|
||||
│ ├── <plugin1>.py
|
||||
│ ├── README.md
|
||||
│ ├── config.json
|
||||
│ ├── config.hjson
|
||||
│ ├── requirements.txt
|
||||
│ └── messages
|
||||
│ ├── messages.<language>.json
|
||||
│ ├── messages.<language>.hjson
|
||||
│ └── help
|
||||
├── <plugin2>
|
||||
╎
|
||||
@ -126,22 +126,22 @@ The code below shows the template for a simple plugin with a few features. The n
|
||||
* The Plugin class must contain a method `help()` which only returns the content of `plugin1/messages/help`
|
||||
|
||||
```python
|
||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
HELP_LOCATION = os.path.join(os.path.dirname(__file__), 'help')
|
||||
MESSAGES_LOCATION = os.path.join(os.path.dirname(__file__),
|
||||
'messages/messages.dutch.json')
|
||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.hjson')
|
||||
MESSAGES_DIR = os.path.join(os.path.dirname(__file__), 'messages')
|
||||
HELP_LOCATION = MESSAGES_DIR + '/help'
|
||||
MESSAGES_LOCATION = MESSAGES_DIR + /messages.dutch.hjson'
|
||||
|
||||
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)
|
||||
with open(CONFIG_LOCATION) as hjson_data:
|
||||
self.config = hjson.load(hjson_data)
|
||||
|
||||
# Load all messages for this plugin
|
||||
with open(MESSAGES_LOCATION) as json_data:
|
||||
self.messages = json.load(json_data)
|
||||
with open(MESSAGES_LOCATION) as hjson_data:
|
||||
self.messages = hjson.load(hjson_data)
|
||||
|
||||
# Define sensitivity
|
||||
self.handler = []
|
||||
|
14
install.sh
14
install.sh
@ -24,12 +24,12 @@
|
||||
# This script does the following:
|
||||
# - create virtualenv
|
||||
# - install requirements of main bot
|
||||
# - create initial config.json
|
||||
# - create initial config.hjson
|
||||
# - (optional) create systemd service
|
||||
|
||||
if [[ $1 == help ]]; then
|
||||
echo "Help:"
|
||||
echo "install.sh : Creates a virtualenv, an initial config.json, and installs"
|
||||
echo "install.sh : Creates a virtualenv, an initial config.hjson, and installs"
|
||||
echo " all required packages"
|
||||
echo "install.sh service: Runs ./install and additionally adds a systemd service."
|
||||
echo " This command will ask you for root credentials!"
|
||||
@ -79,7 +79,7 @@ availability pip3
|
||||
pip3 install -r requirements.txt
|
||||
|
||||
#################################################################
|
||||
# Create config.json
|
||||
# Create config.hjson
|
||||
#################################################################
|
||||
echo ""
|
||||
echo "############################################################################"
|
||||
@ -96,11 +96,11 @@ echo "plugins."
|
||||
echo "############################################################################"
|
||||
echo ""
|
||||
|
||||
if [[ -f $DIR/config.json ]]; then
|
||||
read -p "$DIR/config.json already exists. Should I overwrite it? [y/n]: " ow
|
||||
if [[ -f $DIR/config.hjson ]]; then
|
||||
read -p "$DIR/config.hjson already exists. Should I overwrite it? [y/n]: " ow
|
||||
|
||||
if [[ $ow != y ]]; then
|
||||
echo "ERR: Cannot write to $DIR/config.json!"
|
||||
echo "ERR: Cannot write to $DIR/config.hjson!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@ -114,7 +114,7 @@ sed -e "s|\${server}|${server}|"\
|
||||
-e "s|\${username}|${username}|"\
|
||||
-e "s|\${password}|${password}|"\
|
||||
-e "s|\${superuser}|${superuser}|"\
|
||||
$DIR/config.json.template > $DIR/config.json
|
||||
$DIR/config.hjson.template > $DIR/config.hjson
|
||||
|
||||
#################################################################
|
||||
# Configure service
|
||||
|
@ -2,6 +2,7 @@ import traceback
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
import hjson
|
||||
import importlib
|
||||
import sqlite3
|
||||
import datetime as dt
|
||||
@ -14,10 +15,11 @@ from matrix_client.user import User
|
||||
|
||||
from matrix_bot_api.mregex_handler import MRegexHandler
|
||||
|
||||
HELP_LOCATION = os.path.join(os.path.dirname(__file__), 'help')
|
||||
MESSAGES_DIR = os.path.join(os.path.dirname(__file__), 'messages')
|
||||
DATA_LOCATION = os.path.join(os.path.dirname(__file__), '../data/bot.db')
|
||||
|
||||
private_message = "Hey {}! Ik heb je even een privébericht gestuurd 🙂"
|
||||
HELP_LOCATION = MESSAGES_DIR + '/help'
|
||||
MESSAGES_LOCATION = MESSAGES_DIR + '/messages.dutch.hjson'
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
"""Print error messages to stderr"""
|
||||
@ -84,6 +86,11 @@ class MatrixBotAPI:
|
||||
self.config['triggers']['help'], self.help)
|
||||
self.add_handler(self.help_handler)
|
||||
|
||||
# Load messages
|
||||
with open(MESSAGES_LOCATION) as hjson_data:
|
||||
self.messages = hjson.load(hjson_data)
|
||||
|
||||
|
||||
def add_plugins(self):
|
||||
"""Acquire list of plugins from configuration, load them,
|
||||
initialize them, and add them to a list of object
|
||||
@ -264,7 +271,8 @@ class MatrixBotAPI:
|
||||
|
||||
if room != orig_room:
|
||||
display_name_sender = self.api.get_display_name(event['sender'])
|
||||
orig_room.send_text(private_message.format(display_name_sender))
|
||||
orig_room.send_text(self.messages['private_message'].format(
|
||||
display_name_sender))
|
||||
|
||||
def help(self, room, event):
|
||||
"""Prints a general help message and then grabs all help
|
||||
|
6
matrix_bot_api/messages/messages.dutch.hjson
Normal file
6
matrix_bot_api/messages/messages.dutch.hjson
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"private_message":
|
||||
'''
|
||||
Hey {}! Ik heb je even een privébericht gestuurd 🙂
|
||||
''',
|
||||
}
|
@ -7,7 +7,7 @@ __maintainer__ = "Dennis Potter"
|
||||
__email__ = "dennis@dennispotter.eu"
|
||||
|
||||
import os
|
||||
import json
|
||||
import hjson
|
||||
import time
|
||||
import sqlite3
|
||||
import threading
|
||||
@ -16,13 +16,13 @@ import MySQLdb as mysql
|
||||
|
||||
from matrix_bot_api.mregex_handler import MRegexHandler
|
||||
|
||||
MESSAGE_DIR = os.path.join(os.path.dirname(__file__), 'messages')
|
||||
MESSAGES_DIR = os.path.join(os.path.dirname(__file__), 'messages')
|
||||
DATA_DIR = os.path.join(os.path.dirname(__file__),'../../data/events')
|
||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.hjson')
|
||||
|
||||
DATA_LOCATION = DATA_DIR + '/data.db'
|
||||
HELP_LOCATION = MESSAGE_DIR + '/help'
|
||||
MESSAGES_LOCATION = MESSAGE_DIR + '/messages.dutch.json'
|
||||
HELP_LOCATION = MESSAGES_DIR + '/help'
|
||||
MESSAGES_LOCATION = MESSAGES_DIR + '/messages.dutch.hjson'
|
||||
|
||||
class Plugin:
|
||||
""" This plugin grabs events from Admidio (https://admidio.org)
|
||||
@ -30,12 +30,12 @@ class Plugin:
|
||||
"""
|
||||
def __init__(self, bot):
|
||||
# Load the configuration
|
||||
with open(CONFIG_LOCATION) as json_data:
|
||||
self.config = json.load(json_data)
|
||||
with open(CONFIG_LOCATION) as hjson_data:
|
||||
self.config = hjson.load(hjson_data)
|
||||
|
||||
# Load all messages for this plugin
|
||||
with open(MESSAGES_LOCATION) as json_data:
|
||||
self.messages = json.load(json_data)
|
||||
with open(MESSAGES_LOCATION) as hjson_data:
|
||||
self.messages = hjson.load(hjson_data)
|
||||
|
||||
# Define sensitivity
|
||||
self.handler = []
|
||||
|
35
plugins/admidio_events/messages/messages.dutch.hjson
Normal file
35
plugins/admidio_events/messages/messages.dutch.hjson
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"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>
|
||||
<li> <a href='{}'>om je op aanwezig te zetten</a> ✅</li>
|
||||
<li> <a href='{}'>om je op misschien te zetten</a> 🤷</li>
|
||||
<li> <a href='{}'>om je op afwezig te zetten</a> ⛔</li>
|
||||
</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.
|
||||
'''
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"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."
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"coupon_message" :
|
||||
'''
|
||||
De huidige code om {}% korting te krijgen is: <i><strong>{}</strong></i>.
|
||||
Ga meteen naar <a href="https://alcuinus.nl/shop">de webshop</a> om
|
||||
hem te gebruiken!
|
||||
'''
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
|
||||
"coupon_message" : "De huidige code om {}% korting te krijgen is: <i><strong>{}</strong></i>. Ga meteen naar <a href=\"https://alcuinus.nl/shop\">de webshop</a> om hem te gebruiken!"
|
||||
|
||||
}
|
@ -1,17 +1,25 @@
|
||||
__author__ = "Dennis Potter"
|
||||
__copyright__ = "Copyright 2019, Dennis Potter"
|
||||
__credits__ = ["Dennis Potter"]
|
||||
__license__ = "GPL-3.0"
|
||||
__version__ = "0.5.0"
|
||||
__maintainer__ = "Dennis Potter"
|
||||
__email__ = "dennis@dennispotter.eu"
|
||||
|
||||
from matrix_bot_api.mregex_handler import MRegexHandler
|
||||
from woocommerce import API
|
||||
from base64 import b64encode
|
||||
import os
|
||||
import json
|
||||
import hjson
|
||||
import datetime as dt
|
||||
|
||||
MESSAGE_DIR = os.path.join(os.path.dirname(__file__), 'messages')
|
||||
DATA_DIR = os.path.join(os.path.dirname(__file__),'../../data/woocommerce')
|
||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.hjson')
|
||||
|
||||
DATA_LOCATION = DATA_DIR + '/id.json'
|
||||
DATA_LOCATION = DATA_DIR + '/id.hjson'
|
||||
HELP_LOCATION = MESSAGE_DIR + '/help'
|
||||
MESSAGES_LOCATION = MESSAGE_DIR + '/messages.dutch.json'
|
||||
MESSAGES_LOCATION = MESSAGE_DIR + '/messages.dutch.hjson'
|
||||
|
||||
class Plugin:
|
||||
""" This is an example plugin with only a single callback. When
|
||||
@ -21,16 +29,16 @@ class Plugin:
|
||||
|
||||
def __init__(self, bot):
|
||||
# Load the configuration
|
||||
with open(CONFIG_LOCATION) as json_data:
|
||||
self.config = json.load(json_data)
|
||||
with open(CONFIG_LOCATION) as hjson_data:
|
||||
self.config = hjson.load(hjson_data)
|
||||
|
||||
# Load ID of coupon
|
||||
with open(DATA_LOCATION) as json_data:
|
||||
self.coupon_id = json.load(json_data)
|
||||
with open(DATA_LOCATION) as hjson_data:
|
||||
self.coupon_id = hjson.load(hjson_data)
|
||||
|
||||
# Load all messages for this plugin
|
||||
with open(MESSAGES_LOCATION) as json_data:
|
||||
self.messages = json.load(json_data)
|
||||
with open(MESSAGES_LOCATION) as hjson_data:
|
||||
self.messages = hjson.load(hjson_data)
|
||||
|
||||
# Define sensitivity
|
||||
self.handler = []
|
||||
@ -91,8 +99,8 @@ def setup():
|
||||
"""This function initializes a coupon with a given percentage"""
|
||||
|
||||
# Load the configuration
|
||||
with open(CONFIG_LOCATION) as json_data:
|
||||
config = json.load(json_data)
|
||||
with open(CONFIG_LOCATION) as hjson_data:
|
||||
config = hjson.load(hjson_data)
|
||||
|
||||
# Create random token and determine max validity
|
||||
vld_days = config['coupon']['max_days']
|
||||
@ -120,12 +128,12 @@ def setup():
|
||||
)
|
||||
|
||||
# Send to shop
|
||||
ret = wcapi.post("coupons", data)
|
||||
ret = wcapi.post("coupons", data).json()
|
||||
|
||||
# Create data directory
|
||||
os.mkdir(DATA_DIR)
|
||||
|
||||
# Write to JSON file to save ID
|
||||
with open(DATA_LOCATION, 'w') as json_data:
|
||||
json.dump(ret['id'], json_data)
|
||||
with open(DATA_LOCATION, 'w') as hjson_data:
|
||||
hjson.dump(ret['id'], hjson_data)
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
matrix-client>=0.3.2
|
||||
hjson>=3.0.1
|
||||
|
8
run.py
8
run.py
@ -11,7 +11,7 @@ __version__ = "0.5.0"
|
||||
__maintainer__ = "Dennis Potter"
|
||||
__email__ = "dennis@dennispotter.eu"
|
||||
|
||||
import json
|
||||
import hjson
|
||||
import os
|
||||
import time
|
||||
import threading
|
||||
@ -19,12 +19,12 @@ import threading
|
||||
# Bot API import
|
||||
from matrix_bot_api.matrix_bot_api import MatrixBotAPI
|
||||
|
||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.json')
|
||||
CONFIG_LOCATION = os.path.join(os.path.dirname(__file__), 'config.hjson')
|
||||
|
||||
def main():
|
||||
# Load the configuration
|
||||
with open(CONFIG_LOCATION) as json_data:
|
||||
config = json.load(json_data)
|
||||
with open(CONFIG_LOCATION) as hjson_data:
|
||||
config = hjson.load(hjson_data)
|
||||
|
||||
# Create an instance of the MatrixBotAPI
|
||||
bot = MatrixBotAPI(config)
|
||||
|
Loading…
Reference in New Issue
Block a user