J'ai pas assez de co donc je commit pour pouvoir le lancer sur ma rpi

This commit is contained in:
fomys 2019-06-05 02:15:29 +02:00
parent 2ef6501905
commit cc85cf5ffd
10 changed files with 294 additions and 234 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
DISCORD_TOKEN="NTUwMDkxOTAyMDY2ODg0NjA4.XPKt2Q.iSlsETqAT-5jW6KgbhkNMIvN0WY"

View File

@ -1,15 +1,23 @@
[[source]] [[source]]
url = "https://pypi.org/simple" url = "https://pypi.org/simple"
verify_ssl = true verify_ssl = true
name = "pypi" name = "pypi"
[packages] [packages]
packaging = "*" packaging = "*"
discord-py = {extras = ["voice"],git = "https://github.com/Rapptz/discord.py",ref = "84c1eac62a775a37b03bd0971b221b0c50724630"} discord-py = {extras = ["voice"],git = "https://github.com/Rapptz/discord.py",ref = "84c1eac62a775a37b03bd0971b221b0c50724630"}
aiohttp = "*" aiohttp = "*"
aiofiles = "*" aiofiles = "*"
lupa = "*"
[dev-packages] [dev-packages]
[requires] [requires]
python_version = "3.7" python_version = "3.7"

8
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "e5ce2d692a19fe61098fd4a82500439d23c83afcc1f305cbe84a1c774fcf3505" "sha256": "d554d2ea6c77f139d26001582b17e7ca5430ed151ab8e92f8f7354c8d59438d4"
}, },
"host-environment-markers": { "host-environment-markers": {
"implementation_name": "cpython", "implementation_name": "cpython",
@ -11,7 +11,7 @@
"platform_python_implementation": "CPython", "platform_python_implementation": "CPython",
"platform_release": "4.19.27-gentoo-r1", "platform_release": "4.19.27-gentoo-r1",
"platform_system": "Linux", "platform_system": "Linux",
"platform_version": "#1 SMP Wed May 1 11:50:20 CEST 2019", "platform_version": "#1 SMP Sat Jun 1 19:49:57 CEST 2019",
"python_full_version": "3.7.3", "python_full_version": "3.7.3",
"python_version": "3.7", "python_version": "3.7",
"sys_platform": "linux" "sys_platform": "linux"
@ -65,6 +65,10 @@
"markers": "python_version < '3.7'", "markers": "python_version < '3.7'",
"version": "==1.1.0" "version": "==1.1.0"
}, },
"lupa": {
"hashes": [],
"version": "==1.8"
},
"multidict": { "multidict": {
"hashes": [], "hashes": [],
"version": "==4.5.2" "version": "==4.5.2"

26
main.py
View File

@ -17,7 +17,7 @@ import discord
from packaging.version import Version from packaging.version import Version
from errors import IncompatibleModule from errors import IncompatibleModule
from modules.base import BaseClass from modules.base import BaseClassPython
__version__ = "0.1.0" __version__ = "0.1.0"
@ -408,40 +408,24 @@ class Communication(asyncio.Protocol):
def connection_lost(self, exc): def connection_lost(self, exc):
print('%s: connection lost: %s' % (self.name, exc)) print('%s: connection lost: %s' % (self.name, exc))
async def parse_set_param(self, data):
values = data[8:].split("$¤$")
for value in values:
value = value.replace(r"\$¤$", "$¤$")
await self.client.dispatch("setparam",
value.split("$=$")[0].replace(r"\$=$", "$=$"),
value.split("$=$")[1].replace(r"\$=$", "$=$"))
# os.path.join("tmp", os.path.dirname(os.path.realpath(__file__)) + ".sock")
communication = Communication(client1) communication = Communication(client1)
async def start_bot(): async def start_bot():
await client1.start('TOKEN', max_messages=500000) await client1.start(os.environ.get("DISCORD_TOKEN"), max_messages=500000)
def communication_execption_handler(loop, context): def execption_handler(loop, context):
print('%s: %s' % ('Connection', context['exception'])) print('%s: %s' % ('Connection', context['exception']))
traceback.print_exc() traceback.print_exc()
async def start_communication(): print(os.path.join("/tmp", os.path.dirname(os.path.realpath(__file__))) + ".sock")
pass
# loop.run_until_complete(f)
# print('Server running on %s forwarding to %s' % (proxy_in_addr, proxy_out_addr))
print(os.path.join("/tmp", os.path.dirname(os.path.realpath(__file__)) + ".sock"))
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, loop.stop) loop.add_signal_handler(signal.SIGINT, loop.stop)
loop.set_exception_handler(communication_execption_handler) loop.set_exception_handler(execption_handler)
t = loop.create_unix_server(Communication, t = loop.create_unix_server(Communication,
path=os.path.join("/tmp", os.path.dirname(os.path.realpath(__file__)) + ".sock")) path=os.path.join("/tmp", os.path.dirname(os.path.realpath(__file__)) + ".sock"))
loop.run_until_complete(t) loop.run_until_complete(t)

48
modules/base/BaseLua.py Normal file
View File

@ -0,0 +1,48 @@
"""Base class for module, never use directly !!!"""
import asyncio
import sys
import pickle
import traceback
import discord
import lupa
from storage import FSStorage
import storage.path as path
class BaseClassLua:
"""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))
if not self.storage.isdir(path.join("storage", self.name)):
self.storage.makedirs(path.join("storage", self.name), exist_ok=True)
# Get lua globals
self.lua = lupa.LuaRuntime(unpack_returned_tuples=True)
self.luaMethods = self.lua.eval("require \"main\"")
def dispatch(self, event, *args, **kwargs):
print(self.luaMethods)
print(self.luaMethods.__dict__)
print(dict(self.luaMethods))

209
modules/base/BasePython.py Normal file
View File

@ -0,0 +1,209 @@
"""Base class for module, never use directly !!!"""
import asyncio
import sys
import pickle
import traceback
import discord
from storage import FSStorage
import storage.path as path
class BaseClassPython:
"""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))
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.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()

View File

@ -1,209 +1,2 @@
"""Base class for module, never use directly !!!""" from .BasePython import BaseClassPython
import asyncio from .BaseLua import BaseClassLua
import sys
import pickle
import traceback
import discord
from storage import FSStorage
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))
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.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()

View File

@ -2,11 +2,11 @@ import os
import discord import discord
from modules.base import BaseClass from modules.base import BaseClassPython
from modules.modules.api import Api from modules.modules.api import Api
class MainClass(BaseClass): class MainClass(BaseClassPython):
name = "modules" name = "modules"
command_text = "modules" command_text = "modules"

View File

@ -0,0 +1,5 @@
from modules.base import BaseClassLua
class MainClass(BaseClassLua):
pass

View File

@ -0,0 +1,8 @@
main = {}
function main.on_message(discord, message)
print("I LOVE LUA")
print(message.content)
end
return main