Petit commit ca faisait longtemps

This commit is contained in:
fomys 2019-06-01 19:24:45 +02:00
parent bd152db5c4
commit 2ef6501905
5 changed files with 91 additions and 56 deletions

116
main.py
View File

@ -6,6 +6,8 @@ import json
import logging import logging
import logging.config import logging.config
import os import os
import signal
import socket
import traceback import traceback
from concurrent.futures.process import ProcessPoolExecutor from concurrent.futures.process import ProcessPoolExecutor
from concurrent.futures.thread import ThreadPoolExecutor from concurrent.futures.thread import ThreadPoolExecutor
@ -191,6 +193,7 @@ log_discord = logging.getLogger('discord')
log_LBI = logging.getLogger('LBI') log_LBI = logging.getLogger('LBI')
log_communication = logging.getLogger('communication') log_communication = logging.getLogger('communication')
def load_modules_info(): def load_modules_info():
for mod in os.listdir("modules"): for mod in os.listdir("modules"):
Module(mod) Module(mod)
@ -224,24 +227,24 @@ class LBI(discord.Client):
with open(config_file, 'rt') as f: with open(config_file, 'rt') as f:
config = json.load(f) config = json.load(f)
self.config.update(config) self.config.update(config)
info("Config successfully loaded.") self.info("Config successfully loaded.")
else: else:
with open(config_file, 'w') as f: with open(config_file, 'w') as f:
json.dump(self.config, f) json.dump(self.config, f)
info("Config successfully created.") self.info("Config successfully created.")
def save_config(self, config_file="config/config.json"): def save_config(self, config_file="config/config.json"):
with open(config_file, "w") as f: with open(config_file, "w") as f:
json.dump(self.config, f) json.dump(self.config, f)
info("Config successfully saved.") self.info("Config successfully saved.")
@modules_edit @modules_edit
def load_modules(self): def load_modules(self):
info("Starts to load modules...") self.info("Starts to load modules...")
e = {} e = {}
for module in self.config["modules"]: for module in self.config["modules"]:
e.update({module: self.load_module(module)}) e.update({module: self.load_module(module)})
info("Finished to load all modules.") self.info("Finished to load all modules.")
return e return e
@modules_edit @modules_edit
@ -273,24 +276,24 @@ class LBI(discord.Client):
if dep not in self.modules.keys(): if dep not in self.modules.keys():
self.load_module(dep) self.load_module(dep)
try: try:
info("Start loading module {module}...".format(module=module)) self.info("Start loading module {module}...".format(module=module))
imported = importlib.import_module('modules.' + module) imported = importlib.import_module('modules.' + module)
importlib.reload(imported) importlib.reload(imported)
initialized_class = imported.MainClass(self) initialized_class = imported.MainClass(self)
self.modules.update({module: {"imported": imported, "initialized_class": initialized_class}}) self.modules.update({module: {"imported": imported, "initialized_class": initialized_class}})
info("Module {module} successfully imported.".format(module=module)) self.info("Module {module} successfully imported.".format(module=module))
initialized_class.on_load() initialized_class.on_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: except AttributeError as e:
error("Module {module} doesn't have MainClass.".format(module=module)) self.error("Module {module} doesn't have MainClass.".format(module=module))
return e return e
return 0 return 0
@modules_edit @modules_edit
def unload_module(self, module): def unload_module(self, module):
info("Start unload module {module}...".format(module=module)) self.info("Start unload module {module}...".format(module=module))
try: try:
if module in self.config["modules"]: if module in self.config["modules"]:
self.config["modules"].remove(module) self.config["modules"].remove(module)
@ -298,7 +301,7 @@ class LBI(discord.Client):
self.unload_all() self.unload_all()
self.load_modules() self.load_modules()
except KeyError as e: except KeyError as e:
error("Module {module} not loaded.").format(module=module) self.error("Module {module} not loaded.").format(module=module)
return e return e
@modules_edit @modules_edit
@ -312,10 +315,10 @@ class LBI(discord.Client):
self.modules = {} self.modules = {}
@event @event
async def dispatch(self, event, *args, **kwargs): def dispatch(self, event, *args, **kwargs):
super().dispatch(event, *args, **kwargs) super().dispatch(event, *args, **kwargs)
for module in self.modules.values(): for module in self.modules.values():
await module["initialized_class"].dispatch(event, *args, **kwargs) module["initialized_class"].dispatch(event, *args, **kwargs)
class ClientById: class ClientById:
@ -375,54 +378,75 @@ class ClientById:
return role return role
return None return None
class Communication:
client1 = LBI()
class Communication(asyncio.Protocol):
debug = log_communication.debug debug = log_communication.debug
info = log_communication.info info = log_communication.info
warning = log_communication.warning warning = log_communication.warning
error = log_communcation.error error = log_communication.error
critical = log_communication.critical critical = log_communication.critical
def __init__(self, client, sock_file=os.path.join("tmp", os.path.dirname(os.path.realpath(__file__))+".sock")): name = "Communication"
self.sock_file = sock_file
self.client = client
async def start(): def __init__(self, client=client1):
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) print("créé")
try: self.client = client
os.remove(self.sock_file) self.transport = None
except OSError:
pass def connection_made(self, transport):
s.bind(sock_file) print('%s: connection made' % self.name)
while True: self.transport = transport
data = conn.recv(1024)
content = data.decode("utf8") def data_received(self, data):
log("Received:"+content) print('%s: data received: %r' % (self.name, data))
if content.startwith("setparam"):
await parse_set_param(content) def eof_received(self):
pass
def connection_lost(self, exc):
print('%s: connection lost: %s' % (self.name, exc))
async def parse_set_param(self, data): async def parse_set_param(self, data):
content = content[8:] values = data[8:].split("$¤$")
values = content.split("$¤$")
for value in values: for value in values:
await client.dispatch("setparam", *values.split("$=$")) 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)
client = LBI()
communication = Communication()
async def start_bot(): async def start_bot():
await client.start('TOKEN', max_messages=500000) await client1.start('TOKEN', max_messages=500000)
def communication_execption_handler(loop, context):
print('%s: %s' % ('Connection', context['exception']))
traceback.print_exc()
async def start_communication(): async def start_communication():
await communication.start() pass
# loop.run_until_complete(f)
# print('Server running on %s forwarding to %s' % (proxy_in_addr, proxy_out_addr))
async def stop_bot(): print(os.path.join("/tmp", os.path.dirname(os.path.realpath(__file__)) + ".sock"))
await client.logout()
loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, loop.stop)
loop.set_exception_handler(communication_execption_handler)
t = loop.create_unix_server(Communication,
path=os.path.join("/tmp", os.path.dirname(os.path.realpath(__file__)) + ".sock"))
loop.run_until_complete(t)
loop.create_task(start_bot())
loop.run_forever()
async def main(): # loop = asyncio.get_event_loop()
loop = asyncio.get_running_loop() # loop.run_forever()
with concurrent.futures.ProcessPoolExecutor() as pool:
await loop.run_in_executor(pool, start_bot)
await loop.run_in_executor(pool, start_communication)
asyncio.run(main())

