Lua modules, storage
This commit is contained in:
parent
5dac2114ff
commit
c99bc0a723
47
main.py
47
main.py
@ -34,6 +34,20 @@ class Module:
|
|||||||
self.name = name
|
self.name = name
|
||||||
MODULES.update({self.name: self})
|
MODULES.update({self.name: self})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self) -> str:
|
||||||
|
"""
|
||||||
|
Return module type. It can be python or lua
|
||||||
|
|
||||||
|
:return: Module type
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
if not os.path.exists(os.path.join("modules", self.name, "version.json")):
|
||||||
|
return ""
|
||||||
|
with open(os.path.join("modules", self.name, "version.json")) as file:
|
||||||
|
versions = json.load(file)
|
||||||
|
return versions["type"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def exists(self) -> bool:
|
def exists(self) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -65,6 +79,8 @@ class Module:
|
|||||||
return False
|
return False
|
||||||
if "bot_version" not in versions.keys():
|
if "bot_version" not in versions.keys():
|
||||||
return False
|
return False
|
||||||
|
if "type" not in versions.keys():
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -274,21 +290,34 @@ class LBI(discord.Client):
|
|||||||
for dep in deps.keys():
|
for dep in deps.keys():
|
||||||
if dep not in self.modules.keys():
|
if dep not in self.modules.keys():
|
||||||
self.load_module(dep)
|
self.load_module(dep)
|
||||||
try:
|
if MODULES[module].type == "python":
|
||||||
self.info("Start loading module {module}...".format(module=module))
|
try:
|
||||||
imported = importlib.import_module('modules.' + module)
|
self.info("Start loading module {module}...".format(module=module))
|
||||||
|
imported = importlib.import_module('modules.' + module)
|
||||||
|
importlib.reload(imported)
|
||||||
|
initialized_class = imported.MainClass(self)
|
||||||
|
self.modules.update({module: {"imported": imported, "initialized_class": initialized_class}})
|
||||||
|
self.info("Module {module} successfully imported.".format(module=module))
|
||||||
|
initialized_class.dispatch("load")
|
||||||
|
if module not in self.config["modules"]:
|
||||||
|
self.config["modules"].append(module)
|
||||||
|
self.save_config()
|
||||||
|
except AttributeError as e:
|
||||||
|
self.error("Module {module} doesn't have MainClass.".format(module=module))
|
||||||
|
return e
|
||||||
|
return 0
|
||||||
|
elif MODULES[module].type == "lua":
|
||||||
|
self.info(f"Start loading module {module}...")
|
||||||
|
imported = importlib.import_module('modules.base.BaseLua')
|
||||||
importlib.reload(imported)
|
importlib.reload(imported)
|
||||||
initialized_class = imported.MainClass(self)
|
initialized_class = imported.BaseClassLua(self, path=f"modules/{module}/main")
|
||||||
self.modules.update({module: {"imported": imported, "initialized_class": initialized_class}})
|
self.modules.update({module: {"imported": imported, "initialized_class": initialized_class}})
|
||||||
self.info("Module {module} successfully imported.".format(module=module))
|
self.info(f"Module {module} successfully imported.")
|
||||||
initialized_class.dispatch("load")
|
initialized_class.dispatch("load")
|
||||||
if module not in self.config["modules"]:
|
if module not in self.config["modules"]:
|
||||||
self.config["modules"].append(module)
|
self.config["modules"].append(module)
|
||||||
self.save_config()
|
self.save_config()
|
||||||
except AttributeError as e:
|
return 0
|
||||||
self.error("Module {module} doesn't have MainClass.".format(module=module))
|
|
||||||
return e
|
|
||||||
return 0
|
|
||||||
|
|
||||||
@modules_edit
|
@modules_edit
|
||||||
def unload_module(self, module):
|
def unload_module(self, module):
|
||||||
|
195
modules/base/Base.py
Normal file
195
modules/base/Base.py
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
"""Base class for module, never use directly !!!"""
|
||||||
|
import asyncio
|
||||||
|
import sys
|
||||||
|
import pickle
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
import discord
|
||||||
|
|
||||||
|
from storage import FSStorage, FSObjects
|
||||||
|
import storage.path as path
|
||||||
|
|
||||||
|
|
||||||
|
class BaseClass:
|
||||||
|
"""Base class for all modules, Override it to make submodules"""
|
||||||
|
name = ""
|
||||||
|
help = {
|
||||||
|
"description": "",
|
||||||
|
"commands": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
help_active = False
|
||||||
|
color = 0x000000
|
||||||
|
command_text = None
|
||||||
|
super_users = []
|
||||||
|
authorized_roles = []
|
||||||
|
|
||||||
|
def __init__(self, client):
|
||||||
|
"""Initialize module class
|
||||||
|
|
||||||
|
Initialize module class, always call it to set self.client when you override it.
|
||||||
|
|
||||||
|
:param client: client instance
|
||||||
|
:type client: NikolaTesla"""
|
||||||
|
self.client = client
|
||||||
|
self.storage = FSStorage(path.join(self.client.base_path, self.name))
|
||||||
|
self.objects = FSObjects(self.storage)
|
||||||
|
if not self.storage.isdir(path.join("storage", self.name)):
|
||||||
|
self.storage.makedirs(path.join("storage", self.name), exist_ok=True)
|
||||||
|
|
||||||
|
async def send_help(self, channel):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="[{nom}] - Aide".format(nom=self.name),
|
||||||
|
description=self.help["description"].format(prefix=self.client.config['prefix']),
|
||||||
|
color=self.color
|
||||||
|
)
|
||||||
|
for command, description in self.help["commands"].items():
|
||||||
|
embed.add_field(name=command.format(prefix=self.client.config['prefix'], command=self.command_text),
|
||||||
|
value=description.format(prefix=self.client.config['prefix'], command=self.command_text),
|
||||||
|
inline=False)
|
||||||
|
await channel.send(embed=embed)
|
||||||
|
|
||||||
|
async def auth(self, user, role_list):
|
||||||
|
if type(role_list) == list:
|
||||||
|
if user.id in self.client.owners:
|
||||||
|
return True
|
||||||
|
for guild in self.client.guilds:
|
||||||
|
if guild.get_member(user.id):
|
||||||
|
for role_id in role_list:
|
||||||
|
if role_id in [r.id for r in guild.get_member(user.id).roles]:
|
||||||
|
return True
|
||||||
|
elif type(role_list) == str:
|
||||||
|
module_name = role_list
|
||||||
|
if user.id in self.client.owners:
|
||||||
|
return True
|
||||||
|
authorized_roles = self.client.modules[module_name]["class"].authorized_roles
|
||||||
|
if len(authorized_roles):
|
||||||
|
for guild in self.client.guilds:
|
||||||
|
if guild.get_member(user.id):
|
||||||
|
for role_id in authorized_roles:
|
||||||
|
if role_id in [r.id for r in guild.get_member(user.id).roles]:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def parse_command(self, message):
|
||||||
|
"""Parse a command_text from received message and execute function
|
||||||
|
%git update
|
||||||
|
com_update(m..)
|
||||||
|
Parse message like `{prefix}{command_text} subcommand` and call class method `com_{subcommand}`.
|
||||||
|
|
||||||
|
:param message: message to parse
|
||||||
|
:type message: discord.Message"""
|
||||||
|
if message.content.startswith(self.client.config["prefix"] + (self.command_text if self.command_text else "")):
|
||||||
|
|
||||||
|
content = message.content.lstrip(
|
||||||
|
self.client.config["prefix"] + (self.command_text if self.command_text else ""))
|
||||||
|
sub_command, args, kwargs = self._parse_command_content(content)
|
||||||
|
sub_command = "com_" + sub_command
|
||||||
|
if sub_command in dir(self):
|
||||||
|
await self.__getattribute__(sub_command)(message, args, kwargs)
|
||||||
|
else:
|
||||||
|
await self.command(message, [sub_command[4:]] + args, kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_command_content(content):
|
||||||
|
"""Parse string
|
||||||
|
|
||||||
|
Parse string like `subcommand argument "argument with spaces" -o -shortwaytopassoncharacteroption --longoption
|
||||||
|
-o "option with argument"`. You can override this function to change parsing.
|
||||||
|
|
||||||
|
:param content: content to parse
|
||||||
|
:type content: str
|
||||||
|
|
||||||
|
:return: parsed arguments: [subcommand, [arg1, arg2, ...], [(option1, arg1), (option2, arg2), ...]]
|
||||||
|
:rtype: list[str, list, list]"""
|
||||||
|
if not len(content.split()):
|
||||||
|
return "", [], []
|
||||||
|
# Sub_command
|
||||||
|
sub_command = content.split()[0]
|
||||||
|
args_ = []
|
||||||
|
kwargs = []
|
||||||
|
if len(content.split()) > 1:
|
||||||
|
# Take the other part of command_text
|
||||||
|
content = content.split(" ", 1)[1].replace("\"", "\"\"")
|
||||||
|
# Splitting around quotes
|
||||||
|
quotes = [element.split("\" ") for element in content.split(" \"")]
|
||||||
|
# Split all sub chains but brute chains and flat the resulting list
|
||||||
|
args = [item.split() if item[0] != "\"" else [item, ] for sublist in quotes for item in sublist]
|
||||||
|
# Second plating
|
||||||
|
args = [item for sublist in args for item in sublist]
|
||||||
|
# args_ are arguments, kwargs are options with arguments
|
||||||
|
i = 0
|
||||||
|
while i < len(args):
|
||||||
|
if args[i].startswith("\""):
|
||||||
|
args_.append(args[i][1:-1])
|
||||||
|
elif args[i].startswith("--"):
|
||||||
|
if i + 1 >= len(args):
|
||||||
|
kwargs.append((args[i].lstrip("-"), None))
|
||||||
|
break
|
||||||
|
if args[i + 1][0] != "-":
|
||||||
|
kwargs.append((args[i].lstrip("-"), args[i + 1].strip("\"")))
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
kwargs.append((args[i].lstrip("-"), None))
|
||||||
|
elif args[i].startswith("-"):
|
||||||
|
if len(args[i]) == 2:
|
||||||
|
if i + 1 >= len(args):
|
||||||
|
break
|
||||||
|
if args[i + 1][0] != "-":
|
||||||
|
kwargs.append((args[i].lstrip("-"), args[i + 1].strip("\"")))
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
kwargs.append((args[i].lstrip("-"), None))
|
||||||
|
else:
|
||||||
|
kwargs.extend([(arg, None) for arg in args[i][1:]])
|
||||||
|
else:
|
||||||
|
args_.append(args[i])
|
||||||
|
i += 1
|
||||||
|
return sub_command, args_, kwargs
|
||||||
|
|
||||||
|
async def on_message(self, message):
|
||||||
|
"""Override this function to deactivate command_text parsing"""
|
||||||
|
await self.parse_command(message)
|
||||||
|
|
||||||
|
async def command(self, message, args, kwargs):
|
||||||
|
"""Override this function to handle all messages starting with `{prefix}{command_text}`
|
||||||
|
|
||||||
|
Function which is executed for all command_text doesn't match with a `com_{subcommand}` function"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def dispatch(self, event, *args, **kwargs):
|
||||||
|
# Method to call
|
||||||
|
method = 'on_' + event
|
||||||
|
try:
|
||||||
|
# Try to get coro, if not exists pass without raise an error
|
||||||
|
coro = getattr(self, method)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# Run event
|
||||||
|
asyncio.ensure_future(self._run_event(coro, method, *args, **kwargs), loop=self.client.loop)
|
||||||
|
|
||||||
|
async def _run_event(self, coro, event_name, *args, **kwargs):
|
||||||
|
# Run event
|
||||||
|
try:
|
||||||
|
await coro(*args, **kwargs)
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
# If function is cancelled pass silently
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
# Call error function
|
||||||
|
await self.on_error(event_name, *args, **kwargs)
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
# If error event is canceled pass silently
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def on_error(self, event_method, *args, **kwargs):
|
||||||
|
# Basic error handler
|
||||||
|
print('Ignoring exception in {}'.format(event_method), file=sys.stderr)
|
||||||
|
traceback.print_exc()
|
@ -1,5 +1,6 @@
|
|||||||
"""Base class for module, never use directly !!!"""
|
"""Base class for module, never use directly !!!"""
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
import pickle
|
import pickle
|
||||||
import traceback
|
import traceback
|
||||||
@ -7,11 +8,12 @@ import traceback
|
|||||||
import discord
|
import discord
|
||||||
import lupa
|
import lupa
|
||||||
|
|
||||||
|
from modules.base.Base import BaseClass
|
||||||
from storage import FSStorage
|
from storage import FSStorage
|
||||||
import storage.path as path
|
import storage.path as path
|
||||||
|
|
||||||
|
|
||||||
class BaseClassLua:
|
class BaseClassLua(BaseClass):
|
||||||
"""Base class for all modules, Override it to make submodules"""
|
"""Base class for all modules, Override it to make submodules"""
|
||||||
name = ""
|
name = ""
|
||||||
help = {
|
help = {
|
||||||
@ -26,22 +28,48 @@ class BaseClassLua:
|
|||||||
super_users = []
|
super_users = []
|
||||||
authorized_roles = []
|
authorized_roles = []
|
||||||
|
|
||||||
def __init__(self, client):
|
def __init__(self, client, path):
|
||||||
"""Initialize module class
|
"""Initialize module class
|
||||||
|
|
||||||
Initialize module class, always call it to set self.client when you override it.
|
Initialize module class, always call it to set self.client when you override it.
|
||||||
|
|
||||||
:param client: client instance
|
:param client: client instance
|
||||||
:type client: NikolaTesla"""
|
:type client: NikolaTesla"""
|
||||||
self.client = client
|
super().__init__(client)
|
||||||
self.storage = FSStorage(path.join(self.client.base_path, self.name))
|
|
||||||
if not self.storage.isdir(path.join("storage", self.name)):
|
|
||||||
self.storage.makedirs(path.join("storage", self.name), exist_ok=True)
|
|
||||||
# Get lua globals
|
# Get lua globals
|
||||||
self.lua = lupa.LuaRuntime(unpack_returned_tuples=True)
|
self.lua = lupa.LuaRuntime(unpack_returned_tuples=True)
|
||||||
self.luaMethods = self.lua.require("modules/test_lua/main")
|
print(os.path.abspath(path))
|
||||||
|
self.luaMethods = self.lua.require(path)
|
||||||
|
|
||||||
def dispatch(self, event, *args, **kwargs):
|
def dispatch(self, event, *args, **kwargs):
|
||||||
if self.luaMethods["on_"+event] is not None:
|
method = "on_"+event
|
||||||
self.luaMethods["on_"+event](asyncio.ensure_future, self.client, *args, **kwargs)
|
if self.luaMethods[method] is not None:
|
||||||
|
self.luaMethods[method](asyncio.ensure_future, self, *args, **kwargs)
|
||||||
|
else: # If lua methods not found, dispatch to python methods
|
||||||
|
super().dispatch(event, *args, **kwargs)
|
||||||
|
|
||||||
|
async def _run_event(self, coro, event_name, *args, **kwargs):
|
||||||
|
# Overide here to execute lua on_error if it exists
|
||||||
|
# Run event
|
||||||
|
try:
|
||||||
|
await coro(*args, **kwargs)
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
# If function is cancelled pass silently
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
# Call error function
|
||||||
|
if self.luaMethods["on_error"] is not None:
|
||||||
|
self.luaMethods["on_error"](self, asyncio.ensure_future, discord, *args, **kwargs)
|
||||||
|
else:
|
||||||
|
await self.on_error(event_name, *args, **kwargs)
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
# If error event is canceled pass silently
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def on_error(self, event_method, *args, **kwargs):
|
||||||
|
# Base on_error event, executed if lua not provide it
|
||||||
|
# Basic error handler
|
||||||
|
print('Ignoring exception in {}'.format(event_method), file=sys.stderr)
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
@ -1,209 +1,8 @@
|
|||||||
"""Base class for module, never use directly !!!"""
|
"""Base class for module, never use directly !!!"""
|
||||||
import asyncio
|
|
||||||
import sys
|
|
||||||
import pickle
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
import discord
|
from modules.base.Base import BaseClass
|
||||||
|
|
||||||
from storage import FSStorage
|
|
||||||
import storage.path as path
|
|
||||||
|
|
||||||
|
|
||||||
class BaseClassPython:
|
class BaseClassPython(BaseClass):
|
||||||
"""Base class for all modules, Override it to make submodules"""
|
"""Base class for all modules, Override it to make submodules"""
|
||||||
name = ""
|
pass
|
||||||
help = {
|
|
||||||
"description": "",
|
|
||||||
"commands": {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
help_active = False
|
|
||||||
color = 0x000000
|
|
||||||
command_text = None
|
|
||||||
super_users = []
|
|
||||||
authorized_roles = []
|
|
||||||
|
|
||||||
def __init__(self, client):
|
|
||||||
"""Initialize module class
|
|
||||||
|
|
||||||
Initialize module class, always call it to set self.client when you override it.
|
|
||||||
|
|
||||||
:param client: client instance
|
|
||||||
:type client: NikolaTesla"""
|
|
||||||
self.client = client
|
|
||||||
self.storage = FSStorage(path.join(self.client.base_path, self.name))
|
|
||||||
if not self.storage.isdir(path.join("storage", self.name)):
|
|
||||||
self.storage.makedirs(path.join("storage", self.name), exist_ok=True)
|
|
||||||
|
|
||||||
async def send_help(self, channel):
|
|
||||||
embed = discord.Embed(
|
|
||||||
title="[{nom}] - Aide".format(nom=self.name),
|
|
||||||
description=self.help["description"].format(prefix=self.client.config['prefix']),
|
|
||||||
color=self.color
|
|
||||||
)
|
|
||||||
for command, description in self.help["commands"].items():
|
|
||||||
embed.add_field(name=command.format(prefix=self.client.config['prefix'], command=self.command_text),
|
|
||||||
value=description.format(prefix=self.client.config['prefix'], command=self.command_text),
|
|
||||||
inline=False)
|
|
||||||
await channel.send(embed=embed)
|
|
||||||
|
|
||||||
async def auth(self, user, role_list):
|
|
||||||
if type(role_list) == list:
|
|
||||||
if user.id in self.client.owners:
|
|
||||||
return True
|
|
||||||
for guild in self.client.guilds:
|
|
||||||
if guild.get_member(user.id):
|
|
||||||
for role_id in role_list:
|
|
||||||
if role_id in [r.id for r in guild.get_member(user.id).roles]:
|
|
||||||
return True
|
|
||||||
elif type(role_list) == str:
|
|
||||||
module_name = role_list
|
|
||||||
if user.id in self.client.owners:
|
|
||||||
return True
|
|
||||||
authorized_roles = self.client.modules[module_name]["class"].authorized_roles
|
|
||||||
if len(authorized_roles):
|
|
||||||
for guild in self.client.guilds:
|
|
||||||
if guild.get_member(user.id):
|
|
||||||
for role_id in authorized_roles:
|
|
||||||
if role_id in [r.id for r in guild.get_member(user.id).roles]:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def parse_command(self, message):
|
|
||||||
"""Parse a command_text from received message and execute function
|
|
||||||
%git update
|
|
||||||
com_update(m..)
|
|
||||||
Parse message like `{prefix}{command_text} subcommand` and call class method `com_{subcommand}`.
|
|
||||||
|
|
||||||
:param message: message to parse
|
|
||||||
:type message: discord.Message"""
|
|
||||||
if message.content.startswith(self.client.config["prefix"] + (self.command_text if self.command_text else "")):
|
|
||||||
|
|
||||||
content = message.content.lstrip(
|
|
||||||
self.client.config["prefix"] + (self.command_text if self.command_text else ""))
|
|
||||||
sub_command, args, kwargs = self._parse_command_content(content)
|
|
||||||
sub_command = "com_" + sub_command
|
|
||||||
if sub_command in dir(self):
|
|
||||||
await self.__getattribute__(sub_command)(message, args, kwargs)
|
|
||||||
else:
|
|
||||||
await self.command(message, [sub_command[4:]] + args, kwargs)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _parse_command_content(content):
|
|
||||||
"""Parse string
|
|
||||||
|
|
||||||
Parse string like `subcommand argument "argument with spaces" -o -shortwaytopassoncharacteroption --longoption
|
|
||||||
-o "option with argument"`. You can override this function to change parsing.
|
|
||||||
|
|
||||||
:param content: content to parse
|
|
||||||
:type content: str
|
|
||||||
|
|
||||||
:return: parsed arguments: [subcommand, [arg1, arg2, ...], [(option1, arg1), (option2, arg2), ...]]
|
|
||||||
:rtype: list[str, list, list]"""
|
|
||||||
if not len(content.split()):
|
|
||||||
return "", [], []
|
|
||||||
# Sub_command
|
|
||||||
sub_command = content.split()[0]
|
|
||||||
args_ = []
|
|
||||||
kwargs = []
|
|
||||||
if len(content.split()) > 1:
|
|
||||||
# Take the other part of command_text
|
|
||||||
content = content.split(" ", 1)[1].replace("\"", "\"\"")
|
|
||||||
# Splitting around quotes
|
|
||||||
quotes = [element.split("\" ") for element in content.split(" \"")]
|
|
||||||
# Split all sub chains but brute chains and flat the resulting list
|
|
||||||
args = [item.split() if item[0] != "\"" else [item, ] for sublist in quotes for item in sublist]
|
|
||||||
# Second plating
|
|
||||||
args = [item for sublist in args for item in sublist]
|
|
||||||
# args_ are arguments, kwargs are options with arguments
|
|
||||||
i = 0
|
|
||||||
while i < len(args):
|
|
||||||
if args[i].startswith("\""):
|
|
||||||
args_.append(args[i][1:-1])
|
|
||||||
elif args[i].startswith("--"):
|
|
||||||
if i + 1 >= len(args):
|
|
||||||
kwargs.append((args[i].lstrip("-"), None))
|
|
||||||
break
|
|
||||||
if args[i + 1][0] != "-":
|
|
||||||
kwargs.append((args[i].lstrip("-"), args[i + 1].strip("\"")))
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
kwargs.append((args[i].lstrip("-"), None))
|
|
||||||
elif args[i].startswith("-"):
|
|
||||||
if len(args[i]) == 2:
|
|
||||||
if i + 1 >= len(args):
|
|
||||||
break
|
|
||||||
if args[i + 1][0] != "-":
|
|
||||||
kwargs.append((args[i].lstrip("-"), args[i + 1].strip("\"")))
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
kwargs.append((args[i].lstrip("-"), None))
|
|
||||||
else:
|
|
||||||
kwargs.extend([(arg, None) for arg in args[i][1:]])
|
|
||||||
else:
|
|
||||||
args_.append(args[i])
|
|
||||||
i += 1
|
|
||||||
return sub_command, args_, kwargs
|
|
||||||
|
|
||||||
async def on_message(self, message):
|
|
||||||
"""Override this function to deactivate command_text parsing"""
|
|
||||||
await self.parse_command(message)
|
|
||||||
|
|
||||||
async def command(self, message, args, kwargs):
|
|
||||||
"""Override this function to handle all messages starting with `{prefix}{command_text}`
|
|
||||||
|
|
||||||
Function which is executed for all command_text doesn't match with a `com_{subcommand}` function"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def save_object(self, object_instance, object_name):
|
|
||||||
"""Save object into pickle file"""
|
|
||||||
with self.storage.open(object_name, "wb") as f:
|
|
||||||
pickler = pickle.Pickler(f)
|
|
||||||
pickler.dump(object_instance)
|
|
||||||
|
|
||||||
def load_object(self, object_name):
|
|
||||||
"""Load object from pickle file"""
|
|
||||||
if self.save_exists(object_name):
|
|
||||||
with self.storage.open(object_name, "rb") as f:
|
|
||||||
unpickler = pickle.Unpickler(f)
|
|
||||||
return unpickler.load()
|
|
||||||
|
|
||||||
def save_exists(self, object_name):
|
|
||||||
"""Check if pickle file exists"""
|
|
||||||
return self.storage.exists(object_name)
|
|
||||||
|
|
||||||
def dispatch(self, event, *args, **kwargs):
|
|
||||||
# Method to call
|
|
||||||
method = 'on_' + event
|
|
||||||
try:
|
|
||||||
# Try to get coro, if not exists pass without raise an error
|
|
||||||
coro = getattr(self, method)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# Run event
|
|
||||||
asyncio.ensure_future(self._run_event(coro, method, *args, **kwargs), loop=self.client.loop)
|
|
||||||
|
|
||||||
async def _run_event(self, coro, event_name, *args, **kwargs):
|
|
||||||
# Run event
|
|
||||||
try:
|
|
||||||
await coro(*args, **kwargs)
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
# If function is cancelled pass silently
|
|
||||||
pass
|
|
||||||
except Exception:
|
|
||||||
try:
|
|
||||||
# Call error function
|
|
||||||
await self.on_error(event_name, *args, **kwargs)
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
# If error event is canceled pass silently
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def on_error(self, event_method, *args, **kwargs):
|
|
||||||
# Basic error handler
|
|
||||||
print('Ignoring exception in {}'.format(event_method), file=sys.stderr)
|
|
||||||
traceback.print_exc()
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version":"0.1.0",
|
"version":"0.1.0",
|
||||||
|
"type": "python",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -32,8 +32,8 @@ class MainClass(BaseClassPython):
|
|||||||
self.icon = ""
|
self.icon = ""
|
||||||
|
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
if self.save_exists('errorsDeque'):
|
if self.objects.save_exists('errorsDeque'):
|
||||||
self.errorsDeque = self.load_object('errorsDeque')
|
self.errorsDeque = self.objects.load_object('errorsDeque')
|
||||||
else:
|
else:
|
||||||
self.errorsDeque = collections.deque()
|
self.errorsDeque = collections.deque()
|
||||||
for i in range(len(self.errorsDeque)):
|
for i in range(len(self.errorsDeque)):
|
||||||
@ -44,7 +44,7 @@ class MainClass(BaseClassPython):
|
|||||||
await delete_message.delete()
|
await delete_message.delete()
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
self.save_object(self.errorsDeque, 'errorsDeque')
|
self.objects.save_object(self.errorsDeque, 'errorsDeque')
|
||||||
|
|
||||||
async def command(self, message, args, kwargs):
|
async def command(self, message, args, kwargs):
|
||||||
raise Exception("Si cette erreur apparait, alors tout est normal")
|
raise Exception("Si cette erreur apparait, alors tout est normal")
|
||||||
@ -72,7 +72,7 @@ class MainClass(BaseClassPython):
|
|||||||
embed=embed.set_footer(text="Ce message ne s'autodétruira pas.", icon_url=self.icon))
|
embed=embed.set_footer(text="Ce message ne s'autodétruira pas.", icon_url=self.icon))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.save_object(self.errorsDeque, 'errorsDeque')
|
self.objects.save_object(self.errorsDeque, 'errorsDeque')
|
||||||
await asyncio.sleep(60)
|
await asyncio.sleep(60)
|
||||||
try:
|
try:
|
||||||
channel = self.client.get_channel(message_list[0])
|
channel = self.client.get_channel(message_list[0])
|
||||||
@ -85,4 +85,4 @@ class MainClass(BaseClassPython):
|
|||||||
self.errorsDeque.remove(message_list)
|
self.errorsDeque.remove(message_list)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
self.save_object(self.errorsDeque, 'errorsDeque')
|
self.objects.save_object(self.errorsDeque, 'errorsDeque')
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
"type": "python",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"base": {
|
"base": {
|
||||||
"min": "0.1.0",
|
"min": "0.1.0",
|
||||||
|
@ -17,7 +17,7 @@ class MainClass(BaseClassPython):
|
|||||||
"`{prefix}{command} list`": "List of available modules.",
|
"`{prefix}{command} list`": "List of available modules.",
|
||||||
"`{prefix}{command} enable <module>`": "Enable module `<module>`.",
|
"`{prefix}{command} enable <module>`": "Enable module `<module>`.",
|
||||||
"`{prefix}{command} disable <module>`": "Disable module `<module>`.",
|
"`{prefix}{command} disable <module>`": "Disable module `<module>`.",
|
||||||
"`{prefix}{command} reload <module>`":"Reload module `<module>`",
|
"`{prefix}{command} reload <module>`": "Reload module `<module>`",
|
||||||
"`{prefix}{command} web_list`": "List all available modules from repository",
|
"`{prefix}{command} web_list`": "List all available modules from repository",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
"type": "python",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"base": {
|
"base": {
|
||||||
"min": "0.1.0",
|
"min": "0.1.0",
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
from modules.base import BaseClassLua
|
|
||||||
|
|
||||||
|
|
||||||
class MainClass(BaseClassLua):
|
|
||||||
pass
|
|
@ -1,11 +1,8 @@
|
|||||||
main = {}
|
main = {}
|
||||||
|
|
||||||
|
function main.on_message(self, await, discord, message)
|
||||||
function main.on_message(await, client, message, ...)
|
|
||||||
print("I LOVE LUA")
|
|
||||||
print(message.content)
|
|
||||||
if message.author.bot == false then
|
if message.author.bot == false then
|
||||||
await(message.channel.send("Tu n'es pas un bot"))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
|
"type":"lua",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"base": {
|
"base": {
|
||||||
"min": "0.1.0",
|
"min": "0.1.0",
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from storage.base import Storage
|
from storage.base import Storage, Objects
|
||||||
|
|
||||||
|
|
||||||
class FSStorage(Storage):
|
class FSStorage(Storage):
|
||||||
"""
|
"""
|
||||||
@ -73,3 +72,6 @@ class FSStorage(Storage):
|
|||||||
|
|
||||||
def isdir(self, path):
|
def isdir(self, path):
|
||||||
return os.path.isdir(self._topath(path))
|
return os.path.isdir(self._topath(path))
|
||||||
|
|
||||||
|
class FSObjects(Objects):
|
||||||
|
pass
|
@ -1 +1,2 @@
|
|||||||
from storage.FileSystem import FSStorage
|
from storage.FileSystem import FSStorage
|
||||||
|
from storage.FileSystem import FSObjects
|
@ -1,3 +1,8 @@
|
|||||||
|
import pickle
|
||||||
|
|
||||||
|
from storage import path as pth
|
||||||
|
|
||||||
|
|
||||||
class Storage:
|
class Storage:
|
||||||
"""Basic class for storage interface
|
"""Basic class for storage interface
|
||||||
|
|
||||||
@ -52,6 +57,7 @@ class Storage:
|
|||||||
async def makedirs(self, path, exist_ok=False):
|
async def makedirs(self, path, exist_ok=False):
|
||||||
"""
|
"""
|
||||||
Create directory `path`
|
Create directory `path`
|
||||||
|
:param exist_ok: Not return error if dir exists
|
||||||
:param path: directory to create
|
:param path: directory to create
|
||||||
:return: Path to new directory
|
:return: Path to new directory
|
||||||
"""
|
"""
|
||||||
@ -113,3 +119,25 @@ class Storage:
|
|||||||
:return: True if path is a directory
|
:return: True if path is a directory
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Objects:
|
||||||
|
def __init__(self, storage):
|
||||||
|
self.storage = storage
|
||||||
|
|
||||||
|
def save_object(self, object_name, object_instance):
|
||||||
|
"""Save object into pickle file"""
|
||||||
|
with self.storage.open(pth.join("objects", object_name), "wb") as f:
|
||||||
|
pickler = pickle.Pickler(f)
|
||||||
|
pickler.dump(object_instance)
|
||||||
|
|
||||||
|
def load_object(self, object_name):
|
||||||
|
"""Load object from pickle file"""
|
||||||
|
if self.save_exists(object_name):
|
||||||
|
with self.storage.open(pth.join("objects", object_name), "rb") as f:
|
||||||
|
unpickler = pickle.Unpickler(f)
|
||||||
|
return unpickler.load()
|
||||||
|
|
||||||
|
def save_exists(self, object_name):
|
||||||
|
"""Check if pickle file exists"""
|
||||||
|
return self.storage.exists(pth.join("objects", object_name))
|
||||||
|
Loading…
Reference in New Issue
Block a user