-
Notifications
You must be signed in to change notification settings - Fork 2
/
wsession.py
191 lines (155 loc) · 7.88 KB
/
wsession.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/usr/bin/python3
import discord
import os
from discord.ext import commands, tasks
from collections import defaultdict
from discord.utils import get
from wolframclient.evaluation import WolframLanguageSession, WolframLanguageAsyncSession
from wolframclient.language import wl, wlexpr
from wolframclient.evaluation import SecuredAuthenticationKey, WolframCloudSession
from wolframclient.exception import WolframEvaluationException, WolframLanguageException, WolframKernelException
from PIL import Image
import PIL
import PIL.ImageOps
import asyncio
#Define paths
img_path = 'D:/dev/discordbots/WolfBot/output/output.jpg'
#img_path = '/home/pi/WolfBot/output/output.jpg'
kernel_path = 'D:/Program Files/Wolfram Research/Wolfram Engine/12.0/WolframKernel.exe'
#kernel_path = '/opt/Wolfram/WolframEngine/12.0/Executables/WolframKernel'
# Authentication Key
sak = SecuredAuthenticationKey(
't9JwbVPeUiX0G38n8/GtrLcz0S1vXrTiNfvHbNFl5U0=',
'dbbLmj8rDSrTEe0A+baPcMIFgFhmVPfFMdLg4trDuFc=')
#
# Enlarges image output from Wolfram calculation, and then saves as png #
async def enlarge(ctx):
img = Image.open(img_path, 'r')
img_w, img_h = img.size
background = Image.new('RGB', (img_w + 25, img_h + 25), (255, 255, 255, 255))
bg_w, bg_h = background.size
background.paste(img,(13,12))
final = PIL.ImageOps.invert(background)
final.save(img_path)
# Creates a discord.Embed object #
def createEmbed(t):
# Embed message
embed = discord.Embed(
title = t)
return embed
client = commands.Bot(command_prefix = '$')
@client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
@client.command()
@commands.has_any_role('Admin', 'Bot Henchmen', 'Development Team')
async def session(ctx):
async with ctx.typing():
channel = ctx.message.channel
def check(m):
return m.channel == channel and ((m.content).startswith('wl ') or (m.content).startswith('```wl ')) and m.author == ctx.message.author
async with WolframLanguageAsyncSession(kernel_path) as session:
async with ctx.typing():
# Start Asynchronous Wolfram Kernel thread #
await session.start()
# Tell user that the session has successfully started
start_alert = discord.Embed(
title = f'**Wolfram Session Started!**',
color = discord.Color.blue(),
description = f'Initiated by\n{ctx.message.author.mention}')
await ctx.send(embed = start_alert)
# Prepares the user input to be passed into Wolfram functions that export the output image, and limit the time of the computation
begin = f'Export["{img_path}", TimeConstrained['
end = ', 60, "Your computation has exceeded one minute."]]'
# Wait for discord user to enter input, and save message to msg.
msg = await client.wait_for('message', check = check)
# save string from message object to a string variable
wolfcommand = msg.content
if wolfcommand.startswith('wl '):
wolfcommand = wolfcommand.replace('wl ', '')
elif wolfcommand.startswith('```wl '):
wolfcommand = wolfcommand.replace('```', '')
wolfcommand = wolfcommand.replace('wl ', '')
#wolfcommand = wolfcommand.replace('wl ', '')
# concatenate the full command for passing to Wolfram
export = begin + wolfcommand + end
# Loop session, sending output from initial input, taking in new input, repeat.
while msg.content != 'wl exit' and msg.content != '```wl exit' :
if msg.content != 'wl exit' and msg.content != '```wl exit':
try:
async with ctx.typing():
await session.evaluate(wlexpr(export))
# if not enlarge():
# await ctx.send('Not enough memory to perform this operation!')
try:
await asyncio.wait_for(enlarge(), 5) # Time out image processing at 10 seconds
except Exception:
log = createEmbed('Timeout Error: Computation took too long!')
await ctx.send(embed = log)
# Send image from Wolfram calculation results
await ctx.send(file=discord.File(img_path))
# Wait for new input from user
msg = await client.wait_for('message', check = check)
wolfcommand = msg.content
if wolfcommand.startswith('wl '):
wolfcommand = wolfcommand.replace('wl ', '')
elif wolfcommand.startswith('```wl '):
wolfcommand = wolfcommand.replace('```', '')
wolfcommand = wolfcommand.replace('wl ', '')
export = begin + wolfcommand + end
except WolframLanguageException as err:
error = err
await ctx.send(error)
# Loop seninent value detected, closes connection to wolfram kernel
await session.stop()
# Send Embed message for end of session #
end_message = discord.Embed(
title = f'**Wolfram session terminated!**',
color = discord.Color.blue(),
description = f'Session started by\n{ctx.message.author.mention}')
await ctx.send(embed = end_message)
@client.command()
@commands.has_any_role('Admin', 'Bot Henchmen', 'Development Team')
async def bark(ctx,*, script):
# Prepares the user input to be passed into Wolfram functions that export the output image, and limit the time of the computation
async with ctx.typing():
begin = f'Export["{img_path}", TimeConstrained[Style['
end = ', Large], 60, "Your computation has exceeded one minute."]]'
export = begin + script + end
async with WolframLanguageAsyncSession(kernel_path) as session:
#await session.start()
try:
eval = await session.evaluate_wrap(wlexpr(export))
# Check for errors before sending result
log = str(eval.messages)
if len(log) > 256:
#log = log[0 : 255 : 1] # Shorten length of string to 255 characters to satify discord embed char limit
log = 'Errors were detected during computation'
if log != 'None':
if (log).startswith('(\'Invalid syntax'):
log = createEmbed('Invalid syntax!')
await ctx.send(embed = log)
else:
log = createEmbed(log)
enlarge()
await ctx.send(file=discord.File(img_path))
await ctx.send(embed = log)
else:
# No errors, continue
if not enlarge():
await ctx.send('Not enough memory to perform this operation!')
# Send image from Wolfram calculation results
await ctx.send(file=discord.File(img_path))
except TimeoutError:
log = createEmbed('Timeout Error: Computation took too long!')
await ctx.send(embed = log)
# Send Goodbye Embed message
end_message = discord.Embed(
title = f'**Learn more the about Wolfram Language**',
color = discord.Color.blue(),
description = f'Requested by\n{ctx.message.author.mention}',
url = 'https://reference.wolfram.com/language/')
end_message.set_thumbnail(url = 'https://media1.tenor.com/images/ed4da9a1bdbd4ff952638b19afa96506/tenor.gif?itemid=12660466')
await ctx.send(embed = end_message)
#await session.stop()
client.run('NjUzODA3MTM3NjkyMTg4Njcy.Xe8Xlg.-EDzSXrTejAAuJ2sCI-0mfwUxjY')