2019-03-02 14:46:48 +01:00
|
|
|
# dummy module
|
2019-02-26 16:31:43 +01:00
|
|
|
import discord
|
2019-03-04 01:25:09 +01:00
|
|
|
import random
|
2019-03-02 14:46:48 +01:00
|
|
|
|
2019-03-04 01:25:09 +01:00
|
|
|
import fractale.source.main
|
|
|
|
from PIL import Image
|
2019-02-26 16:31:43 +01:00
|
|
|
class MainClass():
|
|
|
|
def __init__(self, client, modules, owners, prefix):
|
|
|
|
self.client = client
|
|
|
|
self.modules = modules
|
|
|
|
self.owners = owners
|
|
|
|
self.prefix = prefix
|
2019-03-02 14:46:48 +01:00
|
|
|
self.events = ['on_message'] # events list
|
|
|
|
self.command = "%sfractale" % self.prefix # command prefix (can be empty to catch every single messages)
|
2019-02-26 16:31:43 +01:00
|
|
|
|
2019-03-02 14:46:48 +01:00
|
|
|
self.name = "Fractale"
|
|
|
|
self.description = "Module de génération de fractales"
|
|
|
|
self.interactive = True
|
|
|
|
self.color = 0x78ffc3
|
|
|
|
self.fractals = {
|
2019-03-04 01:25:09 +01:00
|
|
|
"von_koch_curve_flake": {"Type": "Figures", "Max": ((5000, 5000), 5000, 10, 16777215, 16777215, 5000), "Min": ((0, 0), 0, 1, 0, 0, 0),
|
|
|
|
"Default": "(2500 2500) 2000 5 #81ff65 #191919 2",
|
2019-03-04 01:48:52 +01:00
|
|
|
"Indication": "(départ) rayon longueur iterations couleur_trait couleur_fond stroke",
|
2019-03-04 01:25:09 +01:00
|
|
|
"ParseData": "pfixxi"},
|
|
|
|
"von_koch_curve": {"Type": "Figures", "Max": ((5000, 5000), (5000, 5000), 10, 16777215, 16777215, 5000), "Min": ((0, 0), (0, 0), 1, 0, 0, 0),
|
|
|
|
"Default": "(0 2500) (5000 2500) 5 #81ff65 #191919 2",
|
|
|
|
"Indication": "(départ) (arrivée) iterations couleur_trait couleur_fond stroke", "ParseData": "ppixxi"},
|
|
|
|
"blanc_manger": {"Type": "Figures", "Max": ((5000, 5000), (5000, 5000), 10, 16777215, 16777215, 5000), "Min": ((0, 0), (0, 0), 1, 0, 0, 0),
|
|
|
|
"Default": "(1000 1000) (4000 4000) 7 #81ff65 #191919 2",
|
|
|
|
"Indication": "(départ) (arrivée) iterations couleur_trait couleur_fond stroke", "ParseData": "ppixxi"},
|
|
|
|
"dragon": {"Type": "Lsystem", "Max": ((5000, 5000), 2500, 19, 16777215, 16777215, 5000), "Min": ((0, 0), 1, 1, 0, 0, 0),
|
|
|
|
"Default": "(2500 2500) 4 18 #81ff65 #191919 2", "Indication": "(origine) longueur iterations couleur_trait couleur_fond stroke",
|
|
|
|
"ParseData": "pfixxi"},
|
|
|
|
"sierpinski_triangle": {"Type": "Lsystem", "Max": ((5000, 5000), 2500, 11, 16777215, 16777215, 5000), "Min": ((0, 0), 0, 1, 0, 0, 0),
|
|
|
|
"Default": "(0 0) 10 9 #81ff65 #191919 2", "Indication": "(origine) longueur iterations couleur_trait couleur_fond stroke",
|
|
|
|
"ParseData": "pfixxi"},
|
|
|
|
"fractal_plant": {"Type": "Lsystem", "Max": ((5000, 5000), 2500, 8, 16777215, 16777215, 5000), "Min": ((0, 0), 0, 1, 0, 0, 0),
|
|
|
|
"Default": "(0 2500) 6.5 8 #81ff65 #191919 2", "Indication": "(origine) longueur iterations couleur_trait couleur_fond stroke",
|
|
|
|
"ParseData": "pfixxi"},
|
|
|
|
"koch_curve_right_angle": {"Type": "Lsystem", "Max": ((5000, 5000), 2500, 9, 16777215, 16777215, 5000), "Min": ((0, 0), 0, 1, 0, 0, 0),
|
|
|
|
"Default": "(0 5000) 2.25 7 #81ff65 #191919 2",
|
|
|
|
"Indication": "(origine) longueur iterations couleur_trait couleur_fond stroke",
|
|
|
|
"ParseData": "pfixxi"},
|
|
|
|
"fractal_binary_tree": {"Type": "Lsystem", "Max": ((5000, 5000), 2500, 15, 16777215, 16777215, 5000), "Min": ((0, 0), 0, 1, 0, 0, 0),
|
|
|
|
"Default": "(0 0) 1.2 12 #81ff65 #191919 2", "Indication": "(origine) longueur iterations couleur_trait couleur_fond stroke",
|
|
|
|
"ParseData": "pfixxi"}
|
2019-03-02 14:46:48 +01:00
|
|
|
}
|
|
|
|
self.help = """\
|
2019-03-02 14:45:04 +01:00
|
|
|
</prefix>fractale info <fractale>
|
|
|
|
=> Affiche les informations relatives à la fractale spécifiée. (paramètres attendus, paramètres par défaut, type des arguments)
|
2019-02-26 19:00:08 +01:00
|
|
|
|
2019-03-02 14:45:04 +01:00
|
|
|
</prefix>fractale <fractale> <arguments>
|
|
|
|
=> Génère une image fractale à partir des arguments fournis. Pour mettre la valeur par défaut pour un des arguments, le remplacer par le caractère *
|
|
|
|
|
|
|
|
</prefix>fractale <fractale>
|
|
|
|
=> Génère une image fractale avec les paramètres par défaut.
|
|
|
|
|
|
|
|
-> Valeurs possible pour <fractale>
|
2019-02-27 02:49:02 +01:00
|
|
|
```..: Toutes les fractales:
|
2019-03-02 14:46:48 +01:00
|
|
|
%s```""" % '\n'.join(['......: %s' % t for t in self.fractals.keys()])
|
2019-03-02 14:41:40 +01:00
|
|
|
|
2019-03-02 14:45:04 +01:00
|
|
|
async def on_message(self, message):
|
2019-03-04 08:56:55 +01:00
|
|
|
async with message.channel.typing():
|
|
|
|
args = message.content.split(" ")
|
|
|
|
if len(args) == 1:
|
|
|
|
await self.modules['help'][1].send_help(message.channel, self)
|
|
|
|
elif len(args) == 2:
|
|
|
|
if args[1] in self.fractals.keys():
|
|
|
|
await self.send_fractal(message, args[1]+' '+' '.join(['*']*len(self.fractals[args[1]]['ParseData'])))
|
|
|
|
else:
|
|
|
|
await self.modules['help'][1].send_help(message.channel, self)
|
|
|
|
elif len(args) == 3:
|
|
|
|
if args[1] == "info" and args[2] in self.fractals.keys():
|
|
|
|
description = """\
|
|
|
|
La fractale {nom} attend les arguments suivant :
|
|
|
|
`{arguments}`
|
|
|
|
avec le type suivant:
|
|
|
|
`{type}`
|
|
|
|
Les nombres décimaux sont des nombres à virgules là où les nombres entiers n'en ont pas. **(mettre un point à la place de la virgule)**
|
2019-03-02 14:45:04 +01:00
|
|
|
|
2019-03-04 08:56:55 +01:00
|
|
|
Attention, les coordonnées des points doivent être entre parentheses et sont considérées comme un unique argument.
|
|
|
|
Gardez aussi en tête que **l'image a pour résolution 5000*5000.**
|
2019-02-28 17:03:42 +01:00
|
|
|
|
2019-03-04 08:56:55 +01:00
|
|
|
Les arguments valent par défaut :
|
|
|
|
`{defaut}`""".format(nom=args[2], arguments=self.fractals[args[2]]['Indication'], type=' '.join(["point decimal entier hexadecimal".split(" ")["pfix".index(ch)] for ch in self.fractals[args[2]]['ParseData']]), defaut=self.fractals[args[2]]['Default'])
|
|
|
|
await message.channel.send(
|
|
|
|
embed=discord.Embed(title="[%s] - Infos : *%s*" % (self.name, args[2]), description=description, color=self.color))
|
|
|
|
else:
|
|
|
|
await self.modules['help'][1].send_help(message.channel, self)
|
|
|
|
elif args[1] in self.fractals.keys():
|
|
|
|
await self.send_fractal(message, ' '.join(args[1:]))
|
2019-03-02 14:45:04 +01:00
|
|
|
else:
|
|
|
|
await self.modules['help'][1].send_help(message.channel, self)
|
2019-03-02 14:46:48 +01:00
|
|
|
|
2019-03-02 14:45:04 +01:00
|
|
|
async def send_fractal(self, message, command):
|
2019-03-04 01:25:09 +01:00
|
|
|
parsed_data=self.parse(command)
|
|
|
|
if parsed_data["Success"]:
|
|
|
|
res=parsed_data["Result"]
|
|
|
|
tmpstr="/tmp/%s.png"%random.randint(1,10000000)
|
|
|
|
im=Image.new('RGB', (5000,5000), tuple([int(i, 16) for i in map(''.join, zip(*[iter(hex(res[-2])[2:].ljust(6,'0'))]*2))]))
|
|
|
|
fig = eval("fractale.source.main."+self.fractals[command.split(' ')[0]]["Type"]+"(im=im)")
|
|
|
|
if self.fractals[command.split(' ')[0]]["Type"]=="Lsystem":
|
|
|
|
fig.state.x,fig.state.y=res[0]
|
|
|
|
#fig.state.color,fig.state.width=tuple([int(i, 16) for i in map(''.join, zip(*[iter(hex(res[-3])[2:].ljust(6,'0'))]*2))]),res[-1]
|
|
|
|
eval("fig."+command.split(' ')[0])(*res[1:-3],color=tuple([int(i, 16) for i in map(''.join, zip(*[iter(hex(res[-3])[2:].ljust(6,'0'))]*2))]), width=res[-1])
|
|
|
|
else:
|
|
|
|
eval("fig."+command.split(' ')[0])(*res[:-3],color=tuple([int(i, 16) for i in map(''.join, zip(*[iter(hex(res[-3])[2:].ljust(6,'0'))]*2))]), width=res[-1])
|
|
|
|
im.save(tmpstr)
|
|
|
|
await message.channel.send(file=discord.File(tmpstr))
|
|
|
|
else:
|
|
|
|
await message.channel.send(parsed_data["Message"])
|
2019-03-02 14:46:48 +01:00
|
|
|
|
2019-02-28 17:03:42 +01:00
|
|
|
def parse(self, inp):
|
2019-03-02 14:46:48 +01:00
|
|
|
retDic = {"Success": False, "Message": "", "Result": ()}
|
|
|
|
# Parsing the fractal name and storing the corresponding dic into a variable
|
2019-02-28 17:03:42 +01:00
|
|
|
try:
|
2019-03-02 14:46:48 +01:00
|
|
|
fractal = self.fractals[inp.split(' ')[0]]
|
2019-02-28 17:03:42 +01:00
|
|
|
except KeyError:
|
2019-03-02 14:46:48 +01:00
|
|
|
retDic.update({"Success": False, "Message": "La fractale %s n'existe pas." % inp.split(' ')[0]})
|
|
|
|
return (retDic)
|
|
|
|
arg = ' '.join(inp.split(' ')[1:]) # Stuff after the fractal name
|
|
|
|
# checking for incoherent parentheses usage
|
|
|
|
parentheses_count = 0
|
|
|
|
for i, char in enumerate(arg):
|
|
|
|
if char == '(':
|
|
|
|
parentheses_count += 1
|
|
|
|
elif char == ')':
|
|
|
|
parentheses_count -= 1
|
|
|
|
if not (-1 < parentheses_count < 2):
|
|
|
|
retDic.update({"Success": False,
|
|
|
|
"Message": "Usage invalide de parentheses au charactère numéro %s (à partir d'après le nom de la fractale)." % i})
|
|
|
|
return (retDic)
|
2019-02-28 17:03:42 +01:00
|
|
|
|
2019-03-02 14:46:48 +01:00
|
|
|
# Here, we have a coherent parentheses usage
|
2019-02-28 17:03:42 +01:00
|
|
|
if ',' in arg:
|
2019-03-02 14:46:48 +01:00
|
|
|
retDic.update({"Success": False,
|
|
|
|
"Message": "Les virgules n'ont pas leur place dans les paramètres de génération. Il ne doit y avoir que des espaces uniques."})
|
|
|
|
return (retDic)
|
2019-02-28 17:03:42 +01:00
|
|
|
|
2019-03-02 14:46:48 +01:00
|
|
|
# parsing the fractal
|
|
|
|
args = arg.replace(')', '').replace('(', '').split(' ')
|
|
|
|
parsed_args = []
|
|
|
|
i = 0
|
|
|
|
for parse in fractal['ParseData']:
|
|
|
|
if parse == 'p':
|
|
|
|
if args[i] != '*':
|
2019-02-28 17:03:42 +01:00
|
|
|
try:
|
|
|
|
int(args[i])
|
2019-03-02 14:46:48 +01:00
|
|
|
int(args[i + 1])
|
2019-02-28 17:03:42 +01:00
|
|
|
except:
|
2019-03-02 14:46:48 +01:00
|
|
|
retDic.update({"Success": False,
|
|
|
|
"Message": "Les valeurs ne sont pas du bon type. (nombre entiers attendus pour les coordonnées d'un point)"})
|
|
|
|
return (retDic)
|
|
|
|
parsed_args.append((int(args[i]), int(args[i + 1])))
|
|
|
|
i += 2
|
2019-02-28 17:03:42 +01:00
|
|
|
else:
|
2019-03-02 14:46:48 +01:00
|
|
|
parsed_args.append(
|
|
|
|
self.parse(inp.split(' ')[0] + ' ' + fractal['Default'])['Result'][len(parsed_args)])
|
|
|
|
i += 1
|
2019-02-28 17:03:42 +01:00
|
|
|
|
2019-03-02 14:46:48 +01:00
|
|
|
elif parse == 'f':
|
|
|
|
if args[i] != '*':
|
2019-02-28 17:03:42 +01:00
|
|
|
try:
|
|
|
|
float(args[i])
|
|
|
|
except:
|
2019-03-02 14:46:48 +01:00
|
|
|
retDic.update({"Success": False,
|
|
|
|
"Message": "Les valeurs ne sont pas du bon type. (Nombre à virgule flottante attendu (mettre un point pour la virgule))"})
|
|
|
|
return (retDic)
|
2019-02-28 17:03:42 +01:00
|
|
|
parsed_args.append(float(args[i]))
|
2019-03-02 14:46:48 +01:00
|
|
|
i += 1
|
2019-02-28 17:03:42 +01:00
|
|
|
else:
|
2019-03-02 14:46:48 +01:00
|
|
|
parsed_args.append(
|
|
|
|
self.parse(inp.split(' ')[0] + ' ' + fractal['Default'])['Result'][len(parsed_args)])
|
|
|
|
i += 1
|
2019-02-28 17:03:42 +01:00
|
|
|
|
2019-03-02 14:46:48 +01:00
|
|
|
elif parse == 'i':
|
|
|
|
if args[i] != '*':
|
2019-02-28 17:03:42 +01:00
|
|
|
try:
|
|
|
|
int(args[i])
|
|
|
|
except:
|
|
|
|
print(args[i])
|
|
|
|
print(i)
|
2019-03-02 14:46:48 +01:00
|
|
|
retDic.update({"Success": False,
|
|
|
|
"Message": "Les valeurs ne sont pas du bon type. (Nombre entier attendu)"})
|
|
|
|
return (retDic)
|
2019-02-28 17:03:42 +01:00
|
|
|
parsed_args.append(int(args[i]))
|
2019-03-02 14:46:48 +01:00
|
|
|
i += 1
|
2019-02-28 17:03:42 +01:00
|
|
|
else:
|
2019-03-02 14:46:48 +01:00
|
|
|
parsed_args.append(
|
|
|
|
self.parse(inp.split(' ')[0] + ' ' + fractal['Default'])['Result'][len(parsed_args)])
|
|
|
|
i += 1
|
2019-02-28 17:03:42 +01:00
|
|
|
|
2019-03-02 14:46:48 +01:00
|
|
|
elif parse == 'x':
|
|
|
|
if args[i] != '*':
|
2019-02-28 17:03:42 +01:00
|
|
|
try:
|
|
|
|
if '#' in args[i]:
|
2019-03-02 14:46:48 +01:00
|
|
|
int(args[i].replace('#', '0x'), 16)
|
2019-02-28 17:03:42 +01:00
|
|
|
else:
|
|
|
|
raise
|
|
|
|
except:
|
2019-03-02 14:46:48 +01:00
|
|
|
retDic.update({"Success": False,
|
|
|
|
"Message": "Les valeurs ne sont pas du bon type. (Valeur hexadécimale attendue)"})
|
|
|
|
return (retDic)
|
|
|
|
parsed_args.append(int(args[i].replace('#', '0x'), 16))
|
|
|
|
i += 1
|
2019-02-28 17:03:42 +01:00
|
|
|
else:
|
2019-03-02 14:46:48 +01:00
|
|
|
parsed_args.append(
|
|
|
|
self.parse(inp.split(' ')[0] + ' ' + fractal['Default'])['Result'][len(parsed_args)])
|
|
|
|
i += 1
|
2019-03-04 01:25:09 +01:00
|
|
|
for i,element in enumerate(parsed_args):
|
|
|
|
print(element,fractal['Max'][i])
|
|
|
|
if element>fractal['Max'][i]:
|
|
|
|
retDic.update({"Success": False,
|
|
|
|
"Message": "Les valeurs sont trop grandes (%s > %s)"%(str(element),str(fractal['Max'][i]))})
|
|
|
|
return retDic
|
|
|
|
elif element<fractal['Min'][i]:
|
|
|
|
retDic.update({"Success": False,
|
|
|
|
"Message": "Les valeurs sont trop petites (%s < %s)"%(str(element),str(fractal['Min'][i]))})
|
|
|
|
return retDic
|
2019-03-02 14:46:48 +01:00
|
|
|
retDic.update({"Success": True, "Result": parsed_args})
|
|
|
|
return (retDic)
|