diff --git a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs index ed6c058b..2aeb3c5b 100644 --- a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs @@ -1,4 +1,7 @@ -ο»Ώusing Discord; +ο»Ώusing AngleSharp; +using AngleSharp.Dom.Html; +using AngleSharp.Extensions; +using Discord; using Discord.Commands; using NadekoBot.Attributes; using NadekoBot.Extensions; @@ -8,6 +11,7 @@ using Newtonsoft.Json.Linq; using NLog; using System; using System.Collections.Generic; +using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -52,6 +56,116 @@ namespace NadekoBot.Modules.Searches }, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29)); } + [NadekoCommand, Usage, Description, Aliases] + [Priority(1)] + public async Task Mal([Remainder] string name) + { + if (string.IsNullOrWhiteSpace(name)) + return; + + var fullQueryLink = "https://myanimelist.net/profile/" + name; + + var config = Configuration.Default.WithDefaultLoader(); + var document = await BrowsingContext.New(config).OpenAsync(fullQueryLink); + + var imageElem = document.QuerySelector("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-left > div.user-profile > div.user-image > img"); + var imageUrl = ((IHtmlImageElement)imageElem)?.Source ?? "http://icecream.me/uploads/870b03f36b59cc16ebfe314ef2dde781.png"; + + var stats = document.QuerySelectorAll("body > div#myanimelist > div.wrapper > div#contentWrapper > div#content > div.content-container > div.container-right > div#statistics > div.user-statistics-stats > div.stats > div.clearfix > ul.stats-status > li > span").Select(x => x.InnerHtml).ToList(); + + var favorites = document.QuerySelectorAll("div.user-favorites > div.di-tc"); + + var favAnime = "No favorite anime yet"; + if (favorites[0].QuerySelector("p") == null) + favAnime = string.Join("\n", favorites[0].QuerySelectorAll("ul > li > div.di-tc.va-t > a") + .Shuffle() + .Take(3) + .Select(x => + { + var elem = (IHtmlAnchorElement)x; + return $"[{elem.InnerHtml}]({elem.Href})"; + })); + + //var favManga = "No favorite manga yet."; + //if (favorites[1].QuerySelector("p") == null) + // favManga = string.Join("\n", favorites[1].QuerySelectorAll("ul > li > div.di-tc.va-t > a") + // .Take(3) + // .Select(x => + // { + // var elem = (IHtmlAnchorElement)x; + // return $"[{elem.InnerHtml}]({elem.Href})"; + // })); + + var info = document.QuerySelectorAll("ul.user-status:nth-child(3) > li") + .Select(x => Tuple.Create(x.Children[0].InnerHtml, x.Children[1].InnerHtml)) + .ToList(); + + var daysAndMean = document.QuerySelectorAll("div.anime:nth-child(1) > div:nth-child(2) > div") + .Select(x => x.TextContent.Split(':').Select(y => y.Trim()).ToArray()) + .ToArray(); + + var embed = new EmbedBuilder() + .WithOkColor() + .WithTitle($"{name}'s MAL profile") + .AddField(efb => efb.WithName("πŸ’š Watching").WithValue(stats[0]).WithIsInline(true)) + .AddField(efb => efb.WithName("πŸ’™ Completed").WithValue(stats[1]).WithIsInline(true)); + if (info.Count < 3) + embed.AddField(efb => efb.WithName("πŸ’› On-Hold").WithValue(stats[2]).WithIsInline(true)); + embed + .AddField(efb => efb.WithName("πŸ’” Dropped").WithValue(stats[3]).WithIsInline(true)) + .AddField(efb => efb.WithName("βšͺ Plan to watch").WithValue(stats[4]).WithIsInline(true)) + .AddField(efb => efb.WithName("πŸ• " + daysAndMean[0][0]).WithValue(daysAndMean[0][1]).WithIsInline(true)) + .AddField(efb => efb.WithName("πŸ“Š " + daysAndMean[1][0]).WithValue(daysAndMean[1][1]).WithIsInline(true)) + .AddField(efb => efb.WithName(MalInfoToEmoji(info[0].Item1) + " " + info[0].Item1).WithValue(info[0].Item2.TrimTo(20)).WithIsInline(true)) + .AddField(efb => efb.WithName(MalInfoToEmoji(info[1].Item1) + " " + info[1].Item1).WithValue(info[1].Item2.TrimTo(20)).WithIsInline(true)); + if (info.Count > 2) + embed.AddField(efb => efb.WithName(MalInfoToEmoji(info[2].Item1) + " " + info[2].Item1).WithValue(info[2].Item2.TrimTo(20)).WithIsInline(true)); + //if(info.Count > 3) + // embed.AddField(efb => efb.WithName(MalInfoToEmoji(info[3].Item1) + " " + info[3].Item1).WithValue(info[3].Item2).WithIsInline(true)) + embed + .WithDescription($@" +** https://myanimelist.net/animelist/{ name } ** + +**Top 3 Favorite Anime:** +{favAnime}" + +//**[Manga List](https://myanimelist.net/mangalist/{name})** +//πŸ’š`Reading:` {stats[5]} +//πŸ’™`Completed:` {stats[6]} +//πŸ’”`Dropped:` {stats[8]} +//βšͺ`Plan to read:` {stats[9]} + +//**Top 3 Favorite Manga:** +//{favManga}" + +) + .WithUrl(fullQueryLink) + .WithImageUrl(imageUrl); + + await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); + } + + private static string MalInfoToEmoji(string info) { + info = info.Trim().ToLowerInvariant(); + switch (info) + { + case "gender": + return "🚁"; + case "location": + return "πŸ—Ί"; + case "last online": + return "πŸ‘₯"; + case "birthday": + return "πŸ“†"; + default: + return "❔"; + } + } + + [NadekoCommand, Usage, Description, Aliases] + [Priority(0)] + public Task Mal(IUser usr) => Mal(usr.Username); + [NadekoCommand, Usage, Description, Aliases] public async Task Anime([Remainder] string query) { diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index f37738f5..ae2ff2c6 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -4406,6 +4406,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to mal. + /// + public static string mal_cmd { + get { + return ResourceManager.GetString("mal_cmd", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Shows basic info from myanimelist profile.. + /// + public static string mal_desc { + get { + return ResourceManager.GetString("mal_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `{0}mal straysocks`. + /// + public static string mal_usage { + get { + return ResourceManager.GetString("mal_usage", resourceCulture); + } + } + /// /// Looks up a localized string similar to manga mang mq. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 95b16f7d..a31288b1 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3024,4 +3024,13 @@ `{0}waifuinfo @MyCrush` or `{0}waifuinfo` + + mal + + + Shows basic info from myanimelist profile. + + + `{0}mal straysocks` + \ No newline at end of file