コード例 #1
0
ファイル: Friendship.cs プロジェクト: CaitSith2/KtaneStuff
        private static void RetrievePonyCoatColorsFromMlpWikia()
        {
            var ponyColors = ClassifyJson.DeserializeFile <Dictionary <string, string> >(_poniesJson);

            ponyColors.Where(kvp => kvp.Value == null).ParallelForEach(kvp =>
            {
                var pony = kvp.Key;
                try
                {
                    var client    = new HClient();
                    var response  = client.Get(@"http://mlp.wikia.com/wiki/" + pony.Replace(' ', '_'));
                    var str       = response.DataString;
                    var doc       = CQ.CreateDocument(str);
                    var infoboxes = doc["table.infobox"];
                    string color  = null;
                    for (int i = 0; i < infoboxes.Length - 1; i++)
                    {
                        if (infoboxes[i].Cq()["th[colspan='2']"].FirstOrDefault()?.InnerText.Contains(pony) != true)
                        {
                            continue;
                        }
                        var colorTr = infoboxes[i + 1].Cq().Find("tr").Where(tr => tr.Cq().Find("td>b").Any(td => td.InnerText == "Coat")).ToArray();
                        if (colorTr.Length == 0 || colorTr[0].Cq().Find("td").Length != 2)
                        {
                            continue;
                        }
                        var colorSpan = colorTr[0].Cq().Find("td>span");
                        var styleAttr = colorSpan[0]["style"];
                        var m         = Regex.Match(styleAttr, @"background-color\s*:\s*#([A-F0-9]{3,6})");
                        if (m.Success)
                        {
                            color = m.Groups[1].Value;
                        }
                    }
                    lock (ponyColors)
                    {
                        ConsoleUtil.WriteLine($"{pony.Color(ConsoleColor.Cyan)} = {(color == null ? "<nope>".Color(ConsoleColor.Red) : color.Color(ConsoleColor.Green))}", null);
                        //if (color != null)
                        ponyColors[pony] = color ?? "?";
                    }
                }
                catch (Exception e)
                {
                    lock (ponyColors)
                        ConsoleUtil.WriteLine($"{pony.Color(ConsoleColor.Cyan)} = {e.Message.Color(ConsoleColor.Red)} ({e.GetType().FullName.Color(ConsoleColor.DarkRed)})", null);
                }
            });
            ClassifyJson.SerializeToFile(ponyColors, _poniesJson);
        }
コード例 #2
0
        // This method is called in Init() (when the server is initialized) and in pull() (when the repo is updated due to a new git commit).
        private void generateTranslationCache()
        {
            var path = Path.Combine(_config.BaseDir, "Translations");

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

#if DEBUG
            ClassifyJson.SerializeToFile(TranslationInfo.Default, Path.Combine(path, "en.json"));
#endif

            _translationCache = new DirectoryInfo(path)
                                .EnumerateFiles("*.json", SearchOption.TopDirectoryOnly)
                                .ParallelSelect(Environment.ProcessorCount, file =>
            {
                try
                {
                    var translationJson  = File.ReadAllText(file.FullName);
                    var translation      = ClassifyJson.Deserialize <TranslationInfo>(JsonDict.Parse(translationJson));
                    translation.langCode = file.Name.Remove(file.Name.Length - 5);
                    var newJson          = ClassifyJson.Serialize(translation);
                    translation.Json     = newJson.ToString();

#if DEBUG
                    var newJsonIndented = newJson.ToStringIndented();
                    if (translationJson != newJsonIndented)
                    {
                        File.WriteAllText(file.FullName, newJsonIndented);
                    }
#endif

                    return(translation);
                }
                catch (Exception e)
                {
#if DEBUG
                    Console.WriteLine(e.Message);
                    Console.WriteLine(e.GetType().FullName);
                    Console.WriteLine(e.StackTrace);
#endif
                    Log.Exception(e);
                    return(null);
                }
            }).ToDictionary(t => t.langCode, t => t);
        }
