private void ensureModuleInfoCache() { if (_moduleInfoCache == null) { lock (this) if (_moduleInfoCache == null) { const int cols = 20; // number of icons per row const int w = 32; // width of an icon in pixels const int h = 32; // height of an icon in pixels var iconFiles = new DirectoryInfo(_config.ModIconDir).EnumerateFiles("*.png", SearchOption.TopDirectoryOnly).OrderBy(file => file.Name != "blank.png").ToArray(); var rows = (iconFiles.Length + cols - 1) / cols; var coords = new Dictionary <string, (int x, int y)>(); using (var bmp = new Bitmap(w * cols, h * rows)) { using (var g = Graphics.FromImage(bmp)) { for (int i = 0; i < iconFiles.Length; i++) { using (var icon = new Bitmap(iconFiles[i].FullName)) g.DrawImage(icon, w * (i % cols), h * (i / cols)); coords.Add(Path.GetFileNameWithoutExtension(iconFiles[i].Name), (i % cols, i / cols)); } } using (var mem = new MemoryStream()) { bmp.Save(mem, ImageFormat.Png); _moduleInfoCache = new ModuleInfoCache { IconSpritePng = mem.ToArray() }; _moduleInfoCache.IconSpriteMd5 = MD5.Create().ComputeHash(_moduleInfoCache.IconSpritePng).ToHex(); var modules = new DirectoryInfo(_config.ModJsonDir) .EnumerateFiles("*.json", SearchOption.TopDirectoryOnly) .ParallelSelect(4, file => { try { var origFile = File.ReadAllText(file.FullName); var modJson = JsonDict.Parse(origFile); var mod = ClassifyJson.Deserialize <KtaneModuleInfo>(modJson); #if DEBUG var newJson = (JsonDict)ClassifyJson.Serialize(mod); var newJsonStr = newJson.ToStringIndented(); if (newJsonStr != origFile) { File.WriteAllText(file.FullName, newJsonStr); } modJson = newJson; #endif return((modJson, mod, file.LastWriteTimeUtc).Nullable()); }
private object translate(Type targetType, JsonValue value) { var remoteId = value.Safe[":remoteid"].GetIntSafe(); if (remoteId != null) { return(new proxy(targetType, _url, remoteId.Value).GetTransparentProxy()); } return(ClassifyJson.Deserialize(targetType, value)); }
private void openCore(string filePath) { if (!File.Exists(filePath)) { DlgMessage.Show("The specified file does not exist.", "Error", DlgType.Error); return; } _currentFilePath = filePath; _file = ClassifyJson.Deserialize <HCFile>(JsonValue.Parse(File.ReadAllText(_currentFilePath))); _anyChanges = false; // _lastFileTime = File.GetLastWriteTimeUtc(_currentFilePath); updateList(); rerender(); }
public override void Init(LoggerBase log) { 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; }
public override IMessage Invoke(IMessage rawMsg) { var msg = (IMethodCallMessage)rawMsg; var method = msg.MethodBase as MethodInfo; var args = msg.Args; if (method == null || args == null) { throw new InternalErrorException("The transparent proxy received an invalid message."); } var parameters = method.GetParameters(); var hArgs = new List <HArg> { new HArg("Method", mangledMethodName(method)), new HArg("Arguments", new JsonList(args.Select((arg, i) => parameters[i].IsOut ? null : arg is Delegate ? new JsonDict { { ":delegate", true } } : ClassifyJson.Serialize(parameters[i].ParameterType, arg)))) }; if (_objectId != -1) { hArgs.Add(new HArg("ObjectID", _objectId)); } var responseRaw = _client.Post(_url, hArgs.ToArray()); var response = ClassifyJson.Deserialize <CommunicatorResult>(responseRaw.DataJson); var responseRet = response as CommunicatorResultReturn; if (responseRet != null) { var refOut = Enumerable.Range(0, parameters.Length) .Where(i => parameters[i].ParameterType.IsByRef) .Select(i => translate(parameters[i].ParameterType.GetElementType(), responseRet.RefOutArguments[i])) .ToArray(); return(new ReturnMessage( translate(method.ReturnType, responseRet.ReturnValue), refOut, refOut.Length, msg.LogicalCallContext, msg)); } throw new NotImplementedException(); }
void IPropellerModule.Init(LoggerBase log, JsonValue settings, ISettingsSaver saver) { SettingsSaver = saver; Log = log; try { Settings = ClassifyJson.Deserialize <TSettings>(settings) ?? new TSettings(); } catch (Exception e) { Log.Exception(e); Settings = new TSettings(); } SaveSettings(); Init(); }
public static void DoGraph() { const string name = "Candidate 1"; //* var graphJson = GenerateGraph(); File.WriteAllText($@"D:\temp\Colored Switches\{name}.json", graphJson.ToStringIndented()); /*/ * var graphJson = JsonValue.Parse(File.ReadAllText($@"D:\temp\Colored Switches\{name}.json")); * /**/ var edges = ClassifyJson.Deserialize <List <Edge> >(graphJson); var nodes = edges.Select(e => e.To).Distinct().ToArray(); var edgesFrom = nodes.ToDictionary(node => node, node => new List <Edge>()); foreach (var node in nodes) { edgesFrom[node] = edges.Where(e => e.From == node).ToList(); } var covered = new bool[_numSwitches]; foreach (var edge in edges) { var b = edge.From.SwitchStates ^ edge.To.SwitchStates; var bit = 0; while (b > 1) { bit++; b >>= 1; } if (covered[bit]) { continue; } if (Enumerable.Range(0, _numColors).All(c => edges.Any(e => e.Color == c && e.From == edge.From && e.To == edge.To))) { continue; } covered[bit] = true; } Console.WriteLine(covered.JoinString(", ")); Console.WriteLine(nodes.Select(n => $"{n.SwitchStates}={edgesFrom[n].Select(e => $"{e.Color}>{e.To.SwitchStates}").JoinString("|")}").JoinString("\n")); //JsonGraphToGraphML(graphJson, name); }
/// <summary> /// Constructs a new instance of <see cref="AjaxHandler{TApi}"/>.</summary> /// <param name="options"> /// Specifies <see cref="AjaxHandler{TApi}"/>’s exception behaviour.</param> public AjaxHandler(AjaxHandlerOptions options = AjaxHandlerOptions.ReturnExceptionsWithoutMessages) { _apiFunctions = new Dictionary <string, Func <HttpRequest, TApi, JsonValue> >(); _options = options; var typeContainingAjaxMethods = typeof(TApi); foreach (var method in typeContainingAjaxMethods.GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(m => m.IsDefined <AjaxMethodAttribute>())) { var parameters = method.GetParameters(); var returnType = method.ReturnType; _apiFunctions.Add(method.Name, (req, api) => { JsonDict json; var rawJson = req.Post["data"].Value; try { json = JsonDict.Parse(rawJson); } catch (Exception e) { throw new AjaxInvalidParameterDataException(rawJson, e); } var arr = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { var paramName = parameters[i].Name; if (parameters[i].IsOptional && !json.ContainsKey(paramName)) { arr[i] = parameters[i].DefaultValue; } else { try { arr[i] = ClassifyJson.Deserialize(parameters[i].ParameterType, json[paramName]); } catch (Exception e) { throw new AjaxInvalidParameterException(paramName, e); } } } object result; try { result = method.Invoke(api, arr); } catch (Exception e) { throw new AjaxException("Error invoking the AJAX method.", e); } if (result is JsonValue) { return((JsonValue)result); } try { return(ClassifyJson.Serialize(returnType, result)); } catch (Exception e) { throw new AjaxInvalidReturnValueException(result, returnType, e); } }); } }
// 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); }
private ModuleInfoCache getModuleInfoCache() { ModuleInfoCache mic = null; do { if (_moduleInfoCache == null) { lock (this) if (_moduleInfoCache == null) { const int cols = 20; // number of icons per row const int w = 32; // width of an icon in pixels const int h = 32; // height of an icon in pixels var iconFiles = new DirectoryInfo(Path.Combine(_config.BaseDir, "Icons")).EnumerateFiles("*.png", SearchOption.TopDirectoryOnly).OrderBy(file => file.Name != "blank.png").ToArray(); var rows = (iconFiles.Length + cols - 1) / cols; var coords = new Dictionary <string, (int x, int y)>(); using var bmp = new Bitmap(w * cols, h * rows); using (var g = Graphics.FromImage(bmp)) { for (int i = 0; i < iconFiles.Length; i++) { using (var icon = new Bitmap(iconFiles[i].FullName)) g.DrawImage(icon, w * (i % cols), h * (i / cols)); coords.Add(Path.GetFileNameWithoutExtension(iconFiles[i].Name), (i % cols, i / cols)); } } using var mem = new MemoryStream(); bmp.Save(mem, ImageFormat.Png); // This needs to be a separate variable (don’t use _moduleInfoCache itself) because that field needs to stay null until it is fully initialized var moduleInfoCache = new ModuleInfoCache { IconSpritePng = mem.ToArray() }; moduleInfoCache.IconSpriteMd5 = MD5.Create().ComputeHash(moduleInfoCache.IconSpritePng).ToHex(); // Load TP data from the spreadsheet JsonList entries; try { entries = new HClient().Get("https://spreadsheets.google.com/feeds/list/1G6hZW0RibjW7n72AkXZgDTHZ-LKj0usRkbAwxSPhcqA/1/public/values?alt=json").DataJson["feed"]["entry"].GetList(); } catch (Exception e) { Log.Exception(e); entries = new JsonList(); } var moduleLoadExceptions = new JsonList(); var modules = new DirectoryInfo(Path.Combine(_config.BaseDir, "JSON")) .EnumerateFiles("*.json", SearchOption.TopDirectoryOnly) .ParallelSelect(Environment.ProcessorCount, file => { try { var origFile = File.ReadAllText(file.FullName); var modJson = JsonDict.Parse(origFile); var mod = ClassifyJson.Deserialize <KtaneModuleInfo>(modJson); #if DEBUG var newJson = (JsonDict)ClassifyJson.Serialize(mod); var newJsonStr = newJson.ToStringIndented(); if (newJsonStr != origFile) { File.WriteAllText(file.FullName, newJsonStr); } modJson = newJson;
private HttpResponse generateJson(HttpRequest req) { if (req.Method != HttpMethod.Post) { return(HttpResponse.PlainText("Only POST requests allowed.", HttpStatusCode._405_MethodNotAllowed)); } void populateObject(object obj, Type type) { foreach (var f in type.GetFields()) { var attr = f.GetCustomAttribute <EditableFieldAttribute>(); if (attr == null) { continue; } var fType = f.FieldType; if (f.FieldType.TryGetGenericParameters(typeof(Nullable <>), out var fTypes)) { fType = fTypes[0]; } var val = req.Post[f.Name].Value; try { if (f.GetCustomAttribute <EditableNestedAttribute>() != null) { if (val != "on") { f.SetValue(obj, null); } else { var nestedObj = Activator.CreateInstance(f.FieldType); populateObject(nestedObj, f.FieldType); f.SetValue(obj, nestedObj); } continue; } if (fType == typeof(string)) { f.SetValue(obj, string.IsNullOrWhiteSpace(val) ? null : val.Trim()); } else if (fType.IsEnum) { var enumVal = val == null ? null : Enum.Parse(fType, val); if (enumVal != null) { f.SetValue(obj, enumVal); } } else if (fType == typeof(DateTime)) { f.SetValue(obj, DateTime.ParseExact(val, "yyyy-MM-dd", null)); } else if (fType == typeof(string[])) { f.SetValue(obj, val.Split(';').Select(str => str.Trim()).ToArray()); } else if (fType == typeof(int)) { f.SetValue(obj, string.IsNullOrWhiteSpace(val) ? 0 : int.Parse(val)); } else if (fType == typeof(decimal)) { f.SetValue(obj, string.IsNullOrWhiteSpace(val) ? 0m : decimal.Parse(val)); } else if (fType == typeof(bool)) { f.SetValue(obj, val == "on"); } else { throw new InvalidOperationException($"Unrecognized field type: {fType.FullName}"); } } catch (Exception e) { _logger.Warn($"Generate JSON: unrecognized value. Field: {f.Name}, Type: {fType}, Value: “{val ?? "<null>"}”, Exception: {e.Message} ({e.GetType().FullName})"); } } } var m = new KtaneModuleInfo(); populateObject(m, typeof(KtaneModuleInfo)); var json = ClassifyJson.Serialize(m); // Now deserialize and then re-serialize this to force KtaneModuleInfo to perform some sanity things var m2 = ClassifyJson.Deserialize <KtaneModuleInfo>(json); return(HttpResponse.PlainText(ClassifyJson.Serialize(m2).ToStringIndented())); }
public bool IsSolved(string json) { var state = JsonValue.Parse(json); var kyudokuGrids = KyudokuGrids.Split(36).Select(grid => grid.Select(ch => ch - '0').ToArray()).ToArray(); var constraints = Constraints == null ? new SvgConstraint[0] : ClassifyJson.Deserialize <SvgConstraint[]>(JsonValue.Parse(Constraints)); // Check that all cells in the Sudoku grid have a digit var sudokuDigits = new int[81]; for (int cell = 0; cell < 81; cell++) { var kyCells = Enumerable.Range(0, 4) .Where(c => cell % 9 >= 3 * (c % 2) && cell % 9 < 6 + 3 * (c % 2) && cell / 9 >= 3 * (c / 2) && cell / 9 < 6 + 3 * (c / 2)) .Select(c => (corner: c, kyCell: cell % 9 - 3 * (c % 2) + 6 * ((cell / 9) - 3 * (c / 2)))) .Where(inf => state["circledDigits"][inf.corner][inf.kyCell].Apply(v => v != null && v.GetBool())) .ToArray(); if (kyCells.Length > 1 && kyCells.Any(inf => kyudokuGrids[inf.corner][inf.kyCell] != kyudokuGrids[kyCells[0].corner][kyCells[0].kyCell])) { return(false); } else if (kyCells.Length >= 1) { sudokuDigits[cell] = kyudokuGrids[kyCells[0].corner][kyCells[0].kyCell]; } else if (state["enteredDigits"][cell] != null) { sudokuDigits[cell] = state["enteredDigits"][cell].GetInt(); } else { return(false); } } // Check the Sudoku rules (rows, columns and regions) for (var i = 0; i < 9; i++) { for (var colA = 0; colA < 9; colA++) { for (var colB = colA + 1; colB < 9; colB++) { if (sudokuDigits[colA + 9 * i] == sudokuDigits[colB + 9 * i]) { return(false); } } } for (var rowA = 0; rowA < 9; rowA++) { for (var rowB = rowA + 1; rowB < 9; rowB++) { if (sudokuDigits[i + 9 * rowA] == sudokuDigits[i + 9 * rowB]) { return(false); } } } for (var cellA = 0; cellA < 9; cellA++) { for (var cellB = cellA + 1; cellB < 9; cellB++) { if (sudokuDigits[cellA % 3 + 3 * (i % 3) + 9 * ((cellA / 3) + 3 * (i / 3))] == sudokuDigits[cellB % 3 + 3 * (i % 3) + 9 * ((cellB / 3) + 3 * (i / 3))]) { return(false); } } } } // Check the Sudoku constraints foreach (var constr in constraints) { if (!constr.Verify(sudokuDigits)) { return(false); } } // Check all of the Kyudokus for (var corner = 0; corner < 4; corner++) { var digitCounts = new int[9]; var rowSums = new int[6]; var colSums = new int[6]; for (var cell = 0; cell < 36; cell++) { if (state["circledDigits"][corner][cell].Apply(v => v != null && v.GetBool())) { digitCounts[kyudokuGrids[corner][cell] - 1]++; rowSums[cell / 6] += kyudokuGrids[corner][cell]; colSums[cell % 6] += kyudokuGrids[corner][cell]; } } if (rowSums.Any(r => r > 9) || colSums.Any(c => c > 9) || digitCounts.Any(c => c != 1)) { return(false); } } return(true); }
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; }
private void ensureModuleInfoCache() { if (_moduleInfoCache == null) { lock (this) if (_moduleInfoCache == null) { const int cols = 20; // number of icons per row const int w = 32; // width of an icon in pixels const int h = 32; // height of an icon in pixels var iconFiles = new DirectoryInfo(_config.ModIconDir).EnumerateFiles("*.png", SearchOption.TopDirectoryOnly).OrderBy(file => file.Name != "blank.png").ToArray(); var rows = (iconFiles.Length + cols - 1) / cols; var coords = new Dictionary <string, (int x, int y)>(); using var bmp = new Bitmap(w * cols, h * rows); using (var g = Graphics.FromImage(bmp)) { for (int i = 0; i < iconFiles.Length; i++) { using (var icon = new Bitmap(iconFiles[i].FullName)) g.DrawImage(icon, w * (i % cols), h * (i / cols)); coords.Add(Path.GetFileNameWithoutExtension(iconFiles[i].Name), (i % cols, i / cols)); } } using var mem = new MemoryStream(); bmp.Save(mem, ImageFormat.Png); _moduleInfoCache = new ModuleInfoCache { IconSpritePng = mem.ToArray() }; _moduleInfoCache.IconSpriteMd5 = MD5.Create().ComputeHash(_moduleInfoCache.IconSpritePng).ToHex(); // Load TP data from the spreadsheet JsonList entries; try { entries = new HClient().Get("https://spreadsheets.google.com/feeds/list/1WEzVOKxOO5CDGoqAHjJKrC-c-ZGgsTPRLXBCs8RrAwU/1/public/values?alt=json").DataJson["feed"]["entry"].GetList(); } catch (Exception e) { _logger.Exception(e); entries = new JsonList(); } var modules = new DirectoryInfo(_config.ModJsonDir) .EnumerateFiles("*.json", SearchOption.TopDirectoryOnly) .ParallelSelect(4, file => { try { var origFile = File.ReadAllText(file.FullName); var modJson = JsonDict.Parse(origFile); var mod = ClassifyJson.Deserialize <KtaneModuleInfo>(modJson); #if DEBUG var newJson = (JsonDict)ClassifyJson.Serialize(mod); var newJsonStr = newJson.ToStringIndented(); if (newJsonStr != origFile) { File.WriteAllText(file.FullName, newJsonStr); } modJson = newJson;
void IPropellerModule.Init(LoggerBase log, JsonValue settings, ISettingsSaver saver) { _log = log; _saver = saver; _settings = ClassifyJson.Deserialize <Settings>(settings) ?? new Settings(); var validPaths = new List <string>(); foreach (var path in _settings.Paths) { if (!Directory.Exists(path)) { _log.Warn(@"DocGen: Warning: The folder ""{0}"" specified in the settings does not exist. Ignoring path.".Fmt(path)); } else { validPaths.Add(path); } } _settings.Paths = validPaths.ToArray(); saver.SaveSettings(ClassifyJson.Serialize(_settings)); string copyToPath = null; if (_settings.DllTempPath != null) { // Try to clean up old folders we've created before var tempPath = _settings.DllTempPath; Directory.CreateDirectory(tempPath); foreach (var path in Directory.GetDirectories(tempPath, "docgen-tmp-*")) { try { Directory.Delete(path, true); } catch { } } // Find a new folder to put the DLL files into int j = 1; copyToPath = Path.Combine(tempPath, "docgen-tmp-" + j); while (Directory.Exists(copyToPath)) { j++; copyToPath = Path.Combine(tempPath, "docgen-tmp-" + j); } Directory.CreateDirectory(copyToPath); } _docGen = new DocumentationGenerator(_settings.Paths, _settings.RequireAuthentication ? _settings.UsernamePasswordFile ?? "" : null, copyToPath); lock (_log) { _log.Info("DocGen initialised with {0} assemblies: {1}".Fmt(_docGen.AssembliesLoaded.Count, _docGen.AssembliesLoaded.JoinString(", "))); if (_docGen.AssemblyLoadErrors.Count > 0) { _log.Warn("{0} assembly load errors:".Fmt(_docGen.AssemblyLoadErrors.Count)); foreach (var tuple in _docGen.AssemblyLoadErrors) { _log.Warn("{0} error: {1}".Fmt(tuple.Item1, tuple.Item2)); } } } }
/// <summary> /// Creates an HTTP request handler that responds to requests from clients to execute methods on the specified factory /// object as well as any remote objects generated from it.</summary> /// <typeparam name="T"> /// The type containing the factory methods. If the client is going to access the factory methods via an interface, /// this should be that interface type rather than the concrete type of <paramref /// name="factoryInstance"/>.</typeparam> /// <param name="factoryInstance"> /// An instance that implements or derives from <typeparamref name="T"/> which provides the factory functionality to /// be accessed by clients.</param> /// <returns> /// An HTTP handler that can be used in <see cref="HttpServer"/> or <see cref="UrlResolver"/>.</returns> public static Func <HttpRequest, HttpResponse> CreateHandlerFromFactory <T>(T factoryInstance) { var thisType = typeof(T); var methods = new Dictionary <Type, Dictionary <string, MethodInfo> > { { thisType, getMethodDictionary(typeof(T)) } }; return(req => { if (req.Method != HttpMethod.Post) { throw new HttpException(HttpStatusCode._400_BadRequest, userMessage: "POST request expected."); } var objectId = req.Post["ObjectID"].Value.NullOr(Convert.ToInt32); var instance = objectId == null ? factoryInstance : _activeObjects[objectId.Value]; var type = objectId == null ? thisType : instance.GetType(); Dictionary <string, MethodInfo> methodDict; if (!methods.TryGetValue(type, out methodDict)) { methods[type] = methodDict = getMethodDictionary(type); } MethodInfo method; if (!methodDict.TryGetValue(req.Post["Method"].Value, out method)) { throw new HttpException(HttpStatusCode._400_BadRequest, userMessage: "The method does not exist."); } var parameters = method.GetParameters(); object[] arguments = new object[parameters.Length]; var argumentsRaw = JsonList.Parse(req.Post["Arguments"].Value); for (int i = 0; i < parameters.Length; i++) { if (parameters[i].IsOut) { continue; } var remoteId = argumentsRaw[i].Safe[":remoteid"].GetIntSafe(); if (remoteId != null) { lock (_activeObjects) arguments[i] = _activeObjects[remoteId.Value]; } else { // TODO: Delegates arguments[i] = ClassifyJson.Deserialize(parameters[i].ParameterType.IsByRef ? parameters[i].ParameterType.GetElementType() : parameters[i].ParameterType, argumentsRaw[i]); } } var returnValue = method.Invoke(instance, arguments); var process = Ut.Lambda((ParameterInfo param, object value) => { if (!param.IsDefined <RemoteAttribute>()) { return ClassifyJson.Serialize(param.ParameterType, value); } lock (_activeObjects) { var remoteId = _activeObjects.IndexOf(value); if (remoteId == -1) { remoteId = _activeObjects.Count; _activeObjects.Add(value); } return new JsonDict { { ":remoteid", remoteId } }; } }); var returnValueRaw = process(method.ReturnParameter, returnValue); for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType.IsByRef) { argumentsRaw[i] = process(parameters[i], arguments[i]); } else { argumentsRaw[i] = null; } } return HttpResponse.Json(ClassifyJson.Serialize <CommunicatorResult>(new CommunicatorResultReturn(returnValueRaw, argumentsRaw))); }); }
private HttpResponse PuzzlePage(HttpRequest req, DbSession session, Db db) { Match m; if ((m = Regex.Match(req.Url.Path, @"^/db-update/(\d+)$")).Success && req.Method == HttpMethod.Post) { return(dbUpdate(req, session, db, int.Parse(m.Groups[1].Value))); } var puzzleIdStr = req.Url.Path.Length == 0 ? "" : req.Url.Path.Substring(1); if (!int.TryParse(puzzleIdStr, out int puzzleId) || puzzleId < 0) { return(page404(req)); } var dbPuzzle = db.Puzzles.FirstOrDefault(p => p.PuzzleID == puzzleId); if (dbPuzzle == null || dbPuzzle.Invalid) { return(page404(req)); } var puzzle = new Kyudosudoku(dbPuzzle.KyudokuGrids.Split(36).Select(subgrid => subgrid.Select(ch => ch - '0').ToArray()).ToArray(), dbPuzzle.Constraints == null ? new SvgConstraint[0] : ClassifyJson.Deserialize <SvgConstraint[]>(JsonValue.Parse(dbPuzzle.Constraints))); var userPuzzle = session.User == null ? null : db.UserPuzzles.FirstOrDefault(up => up.UserID == session.User.UserID && up.PuzzleID == puzzleId); var extraTop = puzzle.Constraints.MaxOrDefault(c => c.ExtraTop, 0); var extraRight = puzzle.Constraints.MaxOrDefault(c => c.ExtraRight, 0); var extraLeft = puzzle.Constraints.MaxOrDefault(c => c.ExtraLeft, 0); var helpSvg = @"<g transform='translate(.05, .05) scale(.008)'> <path fill='#fcedca' stroke='black' stroke-width='2' d='M12.5 18.16h75v25h-75z'/> <text class='label' x='50' y='33.4' font-size='24' text-anchor='middle' transform='translate(0 5.66)'>???</text> <path fill='white' stroke='black' stroke-width='2' d='M53.238 33.237V73.17l9.513-9.513 7.499 18.106 5.272-2.184-7.38-17.818h13.62z'/> </g>"; var fillSvg = @"<text x='.45' y='.4' font-size='.25'>Auto</text><text x='.45' y='.65' font-size='.25' fill='hsl(217, 80%, 50%)'>123</text>"; var buttonsRight = Ut.NewArray <(string label, bool isSvg, string id, double width, int row)>(9, btn => ((btn + 1).ToString(), false, (btn + 1).ToString(), .9, 0)) .Concat(Ut.NewArray <(string label, bool isSvg, string id, double width, int row)>( ("Normal", false, "normal", 2.6, 1), ("Corner", false, "corner", 2.6, 1), ("Center", false, "center", 2.6, 1), (fillSvg, true, "fill", .9, 1), ("<path d='m 0.65,0.25 v 0.4 l -0.4,-0.2 z' />", true, "switch", .9, 2), ("Clear", false, "clear", 2.55, 2), ("Undo", false, "undo", 2.1, 2), ("Redo", false, "redo", 2.1, 2), (helpSvg, true, "help", .9, 2))); var buttonsLeft = Ut.NewArray <(string label, bool isSvg, string id, double width, int row)>(9, btn => ((btn + 1).ToString(), false, $"{btn + 1}-left", .85, 0)) .Concat(Ut.NewArray <(string label, bool isSvg, string id, double width, int row)>( ("Clear", false, "clear-left", 2.45, 1), ("Undo", false, "undo-left", 2.45, 1), ("Redo", false, "redo-left", 2.45, 1), ("<path d='m 0.25,0.25 v 0.4 l 0.4,-0.2 z' />", true, "switch-left", .9, 1))); string renderButton(string id, double x, double y, double width, string label, bool isSvg = false) => $@" <g class='button' id='{id}' transform='translate({x}, {y})'> <rect class='clickable' x='0' y='0' width='{width}' height='.9' stroke-width='.025' rx='.08' ry='.08'/> {(isSvg ? label : $"<text class='label' x='{width / 2}' y='.65' font-size='.55' text-anchor='middle'>{label}</text>")}
public static void JsonGraphToGraphML(JsonValue json, string filenamePart) { var edges = ClassifyJson.Deserialize <List <Edge> >(json); var nodes = edges.Select(e => e.To).Distinct().ToArray(); var edgesFrom = nodes.ToDictionary(node => node, node => new List <Edge>()); foreach (var node in nodes) { edgesFrom[node] = edges.Where(e => e.From == node).ToList(); } var xml = XElement.Parse(@"<graphml xmlns='http://graphml.graphdrawing.org/xmlns' xmlns:y='http://www.yworks.com/xml/graphml'> <key for='node' id='d6' yfiles.type='nodegraphics'/> <key for='edge' id='d10' yfiles.type='edgegraphics'/> <graph edgedefault='directed' id='G' /> </graphml>"); var g = xml.Elements().FirstOrDefault(e => e.Name.LocalName == "graph"); var nNode = XName.Get("node", g.Name.NamespaceName); var nEdge = XName.Get("edge", g.Name.NamespaceName); var nData = XName.Get("data", g.Name.NamespaceName); XName nm(string name) => XName.Get(name, "http://www.yworks.com/xml/graphml"); foreach (var node in nodes) { g.Add( new XElement(nNode, new XAttribute("id", "n" + node.SwitchStates), new XElement(nData, new XAttribute("key", "d6"), new XElement(nm("ShapeNode"), new XElement(nm("Geometry"), new XAttribute("height", "30"), new XAttribute("width", "45"), new XAttribute("x", "-15"), new XAttribute("y", "-15")), new XElement(nm("NodeLabel"), node.ToString()), new XElement(nm("Shape"), new XAttribute("type", "rectangle")))))); } var eIx = 0; var colorStrs = "#BB0000|#00AA00|#0000FF|#C000DD|#FF8800|#00D2EE".Split('|'); while (edges.Count > 0) { var sameNodes = edgesFrom[edges[0].From].Where(e => e.To == edges[0].To).ToArray(); if (sameNodes.Length == _numColors) { g.Add( new XElement(nEdge, new XAttribute("id", "e" + eIx), new XAttribute("source", "n" + edges[0].From.SwitchStates), new XAttribute("target", "n" + edges[0].To.SwitchStates), new XElement(nData, new XAttribute("key", "d10"), new XElement(nm("PolyLineEdge"), new XElement(nm("Arrows"), new XAttribute("source", "none"), new XAttribute("target", "standard")), new XElement(nm("LineStyle"), new XAttribute("color", "#000000"), new XAttribute("type", "line"), new XAttribute("width", "3.0")))))); edges.RemoveRange(sameNodes); } else { g.Add( new XElement(nEdge, new XAttribute("id", "e" + eIx), new XAttribute("source", "n" + edges[0].From.SwitchStates), new XAttribute("target", "n" + edges[0].To.SwitchStates), new XElement(nData, new XAttribute("key", "d10"), new XElement(nm("PolyLineEdge"), new XElement(nm("Arrows"), new XAttribute("source", "none"), new XAttribute("target", "standard")), new XElement(nm("LineStyle"), new XAttribute("color", colorStrs[edges[0].Color]), new XAttribute("type", "line"), new XAttribute("width", "1.0")))))); edges.RemoveAt(0); } eIx++; } File.WriteAllText($@"D:\temp\Colored Switches\{filenamePart}.graphml", xml.ToString()); }
private HttpResponse generateJson(HttpRequest req) { if (req.Method != HttpMethod.Post) { return(HttpResponse.PlainText("Only POST requests allowed.", HttpStatusCode._405_MethodNotAllowed)); } void populateObject(object obj, Type type) { foreach (var f in type.GetFields()) { var attr = f.GetCustomAttribute <EditableFieldAttribute>(); if (attr == null || attr.ReadableName == null) { continue; } var fType = f.FieldType; if (f.FieldType.TryGetGenericParameters(typeof(Nullable <>), out var fTypes)) { fType = fTypes[0]; } var val = req.Post[f.Name].Value; try { if (f.GetCustomAttribute <EditableNestedAttribute>() != null) { if (val != "on") { f.SetValue(obj, null); } else { var nestedObj = Activator.CreateInstance(f.FieldType); populateObject(nestedObj, f.FieldType); f.SetValue(obj, nestedObj); } continue; } if (fType == typeof(string)) { f.SetValue(obj, string.IsNullOrWhiteSpace(val) ? null : val.Trim()); } else if (fType.IsEnum && fType.GetCustomAttribute <FlagsAttribute>() != null) { var intVal = 0; foreach (var value in Enum.GetValues(fType)) { if (req.Post[$"{f.Name}-{value}"].Value != null) { intVal |= (int)value; } } f.SetValue(obj, intVal); } else if (fType.IsEnum) { var enumVal = val == null ? null : Enum.Parse(fType, val); if (enumVal != null) { f.SetValue(obj, enumVal); } } else if (fType == typeof(DateTime)) { f.SetValue(obj, DateTime.ParseExact(val, "yyyy-MM-dd", null)); } else if (fType == typeof(string[])) { f.SetValue(obj, val.Split(attr.AllowedSeparators).Select(str => str.Trim()).ToArray().Apply(list => list.Length == 0 || (list.Length == 1 && string.IsNullOrWhiteSpace(list[0])) ? null : list)); } else if (fType == typeof(Dictionary <string, string>)) { if (val.Trim() == "") { continue; } else if (!attr.AllowedDictSeparators.Any(sep => val.Contains(sep))) { f.SetValue(obj, new Dictionary <string, string>() { { attr.DefaultKey, string.IsNullOrWhiteSpace(val) ? null : val.Trim() } }); } else { f.SetValue(obj, val.Split(attr.AllowedSeparators).Select(str => str.Split(attr.AllowedDictSeparators)).ToDictionary(x => x[0].Trim(), x => x[1].Trim())); } } else if (fType == typeof(int)) { f.SetValue(obj, string.IsNullOrWhiteSpace(val) ? 0 : int.Parse(val)); } else if (fType == typeof(decimal)) { f.SetValue(obj, string.IsNullOrWhiteSpace(val) ? 0m : decimal.Parse(val)); } else if (fType == typeof(bool)) { f.SetValue(obj, val == "on"); } else if (fType == typeof(TutorialVideoInfo[])) { f.SetValue(obj, ClassifyJson.Deserialize <TutorialVideoInfo[]>(val)); } else { throw new InvalidOperationException($"Unrecognized field type: {fType.FullName}"); } } catch (Exception e) { Log.Warn($"Generate JSON: unrecognized value. Field: {f.Name}, Type: {fType}, Value: “{val ?? "<null>"}”, Exception: {e.Message} ({e.GetType().FullName})"); } } } var m = new KtaneModuleInfo(); populateObject(m, typeof(KtaneModuleInfo)); if (string.IsNullOrWhiteSpace(m.Name)) { return(HttpResponse.PlainText("You did not specify a module name.")); } var json = ClassifyJson.Serialize(m); // Now deserialize and then re-serialize this to force KtaneModuleInfo to perform some sanity things var m2 = ClassifyJson.Deserialize <KtaneModuleInfo>(json); return(HttpResponse.PlainText(ClassifyJson.Serialize(m2).ToStringIndented())); }