<commit_before>﻿using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;

using CwIRC;
using MBFunctionInterface;

using MBUtilities;
using MBUtilities.Channel;

namespace Internet
{
    /// <summary>
    /// A Function which returns the last song a user played, from Last.fm
    /// </summary>
    public class NowPlaying : Function
    {
        public static Dictionary<string, string> AccountMap = new Dictionary<string, string>();

        public NowPlaying()
        {
            Help = "np (<user>) - Returns your currently playing music (from LastFM). You can also supply a specific username to check.";
            Type = Types.Command;
            AccessLevel = AccessLevels.Anyone;

            LoadLinks();
        }

        ~NowPlaying()
        {
            SaveLinks();
        }

        public override List<IRCResponse> GetResponse(BotMessage message)
        {
            if (Regex.IsMatch(message.Command, "^(np|nowplaying)$", RegexOptions.IgnoreCase))
            {
                string lastfmName = "";

                if (message.ParameterList.Count > 0)
                {
                    if (AccountMap.ContainsKey(message.ParameterList[0].ToUpper()))
                    {
                        lastfmName = AccountMap[message.ParameterList[0].ToUpper()];
                    }
                    else
                    {
                        lastfmName = message.ParameterList[0];
                    }
                }
                else
                {
                    if (AccountMap.ContainsKey(message.User.Name.ToUpper()))
                    {
                        lastfmName = AccountMap[message.User.Name.ToUpper()];
                    }
                    else
                    {
                        lastfmName = message.User.Name;
                    }
                }

                URL.WebPage recentFeed = new URL.WebPage();

                try
                {
                    recentFeed = URL.FetchURL("http://ws.audioscrobbler.com/1.0/user/" + lastfmName + "/recenttracks.rss");
                }
                catch (System.Net.WebException ex)
                {
                    Logger.Write(ex.ToString(), Settings.Instance.ErrorFile);
                    return new List<IRCResponse>() { new IRCResponse(ResponseType.Say, "User \"" + lastfmName + "\" not found on LastFM", message.ReplyTo) };
                }

                Match track = Regex.Match(recentFeed.Page, @"<item>\s*?<title>(?<band>.+?)–(?<song>.+?)</title>\s*?<link>(?<link>.+?)</link>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                if (track.Success)
                {
                    string band = track.Groups["band"].Value;
                    string song = track.Groups["song"].Value;

                    string songMessage = "\"" + song.Trim() + "\" by " + band.Trim();

                    songMessage += " (" + /*ChannelList.EvadeChannelLinkBlock(message, URL.Shorten(*/track.Groups["link"].Value/*))*/ + ")";

                    return new List<IRCResponse>() { new IRCResponse(ResponseType.Say, songMessage, message.ReplyTo) };
                }
                else
                {
                    return new List<IRCResponse>() { new IRCResponse(ResponseType.Say, "User \"" + lastfmName + "\" exists on LastFM, but hasn't scrobbled any music to it", message.ReplyTo) };
                }
            }
            else
            {
                return null;
            }
        }

        public static void SaveLinks()
        {
            string fileName = Path.Combine(Settings.Instance.DataPath, Settings.Instance.Server + string.Format("{0}NowPlayingLinks.xml", Path.DirectorySeparatorChar));

            FileUtils.CreateDirIfNotExists(fileName);

            XmlWriterSettings xws = new XmlWriterSettings();
            xws.Indent = true;
            xws.NewLineOnAttributes = true;
            using (XmlWriter writer = XmlWriter.Create(fileName, xws))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("Links");

                foreach (KeyValuePair<string, string> link in AccountMap)
                {
                    writer.WriteStartElement("Link");

                    writer.WriteElementString("IRCName", link.Key);
                    writer.WriteElementString("LastFMName", link.Value);

                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
                writer.WriteEndDocument();
            }
        }

        public void LoadLinks()
        {
            string fileName = Path.Combine(Settings.Instance.DataPath, Settings.Instance.Server + string.Format("{0}NowPlayingLinks.xml", Path.DirectorySeparatorChar));

            if (!File.Exists(fileName))
                return;

            XmlDocument doc = new XmlDocument();
            doc.Load(new StreamReader(File.OpenRead(fileName)));
            XmlNode root = doc.DocumentElement;

            foreach (XmlNode linkNode in root.SelectNodes(@"/Links/Link"))
            {
                string IRCName = linkNode.SelectSingleNode("IRCName").FirstChild.Value;
                string LastFMName = linkNode.SelectSingleNode("LastFMName").FirstChild.Value;

                AccountMap.Add(IRCName, LastFMName);
            }
        }
    }

    public class NowPlayingRegister : Function
    {
        public NowPlayingRegister()
        {
            Help = "npregister/nplink <LastFM Name> - Links the specified LastFM account name to your IRC name.";
            Type = Types.Command;
            AccessLevel = AccessLevels.Anyone;
        }