コード例 #3
0
ファイル: SettingsUtil.cs プロジェクト: biorpg/RT.Util
        internal static void serialize(object settings, Type settingsType, string filename, SettingsSerializer serializer)
        {
            var tempname = filename + ".~tmp";

            Ut.WaitSharingVio(() =>
            {
                switch (serializer)
                {
                case SettingsSerializer.ClassifyXml:
                    // SerializeToFile automatically creates the folder if necessary
                    ClassifyXml.SerializeToFile(settingsType, settings, tempname, format: ClassifyXmlFormat.Create("Settings"));
                    break;

                case SettingsSerializer.ClassifyJson:
                    // SerializeToFile automatically creates the folder if necessary
                    ClassifyJson.SerializeToFile(settingsType, settings, tempname);
                    break;

                case SettingsSerializer.ClassifyBinary:
                    // SerializeToFile automatically creates the folder if necessary
                    ClassifyBinary.SerializeToFile(settingsType, settings, tempname);
                    break;

                case SettingsSerializer.DotNetBinary:
                    PathUtil.CreatePathToFile(tempname);
                    var bf = new BinaryFormatter();
                    using (var fs = File.Open(tempname, FileMode.Create, FileAccess.Write, FileShare.Read))
                        bf.Serialize(fs, settings);
                    break;

                default:
                    throw new InternalErrorException("4968453");
                }
                File.Delete(filename);
                File.Move(tempname, filename);
            }, TimeSpan.FromSeconds(5));
        }
