<commit_before>﻿using LiveSplit.Model;
using LiveSplit.Options;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;

namespace LiveSplit.Web.Share
{
    public class SpeedrunCom
    {
        public struct Record
        {
            public int ID;
            public int? Place;
            public IEnumerable<string> Runners;
            public Time Time;
            public DateTime? Date;
            public Uri Video;
            public bool RunAvailable { get { return Run != null; } }
            public Lazy<IRun> Run;
        }

        private struct GamePair
        {
            public string Name;
            public string ID;
        }

        public enum CoverResolution : int
        {
            x32 = 32,
            x64 = 64,
            x128 = 128,
            x256 = 256
        }

        protected static readonly SpeedrunCom _Instance = new SpeedrunCom();

        public static SpeedrunCom Instance { get { return _Instance; } }

        public static readonly Uri BaseUri = new Uri("http://www.speedrun.com/");
        public static readonly Uri APIUri = new Uri(BaseUri, "");

        private List<GamePair> gameList;

        protected SpeedrunCom() { }

        public Uri GetSiteUri(string subUri)
        {
            return new Uri(BaseUri, subUri);
        }

        public Uri GetAPIUri(string subUri)
        {
            return new Uri(APIUri, subUri);
        }

        public Uri GetGameUri(string gameId)
        {
            return GetSiteUri(HttpUtility.UrlPathEncode(gameId));
        }

        public Uri GetCategoryUri(string gameId, string categoryId)
        {
            var uri = string.Format("{0}#{1}", HttpUtility.UrlPathEncode(gameId), HttpUtility.UrlPathEncode(categoryId));
            return GetSiteUri(uri);
        }

        public Uri GetUserUri(string userName)
        {
            var uri = string.Format("user/{0}", HttpUtility.UrlPathEncode(userName));
            return GetSiteUri(uri);
        }

        public Uri GetRunUri(int runId)
        {
            var uri = string.Format("run/{0}", runId);
            return GetSiteUri(uri);
        }

        public Uri GetGameCoverUri(string gameId, CoverResolution resolution = CoverResolution.x128)
        {
            var uri = string.Format("themes/{0}/cover-{1}.png", HttpUtility.UrlPathEncode(gameId), (int)resolution);
            return GetSiteUri(uri);
        }

        private dynamic findCategory(IDictionary<string, dynamic> categories, string categoryName)
        {
            var categoryNameLower = (categoryName ?? "").Trim().ToLowerInvariant();
            return categories.Where(x => (x.Key ?? "").Trim().ToLowerInvariant() == categoryNameLower).First();
        }

