-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathGenerateJson.cs
More file actions
108 lines (102 loc) · 5.45 KB
/
Copy pathGenerateJson.cs
File metadata and controls
108 lines (102 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using RT.Json;
using RT.Serialization;
using RT.Servers;
using RT.Util;
using RT.Util.ExtensionMethods;
namespace KtaneWeb
{
public sealed partial class KtanePropellerModule
{
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(DescriptionInfo[]))
f.SetValue(obj, ClassifyJson.Deserialize<DescriptionInfo[]>(val));
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.");
if (m.Contributors != null)
m.Author = null;
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());
}
}
}