1919import org .togetherjava .tjbot .config .Config ;
2020
2121import javax .imageio .ImageIO ;
22- import java .awt .*;
22+ import java .awt .Color ;
23+ import java .awt .Font ;
24+ import java .awt .Graphics ;
25+ import java .awt .font .TextAttribute ;
2326import java .awt .image .BufferedImage ;
24- import java .io .ByteArrayInputStream ;
2527import java .io .ByteArrayOutputStream ;
26- import java .io .File ;
2728import java .io .IOException ;
2829import java .net .URL ;
2930import java .net .http .HttpClient ;
3031import java .net .http .HttpRequest ;
3132import java .net .http .HttpResponse ;
3233import java .util .ArrayList ;
3334import java .util .List ;
35+ import java .util .Map ;
3436import java .util .Objects ;
3537import java .util .Optional ;
3638
@@ -43,13 +45,21 @@ public final class WolframAlphaCommand extends SlashCommandAdapter {
4345 * WolframAlpha API endpoint to connect to.
4446 *
4547 * @see <a href=
46- * "https://products.wolframalpha.com/docs/WolframAlpha-API-Reference.pdf">WolframAlpha API
47- * Reference</a>.
48+ * "https://products.wolframalpha.com/docs/WolframAlpha-API-Reference.pdf">WolframAlpha API
49+ * Reference</a>.
4850 */
4951 private static final String API_ENDPOINT = "http://api.wolframalpha.com/v2/query" ;
5052 private static final int MAX_IMAGE_HEIGHT_PX = 300 ;
51- private final HttpClient client = HttpClient .newHttpClient ();
53+ /**
54+ * WolframAlpha text Color
55+ */
5256 private static final Color WOLFRAM_ALPHA_TEXT_COLOR = Color .decode ("#3C3C3C" );
57+ /**
58+ * WolframAlpha Font
59+ */
60+ private static final Font WOLFRAM_ALPHA_FONT = new Font ("Times" , Font .PLAIN , 15 ).deriveFont (
61+ Map .of (TextAttribute .UNDERLINE , TextAttribute .UNDERLINE_ON ));
62+ private final HttpClient client = HttpClient .newHttpClient ();
5363
5464 public WolframAlphaCommand () {
5565 super ("wolf" , "Renders mathematical queries using WolframAlpha" ,
@@ -58,8 +68,7 @@ public WolframAlphaCommand() {
5868 true );
5969 }
6070
61- @ Override
62- public void onSlashCommand (@ NotNull SlashCommandEvent event ) {
71+ @ Override public void onSlashCommand (@ NotNull SlashCommandEvent event ) {
6372
6473 // The processing takes some time
6574 event .deferReply ().queue ();
@@ -84,26 +93,26 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
8493 response = client .send (request , HttpResponse .BodyHandlers .ofString ());
8594 } catch (IOException e ) {
8695 event .getHook ()
87- .setEphemeral (true )
88- .editOriginal ("Unable to get a response from WolframAlpha API" )
89- .queue ();
96+ .setEphemeral (true )
97+ .editOriginal ("Unable to get a response from WolframAlpha API" )
98+ .queue ();
9099 logger .warn ("Could not get the response from the server" , e );
91100 return Optional .empty ();
92101 } catch (InterruptedException e ) {
93102 event .getHook ()
94- .setEphemeral (true )
95- .editOriginal ("Connection to WolframAlpha was interrupted" )
96- .queue ();
103+ .setEphemeral (true )
104+ .editOriginal ("Connection to WolframAlpha was interrupted" )
105+ .queue ();
97106 logger .info ("Connection to WolframAlpha was interrupted" , e );
98107 Thread .currentThread ().interrupt ();
99108 return Optional .empty ();
100109 }
101110
102111 if (response .statusCode () != HTTP_STATUS_CODE_OK ) {
103112 event .getHook ()
104- .setEphemeral (true )
105- .editOriginal ("The response' status code was incorrect" )
106- .queue ();
113+ .setEphemeral (true )
114+ .editOriginal ("The response' status code was incorrect" )
115+ .queue ();
107116 logger .warn ("Unexpected status code: Expected: {} Actual: {}" , HTTP_STATUS_CODE_OK ,
108117 response .statusCode ());
109118 return Optional .empty ();
@@ -112,14 +121,11 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
112121 }
113122
114123 private @ NotNull HttpRequest sendQuery (@ NotNull String query ) {
115- return HttpRequest
116- .newBuilder (UrlBuilder .fromString (API_ENDPOINT )
124+ return HttpRequest .newBuilder (UrlBuilder .fromString (API_ENDPOINT )
117125 .addParameter ("appid" , Config .getInstance ().getWolframAlphaAppId ())
118126 .addParameter ("format" , "image,plaintext" )
119127 .addParameter ("input" , query )
120- .toUri ())
121- .GET ()
122- .build ();
128+ .toUri ()).GET ().build ();
123129
124130 }
125131
@@ -130,19 +136,19 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
130136 result = XML .readValue (response .body (), QueryResult .class );
131137 } catch (JsonProcessingException e ) {
132138 event .getHook ()
133- .setEphemeral (true )
134- .editOriginal ("Unexpected response from WolframAlpha API" )
135- .queue ();
139+ .setEphemeral (true )
140+ .editOriginal ("Unexpected response from WolframAlpha API" )
141+ .queue ();
136142 logger .error ("Unable to deserialize the class " , e );
137143 return Optional .empty ();
138144 }
139145
140146 if (!result .isSuccess ()) {
141147 event .getHook ()
142- .setEphemeral (true )
143- .editOriginal ("Could not successfully receive the result %s"
144- . formatted ( result .getTips ().toMessage ()))
145- .queue ();
148+ .setEphemeral (true )
149+ .editOriginal ("Could not successfully receive the result %s" . formatted (
150+ result .getTips ().toMessage ()))
151+ .queue ();
146152
147153 // TODO The exact error details have a different POJO structure,
148154 // POJOs have to be added to get those details. See the Wolfram doc.
@@ -158,30 +164,34 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
158164 // For each probably much more readable.
159165 try {
160166 result .getPods ()
161- .forEach (pod -> pod .getSubPods ().stream ().map (SubPod ::getImage ).forEach (image -> {
162- try {
163- String name = image .getTitle ();
164- String source = image .getSource ();
165- String extension = ".png" ;
166- if (name .isEmpty ())
167- name = pod .getTitle ();
168- name += extension ;
169- BufferedImage img = ImageIO .read (new URL (source ));
170- ByteArrayOutputStream stream = new ByteArrayOutputStream ();
171- ImageIO .write (img , "png" , stream );
172- messages .add (channel .sendFile (stream .toByteArray (), name ));
173- } catch (IOException e ) {
174- event .getHook ()
175- .setEphemeral (true )
176- .editOriginal (
177- "Unable to generate message based on the WolframAlpha response" )
167+ .forEach (pod -> pod .getSubPods ()
168+ .stream ()
169+ .map (SubPod ::getImage )
170+ .forEach (image -> {
171+ try {
172+ String name = image .getTitle ();
173+ String source = image .getSource ();
174+ String extension = ".png" ;
175+ if (name .isEmpty ())
176+ name = pod .getTitle ();
177+ name += extension ;
178+ BufferedImage img = ImageIO .read (new URL (source ));
179+ ByteArrayOutputStream stream = new ByteArrayOutputStream ();
180+ ImageIO .write (img , "png" , stream );
181+ messages .add (channel .sendFile (stream .toByteArray (), name ));
182+ } catch (IOException e ) {
183+ event .getHook ()
184+ .setEphemeral (true )
185+ .editOriginal (
186+ "Unable to generate message based on the WolframAlpha response" )
178187
179- .queue ();
180- logger .error ("Failed to read image {} from the WolframAlpha response" ,
181- image , e );
182- throw new Error ();
183- }
184- }));
188+ .queue ();
189+ logger .error (
190+ "Failed to read image {} from the WolframAlpha response" ,
191+ image , e );
192+ throw new Error ();
193+ }
194+ }));
185195 } catch (Error e ) {
186196 return Optional .empty ();
187197 }
@@ -197,16 +207,17 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
197207 int resultHeight = 0 ;
198208 int maxWidth = Integer .MIN_VALUE ;
199209 List <BufferedImage > images = new ArrayList <>();
210+ List <byte []> bytes = new ArrayList <>();
211+ List <String > names = new ArrayList <>();
200212 List <Pod > pods = new ArrayList <>(result .getPods ());
201- // Collections.reverse(pods);
202213 logger .info ("There are {} pods" , pods .size ());
203- OUTER : for (int i = 0 ; i < pods .size ();) {
214+ OUTER :
215+ for (int i = 0 ; i < pods .size (); ) {
204216 Pod pod = pods .get (i );
205217 List <SubPod > subPods = new ArrayList <>(pod .getSubPods ());
206- // Collections.reverse(subPods);
207218 logger .info ("pod number {}" , ++i );
208219 logger .info ("There are {} sub pods within this pod" , subPods .size ());
209- for (int j = 0 ; j < subPods .size ();) {
220+ for (int j = 0 ; j < subPods .size (); ) {
210221
211222 SubPod subPod = subPods .get (j );
212223 logger .info ("sub pod number {}" , ++j );
@@ -216,11 +227,12 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
216227 String source = image .getSource ();
217228 String extension = ".png" ;
218229 String header = pod .getTitle ();
219- BufferedImage readImage = new BufferedImage (image .getWidth (),
220- image .getHeight () + 20 , BufferedImage .TYPE_4BYTE_ABGR );
230+ BufferedImage readImage =
231+ new BufferedImage (image .getWidth (), image .getHeight () + 20 ,
232+ BufferedImage .TYPE_4BYTE_ABGR );
221233 Graphics graphics = readImage .getGraphics ();
234+ graphics .setFont (WOLFRAM_ALPHA_FONT );
222235 graphics .setColor (Color .WHITE );
223- graphics .fillRect (0 , 0 , header .length () * 10 , 20 );
224236 graphics .setColor (WOLFRAM_ALPHA_TEXT_COLOR );
225237 graphics .drawString (header , 10 , 10 );
226238 graphics .drawImage (ImageIO .read (new URL (source )), 0 , 20 , null );
@@ -240,32 +252,19 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
240252 byte [] arr = WolfCommandUtils .imageToBytes (
241253 WolfCommandUtils .combineImages (images , maxWidth , resultHeight ));
242254 images .clear ();
243- action = action .addFile (arr , name );
255+ bytes .add (arr );
256+ names .add (name );
244257 filesAttached ++;
245- logger .info ("Image added" );
246- if (ImageIO
247- .write (ImageIO .read (new ByteArrayInputStream (arr )), "png" , new File (
248- "C:\\ Users\\ Abc\\ IdeaProjects\\ TJ-Bot-baseRepo\\ application\\ src\\ main\\ java\\ org\\ togetherjava\\ tjbot\\ commands\\ mathcommands\\ wolframalpha\\ img%d.png"
249- .formatted (filesAttached ))))
250- logger .info ("Wrote image to local file" );
251- else
252- logger .info ("Could not write the image to local file" );
253258 resultHeight = 0 ;
254259 maxWidth = Integer .MIN_VALUE ;
255- } else if (pod == pods .get (pods .size () - 1 )
256- && subPod == subPods . get ( subPods .size () - 1 )) {
260+ } else if (pod == pods .get (pods .size () - 1 ) && subPod == subPods . get (
261+ subPods .size () - 1 )) {
257262 logger .info ("The last image" );
258263 byte [] arr = WolfCommandUtils .imageToBytes (
259264 WolfCommandUtils .combineImages (images , maxWidth , resultHeight ));
260265 filesAttached ++;
261- if (ImageIO
262- .write (ImageIO .read (new ByteArrayInputStream (arr )), "png" , new File (
263- "C:\\ Users\\ Abc\\ IdeaProjects\\ TJ-Bot-baseRepo\\ application\\ src\\ main\\ java\\ org\\ togetherjava\\ tjbot\\ commands\\ mathcommands\\ wolframalpha\\ img%d.png"
264- .formatted (filesAttached ))))
265- logger .info ("Wrote image to local file" );
266- else
267- logger .info ("Could not write the image to local file" );
268- action = action .addFile (arr , name );
266+ bytes .add (arr );
267+ names .add (name );
269268 }
270269 resultHeight += image .getHeight ();
271270 images .add (readImage );
@@ -275,15 +274,18 @@ public void onSlashCommand(@NotNull SlashCommandEvent event) {
275274 filesAttached );
276275 } catch (IOException e ) {
277276 event .reply ("Unable to generate message based on the WolframAlpha response" )
278- .setEphemeral (true )
279- .queue ();
277+ .setEphemeral (true )
278+ .queue ();
280279 logger .error ("Failed to read image {} from the WolframAlpha response" , image ,
281280 e );
282281 return Optional .empty ();
283282 }
284283 }
285284 logger .info ("Exiting pod number {}" , i );
286285 }
286+ for (int i = bytes .size () - 1 ; i >= 0 ; i --) {
287+ action = action .addFile (bytes .get (i ), names .get (i ));
288+ }
287289 return Optional .of (action );
288290 }
289291}
0 commit comments