        private IEnumerable<GamePair> getGameList()
        {
            if (gameList == null)
            {
                gameList = new List<GamePair>();

                var request = WebRequest.Create(GetSiteUri("games"));
                var stream = request.GetResponse().GetResponseStream();
                using (var reader = new StreamReader(stream))
                {
                    var html = reader.ReadToEnd();

                    var indexAlphabetic = html.IndexOf("<div class='optionon' id='alphabeticlist' style='display:none;'>");
                    var indexByPlatform = html.IndexOf("<div class='optionon' id='byplatformlist' style='display:none;'>");
                    var alphabeticList = html.Substring(indexAlphabetic, indexByPlatform - indexAlphabetic);
                    var gamesHtml = alphabeticList.Split(new[] { "<a href='/" }, StringSplitOptions.None);

                    foreach (var gameHtml in gamesHtml.Skip(1))
                    {
                        var indexGameId = gameHtml.IndexOf("'");
                        var indexBeginGameName = gameHtml.IndexOf("'>") + 2;
                        var indexEndGameName = gameHtml.IndexOf("</a>");
                        var gameId = HttpUtility.HtmlDecode(gameHtml.Substring(0, indexGameId));
                        var gameName = HttpUtility.HtmlDecode(gameHtml.Substring(indexBeginGameName, indexEndGameName - indexBeginGameName));<commit_msg>Fixed a bug with the fuzzy category matching<commit_after>﻿using LiveSplit.Model;
using LiveSplit.Options;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;

namespace LiveSplit.Web.Share
{
    public class SpeedrunCom
    {
        public struct Record
        {
            public int ID;
            public int? Place;
            public IEnumerable<string> Runners;
            public Time Time;
            public DateTime? Date;
            public Uri Video;
            public bool RunAvailable { get { return Run != null; } }
            public Lazy<IRun> Run;
        }

        private struct GamePair
        {
            public string Name;
            public string ID;
        }

        public enum CoverResolution : int
        {
            x32 = 32,
            x64 = 64,
            x128 = 128,
            x256 = 256
        }

        protected static readonly SpeedrunCom _Instance = new SpeedrunCom();

        public static SpeedrunCom Instance { get { return _Instance; } }

        public static readonly Uri BaseUri = new Uri("http://www.speedrun.com/");
        public static readonly Uri APIUri = new Uri(BaseUri, "");

        private List<GamePair> gameList;

        protected SpeedrunCom() { }

        public Uri GetSiteUri(string subUri)
        {
            return new Uri(BaseUri, subUri);
        }

        public Uri GetAPIUri(string subUri)
        {
            return new Uri(APIUri, subUri);
        }

        public Uri GetGameUri(string gameId)
        {
            return GetSiteUri(HttpUtility.UrlPathEncode(gameId));
        }

        public Uri GetCategoryUri(string gameId, string categoryId)
        {
            var uri = string.Format("{0}#{1}", HttpUtility.UrlPathEncode(gameId), HttpUtility.UrlPathEncode(categoryId));
            return GetSiteUri(uri);
        }

        public Uri GetUserUri(string userName)
        {
            var uri = string.Format("user/{0}", HttpUtility.UrlPathEncode(userName));
            return GetSiteUri(uri);
        }

        public Uri GetRunUri(int runId)
        {
            var uri = string.Format("run/{0}", runId);
            return GetSiteUri(uri);
        }

        public Uri GetGameCoverUri(string gameId, CoverResolution resolution = CoverResolution.x128)
        {
            var uri = string.Format("themes/{0}/cover-{1}.png", HttpUtility.UrlPathEncode(gameId), (int)resolution);
            return GetSiteUri(uri);
        }

        private dynamic findCategory(IDictionary<string, dynamic> categories, string categoryName)
        {
            var categoryNameLower = (categoryName ?? "").Trim().ToLowerInvariant();
            return categories.Where(x => (x.Key ?? "").Trim().ToLowerInvariant() == categoryNameLower).First().Value;
        }

        private IEnumerable<GamePair> getGameList()
        {
            if (gameList == null)
            {
                gameList = new List<GamePair>();

                var request = WebRequest.Create(GetSiteUri("games"));
                var stream = request.GetResponse().GetResponseStream();
                using (var reader = new StreamReader(stream))
                {
                    var html = reader.ReadToEnd();

                    var indexAlphabetic = html.IndexOf("<div class='optionon' id='alphabeticlist' style='display:none;'>");
                    var indexByPlatform = html.IndexOf("<div class='optionon' id='byplatformlist' style='display:none;'>");
                    var alphabeticList = html.Substring(indexAlphabetic, indexByPlatform - indexAlphabetic);
                    var gamesHtml = alphabeticList.Split(new[] { "<a href='/" }, StringSplitOptions.None);

                    foreach (var gameHtml in gamesHtml.Skip(1))
                    {
                        var indexGameId = gameHtml.IndexOf("'");
                        var indexBeginGameName = gameHtml.IndexOf("'>") + 2;
                        var indexEndGameName = gameHtml.IndexOf("</a>");
                        var gameId = HttpUtility.HtmlDecode(gameHtml.Substring(0, indexGameId));
                        var gameName = HttpUtility.HtmlDecode(gameHtml.Substring(indexBeginGameName, indexEndGameName - indexBeginGameName));
{'fraction_non_alphanumeric': 0.10019737605944502, 'fraction_numerical': 0.007430628120283293, 'mean_word_length': 1.9672752325180847, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3011367', 'n_tokens_mistral': 2332, 'n_tokens_neox': 2187, 'n_words': 536}