View File

@ -1,16 +1,13 @@
"""Base class for module, never use directly !!!""" """Base class for module, never use directly !!!"""
import asyncio import asyncio
import sys import sys
import os
import pickle import pickle
import traceback import traceback
import zipfile
import discord import discord
from storage import FSStorage from storage import FSStorage
from storage.path import join import storage.path as path
class BaseClass: class BaseClass:
@ -36,9 +33,9 @@ class BaseClass:
:param client: client instance :param client: client instance
:type client: NikolaTesla""" :type client: NikolaTesla"""
self.client = client self.client = client
if not os.path.isdir(os.path.join("storage", self.name)): self.storage = FSStorage(path.join(self.client.base_path, self.name))
os.makedirs(os.path.join("storage", self.name)) if not self.storage.isdir(path.join("storage", self.name)):
self.storage = FSStorage(join(self.client.base_path, self.name)) self.storage.makedirs(path.join("storage", self.name), exist_ok=True)
async def send_help(self, channel): async def send_help(self, channel):
embed = discord.Embed( embed = discord.Embed(

View File

@ -24,7 +24,7 @@ class MainClass(BaseClass):
def __init__(self, client): def __init__(self, client):
super().__init__(client) super().__init__(client)
self.storage.mkdir("modules") self.storage.mkdir("modules", exist_ok=True)
self.api = Api() self.api = Api()
def get_all_modules(self): def get_all_modules(self):

View File

@ -11,7 +11,7 @@ class FSStorage(Storage):
def __init__(self, base_path="storage"): def __init__(self, base_path="storage"):
super().__init__() super().__init__()
self.base_path = os.path.abspath(base_path) self.base_path = os.path.abspath(base_path)
os.makedirs(self.base_path) os.makedirs(self.base_path, exist_ok=True)
self.current_dir = "/" self.current_dir = "/"
def _topath(self, path): def _topath(self, path):
@ -41,7 +41,10 @@ class FSStorage(Storage):
def listdir(self, path="."): def listdir(self, path="."):
return os.listdir(self._topath(path)) return os.listdir(self._topath(path))
def mkdir(self, path): def mkdir(self, path, exist_ok=False):
if exist_ok:
if self.exists(path):
return self._topath(path)
os.mkdir(self._topath(path)) os.mkdir(self._topath(path))
return self._topath(path) return self._topath(path)
@ -67,3 +70,6 @@ class FSStorage(Storage):
def exists(self, path): def exists(self, path):
return os.path.exists(path) return os.path.exists(path)
def isdir(self, path):
return os.path.isdir(self._topath(path))

View File

@ -105,3 +105,11 @@ class Storage:
:return: True if file exists :return: True if file exists
""" """
pass pass
async def isdir(self, path):
"""
Return if path is a directory
:param path: Path to test
:return: True if path is a directory
"""
pass