コード例 #4
0
        public override void Init(LoggerBase log)
        {
#if DEBUG
            if (string.IsNullOrWhiteSpace(Settings.ConfigFile))
            {
                var config = new KtaneWebConfig();
                Console.WriteLine();
                ConsoleUtil.WriteLine("It appears that you are running KtaneWeb for the first time.".Color(ConsoleColor.White));
tryAgain1:
                ConsoleUtil.WriteLine(@"Please provide a location for the JSON settings file (for example: {0/DarkCyan}):".Color(ConsoleColor.Gray).Fmt(@"C:\Path\KtaneWeb.settings.json"));
                var path = Console.ReadLine();
                try
                {
                    ClassifyJson.SerializeToFile(config, path);
                }
                catch (Exception e)
                {
                    ConsoleUtil.WriteLine($"{"Problem:".Color(ConsoleColor.Magenta)} {e.Message.Color(ConsoleColor.Red)} {$"({e.GetType().FullName})".Color(ConsoleColor.DarkRed)}", null);
                    goto tryAgain1;
                }

                Console.WriteLine();
tryAgain2:
                ConsoleUtil.WriteLine("Do you already have a local clone of the KtaneContent repository that you want the website to use?".Color(ConsoleColor.White));
                Console.WriteLine("If yes, please type the full path to that repository. If no, just press Enter.");
                var ktaneContent       = Console.ReadLine();
                var expectedSubfolders = "HTML,More,JSON,Icons".Split(',');
                if (string.IsNullOrWhiteSpace(ktaneContent))
                {
                    ConsoleUtil.WriteLine(@"In that case we will create a new clone. I can do that automatically if you have git installed (if you don’t, please abort now).".Color(ConsoleColor.White));
                    ConsoleUtil.WriteLine("This will take a long time as the repository is large.".Color(ConsoleColor.White));
                    Console.WriteLine();
tryAgain3:
                    ConsoleUtil.WriteLine("Please choose a path where you would like all the data stored (for example: {0/DarkCyan}):".Color(ConsoleColor.Gray).Fmt(@"C:\Path\KtaneContent"));
                    var cloneFolder = Console.ReadLine();
                    try
                    {
                        Directory.CreateDirectory(cloneFolder);
                    }
                    catch (Exception e)
                    {
                        ConsoleUtil.WriteLine($"{"Problem:".Color(ConsoleColor.Magenta)} {e.Message.Color(ConsoleColor.Red)} {$"({e.GetType().FullName})".Color(ConsoleColor.DarkRed)}", null);
                        goto tryAgain3;
                    }
                    try
                    {
                        config.BaseDir = Path.Combine(cloneFolder, "Public");
                        CommandRunner.Run("git", "clone", "https://github.com/Timwi/KtaneContent.git", config.BaseDir).Go();
                        config.MergedPdfsDir = Path.Combine(cloneFolder, "MergedPdfs");
                        Directory.CreateDirectory(config.MergedPdfsDir);
                        config.LogfilesDir = Path.Combine(cloneFolder, "Logfiles");
                        Directory.CreateDirectory(config.LogfilesDir);
                    }
                    catch (Exception e)
                    {
                        ConsoleUtil.WriteLine($"{"Problem:".Color(ConsoleColor.Magenta)} {e.Message.Color(ConsoleColor.Red)} {$"({e.GetType().FullName})".Color(ConsoleColor.DarkRed)}", null);
                        goto tryAgain2;
                    }
                }
                else if (expectedSubfolders.Any(s => !Directory.Exists(Path.Combine(ktaneContent, s))))
                {
                    ConsoleUtil.WriteLine($"{"Problem:".Color(ConsoleColor.Magenta)} {"That folder does not appear to contain KtaneContent.".Color(ConsoleColor.Red)}", null);
                    ConsoleUtil.WriteLine("(We’re looking for a folder that contains subfolders named: {0/DarkMagenta})".Color(ConsoleColor.Magenta).Fmt(expectedSubfolders.JoinString(", ")));
                    goto tryAgain2;
                }
                else
                {
                    var p = ktaneContent;
                    while (p.EndsWith("\""))
                    {
                        p = Path.GetDirectoryName(p);
                    }
                    config.BaseDir = p;
                    p = Path.GetDirectoryName(p);

                    Console.WriteLine();
tryAgain4:
                    var logfiles = Path.Combine(p, "Logfiles");
                    ConsoleUtil.WriteLine("Please choose a path where you would like KtaneWeb to store logfiles uploaded through the Logfile Analyzer, or just press Enter to use the default ({0/DarkCyan}):".Color(ConsoleColor.Gray).Fmt(logfiles));
                    config.LogfilesDir = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(config.LogfilesDir))
                    {
                        ConsoleUtil.WriteLine("Using default: {0/DarkCyan}".Color(ConsoleColor.Gray).Fmt(logfiles));
                        config.LogfilesDir = logfiles;
                    }
                    try
                    {
                        Directory.CreateDirectory(config.LogfilesDir);
                    }
                    catch (Exception e)
                    {
                        ConsoleUtil.WriteLine($"{"Problem:".Color(ConsoleColor.Magenta)} {e.Message.Color(ConsoleColor.Red)} {$"({e.GetType().FullName})".Color(ConsoleColor.DarkRed)}", null);
                        goto tryAgain4;
                    }

                    Console.WriteLine();
tryAgain5:
                    var mergedPdfs = Path.Combine(p, "MergedPdfs");
                    ConsoleUtil.WriteLine("Please choose a path where you would like KtaneWeb to store merged PDFs, or just press Enter to use the default ({0/DarkCyan}):".Color(ConsoleColor.Gray).Fmt(mergedPdfs));

                    config.MergedPdfsDir = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(config.MergedPdfsDir))
                    {
                        ConsoleUtil.WriteLine("Using default: {0/DarkCyan}".Color(ConsoleColor.Gray).Fmt(mergedPdfs));
                        config.MergedPdfsDir = mergedPdfs;
                    }
                    try
                    {
                        Directory.CreateDirectory(config.MergedPdfsDir);
                    }
                    catch (Exception e)
                    {
                        ConsoleUtil.WriteLine($"{"Problem:".Color(ConsoleColor.Magenta)} {e.Message.Color(ConsoleColor.Red)} {$"({e.GetType().FullName})".Color(ConsoleColor.DarkRed)}", null);
                        goto tryAgain5;
                    }

                    var appPath = PathUtil.AppPathCombine(@"..\..");
                    config.JavaScriptFile = Path.Combine(appPath, @"Src\Resources\KtaneWeb.js");
                    config.CssFile        = Path.Combine(appPath, @"Src\Resources\KtaneWeb.css");
                    if (!File.Exists(config.JavaScriptFile) || !File.Exists(config.CssFile))
                    {
                        Console.WriteLine();
tryAgain6:
                        ConsoleUtil.WriteLine("Finally, please let me know where you placed the KtaneWeb source code (what you’re running right now):".Color(ConsoleColor.Gray));
                        appPath = Console.ReadLine();
                        config.JavaScriptFile = Path.Combine(appPath, @"Src\Resources\KtaneWeb.js");
                        config.CssFile        = Path.Combine(appPath, @"Src\Resources\KtaneWeb.css");
                        if (!File.Exists(config.JavaScriptFile) || !File.Exists(config.CssFile))
                        {
                            ConsoleUtil.WriteLine($"{"Problem:".Color(ConsoleColor.Magenta)} {"That does not look like the KtaneWeb source code folder.".Color(ConsoleColor.Red)}", null);
                            goto tryAgain6;
                        }
                    }
                }

                try
                {
                    ClassifyJson.SerializeToFile(config, path);
                    Settings.ConfigFile = path;
                    SaveSettings();
                }
                catch (Exception e)
                {
                    ConsoleUtil.WriteLine($"{"Problem:".Color(ConsoleColor.Magenta)} {e.Message.Color(ConsoleColor.Red)} {$"({e.GetType().FullName})".Color(ConsoleColor.DarkRed)}", null);
                    goto tryAgain1;
                }

                Console.WriteLine();
                ConsoleUtil.WriteLine("That should be all set up for you now!".Color(ConsoleColor.Green));
                ConsoleUtil.WriteLine("Feel free to browse the settings file we just created if you’re curious.".Color(ConsoleColor.DarkGreen));
                ConsoleUtil.WriteLine(@"For automatic PDF generation, we are assuming that Google Chrome is at its default location; if not, please change it manually in the JSON file.".Color(ConsoleColor.DarkGreen));
                Console.WriteLine();
                Console.WriteLine();
            }
