/botly/reaction.py (cf7bdb8446f0853d984b5088ce21526d38c9777e) (5006 bytes) (mode 100644) (type blob)
#!/usr/bin/env python
"""Contains the ReactionBase class and load_reactions function."""
import asyncio
from importlib import import_module
from os import listdir
from os.path import isfile, join
from botly.trigger import Trigger
class ReactionBase:
"""Subclass this class in a reaction module to create a new Reaction.
When sublcassed, it should pass the event name hook through the constructor
and should redefine these two methods:
def prepare_trigger(self, trigger)
async def react(self)
The first method is called when the object is created. It should defines
the trigger's conditions.
The second one is called when an event triggers this reaction. Place the
actions there.
"""
def __init__(self, eventName):
"""When subclassed, pass the event name to the mother class."""
self.eventName = eventName
self.bot = False
self.knowledge = False
trigger = Trigger(eventName)
# Call the function that should have been subclassed
self.prepare_trigger(trigger)
self.trigger = trigger
def prepare_trigger(self, trigger):
"""Allows the trigger to be personalized. Meant to be subclassed.
This method should be redefined in the subclass.
It should prepare the given trigger by defining its conditions.
It does not require to return anything
"""
raise NotImplementedError
@asyncio.coroutine
def react(self):
"""Method to be subclassed. Called when conditions were met."""
raise NotImplementedError
def print(self, message):
"""Helper for console printing. Will prepend current Reaction name."""
self.bot.print('[Reaction][{0}] {1}'.format(self.moduleName, message))
def is_mentioned(self):
"""Returns whether or not our bot was mentioned in the message."""
assert self.bot, 'Botly instance not passed to this object'
if self.message:
return self.bot.me.mentioned_in(self.message)
@asyncio.coroutine
def reply(self, message):
"""Coroutine that replies in current chan with given message."""
if self.channel:
yield from self.bot.say(self.channel, message)
@asyncio.coroutine
def send_to_chan(self, channel, message):
"""Coroutine that send message to given channel."""
yield from self.bot.say(channel, message)
def set_instance_info(self, bot):
"""Saves botly instance. Only meant to becalled upon module import."""
self.bot = bot
self.knowledge = bot.knowledge
def set_module_name(self, name):
"""Saves the name of this Reaction. Called upon module import."""
self.moduleName = name
def prepare_react(self, **eventInfo):
"""Only meant to be called from Botly. Do not call elsewhere."""
self.message = False
self.messageAfter = False
self.author = False
self.channel = False
self.user = False
self.when = False
self.before = False
self.after = False
if 'message' in self.eventName:
self.message = eventInfo['message']
self.author = eventInfo['message'].author
self.channel = eventInfo['message'].channel
if 'on_message_edit' == self.eventName:
self.messageAfter = eventInfo['after']
elif 'on_typing' == self.eventName:
self.channel = eventInfo['channel']
self.user = eventInfo['user']
self.when = eventInfo['when']
elif 'on_member_update' == self.eventName:
self.before = eventInfo['before']
self.after = eventInfo['after']
elif 'reaction' in self.eventName:
self.reaction = eventInfo['reaction']
self.user = eventInfo['user']
self.channel = self.reaction.message.channel
self.author = self.reaction.message.author
def load_reactions(bot, reactionsParent):
"""Function that loads reactions from given parent module directory."""
# Convert module path to drive path.
dpath = './' + reactionsParent.replace('.', '/')
# Retreive every python script in the reaction module directory
files = [f for f in listdir(dpath)
if isfile(join(dpath,f))
and f.endswith('.py')]
# Build the list of reactions
reactions = []
for file in files:
# Module name does not include '.py' so remove that part
module = file[:-3]
_reaction = import_module(reactionsParent + '.' + module)
reaction = _reaction.Reaction()
reactions.append(reaction)
assert len(reaction.eventName), \
'Loaded a reaction linked to no event.'
# Inject instance info in reaction object
reaction.set_instance_info(bot)
reaction.set_module_name(module)
bot.print('Loaded ' + str(len(reactions)) + ' reactions from drive.')
return reactions
Mode |
Type |
Size |
Ref |
File |
100644 |
blob |
10175 |
e454a52586f29b8ce8a6799163eac1f875e9ac01 |
LICENSE |
100644 |
blob |
912 |
43cc367ee8608a8760e6665ac29c411d58dc8b99 |
README.md |
040000 |
tree |
- |
66dcfaf2ba5cd5742f36e01d7785daf5113c2107 |
botly |
100644 |
blob |
172 |
3f148ab99d152565c46e51fd45e51030417f7faa |
example.py |
040000 |
tree |
- |
e05b34e00f419ee6a20bf1bb6a0603727b1b4399 |
examplebot |
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"
Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/detche/Botly
Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/detche/Botly
Clone this repository using git:
git clone git://git.rocketgit.com/user/detche/Botly
You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a
merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main