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