        public override List<IRCResponse> GetResponse(BotMessage message)
        {
            if (Regex.IsMatch(message.Command, "^(np(register|link))$", RegexOptions.IgnoreCase))
            {
                if (message.ParameterList.Count > 0)
                {
                    string lastFMName = StringUtils.ReplaceNewlines(StringUtils.StripIRCFormatChars(message.ParameterList[0]), "");<commit_msg>Renamed NowPlayingRegister to NowPlayingLink, as nobody uses the '|npregister' form.<commit_after>﻿using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;

using CwIRC;
using MBFunctionInterface;

using MBUtilities;
using MBUtilities.Channel;

namespace Internet
{
    /// <summary>
    /// A Function which returns the last song a user played, from Last.fm
    /// </summary>
    public class NowPlaying : Function
    {
        public static Dictionary<string, string> AccountMap = new Dictionary<string, string>();

        public NowPlaying()
        {
            Help = "np (<user>) - Returns your currently playing music (from LastFM). You can also supply a specific username to check.";
            Type = Types.Command;
            AccessLevel = AccessLevels.Anyone;

            LoadLinks();
        }

        ~NowPlaying()
        {
            SaveLinks();
        }

        public override List<IRCResponse> GetResponse(BotMessage message)
        {
            if (Regex.IsMatch(message.Command, "^(np|nowplaying)$", RegexOptions.IgnoreCase))
            {
                string lastfmName = "";

                if (message.ParameterList.Count > 0)
                {
                    if (AccountMap.ContainsKey(message.ParameterList[0].ToUpper()))
                    {
                        lastfmName = AccountMap[message.ParameterList[0].ToUpper()];
                    }
                    else
                    {
                        lastfmName = message.ParameterList[0];
                    }
                }
                else
                {
                    if (AccountMap.ContainsKey(message.User.Name.ToUpper()))
                    {
                        lastfmName = AccountMap[message.User.Name.ToUpper()];
                    }
                    else
                    {
                        lastfmName = message.User.Name;
                    }
                }

                URL.WebPage recentFeed = new URL.WebPage();

                try
                {
                    recentFeed = URL.FetchURL("http://ws.audioscrobbler.com/1.0/user/" + lastfmName + "/recenttracks.rss");
                }
                catch (System.Net.WebException ex)
                {
                    Logger.Write(ex.ToString(), Settings.Instance.ErrorFile);
                    return new List<IRCResponse>() { new IRCResponse(ResponseType.Say, "User \"" + lastfmName + "\" not found on LastFM", message.ReplyTo) };
                }

                Match track = Regex.Match(recentFeed.Page, @"<item>\s*?<title>(?<band>.+?)–(?<song>.+?)</title>\s*?<link>(?<link>.+?)</link>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                if (track.Success)
                {
                    string band = track.Groups["band"].Value;
                    string song = track.Groups["song"].Value;

                    string songMessage = "\"" + song.Trim() + "\" by " + band.Trim();

                    songMessage += " (" + /*ChannelList.EvadeChannelLinkBlock(message, URL.Shorten(*/track.Groups["link"].Value/*))*/ + ")";

                    return new List<IRCResponse>() { new IRCResponse(ResponseType.Say, songMessage, message.ReplyTo) };
                }
                else
                {
                    return new List<IRCResponse>() { new IRCResponse(ResponseType.Say, "User \"" + lastfmName + "\" exists on LastFM, but hasn't scrobbled any music to it", message.ReplyTo) };
                }
            }
            else
            {
                return null;
            }
        }

        public static void SaveLinks()
        {
            string fileName = Path.Combine(Settings.Instance.DataPath, Settings.Instance.Server + string.Format("{0}NowPlayingLinks.xml", Path.DirectorySeparatorChar));

            FileUtils.CreateDirIfNotExists(fileName);

            XmlWriterSettings xws = new XmlWriterSettings();
            xws.Indent = true;
            xws.NewLineOnAttributes = true;
            using (XmlWriter writer = XmlWriter.Create(fileName, xws))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("Links");

                foreach (KeyValuePair<string, string> link in AccountMap)
                {
                    writer.WriteStartElement("Link");

                    writer.WriteElementString("IRCName", link.Key);
                    writer.WriteElementString("LastFMName", link.Value);

                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
                writer.WriteEndDocument();
            }
        }

        public void LoadLinks()
        {
            string fileName = Path.Combine(Settings.Instance.DataPath, Settings.Instance.Server + string.Format("{0}NowPlayingLinks.xml", Path.DirectorySeparatorChar));

            if (!File.Exists(fileName))
                return;

            XmlDocument doc = new XmlDocument();
            doc.Load(new StreamReader(File.OpenRead(fileName)));
            XmlNode root = doc.DocumentElement;

            foreach (XmlNode linkNode in root.SelectNodes(@"/Links/Link"))
            {
                string IRCName = linkNode.SelectSingleNode("IRCName").FirstChild.Value;
                string LastFMName = linkNode.SelectSingleNode("LastFMName").FirstChild.Value;

                AccountMap.Add(IRCName, LastFMName);
            }
        }
    }

    public class NowPlayingLink : Function
    {
        public NowPlayingLink()
        {
            Help = "nplink <LastFM Name> - Links the specified LastFM account name to your IRC name.";
            Type = Types.Command;
            AccessLevel = AccessLevels.Anyone;
        }

        public override List<IRCResponse> GetResponse(BotMessage message)
        {
            if (Regex.IsMatch(message.Command, "^n(ow)?p(laying)?link$", RegexOptions.IgnoreCase))
            {
                if (message.ParameterList.Count > 0)
                {
                    string lastFMName = StringUtils.ReplaceNewlines(StringUtils.StripIRCFormatChars(message.ParameterList[0]), "");
{'fraction_non_alphanumeric': 0.10863373748881114, 'fraction_numerical': 0.0016274717226788184, 'mean_word_length': 1.603813559322034, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, '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': '6877414', 'n_tokens_mistral': 3229, 'n_tokens_neox': 2994, 'n_words': 591}