From 2ac37f79d9fdb151a5805f1692cbd1e8ec1fea38 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 5 Apr 2016 23:55:08 +0200 Subject: [PATCH] New class storing scope --- nemubot/datastore/xml.py | 2 + nemubot/message/abstract.py | 8 ++++ nemubot/scope.py | 83 +++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 nemubot/scope.py diff --git a/nemubot/datastore/xml.py b/nemubot/datastore/xml.py index 0c5c0b1..a82318d 100644 --- a/nemubot/datastore/xml.py +++ b/nemubot/datastore/xml.py @@ -121,6 +121,7 @@ class XML(Abstract): from nemubot.datastore.nodes import basic as basicNodes from nemubot.datastore.nodes import python as pythonNodes from nemubot.message.command import Command + from nemubot.scope import Scope d = { basicNodes.ListNode.serializetag: basicNodes.ListNode, @@ -129,6 +130,7 @@ class XML(Abstract): pythonNodes.FloatNode.serializetag: pythonNodes.FloatNode, pythonNodes.StringNode.serializetag: pythonNodes.StringNode, Command.serializetag: Command, + Scope.serializetag: Scope, } d.update(extendsTags) diff --git a/nemubot/message/abstract.py b/nemubot/message/abstract.py index f3a4e03..bf9a030 100644 --- a/nemubot/message/abstract.py +++ b/nemubot/message/abstract.py @@ -70,6 +70,14 @@ class Abstract(Serializable): return self.frm + @property + def scope(self): + from nemubot.scope import Scope + return Scope(server=self.server, + channel=self.to_response[0], + nick=self.frm) + + def accept(self, visitor): visitor.visit(self) diff --git a/nemubot/scope.py b/nemubot/scope.py new file mode 100644 index 0000000..5da1542 --- /dev/null +++ b/nemubot/scope.py @@ -0,0 +1,83 @@ +# Nemubot is a smart and modulable IM bot. +# Copyright (C) 2012-2016 Mercier Pierre-Olivier +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from nemubot.datastore.nodes import Serializable + + +class Scope(Serializable): + + + serializetag = "nemubot-scope" + default_limit = "channel" + + + def __init__(self, server, channel, nick, limit=default_limit): + self._server = server + self._channel = channel + self._nick = nick + self._limit = limit + + + def sameServer(self, server): + return self._server is None or self._server == server + + + def sameChannel(self, server, channel): + return self.sameServer(server) and (self._channel is None or self._channel == channel) + + + def sameNick(self, server, channel, nick): + return self.sameChannel(server, channel) and (self._nick is None or self._nick == nick) + + + def check(self, scope, limit=None): + return self.checkScope(scope._server, scope._channel, scope._nick, limit) + + + def checkScope(self, server, channel, nick, limit=None): + if limit is None: limit = self._limit + assert limit == "global" or limit == "server" or limit == "channel" or limit == "nick" + + if limit == "server": + return self.sameServer(server) + elif limit == "channel": + return self.sameChannel(server, channel) + elif limit == "nick": + return self.sameNick(server, channel, nick) + else: + return True + + + def narrow(self, scope): + return scope is None or ( + scope._limit == "global" or + (scope._limit == "server" and (self._limit == "nick" or self._limit == "channel")) or + (scope._limit == "channel" and self._limit == "nick") + ) + + + def serialize(self): + from nemubot.datastore.nodes import ParsingNode + args = {} + if self._server is not None: + args["server"] = self._server + if self._channel is not None: + args["channel"] = self._channel + if self._nick is not None: + args["nick"] = self._nick + if self._limit is not None: + args["limit"] = self._limit + return ParsingNode(tag=self.serializetag, **args)