diff --git a/RAE.Demo/Program.cs b/RAE.Demo/Program.cs index e8096d1..a39bee1 100644 --- a/RAE.Demo/Program.cs +++ b/RAE.Demo/Program.cs @@ -13,7 +13,11 @@ class Program GetKeysAsync, SearchWordAsync, WordOfTheDayAsync, - FetchRandomWorldAsync + FetchRandomWorldAsync, + GetRandomWorldAsync, + GetWordsStartWithAsync, + GetWordsContainAsync, + GetAllWordsAsync }; static async Task Main() @@ -34,7 +38,7 @@ static async Task Main() static async Task GetKeysAsync() { - var query = "hola"; + var query = "w"; var keys = await drae.GetKeysAsync(query); Console.WriteLine($"GetKeys ({query}): {string.Join(", ", keys)}"); @@ -70,5 +74,28 @@ static async Task FetchRandomWorldAsync() Console.WriteLine($"Definitions of {word.Content}:"); Array.ForEach(definitions, Console.WriteLine); } + + static async Task GetWordsStartWithAsync() + { + string character = "A"; + string[] words = await drae.GetWordsStartWithAsync(character); + + Console.WriteLine($"There are {words.Length} words in the dictionary that start with '{character}'"); + } + + static async Task GetWordsContainAsync() + { + string character = "A"; + string[] words = await drae.GetWordsContainAsync(character); + + Console.WriteLine($"There are {words.Length} words in the dictionary that contain '{character}'"); + } + + static async Task GetAllWordsAsync() + { + string[] allWords = await drae.GetAllWordsAsync(); + + Console.WriteLine($"There are {allWords.Length} words in the dictionary"); + } } } diff --git a/RAE/DRAE.cs b/RAE/DRAE.cs index c081c77..6900631 100644 --- a/RAE/DRAE.cs +++ b/RAE/DRAE.cs @@ -1,30 +1,17 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.Linq; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text.RegularExpressions; +using System.Collections.Generic; using System.Threading.Tasks; namespace RAE { - /* - Based on information obtained from: - Basado en la información obtenida de: - https://devhub.io/repos/mgp25-RAE-API - */ public class DRAE { - private const string URLBASE = "https://dle.rae.es/data"; - private const string TOKEN = "cDY4MkpnaFMzOmFHZlVkQ2lFNDM0"; - - private HttpClient _httpClient; + private RAEAPI _raeAPI; + private ListaPalabrasAPI _listaPalabrasAPI; public DRAE() { - _httpClient = new HttpClient(); - _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", TOKEN); + _raeAPI = new RAEAPI(); + _listaPalabrasAPI = new ListaPalabrasAPI(); } /// @@ -35,17 +22,18 @@ public DRAE() /// The id of the word to search. /// El id de la palabra a buscar. /// - public async Task FetchWordByIdAsync(string wordId) + public Task FetchWordByIdAsync(string wordId) { - var response = await _httpClient.GetStringAsync($"{URLBASE}/fetch?id={wordId}"); - - MatchCollection matches = Regex.Matches(response, "

.*?

"); - - string[] definitions = matches.Cast() - .Select(m => Regex.Replace(m.Value, "<.*?>", "")) - .ToArray(); + return _raeAPI.FetchWordByIdAsync(wordId); + } - return definitions; + /// + /// Get all the words that exist. + /// Obtiene todas las palabras que existen. + /// + public Task GetAllWordsAsync() + { + return _listaPalabrasAPI.GetAllWordsAsync(); } /// @@ -56,49 +44,53 @@ public async Task FetchWordByIdAsync(string wordId) /// The base word. /// La palabra base. /// - public async Task> GetKeysAsync(string query) + public Task GetKeysAsync(string query) { - string response = await _httpClient.GetStringAsync($"{URLBASE}/keys?q={query}&callback="); - string json = Regex.Match(response, @"\[.*?\]").Value; - - var keys = JsonConvert.DeserializeObject>(json); - - return keys; + return _raeAPI.GetKeysAsync(query); } /// /// Get a random word. /// Obtiene una palabra aleatoria. /// - public async Task GetRandomWordAsync() + public Task GetRandomWordAsync() { - string response = await _httpClient.GetStringAsync($"{URLBASE}/random"); - - string idFormat = "article id=\""; - Match idMatch = Regex.Match(response, $@"{idFormat}\w+"); - string id = Regex.Replace(idMatch.Value, idFormat, ""); - - string contentFormat = "class=\"f\".*?>"; - Match contentMatch = Regex.Match(response, $@"{contentFormat}\w[\,\s\w]*"); - string content = Regex.Replace(contentMatch.Value, contentFormat, ""); - - return new Word(id, content); + return _raeAPI.GetRandomWordAsync(); } /// /// Get the word of the day. /// Obtiene la palabra del día. /// - public async Task GetWordOfTheDayAsync() + public Task GetWordOfTheDayAsync() { - string response = await _httpClient.GetStringAsync($"{URLBASE}/wotd?callback="); - string json = response.Substring(1, response.Length - 2); - JObject jobject = JObject.Parse(json); + return _raeAPI.GetWordOfTheDayAsync(); + } - string id = jobject.Value("id"); - string content = jobject.Value("header"); + /// + /// Gets the words that start with a sequence of letters. + /// Obtiene las palabras que empiezan con una secuencia de letras. + /// + /// + /// Sequence of letters to search. + /// Secuencia de letras a buscar. + /// + public Task GetWordsStartWithAsync(string query) + { + return _listaPalabrasAPI.GetWordsStartWithAsync(query); + } - return new Word(id, content); + /// + /// Gets the words that contain a sequence of letters. + /// Obtiene las palabras que contienen una secuencia de letras. + /// + /// + /// Sequence of letters to search. + /// Secuencia de letras a buscar. + /// + public Task GetWordsContainAsync(string query) + { + return _listaPalabrasAPI.GetWordsContainAsync(query); } /// @@ -113,28 +105,9 @@ public async Task GetWordOfTheDayAsync() /// If true it will take secondary entries. /// Si es verdadero cogerá entradas secundarias. /// - public async Task> SearchWordAsync(string word, bool allGroups = true) - { - string response = await _httpClient.GetStringAsync($"{URLBASE}/search?w={word}"); - JToken jtoken = JToken.Parse(response); - - var words = new List(); - foreach (var w in jtoken.SelectToken("res")) - { - int group = w.Value("grp"); - - if (allGroups || group == 0) - { - string id = w.Value("id"); - string content = w.Value("header"); - - Match contentMatch = Regex.Match(content, @"[A-Za-z/-]+"); - - words.Add(new Word(id, contentMatch.Success ? contentMatch.Value : content)); - } - } - - return words; + public Task> SearchWordAsync(string word, bool allGroups = true) + { + return _raeAPI.SearchWordAsync(word, allGroups); } } } diff --git a/RAE/ListaPalabrasAPI.cs b/RAE/ListaPalabrasAPI.cs new file mode 100644 index 0000000..6c8458c --- /dev/null +++ b/RAE/ListaPalabrasAPI.cs @@ -0,0 +1,87 @@ +using HtmlAgilityPack; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace RAE +{ + internal class ListaPalabrasAPI + { + private const string URLBASE = "https://www.listapalabras.com"; + private static readonly string[] ALPHABET = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "Ñ", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" }; + + private HttpClient _httpClient; + + public ListaPalabrasAPI() + { + _httpClient = new HttpClient(); + } + + public async Task GetAllWordsAsync() + { + List words = new List(); + + await Task.Run(() => Array.ForEach(ALPHABET, s => words.AddRange(GetWordsStartWithAsync(s).Result))); + + return words.ToArray(); + } + + public async Task GetWordsStartWithAsync(string query) + { + HtmlDocument page = await LoadPageAsync($"{URLBASE}/palabras-con.php?letra={query}&total=s"); + + return GetWords(page); + } + + public async Task GetWordsContainAsync(string query) + { + var content = new FormUrlEncodedContent(new[] + { + new KeyValuePair("busqueda", query) + }); + + HtmlDocument page = await LoadPageAsync($"{URLBASE}/palabras-con.php", content); + + return GetWords(page); + } + + private async Task LoadPageAsync(string url) + { + var document = new HtmlDocument(); + + using (Stream documentStream = await _httpClient.GetStreamAsync(url)) + { + document.Load(documentStream); + } + + return document; + } + + private async Task LoadPageAsync(string url, HttpContent content) + { + var document = new HtmlDocument(); + + var response = await _httpClient.PostAsync(url, content); + + using (Stream documentStream = await response.Content.ReadAsStreamAsync()) + { + document.Load(documentStream); + } + + return document; + } + + private string[] GetWords(HtmlDocument document) + { + string[] words = document.GetElementbyId("columna_resultados_generales") + .SelectNodes("descendant::*[@id='palabra_resultado']") + .Select(n => n.InnerText.Trim(' ', '\n')) + .ToArray(); + + return words; + } + } +} diff --git a/RAE/RAE.csproj b/RAE/RAE.csproj index 29fd792..1d70dc0 100644 --- a/RAE/RAE.csproj +++ b/RAE/RAE.csproj @@ -14,6 +14,7 @@ + diff --git a/RAE/RAEAPI.cs b/RAE/RAEAPI.cs new file mode 100644 index 0000000..5e39bac --- /dev/null +++ b/RAE/RAEAPI.cs @@ -0,0 +1,104 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace RAE +{ +/* + Based on information obtained from: + Basado en la información obtenida de: + https://devhub.io/repos/mgp25-RAE-API +*/ + internal class RAEAPI + { + private const string URLBASE = "https://dle.rae.es/data"; + private const string TOKEN = "cDY4MkpnaFMzOmFHZlVkQ2lFNDM0"; + + private HttpClient _httpClient; + + public RAEAPI() + { + _httpClient = new HttpClient(); + _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", TOKEN); + } + + public async Task FetchWordByIdAsync(string wordId) + { + var response = await _httpClient.GetStringAsync($"{URLBASE}/fetch?id={wordId}"); + + MatchCollection matches = Regex.Matches(response, "

.*?

"); + + string[] definitions = matches.Cast() + .Select(m => Regex.Replace(m.Value, "<.*?>", "")) + .ToArray(); + + return definitions; + } + + public async Task GetKeysAsync(string query) + { + string response = await _httpClient.GetStringAsync($"{URLBASE}/keys?q={query}&callback="); + string json = Regex.Match(response, @"\[.*?\]").Value; + + var keys = JsonConvert.DeserializeObject(json); + + return keys; + } + + public async Task GetRandomWordAsync() + { + string response = await _httpClient.GetStringAsync($"{URLBASE}/random"); + + string idFormat = "article id=\""; + Match idMatch = Regex.Match(response, $@"{idFormat}\w+"); + string id = Regex.Replace(idMatch.Value, idFormat, ""); + + string contentFormat = "class=\"f\".*?>"; + Match contentMatch = Regex.Match(response, $@"{contentFormat}\w[\,\s\w]*"); + string content = Regex.Replace(contentMatch.Value, contentFormat, ""); + + return new Word(id, content); + } + + public async Task GetWordOfTheDayAsync() + { + string response = await _httpClient.GetStringAsync($"{URLBASE}/wotd?callback="); + string json = response.Substring(1, response.Length - 2); + JObject jobject = JObject.Parse(json); + + string id = jobject.Value("id"); + string content = jobject.Value("header"); + + return new Word(id, content); + } + + public async Task> SearchWordAsync(string word, bool allGroups = true) + { + string response = await _httpClient.GetStringAsync($"{URLBASE}/search?w={word}"); + JToken jtoken = JToken.Parse(response); + + var words = new List(); + foreach (var w in jtoken.SelectToken("res")) + { + int group = w.Value("grp"); + + if (allGroups || group == 0) + { + string id = w.Value("id"); + string content = w.Value("header"); + + Match contentMatch = Regex.Match(content, @"[A-Za-z/-]+"); + + words.Add(new Word(id, contentMatch.Success ? contentMatch.Value : content)); + } + } + + return words; + } + } +}