<commit_before>﻿using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Humanizer;
using Humanizer.Localisation;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;

namespace Modix.Modules
{
    public class UserInfoModule : ModuleBase
    {
        public UserInfoModule(ILogger<UserInfoModule> logger)
        {
            Log = logger ?? new NullLogger<UserInfoModule>();
        }

        private ILogger<UserInfoModule> Log { get; }

        [Command("info")]
        public async Task GetUserInfo([Remainder] IUser user = null)
        {
            user = user ?? Context.User;

            var utcNow = DateTime.UtcNow;
            var builder = new StringBuilder();
            builder.AppendLine("**\u276F User Information**");
            builder.AppendLine("ID: " + user.Id);
            builder.AppendLine("Profile: " + user.Mention);

            // TODO: Add content about the user's presence, if any

            builder.AppendFormat(
                CultureInfo.InvariantCulture,
                "Created: {0} ago ({1:yyyy-MM-ddTHH:mm:ssK})\n",
                (utcNow - user.CreatedAt).Humanize(maxUnit: TimeUnit.Year, culture: CultureInfo.InvariantCulture),
                user.CreatedAt.UtcDateTime);

            if (user is IGuildUser member)
            {
                builder.AppendLine();
                builder.AppendLine("**\u276F Member Information**");

                if (!string.IsNullOrEmpty(member.Nickname))
                {
                    builder.AppendLine("Nickname: " + member.Nickname);
                }

                if (member.JoinedAt is DateTimeOffset joinedAt)
                {
                    builder.AppendFormat(
                        CultureInfo.InvariantCulture,
                        "Joined: {0} ago ({1:yyyy-MM-ddTHH:mm:ssK})\n",
                        (utcNow - joinedAt).Humanize(maxUnit: TimeUnit.Year, culture: CultureInfo.InvariantCulture),
                        joinedAt.UtcDateTime);
                }

                if (member.RoleIds.Count > 0)
                {
                    var roles = member.RoleIds.Select(x => member.Guild.Roles.Single(y => y.Id == x))
                        .Where(x => x.Id != x.Guild.Id) // @everyone role always has same ID than guild
                        .ToArray();

                    if (roles.Length > 0)
                    {
                        Array.Sort(roles);

                        builder.Append(roles.Length > 1 ? "Roles: " : "Role: ");
                        builder.AppendLine(BuildList(roles, r => r.Mention));
                    }
                }
            }

            // TODO: Add infraction summary

            // TODO: Add voice session data

            var embedBuilder = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name = user.Username + "#" + user.Discriminator,
                    IconUrl = user.GetAvatarUrl()
                },
                Color = GetDominateColor(user),
                Description = builder.ToString(),
                ThumbnailUrl = user.GetAvatarUrl()
            };

            await ReplyAsync(string.Empty, embed: embedBuilder.Build());
        }
<commit_msg>Fix role ordering<commit_after>﻿using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Humanizer;
using Humanizer.Localisation;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;

namespace Modix.Modules
{
    public class UserInfoModule : ModuleBase
    {
        public UserInfoModule(ILogger<UserInfoModule> logger)
        {
            Log = logger ?? new NullLogger<UserInfoModule>();
        }

        private ILogger<UserInfoModule> Log { get; }

        [Command("info")]
        public async Task GetUserInfo([Remainder] IUser user = null)
        {
            user = user ?? Context.User;

            var utcNow = DateTime.UtcNow;
            var builder = new StringBuilder();
            builder.AppendLine("**\u276F User Information**");
            builder.AppendLine("ID: " + user.Id);
            builder.AppendLine("Profile: " + user.Mention);

            // TODO: Add content about the user's presence, if any

            builder.AppendFormat(
                CultureInfo.InvariantCulture,
                "Created: {0} ago ({1:yyyy-MM-ddTHH:mm:ssK})\n",
                (utcNow - user.CreatedAt).Humanize(maxUnit: TimeUnit.Year, culture: CultureInfo.InvariantCulture),
                user.CreatedAt.UtcDateTime);

            if (user is IGuildUser member)
            {
                builder.AppendLine();
                builder.AppendLine("**\u276F Member Information**");

                if (!string.IsNullOrEmpty(member.Nickname))
                {
                    builder.AppendLine("Nickname: " + member.Nickname);
                }

                if (member.JoinedAt is DateTimeOffset joinedAt)
                {
                    builder.AppendFormat(
                        CultureInfo.InvariantCulture,
                        "Joined: {0} ago ({1:yyyy-MM-ddTHH:mm:ssK})\n",
                        (utcNow - joinedAt).Humanize(maxUnit: TimeUnit.Year, culture: CultureInfo.InvariantCulture),
                        joinedAt.UtcDateTime);
                }

                if (member.RoleIds.Count > 0)
                {
                    var roles = member.RoleIds.Select(x => member.Guild.Roles.Single(y => y.Id == x))
                        .Where(x => x.Id != x.Guild.Id) // @everyone role always has same ID than guild
                        .ToArray();

                    if (roles.Length > 0)
                    {
                        Array.Sort(roles); // Sort by position: lowest positioned role is first
                        Array.Reverse(roles); // Reverse the sort: highest positioned role is first

                        builder.Append(roles.Length > 1 ? "Roles: " : "Role: ");
                        builder.AppendLine(BuildList(roles, r => r.Mention));
                    }
                }
            }

            // TODO: Add infraction summary

            // TODO: Add voice session data

            var embedBuilder = new EmbedBuilder
            {
                Author = new EmbedAuthorBuilder
                {
                    Name = user.Username + "#" + user.Discriminator,
                    IconUrl = user.GetAvatarUrl()
                },
                Color = GetDominateColor(user),
                Description = builder.ToString(),
                ThumbnailUrl = user.GetAvatarUrl()
            };

            await ReplyAsync(string.Empty, embed: embedBuilder.Build());
        }

{'fraction_non_alphanumeric': 0.10207336523125997, 'fraction_numerical': 0.0037697549659272147, 'mean_word_length': 1.5165997811017877, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2206464', 'n_tokens_mistral': 1852, 'n_tokens_neox': 1718, 'n_words': 375}