Validating the input of Json, against defined models and only parse them if the match

This commit is contained in:
BlubbFish 2021-08-29 00:46:11 +02:00
parent e90bd678c1
commit 00b228c008
8 changed files with 395 additions and 131 deletions

View File

@ -2,10 +2,13 @@
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using BlubbFish.Utils;
using BlubbFish.Utils.IoT.Bots;
using Fraunhofer.Fit.IoT.LoraMap.Model.JsonObjects;
using LitJson;
namespace Fraunhofer.Fit.IoT.LoraMap.Model.Admin {
@ -52,27 +55,33 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Admin {
}
}
Console.WriteLine("200 - Send names.json " + cont.Request.Url.PathAndQuery);
return Webserver.SendJsonResponse(ret, cont);
return cont.SendStringResponse(JsonMapper.ToJson(ret));
}
} else if(cont.Request.HttpMethod == "PUT") {
if(cont.Request.Url.AbsolutePath.Length > 16) {
String part = cont.Request.Url.AbsolutePath[16..];
if(this.datastorage.ContainsKey(part)) {
return this.SetJsonFile(cont, "json/" + this.datastorage[part].Item1 + ".json", this.datastorage[part].Item2);
return this.SetJsonFile(cont, part);
}
}
}
}
return Webserver.SendFileResponse(cont);
return cont.SendFileResponse();
}
private Boolean SetJsonFile(HttpListenerContext cont, String filename, String updatenotifier) {
private Boolean SetJsonFile(HttpListenerContext cont, String part) {
StreamReader reader = new StreamReader(cont.Request.InputStream, cont.Request.ContentEncoding);
String filename = "json/" + this.datastorage[part].Item1 + ".json";
String rawData = reader.ReadToEnd();
cont.Request.InputStream.Close();
reader.Close();
try {
_ = JsonMapper.ToObject(rawData);
JsonData json = JsonMapper.ToObject(rawData);
if(part == "name") {
if(!NamesModel.CheckJson(json)) {
throw new Exception("Check against model failed.");
}
}
} catch (Exception) {
Helper.WriteError("501 - Error recieving " + filename + ", no valid json " + cont.Request.Url.PathAndQuery);
cont.Response.StatusCode = 501;
@ -80,12 +89,12 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Admin {
}
File.WriteAllText(filename, rawData);
Console.WriteLine("200 - PUT " + filename + " " + cont.Request.Url.PathAndQuery);
this.GetEvent<AdminEvent>(updatenotifier)?.Invoke(this, new EventArgs());
this.GetEvent<AdminEvent>(this.datastorage[part].Item2)?.Invoke(this, new EventArgs());
return true;
}
private Boolean Login(HttpListenerContext cont) {
Dictionary<String, String> POST = Webserver.GetPostParams(cont.Request);
Dictionary<String, String> POST = cont.Request.GetPostParams();
if(POST.ContainsKey("user") && POST["user"] == this.settings["admin_user"] && POST.ContainsKey("pass") && POST["pass"] == this.settings["admin_pass"]) {
Int64 sessionid;
while(true) {

View File

@ -0,0 +1,99 @@
using System;
using System.Globalization;
using LitJson;
namespace Fraunhofer.Fit.IoT.LoraMap.Model.JsonObjects {
public class LoraData {
#region mandatory field
public Double BatteryLevel {
get;
}
public Boolean CorrectInterface {
get;
}
public LoraDataGps Gps {
get;
}
public String Hash {
get;
}
public String Name {
get;
}
#endregion
#region optional field
public DateTime Receivedtime {
get;
}
public Double Rssi {
get;
}
public Double Snr {
get;
}
#endregion
public static Boolean CheckJson(JsonData json) =>
json.ContainsKey("BatteryLevel") && (json["BatteryLevel"].IsDouble || json["BatteryLevel"].IsInt)
&& json.ContainsKey("CorrectInterface") && json["CorrectInterface"].IsBoolean
&& json.ContainsKey("Gps") && json["Gps"].IsObject
&& LoraDataGps.CheckJson(json["Gps"])
&& json.ContainsKey("Hash") && json["Hash"].IsString
&& json.ContainsKey("Name") && json["Name"].IsString;
public LoraData(JsonData json) {
//mandatory field
this.BatteryLevel = json["BatteryLevel"].IsInt ? (Int32)json["BatteryLevel"] : (Double)json["BatteryLevel"];
this.CorrectInterface = (Boolean)json["CorrectInterface"];
this.Gps = new LoraDataGps(json["Gps"]);
this.Hash = (String)json["Hash"];
this.Name = (String)json["Name"];
//optional field
this.Rssi = json.ContainsKey("Rssi") && (json["Rssi"].IsDouble || json["Rssi"].IsInt) ? json["Rssi"].IsInt ? (Int32)json["Rssi"] : (Double)json["Rssi"] : 0;
this.Snr = json.ContainsKey("Snr") && (json["Snr"].IsDouble || json["Snr"].IsInt) ? json["Snr"].IsInt ? (Int32)json["Snr"] : (Double)json["Snr"] : 0;
this.Receivedtime = json.ContainsKey("Receivedtime") && json["Receivedtime"].IsString && DateTime.TryParse((String)json["Receivedtime"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime) ? updatetime.ToUniversalTime() : DateTime.UtcNow;
}
}
public class LoraDataGps {
#region mandatory field
public Double Latitude {
get;
}
public Double Longitude {
get;
}
public Boolean Fix {
get;
}
public Double Height {
get;
}
#endregion
#region optional field
public Double Hdop {
get;
}
#endregion
public static Boolean CheckJson(JsonData json) =>
json.ContainsKey("Latitude") && (json["Latitude"].IsDouble || json["Latitude"].IsInt)
&& json.ContainsKey("Longitude") && (json["Longitude"].IsDouble || json["Longitude"].IsInt)
&& json.ContainsKey("Fix") && json["Fix"].IsBoolean
&& json.ContainsKey("Height") && (json["Height"].IsDouble || json["Height"].IsInt);
public LoraDataGps(JsonData json) {
//mandatory field
this.Latitude = json["Latitude"].IsInt ? (Int32)json["Latitude"] : (Double)json["Latitude"];
this.Longitude = json["Longitude"].IsInt ? (Int32)json["Longitude"] : (Double)json["Longitude"];
this.Fix = (Boolean)json["Fix"];
this.Height = json["Height"].IsInt ? (Int32)json["Height"] : (Double)json["Height"];
//optional field
this.Hdop = json.ContainsKey("Hdop") && (json["Hdop"].IsDouble || json["Hdop"].IsInt) ? json["Hdop"].IsInt ? (Int32)json["Hdop"] : (Double)json["Hdop"] : 0;
}
}
}

View File

@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.IO;
using BlubbFish.Utils;
using LitJson;
namespace Fraunhofer.Fit.IoT.LoraMap.Model.JsonObjects {
public class NamesModel {
public SortedDictionary<String, NamesModelData> Items {
get;
}
public static Boolean CheckJson(JsonData json) {
if(!json.IsObject) {
return false;
}
foreach(String item in json.Keys) {
if(!NamesModelData.CheckJson(json[item])) {
return false;
}
}
return true;
}
public NamesModel() {
this.Items = new SortedDictionary<String, NamesModelData>();
JsonData json = this.LoadFromFile();
if(json != null && CheckJson(json)) {
foreach(String item in json.Keys) {
this.Items.Add(item, new NamesModelData(json[item]));
}
}
}
private JsonData LoadFromFile() {
try {
if(!Directory.Exists("json")) {
_ = Directory.CreateDirectory("json");
}
if(!File.Exists("json/names.json")) {
File.WriteAllText("json/names.json", "{}");
}
return JsonMapper.ToObject(File.ReadAllText("json/names.json"));
} catch {
Helper.WriteError("Could not load json/names.json");
return null;
}
}
}
public class NamesModelData {
#region mandatory field
public String Name {
get;
}
public String Group {
get;
}
#endregion
#region optional field
public String Icon {
get;
}
public NamesModelDataMarkerSvg MarkerSvg {
get;
}
#endregion
public static Boolean CheckJson(JsonData json) =>
json.ContainsKey("name") && json["name"].IsString
&& json.ContainsKey("Group") && json["Group"].IsString;
public NamesModelData(JsonData json) {
//mandatory field
this.Name = (String)json["name"];
this.Group = (String)json["Group"];
//optional field
this.MarkerSvg = json.ContainsKey("marker.svg") && json["marker.svg"].IsObject && NamesModelDataMarkerSvg.CheckJson(json["marker.svg"]) ? new NamesModelDataMarkerSvg(json["marker.svg"]) : null;
this.Icon = json.ContainsKey("icon") && json["icon"].IsString ? (String)json["icon"] : null;
}
}
public class NamesModelDataMarkerSvg {
#region optional field
public NamesModelDataMarkerSvgPerson Person {
get;
}
#endregion
public static Boolean CheckJson(JsonData json) =>
json.ContainsKey("person") && json["person"].IsObject;
public NamesModelDataMarkerSvg(JsonData json) {
//optional field
#pragma warning disable IDE0021 // Ausdruckskörper für Konstruktoren verwenden
this.Person = json.ContainsKey("person") && json["person"].IsObject && NamesModelDataMarkerSvgPerson.CheckJson(json["person"]) ? new NamesModelDataMarkerSvgPerson(json["person"]) : null;
#pragma warning restore IDE0021 // Ausdruckskörper für Konstruktoren verwenden
}
}
public class NamesModelDataMarkerSvgPerson {
#region mandatory field
public String Funktion {
get;
}
public String Organisation {
get;
}
public String Rang {
get;
}
#endregion
#region optional field
public String Text {
get;
}
public List<String> Typ {
get;
}
#endregion
public static Boolean CheckJson(JsonData json) =>
json.ContainsKey("org") && json["org"].IsString
&& json.ContainsKey("funct") && json["funct"].IsString
&& json.ContainsKey("rang") && json["rang"].IsString;
public NamesModelDataMarkerSvgPerson(JsonData json) {
//mandatory field
this.Organisation = (String)json["org"];
this.Funktion = (String)json["funct"];
this.Rang = (String)json["rang"];
//optional field
this.Text = json.ContainsKey("text") && json["text"].IsString ? (String)json["text"] : null;
List<String> typs = new List<String>();
if(json.ContainsKey("typ") && json["typ"].IsArray) {
foreach(JsonData item in json["typ"]) {
if(item.IsString) {
typs.Add(item.ToString());
}
}
}
this.Typ = typs;
}
}
}

View File

@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using LitJson;
using Fraunhofer.Fit.IoT.LoraMap.Model.JsonObjects;
namespace Fraunhofer.Fit.IoT.LoraMap.Model.Position {
public class PositionAlarm : PositionItem {
@ -9,22 +10,19 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Position {
public List<DateTime> ButtonPressed => this.buttonhistory.Keys.ToList();
public PositionAlarm(JsonData json) : base(json, null) {
public PositionAlarm(LoraData data) : base(data, null) {
}
public override void Update(JsonData json) {
base.Update(json);
this.SetHistory(json);
public override void Update(LoraData data) {
base.Update(data);
this.SetHistory(data);
}
private void SetHistory(JsonData json) {
if(json.ContainsKey("Hash") && json["Hash"].IsString) {
String key = json["Hash"].ToString();
if(!this.buttonhistory.ContainsValue(key)) {
this.buttonhistory.Add(DateTime.UtcNow, key);
if(this.buttonhistory.Count > 10) {
_ = this.buttonhistory.Remove(this.buttonhistory.Keys.ToList().First());
}
private void SetHistory(LoraData data) {
if(!this.buttonhistory.ContainsValue(data.Hash)) {
this.buttonhistory.Add(DateTime.UtcNow, data.Hash);
if(this.buttonhistory.Count > 10) {
_ = this.buttonhistory.Remove(this.buttonhistory.Keys.ToList().First());
}
}
}

View File

@ -1,14 +1,17 @@
using System;
using System.Globalization;
using System.Collections.Generic;
using System.Linq;
using Fraunhofer.Fit.IoT.LoraMap.Model.JsonObjects;
using Fraunhofer.Fit.IoT.LoraMap.Model.Svg;
using LitJson;
namespace Fraunhofer.Fit.IoT.LoraMap.Model.Position {
public class PositionItem {
private Double _lastLat = 0;
private Double _lastLon = 0;
private readonly SortedDictionary<DateTime, Double[]> _history = new SortedDictionary<DateTime, Double[]>();
private String _lastHash = "";
private Boolean _isdublicate = false;
public Double Rssi { get; private set; }
public Double Snr { get; private set; }
@ -27,19 +30,20 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Position {
public String Icon { get; private set; }
public String MenuIcon { get; private set; }
public String Group { get; private set; }
public List<Double[]> History => this._history.Values.ToList();
public PositionItem(JsonData json, JsonData marker) {
this.Update(json);
this.UpdateMarker(marker, GetId(json));
public PositionItem(LoraData data, NamesModel marker) {
this.Update(data);
this.UpdateMarker(marker, data.Name);
}
public void UpdateMarker(JsonData marker, String id) {
if(marker != null && marker.ContainsKey(id)) {
this.Name = marker[id].ContainsKey("name") && marker[id]["name"].IsString ? (String)marker[id]["name"] : id;
Tuple<String, String> icons = this.ParseIconConfig(marker[id]);
public void UpdateMarker(NamesModel marker, String id) {
if(marker.Items.ContainsKey(id)) {
this.Name = marker.Items[id].Name;
Tuple<String, String> icons = this.ParseIconConfig(marker.Items[id]);
this.Icon = icons.Item1;
this.MenuIcon = icons.Item2;
this.Group = marker[id].ContainsKey("Group") && marker[id]["Group"].IsString ? (String)marker[id]["Group"] : "no";
this.Group = marker.Items[id].Group;
} else {
this.Name = id;
this.Icon = null;
@ -47,44 +51,43 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Position {
}
}
private Tuple<String, String> ParseIconConfig(JsonData marker) {
private Tuple<String, String> ParseIconConfig(NamesModelData marker) {
String icon = null;
String menu = null;
if(marker.ContainsKey("marker.svg") && marker["marker.svg"].IsObject) {
icon = SVGMarker.ParseConfig(marker["marker.svg"], this.Name);
if(marker["marker.svg"].ContainsKey("person") && marker["marker.svg"]["person"].IsObject) {
menu = SVGPerson.ParseConfig(marker["marker.svg"]["person"]);
if(marker.MarkerSvg != null) {
icon = SVGMarker.ParseConfig(marker.MarkerSvg, this.Name);
if(marker.MarkerSvg.Person != null) {
menu = SVGPerson.ParseConfig(marker.MarkerSvg.Person);
}
} else if(marker.ContainsKey("icon") && marker["icon"].IsString) {
icon = (String)marker["icon"];
} else if(marker.Icon != null) {
icon = marker.Icon;
}
return new Tuple<String, String>(icon, menu);
}
public static Boolean CheckJson(JsonData json) =>
json.ContainsKey("BatteryLevel") && (json["BatteryLevel"].IsDouble || json["BatteryLevel"].IsInt)
&& json.ContainsKey("Gps") && json["Gps"].IsObject
&& json["Gps"].ContainsKey("Latitude") && (json["Gps"]["Latitude"].IsDouble || json["Gps"]["Latitude"].IsInt)
&& json["Gps"].ContainsKey("Longitude") && (json["Gps"]["Longitude"].IsDouble || json["Gps"]["Longitude"].IsInt)
&& json["Gps"].ContainsKey("Fix") && json["Gps"]["Fix"].IsBoolean
&& json["Gps"].ContainsKey("Height") && (json["Gps"]["Height"].IsDouble || json["Gps"]["Height"].IsInt)
&& json.ContainsKey("Name") && json["Name"].IsString;
public static String GetId(JsonData json) => (String)json["Name"];
public virtual void Update(JsonData json) {
this.Rssi = json.ContainsKey("Rssi") && (json["Rssi"].IsDouble || json["Rssi"].IsInt) && Double.TryParse(json["Rssi"].ToString(), out Double rssi) ? rssi : 0;
this.Snr = json.ContainsKey("Snr") && (json["Snr"].IsDouble || json["Snr"].IsInt) && Double.TryParse(json["Snr"].ToString(), out Double snr) ? snr : 0;
this.Lorarecievedtime = json.ContainsKey("Receivedtime") && json["Receivedtime"].IsString && DateTime.TryParse((String)json["Receivedtime"], DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime updatetime) ? updatetime.ToUniversalTime() : DateTime.UtcNow;
public virtual void Update(LoraData data) {
this._isdublicate = false;
if(data.Hash == this._lastHash) {
if(!data.CorrectInterface) {
Console.WriteLine("dublicate-Paket, reomove wrong reciever!");
return;
}
this._isdublicate = true;
Console.WriteLine("dublicate-Paket!");
}
this._lastHash = data.Hash;
this.Rssi = data.Rssi;
this.Snr = data.Snr;
this.Lorarecievedtime = data.Receivedtime;
this.Recievedtime = DateTime.UtcNow;
this.Battery = Math.Round(json["BatteryLevel"].IsInt ? (Int32)json["BatteryLevel"] : (Double)json["BatteryLevel"], 2);
this.Battery = Math.Round(data.BatteryLevel, 2);
this.Batterysimple = this.Battery < 3.44 ? 0 : this.Battery < 3.53 ? 1 : this.Battery < 3.6525 ? 2 : this.Battery < 3.8825 ? 3 : 4;
this.Latitude = json["Gps"]["Latitude"].IsInt ? (Int32)json["Gps"]["Latitude"] : (Double)json["Gps"]["Latitude"];
this.Longitude = json["Gps"]["Longitude"].IsInt ? (Int32)json["Gps"]["Longitude"] : (Double)json["Gps"]["Longitude"];
this.Fix = (Boolean)json["Gps"]["Fix"];
this.Height = json["Gps"]["Height"].IsInt ? (Int32)json["Gps"]["Height"] : (Double)json["Gps"]["Height"];
this.Hdop = json["Gps"].ContainsKey("Hdop") && (json["Gps"]["Hdop"].IsDouble || json["Gps"]["Hdop"].IsInt) && Double.TryParse(json["Gps"]["Hdop"].ToString(), out Double hdop) ? hdop : 0;
this.Latitude = data.Gps.Latitude;
this.Longitude = data.Gps.Longitude;
this.Fix = data.Gps.Fix;
this.Height = data.Gps.Height;
this.Hdop = data.Gps.Hdop;
if(!this.Fix) {
this.Latitude = this._lastLat;
@ -93,10 +96,38 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Position {
this._lastLat = this.Latitude;
this._lastLon = this.Longitude;
this.Lastgpspostime = DateTime.UtcNow;
if(!this._isdublicate) {
this.StoreHistory();
}
}
this.UTM = new UTMData(this.Latitude, this.Longitude);
}
private void StoreHistory() {
if(Settings.Instance.Internal.History.Enabled) {
if(Settings.Instance.Internal.History.Amount != 0 && this._history.Count > Settings.Instance.Internal.History.Amount) {
_ = this._history.Remove(this._history.Keys.ToList().First());
}
if(Settings.Instance.Internal.History.Time != 0) {
List<DateTime> removeCandidates = new List<DateTime>();
DateTime now = DateTime.UtcNow;
foreach(KeyValuePair<DateTime, Double[]> item in this._history) {
if((now - item.Key).TotalSeconds > Settings.Instance.Internal.History.Time) {
removeCandidates.Add(item.Key);
}
}
if(removeCandidates.Count > 0) {
foreach(DateTime item in removeCandidates) {
_ = this._history.Remove(item);
}
}
}
if(!this._history.ContainsKey(this.Recievedtime)) {
this._history.Add(this.Recievedtime, new Double[] { this.Latitude, this.Longitude });
}
} else {
this._history.Clear();
}
}
}
}

View File

@ -1,16 +1,17 @@
using System;
using System.Collections.Generic;
using System.IO;
using BlubbFish.Utils;
using Fraunhofer.Fit.IoT.LoraMap.Model.JsonObjects;
using LitJson;
namespace Fraunhofer.Fit.IoT.LoraMap.Model.Position {
public class PositionModel : OwnSingeton<PositionModel> {
private readonly Object lockData = new Object();
private readonly Object lockPanic = new Object();
private JsonData marker;
private readonly Object lockAlarm = new Object();
private NamesModel marker;
public SortedDictionary<String, PositionItem> Positions {
get; private set;
@ -23,27 +24,25 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Position {
protected PositionModel() {
this.Positions = new SortedDictionary<String, PositionItem>();
this.Alarms = new SortedDictionary<String, PositionAlarm>();
this.CheckJsonFile();
this.marker = JsonMapper.ToObject(File.ReadAllText("json/names.json"));
this.marker = new NamesModel();
}
public void ParseMqttJson(JsonData mqtt, String from) {
if((from.Contains("lora/data") || from.Contains("lora/panic")) && PositionItem.CheckJson(mqtt)) {
String name = PositionItem.GetId(mqtt);
if((from.Contains("lora/data") || from.Contains("lora/panic")) && LoraData.CheckJson(mqtt)) {
LoraData data = new LoraData(mqtt);
lock(this.lockData) {
if(this.Positions.ContainsKey(name)) {
this.Positions[name].Update(mqtt);
if(this.Positions.ContainsKey(data.Name)) {
this.Positions[data.Name].Update(data);
} else {
this.Positions.Add(name, new PositionItem(mqtt, this.marker));
this.Positions.Add(data.Name, new PositionItem(data, this.marker));
}
}
if(from.Contains("lora/panic")) {
lock(this.lockPanic) {
if(this.Alarms.ContainsKey(name)) {
this.Alarms[name].Update(mqtt);
lock(this.lockAlarm) {
if(this.Alarms.ContainsKey(data.Name)) {
this.Alarms[data.Name].Update(data);
} else {
this.Alarms.Add(name, new PositionAlarm(mqtt));
this.Alarms.Add(data.Name, new PositionAlarm(data));
}
}
Console.WriteLine("PANIC erhalten!");
@ -53,21 +52,11 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Position {
}
public void ReloadNames(Object sender, EventArgs e) {
this.CheckJsonFile();
this.marker = JsonMapper.ToObject(File.ReadAllText("json/names.json"));
this.marker = new NamesModel();
foreach(KeyValuePair<String, PositionItem> item in this.Positions) {
item.Value.UpdateMarker(this.marker, item.Key);
}
Console.WriteLine("Namen und Icons aktualisiert!");
}
private void CheckJsonFile() {
if(!Directory.Exists("json")) {
_ = Directory.CreateDirectory("json");
}
if(!File.Exists("json/names.json")) {
File.WriteAllText("json/names.json", "{}");
}
}
}
}

View File

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using LitJson;
using Fraunhofer.Fit.IoT.LoraMap.Model.JsonObjects;
namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
public class SVGMarker : SVGFile {
@ -12,7 +12,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
public SVGMarker(String query) : base(query, 86, 121.25, new List<Double>() { 0, 0, 86, 121.25 }) => this.css.Add("#marker-name tspan {\n font-size: 20px;\n font-family: DIN1451;\n}");
public static String ParseConfig(JsonData json, String name) => "api/svg/marker.svg" + DictionaryConfigToString(GenerateConfig(json, name));
public static String ParseConfig(NamesModelDataMarkerSvg json, String name) => "api/svg/marker.svg" + DictionaryConfigToString(GenerateConfig(json, name));
protected override void ParseParams() {
String[] parts = this.query.Split('&');
@ -21,7 +21,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
if(keyvalue.Length == 2) {
switch(keyvalue[0].ToLower()) {
case "name":
this.name = keyvalue[1];
this.name = HttpUtility.UrlDecode(keyvalue[1]);
break;
case "icon":
this.icon = keyvalue[1].ToLower();
@ -31,14 +31,14 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
}
}
public static Dictionary<String, String> GenerateConfig(JsonData json, String name) {
Dictionary<String, String> config = new Dictionary<String, String>();
public static Dictionary<String, List<String>> GenerateConfig(NamesModelDataMarkerSvg json, String name) {
Dictionary<String, List<String>> config = new Dictionary<String, List<String>>();
if(name != "") {
config.Add("name", name);
config.Add("name", new List<String>() { name });
}
if(json.ContainsKey("person") && json["person"].IsObject) {
config.Add("icon", "person");
Dictionary<String, String> personconfig = SVGPerson.GenerateConfig(json["person"]);
if(json.Person != null) {
config.Add("icon", new List<String>() { "person" });
Dictionary<String, List<String>> personconfig = SVGPerson.GenerateConfig(json.Person);
personconfig.ToList().ForEach(x => config.Add(x.Key, x.Value));
}
return config;
@ -52,7 +52,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
svg += "</g>\n";
svg += "<g inkscape:groupmode=\"layer\" id=\"marker-name\" inkscape:label=\"Name\">\n";
svg += $"<text><tspan x=\"5\" y=\"20\" id=\"marker-name-text\">{this.name}</tspan></text>\n";
svg += $"<text><tspan x=\"5\" y=\"20\" id=\"marker-name-text\">{HttpUtility.HtmlEncode(this.name)}</tspan></text>\n";
svg += "</g>\n";
if(this.icon == "person") {

View File

@ -2,8 +2,9 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using LitJson;
using Fraunhofer.Fit.IoT.LoraMap.Model.JsonObjects;
namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
public class SVGPerson : SVGFile {
@ -11,7 +12,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
private String function;
private String rang;
private String text;
private String[] typs;
private readonly List<String> typs = new List<String>();
@ -23,7 +24,7 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
this.css.Add("#person-layer-typ line {\n stroke-width: 3px;\n stroke: black;\n}");
}
public static String ParseConfig(JsonData json) => "api/svg/person.svg" + DictionaryConfigToString(GenerateConfig(json));
public static String ParseConfig(NamesModelDataMarkerSvgPerson json) => "api/svg/person.svg" + DictionaryConfigToString(GenerateConfig(json));
protected override void ParseParams() {
String[] parts = this.query.Split('&');
@ -41,38 +42,27 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
this.rang = keyvalue[1].ToLower();
break;
case "person-text":
this.text = keyvalue[1];
this.text = HttpUtility.UrlDecode(keyvalue[1]);
break;
case "person-typ":
this.typs = keyvalue[1].ToLower().Split(",");
case "person-typ[]":
this.typs.Add(HttpUtility.UrlDecode(keyvalue[1]).ToLower());
break;
}
}
}
}
public static Dictionary<String, String> GenerateConfig(JsonData json) {
Dictionary<String, String> config = new Dictionary<String, String>();
if(json.ContainsKey("org") && json["org"].IsString) {
config.Add("person-org", json["org"].ToString());
public static Dictionary<String, List<String>> GenerateConfig(NamesModelDataMarkerSvgPerson json) {
Dictionary<String, List<String>> config = new Dictionary<String, List<String>> {
{ "person-org", new List<String>() { json.Organisation } },
{ "person-funct", new List<String>() { json.Funktion } },
{ "person-rang", new List<String>() { json.Rang } }
};
if(json.Text != null) {
config.Add("person-text", new List<String>() { json.Text });
}
if(json.ContainsKey("funct") && json["funct"].IsString) {
config.Add("person-funct", json["funct"].ToString());
}
if(json.ContainsKey("rang") && json["rang"].IsString) {
config.Add("person-rang", json["rang"].ToString());
}
if(json.ContainsKey("text") && json["text"].IsString) {
config.Add("person-text", json["text"].ToString());
}
if(json.ContainsKey("typ") && json["typ"].IsArray) {
List<String> typs = new List<String>();
foreach(JsonData item in json["person"]["typ"]) {
if(item.IsString) {
typs.Add(item.ToString());
}
}
config.Add("person-typ", String.Join(",", typs));
if(json.Typ.Count > 0) {
config.Add("person-typ[]", json.Typ);
}
return config;
}
@ -104,12 +94,11 @@ namespace Fraunhofer.Fit.IoT.LoraMap.Model.Svg {
svg += "</g>\n";
svg += "</g>\n";
}
if(this.text != null || this.typs != null && this.typs.All(x => this.typlookup.ContainsKey(x))) {
if(this.text != null || this.typs.Count > 0 && this.typs.All(x => this.typlookup.ContainsKey(x))) {
svg += "<g inkscape:groupmode=\"layer\" id=\"person-layer-typ\" inkscape:label=\"Typ\">\n";
if(this.text != null && this.typs == null) {
svg += $"<text><tspan y=\"42\" x=\"0\" id=\"person-layer-typ-text\">{this.text}</tspan></text>\n";
}
if(this.text == null && this.typs != null && this.typs.All(x => this.typlookup.ContainsKey(x))) {
if(this.text != null) {
svg += $"<text><tspan y=\"42\" x=\"0\" id=\"person-layer-typ-text\">{HttpUtility.HtmlEncode(this.text)}</tspan></text>\n";
} else if(this.typs.Count > 0 && this.typs.All(x => this.typlookup.ContainsKey(x))) {
foreach(String typ in this.typs) {
svg += $"<g id=\"person-layer-typ-{typ}\" inkscape:label=\"{this.typlookup[typ].Name}\">\n";
foreach(Tuple<Double, Double, Double, Double> item in this.typlookup[typ].Lines) {