how to show them who's boss
#5089
so i got a chatbot going with a word definition command and it's written in C#. .net does not have a native json parsing pile of trash so I used Wordnik's XML api. come a few weeks ago and the definition command stops working, i check why and it turns out they shut down their XML apis. best part about it is that i didn't get an email about it or anything and also the return data of the api telling you the endpoints were deprecated are json encoded.
//i.fii.moe/KwZkc67zEkFtYCnaysWhlcBzW_TmRTWh

It wasn't all bad because it lead to this beauty of a commit comment:
//i.fii.moe/j-5oLveyqzIMP9RhmXZ5RRIDyE-LIU67

Now here's the diff of the change, I just said fuck it and used Regex to swoop the data out of the json encoded string. It's horribly imperfect but works good enough for my needs.

diff --git a/Satori/Wordnik/DefineCommand.cs b/Satori/Wordnik/DefineCommand.cs
index 5ad03b1..3319911 100644
--- a/Satori/Wordnik/DefineCommand.cs
+++ b/Satori/Wordnik/DefineCommand.cs
@@ -25,6 +25,8 @@ public override void Dispatch(StringBuilder output, CommandArgs args)
 
             if (!int.TryParse(args.Arguments.Skip(2).Take(1)?.FirstOrDefault() ?? string.Empty, out int page))
                 page = 1;
+            else
+                word = word.Substring(0, word.LastIndexOf(' '));
 
             if (string.IsNullOrEmpty(word))
                 return;
diff --git a/Satori/Wordnik/WordDefinition.cs b/Satori/Wordnik/WordDefinition.cs
index 71b3a39..486bddd 100644
--- a/Satori/Wordnik/WordDefinition.cs
+++ b/Satori/Wordnik/WordDefinition.cs
@@ -1,17 +1,11 @@
-using System.Xml.Serialization;
-
-namespace Satori.Wordnik
+namespace Satori.Wordnik
 {
-    [XmlType(@"definition")]
     public sealed class WordDefinition
     {
-        [XmlElement(@"text")]
         public string Text { get; set; }
 
-        [XmlElement(@"word")]
         public string Word { get; set; }
 
-        [XmlElement(@"partOfSpeech")]
         public string PartOfSpeech { get; set; }
     }
 }
diff --git a/Satori/Wordnik/WordnikApi.cs b/Satori/Wordnik/WordnikApi.cs
index d12182d..c9bc786 100644
--- a/Satori/Wordnik/WordnikApi.cs
+++ b/Satori/Wordnik/WordnikApi.cs
@@ -1,16 +1,15 @@
 using System;
 using System.Collections.Generic;
-using System.IO;
 using System.Linq;
 using System.Net.Http;
-using System.Xml.Serialization;
+using System.Text.RegularExpressions;
 
 namespace Satori.Wordnik
 {
     public sealed class WordnikApi : IDisposable
     {
         private const string BASE_URL = @"https://api.wordnik.com/v4/";
-        private const string WORD_API = BASE_URL + @"word.xml/";
+        private const string WORD_API = BASE_URL + @"word.json/";
 
         private readonly IBindable<string> ApiKey;
         private readonly HttpClient HttpClient;
@@ -19,6 +18,8 @@ public sealed class WordnikApi : IDisposable
 
         private Dictionary<string, IEnumerable<WordDefinition>> Definitions = new Dictionary<string, IEnumerable<WordDefinition>>();
 
+        public readonly Regex DataGrab = new Regex("\"(partOfSpeech|word|text)\":\"(.*?)\"");
+
         public WordnikApi(HttpClient client, IBindable<string> apiKey)
         {
             HttpClient = client;
@@ -27,26 +28,78 @@ public WordnikApi(HttpClient client, IBindable<string> apiKey)
 
         public IEnumerable<WordDefinition> DefineWord(string word)
         {
-            word = word.Replace(@" ", @"%20");
-            word = string.Join(string.Empty, word.Where(c => char.IsLetterOrDigit(c) || c == '+')).ToLowerInvariant();
-
-            if (Definitions.ContainsKey(word))
-                return Definitions[word];
-
-            string url = WORD_API + word + @"/definitions?limit=200&includeRelated=false&sourceDictionaries=all&useCanonical=true&includeTags=false&api_key=" + ApiKey.Value;
-
-            XmlSerializer xml = new XmlSerializer(typeof(List<WordDefinition>), new XmlRootAttribute(@"definitions"));
-            List<WordDefinition> defs;
-
-            using (HttpResponseMessage r = HttpClient.GetAsync(url).Result)
-            using (HttpContent c = r.Content)
-            using (Stream s = c.ReadAsStreamAsync().Result)
-                defs = xml.Deserialize(s) as List<WordDefinition>;
+            try
+            {
+                word = word.Replace(@" ", @"%20");
+                word = string.Join(string.Empty, word.Where(c => char.IsLetterOrDigit(c) || c == '+')).ToLowerInvariant();
+
+                if (Definitions.ContainsKey(word))
+                    return Definitions[word];
+
+                string url = WORD_API + word + @"/definitions?limit=200&includeRelated=false&sourceDictionaries=all&useCanonical=true&includeTags=false&api_key=" + ApiKey.Value;
+
+                string output;
+
+                using (HttpResponseMessage r = HttpClient.GetAsync(url).Result)
+                using (HttpContent c = r.Content)
+                    output = c.ReadAsStringAsync().Result;
+
+                List<WordDefinition> defs = new List<WordDefinition>();
+                MatchCollection matches = DataGrab.Matches(output);
+                WordDefinition current = new WordDefinition();
+
+                foreach (Match match in matches)
+                {
+                    string key = match.Groups[1].Value;
+                    string value = match.Groups[2].Value;
+
+                    switch (key)
+                    {
+                        case @"partOfSpeech":
+                            if (!string.IsNullOrEmpty(current.PartOfSpeech))
+                            {
+                                defs.Add(current);
+                                current = new WordDefinition();
+                            }
+
+                            current.PartOfSpeech = value;
+                            break;
+
+                        case @"word":
+                            if (!string.IsNullOrEmpty(current.Word))
+                            {
+                                defs.Add(current);
+                                current = new WordDefinition();
+                            }
+
+                            current.Word = value;
+                            break;
+
+                        case @"text":
+                            if (!string.IsNullOrEmpty(current.Text))
+                            {
+                                defs.Add(current);
+                                current = new WordDefinition();
+                            }
+
+                            current.Text = value;
+                            break;
+                    }
+                }
+
+                if (!defs.Contains(current) && !string.IsNullOrEmpty(current.PartOfSpeech)
+                    && !string.IsNullOrEmpty(current.Word) && !string.IsNullOrEmpty(current.Text))
+                    defs.Add(current);
 
-            if (defs != null)
                 Definitions.Add(word, defs);
 
-            return defs;
+                return defs;
+            }
+            catch
+            {
+                Definitions.Remove(word);
+                return Enumerable.Empty<WordDefinition>();
+            }
         }
 
         ~WordnikApi()


this post has no real point or purpose, i just wanted to share the commit comment and my beautiful solution
https://sig.flash.moe/signature.png
#5098
i love you
https://wart.host/20240430_GvH.gif