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.
https://i.flashii.net/KwZkc67zEkFtYCnaysWhlcBzW_TmRTWh

It wasn't all bad because it lead to this beauty of a commit comment:
https://i.flashii.net/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://flash.moe/signature/signature.php?p=bodyhttps://flash.moe/signature/signature.php?p=album
#5098
i love you
https://wart.host/20190201_qaG.png