#endif
            var original = File.ReadAllText(Settings.ConfigFile);
            _config = ClassifyJson.Deserialize <KtaneWebConfig>(JsonValue.Parse(original));
            var rewrite = serializeConfig();
            if (rewrite != original)
            {
                File.WriteAllText(Settings.ConfigFile, rewrite);
            }
            base.Init(log);
            _logger = log;
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: rstarkov/HoboMirror
        static int DoMain(string[] args)
        {
            // Parse command-line arguments
            Args = CommandLineParser.ParseOrWriteUsageToConsole <CmdLine>(args);
            if (Args == null)
            {
                return(-1);
            }

            // Load settings file
            if (Args.SettingsPath != null)
            {
                if (File.Exists(Args.SettingsPath))
                {
                    Settings = ClassifyJson.DeserializeFile <Settings>(Args.SettingsPath);
                }
                else
                {
                    Settings = new Settings();
                    ClassifyJson.SerializeToFile(Settings, Args.SettingsPath);
                }
                RefreshAccessControl = Settings.SkipRefreshAccessControlDays == null || (Settings.LastRefreshAccessControl + TimeSpan.FromDays((double)Settings.SkipRefreshAccessControlDays) < DateTime.UtcNow);
                Console.WriteLine($"Refresh access control: {RefreshAccessControl}");
                Console.WriteLine($"Update metadata: {UpdateMetadata}");
            }

            // Initialise log files
            var startTime = DateTime.UtcNow;

            if (Args.LogPath != null)
            {
                if (Args.LogPath == "")
                {
                    Args.LogPath = PathUtil.AppPath;
                }
                var enc = new UTF8Encoding(false, throwOnInvalidBytes: false); // allows us to log filenames that are not valid UTF-16 (unpaired surrogates)
                ActionLog        = new IO.StreamWriter(IO.File.Open(Path.Combine(Args.LogPath, $"HoboMirror-Actions.{DateTime.Today:yyyy-MM-dd}.txt"), IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Read), enc);
                ChangeLog        = new IO.StreamWriter(IO.File.Open(Path.Combine(Args.LogPath, $"HoboMirror-Changes.{DateTime.Today:yyyy-MM-dd}.txt"), IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Read), enc);
                ErrorLog         = new IO.StreamWriter(IO.File.Open(Path.Combine(Args.LogPath, $"HoboMirror-Errors.{DateTime.Today:yyyy-MM-dd}.txt"), IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Read), enc);
                CriticalErrorLog = new IO.StreamWriter(IO.File.Open(Path.Combine(Args.LogPath, $"HoboMirror-ErrorsCritical.{DateTime.Today:yyyy-MM-dd}.txt"), IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Read), enc);
                DebugLog         = new IO.StreamWriter(IO.File.Open(Path.Combine(Args.LogPath, $"HoboMirror-Debug.{DateTime.Today:yyyy-MM-dd}.txt"), IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Read), enc);
            }

            try
            {
                // Parse volumes to be snapshotted
                var tasks = Args.FromPath.Zip(Args.ToPath, (from, to) => new
                {
                    FromPath   = from,
                    ToPath     = to,
                    ToGuard    = Path.Combine(to, "__HoboMirrorTarget__.txt"),
                    FromVolume =
                        Regex.Match(from, @"^\\\\\?\\Volume{[^}]+}\\").Apply(match => match.Success ? match.Groups[0].Value : null)
                        ?? Regex.Match(from, @"^\w:\\").Apply(match => match.Success ? match.Groups[0].Value : null)
                        ?? Ut.Throw <string>(new InvalidOperationException($"Expected absolute path: {from}")) // this should be taken care of by the CmdLine specification, so throw here
                });

                // Log header
                LogAll("==============");
                LogAll($"Started at {DateTime.Now}");

                // Refuse to mirror without a guard file
                foreach (var task in tasks)
                {
                    if (!File.Exists(task.ToGuard) || !File.ReadAllText(task.ToGuard).ToLower().Contains("allow"))
                    {
                        LogError($"Target path is not marked with a guard file: {task.ToPath}");
                        LogError($"Due to the potentially destructive nature of mirroring, every mirror destination must contain a guard file. This path does not. Mirroring aborted.");
                        LogError($"To allow mirroring to this path, please create a file at {task.ToGuard}. The file must contain the word “allow”.");
                        LogError($"Remember that HoboMirror will delete files at this path without confirmation.");
                        return(-1);
                    }
                }

                // Enable the necessary privilege to read and write everything
                try
                {
                    WinAPI.ModifyPrivilege(PrivilegeName.SeBackupPrivilege, true);
                    WinAPI.ModifyPrivilege(PrivilegeName.SeRestorePrivilege, true);
                    //WinAPI.ModifyPrivilege(PrivilegeName.SeSecurityPrivilege, true);
                    //WinAPI.ModifyPrivilege(PrivilegeName.SeTakeOwnershipPrivilege, true);
                }
                catch (Win32Exception e)
                {
                    LogError("Unable to obtain the necessary privileges. Some files and/or attributes will not be replicated.");
                    LogError(e.Message);
                }

                // Perform the mirroring
                var volumes = tasks.GroupBy(t => t.FromVolume).Select(g => g.Key).ToArray();
                using (var vsc = UseVolumeShadowCopy ? new VolumeShadowCopy(volumes) : null)
                {
                    var vscVolumes = UseVolumeShadowCopy ? vsc.Volumes : new ReadOnlyDictionary <string, VolumeShadowCopyVol>(volumes.ToDictionary(vol => vol, vol => new VolumeShadowCopyVol {
                        Path = vol, SnapshotPath = vol
                    }));
                    foreach (var task in tasks)
                    {
                        var fromPath = Path.Combine(vscVolumes[task.FromVolume].SnapshotPath, task.FromPath.Substring(task.FromVolume.Length));
                        LogAll($"    Mirror task: from “{task.FromPath}” to “{task.ToPath}” (volume snapshot path: {fromPath})");
                    }
                    foreach (var ignore in Args.IgnorePath.Concat(Settings.IgnorePaths).Order())
                    {
                        LogAll($"    Ignore path: “{ignore}”");
                    }
                    foreach (var ignore in Settings.IgnoreDirNames)
                    {
                        LogAll($"    Ignore directory name: “{ignore}”");
                    }

                    foreach (var task in tasks)
                    {
                        GetOriginalSrcPath = str => str.Replace(vscVolumes[task.FromVolume].SnapshotPath, task.FromVolume).Replace(@"\\", @"\");
                        if (!Directory.Exists(task.ToPath))
                        {
                            ActCreateDirectory(task.ToPath);
                        }
                        var srcItem = new Item(new DirectoryInfo(Path.Combine(vscVolumes[task.FromVolume].SnapshotPath, task.FromPath.Substring(task.FromVolume.Length))), ItemType.Dir);
                        var tgtItem = CreateItem(new DirectoryInfo(task.ToPath));
                        if (tgtItem != null)
                        {
                            SyncDir(srcItem, tgtItem);
                        }
                        else
                        {
                            LogError($"Unable to execute mirror task: {task.FromPath}");
                        }
                    }
                }

                // List changed directories and update change counts
                LogChange("", null);
                LogChange("DIRECTORIES WITH AT LEAST ONE CHANGE:", null);
                if (Settings == null)
                {
                    foreach (var chg in ChangedDirs.Order())
                    {
                        LogChange("  " + chg, null);
                    }
                }
                else
                {
                    foreach (var dir in ChangedDirs)
                    {
                        Settings.DirectoryChangeCount[dir].TimesChanged++;
                    }
                    LogChange("(sorted from rarely changing to frequently changing)", null);
                    var changes =
                        from dir in ChangedDirs
                        let match = Settings.GroupDirectoriesForChangeReport.Select(dg => dg.GetMatch(dir)).Where(m => m != null).MinElementOrDefault(s => s.Length)
                                    group dir by match ?? dir into grp
                                    let changeCounts = grp.Select(p => Settings.DirectoryChangeCount[p])
                                                       select new { path = grp.Key, changeFreq = changeCounts.Sum(ch => ch.TimesChanged) / (double)changeCounts.Sum(ch => ch.TimesScanned) };
                    foreach (var chg in changes.OrderBy(ch => ch.changeFreq))
                    {
                        LogChange($"  {chg.path} — {chg.changeFreq:0.0%}", null);
                    }
                }

                if (RefreshAccessControl)
                {
                    Settings.LastRefreshAccessControl = DateTime.UtcNow;
                }

                // Save settings file
                if (Args.SettingsPath != null)
                {
                    ClassifyJson.SerializeToFile(Settings, Args.SettingsPath);
                }

                return(CriticalErrors > 0 ? 2 : Errors > 0 ? 1 : 0);
            }
#if !DEBUG
            catch (Exception e)
            {
                LogCriticalError($"Unhandled exception ({e.GetType().Name}): {e.Message}");
                LogCriticalError(e.StackTrace);
                return(1);
            }
#endif
            finally
            {
                // Close log files
                if (Args.LogPath != null)
                {
                    foreach (var log in new[] { ActionLog, ChangeLog, ErrorLog, CriticalErrorLog, DebugLog })
                    {
                        log.WriteLine($"Ended at {DateTime.Now}. Time taken: {(DateTime.UtcNow - startTime).TotalMinutes:#,0.0} minutes");
                        log.Dispose();
                    }
                }
            }
        }
コード例 #6
0
        private HttpResponse processPost(HttpRequest req)
        {
            switch (req.Post["fnc"].Value)
            {
            case "create":
                var items  = req.Post["items"].Value.Replace("\r", "").Trim().Split('\n').Select(line => line.Trim()).ToArray();
                var hash   = MD5.Create().ComputeHash(items.JoinString("\n").ToUtf8()).ToHex();
                var newSet = new RankSet {
                    Hash = hash, Items = items, Name = req.Post["title"].Value
                };
                if (!_setsDic.ContainsKey(hash))
                {
                    lock (this)
                        if (!_setsDic.ContainsKey(hash))
                        {
                            var newSetSlim = newSet.ToSlim();
                            _setsDic[hash] = newSetSlim;
                            _setsList.Add(newSetSlim);
                            ClassifyJson.SerializeToFile(newSet, setPath(hash));
                        }
                }
                return(HttpResponse.Redirect(req.Url.WithQuery("set", hash)));

            case "start":
                lock (this)
                {
                    var currentSetHash = req.Post["set"].Value;
                    var setFilePath    = setPath(currentSetHash);
                    if (!File.Exists(setFilePath))
                    {
                        return(HttpResponse.PlainText("That set does not exist.", HttpStatusCode._404_NotFound));
                    }
                    var currentSet = ClassifyJson.DeserializeFile <RankSet>(setFilePath);

retry:
                    var publicToken = Rnd.GenerateString(32);
                    var privateToken = Rnd.GenerateString(32);
                    var path         = rankingPath(publicToken);
                    if (File.Exists(path) || currentSet.DicRankings.ContainsKey(publicToken))
                    {
                        goto retry;
                    }
                    var newRanking = new RankRanking {
                        Finished = false, PublicToken = publicToken, PrivateToken = privateToken, SetHash = currentSetHash, Title = req.Post["title"].Value, Question = req.Post["question"].Value
                    };
                    var newRankingSlim = newRanking.ToSlim();
                    currentSet.DicRankings[publicToken] = newRankingSlim;
                    currentSet.ListRankings.Add(newRankingSlim);
                    ClassifyJson.SerializeToFile(newRanking, path);
                    ClassifyJson.SerializeToFile(currentSet, setFilePath);
                    return(HttpResponse.Redirect(req.Url.WithoutQuery().WithQuery("ranking", publicToken).WithQuery("secret", privateToken)));
                }

            case "rank":
                lock (this)
                {
                    var publicToken     = req.Post["ranking"].Value;
                    var privateToken    = req.Post["secret"].Value;
                    var rankingFilePath = rankingPath(publicToken);
                    if (!File.Exists(rankingFilePath))
                    {
                        return(HttpResponse.PlainText("That ranking does not exist.", HttpStatusCode._404_NotFound));
                    }
                    var currentRanking = ClassifyJson.DeserializeFile <RankRanking>(rankingFilePath);
                    if (privateToken != currentRanking.PrivateToken)
                    {
                        return(HttpResponse.PlainText("You cannot vote in this ranking.", HttpStatusCode._404_NotFound));
                    }

                    var setFilePath = setPath(currentRanking.SetHash);
                    if (!File.Exists(setFilePath))
                    {
                        return(HttpResponse.PlainText("That set does not exist.", HttpStatusCode._404_NotFound));
                    }
                    var currentSet = ClassifyJson.DeserializeFile <RankSet>(setFilePath);

                    if (!int.TryParse(req.Post["ix1"].Value, out var ix1) || !int.TryParse(req.Post["ix2"].Value, out var ix2) || !int.TryParse(req.Post["more"].Value, out var more) || (more != ix1 && more != ix2))
                    {
                        return(HttpResponse.PlainText("Invalid integers.", HttpStatusCode._404_NotFound));
                    }

                    var newComparison = new RankComparison(more == ix1 ? ix2 : ix1, more == ix1 ? ix1 : ix2);

                    // Transitive closure
                    var ancestorLesses = currentRanking.Comparisons.Where(c => c.More == newComparison.Less).Select(c => c.Less).ToList();
                    ancestorLesses.Add(newComparison.Less);
                    var descendantMores = currentRanking.Comparisons.Where(c => c.Less == newComparison.More).Select(c => c.More).ToList();
                    descendantMores.Add(newComparison.More);
                    for (int i = 0; i < ancestorLesses.Count; i++)
                    {
                        for (int j = 0; j < descendantMores.Count; j++)
                        {
                            currentRanking.Comparisons.Add(new RankComparison(ancestorLesses[i], descendantMores[j]));
                        }
                    }

                    var result = attemptRanking(currentRanking, currentSet);
                    if (result.ix1 == -1)
                    {
                        currentRanking.Finished = true;

                        // This relies on reference equality, i.e. that currentSet.ListRankings contains the same object
                        currentSet.DicRankings[publicToken].Finished = true;

                        ClassifyJson.SerializeToFile(currentSet, setFilePath);
                    }
                    ClassifyJson.SerializeToFile(currentRanking, rankingFilePath);

                    return(HttpResponse.Redirect(req.Url.WithoutQuery().WithQuery("ranking", publicToken).WithQuery("secret", privateToken)));
                }
            }

            return(HttpResponse.PlainText("What?", HttpStatusCode._500_InternalServerError));
        }
コード例 #7
0
        private static void GenerateNumerals()
        {
            var oldNumberData = new Dictionary<string, double>();
            try { oldNumberData = ClassifyJson.DeserializeFile<Dictionary<string, double>>(@"D:\temp\TheClockNumberData.json"); } catch { }

            var numberData = new Dictionary<string, double>()
            {
                { "AAgency FB", 1.2 },
                { "RAgency FB", 1.0 },
                { "ABaskerville Old Face|.1|.09", 1.2 },
                { "RBaskerville Old Face", 0.7 },
                { "ABodoni MT Condensed|.07|.06", 1.6 },
                { "RBodoni MT Condensed", 1.2 },
                { "ACentury|.11|.1", 1.1 },
                { "RCentury", 0.7 },
                { "ACentury Gothic|.1|.07", 1.1 },
                { "RCentury Gothic", 0.9 },
                { "AHarrington|.09|.06", 1.4 },
                { "RCopperplate Gothic Light", 0.9 },
                { "AEdwardian Script ITC|.09|.06", 1.4 },
                { "RDejaVu Serif", 0.7 },
                { "AFelix Titling", 1.25 },
                { "RFelix Titling", 0.85 },
                { "AGill Sans MT Ext Condensed Bold", 1.4 },
                { "RGill Sans MT Ext Condensed Bold", 1.1 },
                { "AJokerman", 0.9 },
                { "RKlotz", 0.943 },
                { "AModern No. 20|.1|.08", 1.27 },
                { "RModern No. 20", 0.7 },
                { "ANiagara Solid", 1.6 },
                { "RNiagara Solid", 1.35 },
                { "AOld English Text MT|.1|.075", 1.2 },
                { "ROstrich Sans Heavy", 1.15 },
                { "AOnyx", 1.5 },
                { "ROnyx", 1.136 },
                { "AP22 Johnston Underground|.08|.05", 1.5 },
                { "RP22 Johnston Underground", 0.9 },
                { "AParchment", 2.75 },
                { "APoor Richard", 1.184 },
                { "RPoor Richard", 0.85 },
                { "AProxima Nova ExCn Th|.06|.05", 1.6 },
                { "RProxima Nova ExCn Th", 1.2 },
                { "AStencil|.11|.09", 1.0 },
                { "RStencil", 0.8 },
                { "AVladimir Script|.08|.06", 1.25 },
                { "RBauhaus 93", 0.9 }
            };
            var indexes = new Dictionary<string, int>();
            var arabicIx = 0;
            var romanIx = 0;
            foreach (var key in numberData.Keys)
                if (key.StartsWith("A"))
                    indexes[key] = arabicIx++;
                else
                    indexes[key] = romanIx++;

            numberData.ParallelForEach(1, kvp =>
            {
                if (oldNumberData != null && oldNumberData.ContainsKey(kvp.Key) && kvp.Value == oldNumberData[kvp.Key])
                    return;
                var arabic = kvp.Key.StartsWith("A");
                var fontFamily = kvp.Key.Substring(1);
                double[] spacing = null;
                var pieces = fontFamily.Split('|');
                if (pieces.Length == 3)
                {
                    fontFamily = pieces[0];
                    spacing = pieces.Skip(1).Select(double.Parse).ToArray();
                }
                var factor = kvp.Value;
                var objName = $"{(arabic ? "Arabic" : "Roman")}{indexes[kvp.Key]}";

                File.WriteAllText($@"D:\c\KTANE\TheClock\Assets\Models\{objName}.obj", GenerateObjFile(Numbers(fontFamily, arabic, factor, spacing), objName));
                lock (indexes)
                    Console.WriteLine($"{fontFamily} {(arabic ? "Arabic" : "Roman")} done");
            });

            ClassifyJson.SerializeToFile(numberData, @"D:\temp\TheClockNumberData.json");
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: Timwi/Kyudosudoku
        private static void RunStatistics()
        {
            var lockObj              = new object();
            var seedCounter          = 1000;
            var stats                = new Dictionary <string, int>();
            var arrowLengthStats     = new Dictionary <int, int>();
            var inclusionNumStats    = new Dictionary <int, int>();
            var killerCageSizeStats  = new Dictionary <int, int>();
            var killerCageSumStats   = new Dictionary <int, int>();
            var renbanCageSizeStats  = new Dictionary <int, int>();
            var palindromeSizeStats  = new Dictionary <int, int>();
            var thermometerSizeStats = new Dictionary <int, int>();
            var cappedLineSizeStats  = new Dictionary <int, int>();

            //var json = JsonValue.Parse(File.ReadAllText(@"D:\temp\kyudo-stats.json"));
            //var strings = @"AntiBishop,AntiKing,AntiKnight,NoConsecutive,OddEven,,,Arrow,KillerCage,Palindrome,RenbanCage,Snowball,Thermometer,,,Battlefield,Binairo,Sandwich,Skyscraper,ToroidalSandwich,XSum,,,Battenburg,Clockface,ConsecutiveNeighbors,DoubleNeighbors,Inclusion,LittleKiller".Split(',');
            //Clipboard.SetText(strings.Select(s => string.IsNullOrWhiteSpace(s) ? "" : json["Stats"][s].GetInt().ToString()).JoinString("\n"));
            //return;

            Enumerable.Range(0, Environment.ProcessorCount).ParallelForEach(proc =>
            {
                var seed = 0;
                while (true)
                {
                    lock (lockObj)
                    {
                        seed = seedCounter++;
                        Console.WriteLine($"Generating {seed}");
                    }
                    var puzzle = Kyudosudoku.Generate(seed);
                    lock (lockObj)
                    {
                        foreach (var constr in puzzle.Constraints)
                        {
                            stats.IncSafe(constr.GetType().Name);
                            if (constr is Arrow a)
                            {
                                arrowLengthStats.IncSafe(a.Cells.Length - 1);
                            }
                            if (constr is Inclusion i)
                            {
                                inclusionNumStats.IncSafe(i.Digits.Length);
                            }
                            if (constr is KillerCage kc)
                            {
                                killerCageSizeStats.IncSafe(kc.Cells.Length); killerCageSumStats.IncSafe(kc.Sum ?? -1);
                            }
                            if (constr is RenbanCage rc)
                            {
                                renbanCageSizeStats.IncSafe(rc.Cells.Length);
                            }
                            if (constr is Palindrome p)
                            {
                                palindromeSizeStats.IncSafe(p.Cells.Length);
                            }
                            if (constr is Thermometer t)
                            {
                                thermometerSizeStats.IncSafe(t.Cells.Length);
                            }
                            if (constr is CappedLine cl)
                            {
                                cappedLineSizeStats.IncSafe(cl.Cells.Length);
                            }
                        }
                        ClassifyJson.SerializeToFile(new
                        {
                            Stats               = stats,
                            ArrowLengths        = arrowLengthStats,
                            InclusionNums       = inclusionNumStats,
                            KillerCageSizes     = killerCageSizeStats,
                            KillerCageSums      = killerCageSumStats,
                            RenbanCageSizes     = renbanCageSizeStats,
                            PalindromeSizes     = palindromeSizeStats,
                            ThermometerSizes    = thermometerSizeStats,
                            CappedLineSizeStats = cappedLineSizeStats
                        }, @"D:\temp\kyudo-stats.json");
                    }
                }
            });
        }