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); }
// 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); }
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)); }
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; }
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(); } } } }
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)); }
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"); }
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"); } } }); }