From 40d888af2424534353319a797466567a51acbd36 Mon Sep 17 00:00:00 2001 From: Thierry Carrez Date: Tue, 18 Apr 2017 16:45:04 +0200 Subject: [PATCH] Add basic JSON backend Add JSON backend and basic command to update it. --- ptgbot/bot.py | 39 +++++++++++++++++++++++++++++-------- ptgbot/db.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 ptgbot/db.py diff --git a/ptgbot/bot.py b/ptgbot/bot.py index 5f222ca..9eff4ee 100644 --- a/ptgbot/bot.py +++ b/ptgbot/bot.py @@ -22,6 +22,7 @@ pass=PASSWORD server=irc.freenode.net port=6667 channels=foo,bar +db=/tmp/db.json """ import argparse @@ -33,6 +34,8 @@ import os import time import ssl +import ptgbot.db + try: import daemon.pidlockfile as pid_file_module except ImportError: @@ -50,7 +53,7 @@ ANTI_FLOOD_SLEEP = 2 class PTGBot(irc.bot.SingleServerIRCBot): log = logging.getLogger("ptgbot.bot") - def __init__(self, nickname, password, server, port, channels): + def __init__(self, nickname, password, server, port, channels, dbfile): if port == 6697: factory = irc.connection.Factory(wrapper=ssl.wrap_socket) irc.bot.SingleServerIRCBot.__init__(self, @@ -65,6 +68,7 @@ class PTGBot(irc.bot.SingleServerIRCBot): self.password = password self.channel_list = channels self.identify_msg_cap = False + self.data = ptgbot.db.PTGDataBase(dbfile) def on_nicknameinuse(self, c, e): self.log.debug("Nickname in use, releasing") @@ -94,22 +98,40 @@ class PTGBot(irc.bot.SingleServerIRCBot): self.log.debug("identify-msg cap acked") self.identify_msg_cap = True + def usage(self, channel): + self.send(channel, "Format is '@ROOM [until|at] HOUR SESSION'") + def on_pubmsg(self, c, e): if not self.identify_msg_cap: self.log.debug("Ignoring message because identify-msg " "cap not enabled") return nick = e.source.split('!')[0] - auth = e.arguments[0][0] + auth = e.arguments[0][0] == '+' msg = e.arguments[0][1:] + chan = e.target - if msg.startswith('#test'): - self.handle_test_command(e.target, nick, auth, msg) + if msg.startswith('@') and auth: + words = msg.split() + if len(words) < 4: + self.send(chan, "%s: Incorrect number of arguments" % (nick,)) + self.usage(chan) + return + room = words[0][1:].lower() + # TODO: Add test for room/day/person match + adverb = words[1].lower() + if adverb not in ['until', 'at']: + self.send(chan, "%s: unknown directive '%s'" % (nick, adverb)) + self.usage(chan) + return + hour = words[2] + # TODO: Add test for hour format + session = str.join(' ', words[3:]) + + msg = '(%s %s) %s' % (adverb, hour, session) + self.data.add(room, adverb, hour, msg) return - def handle_test_command(self, channel, nick, auth, msg): - self.send(channel, "%s: I'm here" % (nick,)) - def send(self, channel, msg): self.connection.privmsg(channel, msg) time.sleep(ANTI_FLOOD_SLEEP) @@ -135,7 +157,8 @@ def start(configpath): config.get('ircbot', 'pass'), config.get('ircbot', 'server'), config.getint('ircbot', 'port'), - channels) + channels, + config.get('ircbot', 'db')) bot.start() diff --git a/ptgbot/db.py b/ptgbot/db.py new file mode 100644 index 0000000..0eb52a4 --- /dev/null +++ b/ptgbot/db.py @@ -0,0 +1,53 @@ +#! /usr/bin/env python + +# Copyright (c) 2017, Thierry Carrez +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import os + + +class PTGDataBase(): + + def __init__(self, filename): + self.filename = filename + if os.path.isfile(filename): + with open(filename, 'r') as fp: + self.data = json.load(fp) + else: + self.data = {} + + def add(self, room, adverb, hour, msg): + if room not in self.data: + self.data[room] = {} + self.data[room][adverb] = {'msg': msg, 'expiry': hour} + self.save() + + def expire(self, now): + newdata = [] + for room, infos in self.data.items(): + for info, session in infos: + if session['expiry'] > now: + newdata[room][info] = session + self.data = newdata + + def from_ethercalc(self): + # TODO: Load from ethercalc + pass + + def save(self): + # self.expire() + # self.from_ethercalc() + with open(self.filename, 'w') as fp: + json.dump(self.data, fp)