2018-03-16 03:13:43 -04:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
"""
|
|
|
|
Methods for loading modules.
|
|
|
|
"""
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import importlib
|
|
|
|
|
|
|
|
def load_module(bot, path):
|
|
|
|
"""
|
|
|
|
Loads a module from the provided path, cleans it up and registers
|
|
|
|
it with the bot's internal callable list.
|
|
|
|
"""
|
|
|
|
module = importlib.import_module(path)
|
|
|
|
if hasattr(module, 'setup'):
|
|
|
|
module.setup(bot)
|
2019-10-08 12:39:13 -04:00
|
|
|
relevant_parts = process_module(module)
|
2018-05-27 14:16:50 -04:00
|
|
|
for part in relevant_parts:
|
|
|
|
bot.register_callable(part)
|
2018-03-16 03:13:43 -04:00
|
|
|
|
|
|
|
|
|
|
|
def unload_module(bot, name):
|
|
|
|
"""
|
|
|
|
Unloads a module and deletes references to it from the bot's memory.
|
|
|
|
"""
|
|
|
|
old_module = sys.modules[name]
|
|
|
|
|
|
|
|
# delete references to the module functions from the bot's memory
|
|
|
|
for obj_name, obj in vars(old_module).items():
|
|
|
|
bot.unregister_callable(obj)
|
|
|
|
|
|
|
|
del old_module
|
2019-10-08 09:06:52 -04:00
|
|
|
delattr(sys.modules['modules'], name.rpartition('.')[2])
|
2018-03-16 03:13:43 -04:00
|
|
|
del sys.modules[name]
|
|
|
|
|
|
|
|
|
2019-10-08 12:39:13 -04:00
|
|
|
def find_modules():
|
2018-03-16 03:13:43 -04:00
|
|
|
"""
|
2019-10-08 12:39:13 -04:00
|
|
|
Searches through 'modules/' for python files and returns a dictionary
|
2018-03-16 03:13:43 -04:00
|
|
|
with the module name as the key and the path as the value.
|
|
|
|
"""
|
|
|
|
modules = {}
|
2019-10-08 12:39:13 -04:00
|
|
|
for file in os.listdir('modules'):
|
2018-03-16 03:13:43 -04:00
|
|
|
if not file.endswith(".py"):
|
|
|
|
continue
|
|
|
|
name = file.replace(".py", "")
|
|
|
|
modules[name] = "modules" + "." + name
|
|
|
|
return modules
|
|
|
|
|
|
|
|
|
2019-10-08 12:39:13 -04:00
|
|
|
def process_module(module):
|
2018-03-16 03:13:43 -04:00
|
|
|
"""
|
|
|
|
Takes a module object and extracts relevant data objects out of it.
|
|
|
|
Returns all callables(read: functions) and shutdowns(?).
|
|
|
|
"""
|
|
|
|
callables = []
|
|
|
|
for key, obj in dict.items(vars(module)):
|
|
|
|
if callable(obj):
|
|
|
|
if is_triggerable(obj):
|
2019-10-08 12:39:13 -04:00
|
|
|
process_callable(obj)
|
2018-03-16 03:13:43 -04:00
|
|
|
callables.append(obj)
|
|
|
|
return callables
|
|
|
|
|
|
|
|
|
|
|
|
def is_triggerable(obj):
|
|
|
|
"""
|
|
|
|
Checks if the given function object is triggerable by Fulvia, eg. has
|
|
|
|
any of a few particular attributes or declarators defined.
|
|
|
|
"""
|
2019-10-07 16:37:39 -04:00
|
|
|
triggerable_attributes = ("commands", "hook", "url_callback", "user_joined")
|
2018-03-16 03:13:43 -04:00
|
|
|
return any(hasattr(obj, attr) for attr in triggerable_attributes)
|
|
|
|
|
|
|
|
|
2019-10-08 12:39:13 -04:00
|
|
|
def process_callable(func):
|
2018-03-16 03:13:43 -04:00
|
|
|
"""
|
|
|
|
Sets various helper atributes about a given function.
|
|
|
|
"""
|
2018-03-25 14:27:40 -04:00
|
|
|
func.thread = getattr(func, "thread", True)
|
|
|
|
func.hook = getattr(func, "hook", False)
|
|
|
|
func.rate = getattr(func, "rate", 0)
|
|
|
|
func.channel_rate = getattr(func, "channel_rate", 0)
|
|
|
|
func.global_rate = getattr(func, "global_rate", 0)
|
2019-10-07 16:37:39 -04:00
|
|
|
func.user_joined = getattr(func, "user_joined", False)
|