diff --git a/models.go b/models.go index d35847b..ffccdf2 100644 --- a/models.go +++ b/models.go @@ -1,6 +1,9 @@ package main -import "time" +import ( + "fmt" + "time" +) type Watch struct { ID uint `form:"watch_id" yaml:"watch_id"` @@ -21,6 +24,15 @@ type Filter struct { Parents []*Filter `gorm:"-:all"` Children []*Filter `gorm:"-:all"` Results []string `gorm:"-:all"` + Logs []string `gorm:"-:all"` +} + +func (filter *Filter) logf(format string, v ...any) { + filter.Logs = append(filter.Logs, fmt.Sprintf(format, v...)) +} + +func (filter *Filter) log(v ...any) { + filter.Logs = append(filter.Logs, fmt.Sprint(v...)) } type FilterConnection struct { diff --git a/scraping.go b/scraping.go index a920fc8..0d77585 100644 --- a/scraping.go +++ b/scraping.go @@ -141,7 +141,7 @@ func getFilterResult(filter *Filter, db *gorm.DB, urlCache map[string]string, us } } default: - log.Println("getFilterResult called with filter.Type == ", filter.Type) + filter.log("getFilterResult called with filter.Type == ", filter.Type) } } @@ -155,13 +155,13 @@ func getFilterResultURL(filter *Filter, urlCache map[string]string, useCache boo resp, err := http.Get(url) if err != nil { - log.Println("Could not fetch url", url) - log.Println("Reason:", err) + filter.log("Could not fetch url", url) + filter.log("Reason:", err) } body, err := ioutil.ReadAll(resp.Body) if err != nil { - log.Println("Could not fetch url", url) - log.Println("Reason:", err) + filter.log("Could not fetch url", url) + filter.log("Reason:", err) } str := string(body) filter.Results = append(filter.Results, str) @@ -171,15 +171,11 @@ func getFilterResultURL(filter *Filter, urlCache map[string]string, useCache boo } func getFilterResultXPath(filter *Filter) { - if filter.Parents == nil { - log.Println("Filter", filter.Name, "called without parents for", filter.Type) - return - } for _, parent := range filter.Parents { for _, result := range parent.Results { doc, err := htmlquery.Parse(strings.NewReader(result)) if err != nil { - log.Print(err) + filter.log(err) continue } nodes, _ := htmlquery.QueryAll(doc, filter.Var1) @@ -193,10 +189,6 @@ func getFilterResultXPath(filter *Filter) { } func getFilterResultJSON(filter *Filter) { - if filter.Parents == nil { - log.Println("Filter", filter.Name, "called without parent for", filter.Type) - return - } for _, parent := range filter.Parents { for _, result := range parent.Results { for _, match := range gjson.Get(result, filter.Var1).Array() { @@ -207,20 +199,16 @@ func getFilterResultJSON(filter *Filter) { } func getFilterResultCSS(filter *Filter) { - if filter.Parents == nil { - log.Println("Filter", filter.Name, "called without parent for", filter.Type) - return - } for _, parent := range filter.Parents { for _, result := range parent.Results { doc, err := html.Parse(strings.NewReader(result)) if err != nil { - log.Print(err) + filter.log(err) continue } sel, err := cascadia.Parse(filter.Var1) if err != nil { - log.Print(err) + filter.log(err) continue } for _, node := range cascadia.QueryAll(doc, sel) { @@ -233,17 +221,13 @@ func getFilterResultCSS(filter *Filter) { } func getFilterResultReplace(filter *Filter) { - if filter.Parents == nil { - log.Println("Filter", filter.Name, "called without parent for", filter.Type) + r, err := regexp.Compile(filter.Var1) + if err != nil { + filter.log(err) return } for _, parent := range filter.Parents { for _, result := range parent.Results { - r, err := regexp.Compile(filter.Var1) - if err != nil { - log.Print(err) - continue - } if filter.Var2 == nil { filter.Results = append(filter.Results, r.ReplaceAllString(result, "")) } else { @@ -254,10 +238,6 @@ func getFilterResultReplace(filter *Filter) { } func getFilterResultMatch(filter *Filter) { - if filter.Parents == nil { - log.Println("Filter", filter.Name, "called without parent for", filter.Type) - return - } r, err := regexp.Compile(filter.Var1) if err != nil { log.Print(err) @@ -273,10 +253,6 @@ func getFilterResultMatch(filter *Filter) { } func getFilterResultSubstring(filter *Filter) { - if filter.Parents == nil { - log.Println("Filter", filter.Name, "called without parent for", filter.Type) - return - } for _, parent := range filter.Parents { for _, result := range parent.Results { substrings := strings.Split(filter.Var1, ",") @@ -287,6 +263,7 @@ func getFilterResultSubstring(filter *Filter) { if strings.Contains(substring, ":") { from_to := strings.Split(substring, ":") if len(from_to) != 2 { + filter.log("Missing value in range: ", substring) return } fromStr := from_to[0] @@ -297,6 +274,7 @@ func getFilterResultSubstring(filter *Filter) { from64, err := strconv.ParseInt(fromStr, 10, 32) var from = int(from64) if hasFrom && err != nil { + filter.log("Could not parse left side of: ", substring) return } else if from < 0 { from = len(asRunes) + from @@ -309,6 +287,7 @@ func getFilterResultSubstring(filter *Filter) { to64, err := strconv.ParseInt(toStr, 10, 32) var to = int(to64) if hasTo && err != nil { + filter.log("Could not parse right side of: ", substring) return } else if to < 0 { to = len(asRunes) + to @@ -323,6 +302,7 @@ func getFilterResultSubstring(filter *Filter) { } else { pos, err := strconv.ParseInt(substring, 10, 32) if err != nil || pos < 0 { + filter.log("Could not parse: ", substring) return } sb.WriteRune(asRunes[pos]) @@ -339,6 +319,12 @@ func getFilterResultSum(filter *Filter) { for _, result := range parent.Results { if number, err := strconv.ParseFloat(result, 64); err == nil { sum += number + } else { + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } } } } @@ -355,6 +341,12 @@ func getFilterResultMin(filter *Filter) { min = number setMin = true } + } else { + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } } } } @@ -374,6 +366,12 @@ func getFilterResultMax(filter *Filter) { max = number setMax = true } + } else { + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } } } } @@ -391,6 +389,12 @@ func getFilterResultAverage(filter *Filter) { if number, err := strconv.ParseFloat(result, 64); err == nil { sum += number count++ + } else { + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } } } } @@ -433,6 +437,12 @@ func getFilterResultRound(filter *Filter) { if number, err := strconv.ParseFloat(result, 64); err == nil { rounded := roundFloat(number, uint(decimals)) filter.Results = append(filter.Results, fmt.Sprintf("%f", rounded)) + } else { + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } } } } @@ -485,12 +495,16 @@ func getFilterResultConditionLowerLast(filter *Filter, db *gorm.DB) { } else { lastValue, err := strconv.ParseFloat(previousOutput.Value, 64) if err != nil { - log.Println("Could not convert previous value to number:", previousOutput.Value) + filter.log("Could not convert previous value to number:", previousOutput.Value) continue } number, err := strconv.ParseFloat(result, 64) if err != nil { - log.Println("Could not convert new value to number:", result) + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } continue } if number < lastValue { @@ -509,7 +523,7 @@ func getFilterResultConditionLowest(filter *Filter, db *gorm.DB) { for _, previousOutput := range previousOutputs { number, err := strconv.ParseFloat(previousOutput.Value, 64) if err != nil { - log.Println("Could not convert result to number:", previousOutput.Value) + filter.log("Could not convert result to number:", previousOutput.Value) continue } if number < lowest { @@ -523,7 +537,11 @@ func getFilterResultConditionLowest(filter *Filter, db *gorm.DB) { for _, result := range parent.Results { number, err := strconv.ParseFloat(result, 64) if err != nil { - log.Println("Could not convert result to number:", result) + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } continue } if number < lowest { @@ -535,19 +553,23 @@ func getFilterResultConditionLowest(filter *Filter, db *gorm.DB) { func getFilterResultConditionLowerThan(filter *Filter) { if filter.Var2 == nil { - log.Println("No threshold given for Lower Than Filter") + filter.log("No threshold given") return } threshold, err := strconv.ParseFloat(*filter.Var2, 64) if err != nil { - log.Println("Could not convert convert threshold to number:", *filter.Var2) + filter.log("Could not convert convert threshold to number:", *filter.Var2) return } for _, parent := range filter.Parents { for _, result := range parent.Results { number, err := strconv.ParseFloat(result, 64) if err != nil { - log.Println("Could not convert new value to number:", result) + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } continue } if number < threshold { @@ -567,12 +589,16 @@ func getFilterResultConditionHigherLast(filter *Filter, db *gorm.DB) { } else { lastValue, err := strconv.ParseFloat(previousOutput.Value, 64) if err != nil { - log.Println("Could not convert previous value to number:", previousOutput.Value) + filter.log("Could not convert previous value to number:", previousOutput.Value) continue } number, err := strconv.ParseFloat(result, 64) if err != nil { - log.Println("Could not convert new value to number:", result) + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } continue } if number > lastValue { @@ -591,7 +617,7 @@ func getFilterResultConditionHighest(filter *Filter, db *gorm.DB) { for _, previousOutput := range previousOutputs { number, err := strconv.ParseFloat(previousOutput.Value, 64) if err != nil { - log.Println("Could not convert result to number:", previousOutput.Value) + filter.log("Could not convert result to number:", previousOutput.Value) continue } if number > highest { @@ -605,7 +631,11 @@ func getFilterResultConditionHighest(filter *Filter, db *gorm.DB) { for _, result := range parent.Results { number, err := strconv.ParseFloat(result, 64) if err != nil { - log.Println("Could not convert result to number:", result) + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } continue } if number > highest { @@ -617,19 +647,23 @@ func getFilterResultConditionHighest(filter *Filter, db *gorm.DB) { func getFilterResultConditionHigherThan(filter *Filter) { if filter.Var2 == nil { - log.Println("No threshold given for Higher Than Filter") + filter.log("No threshold given for Higher Than Filter") return } threshold, err := strconv.ParseFloat(*filter.Var2, 64) if err != nil { - log.Println("Could not convert convert threshold to number:", *filter.Var2) + filter.log("Could not convert convert threshold to number:", *filter.Var2) return } for _, parent := range filter.Parents { for _, result := range parent.Results { number, err := strconv.ParseFloat(result, 64) if err != nil { - log.Println("Could not convert new value to number:", result) + if len(result) > 50 { + filter.log("Could not convert value, with length ", len(result), ", to number") + } else { + filter.log("Could not convert value, ", result, ", to number") + } continue } if number > threshold { diff --git a/static/diagram.js b/static/diagram.js index 1eb07f8..80c1177 100644 --- a/static/diagram.js +++ b/static/diagram.js @@ -273,9 +273,10 @@ var NewConnection = /** @class */ (function (_super) { }(CanvasObject)); var DiagramNode = /** @class */ (function (_super) { __extends(DiagramNode, _super); - function DiagramNode(id, x, y, label, meta, ctx, results) { + function DiagramNode(id, x, y, label, meta, ctx, results, logs) { if (meta === void 0) { meta = {}; } if (results === void 0) { results = new Array(); } + if (logs === void 0) { logs = new Array(); } var _this = _super.call(this, x, y, 0, 0) || this; _this.dragging = false; _this.dragOrigin = new Point(); @@ -287,10 +288,11 @@ var DiagramNode = /** @class */ (function (_super) { _this.resize(ctx); _this.deleteButton = new Button(0, 0, "Del", ctx, _diagram.deleteNodeCallback, _this); _this.editButton = new Button(0, 0, "Edit", ctx, _diagram.editNodeCallback, _this); - _this.logButton = new Button(0, 0, "Log", ctx, _diagram.editNodeCallback, _this); + _this.logButton = new Button(0, 0, "Log", ctx, _diagram.logNodeCallback, _this); _this.input = new NodeIO(_this, true); _this.output = new NodeIO(_this, false); _this.results = results; + _this.logs = logs; return _this; } DiagramNode.prototype.update = function (ms) { @@ -359,6 +361,15 @@ var DiagramNode = /** @class */ (function (_super) { this.logButton.draw(ctx, ms); this.input.draw(ctx, ms); this.output.draw(ctx, ms); + if (this.logs.length > 0) { + ctx.moveTo(this.x + 21, this.y + 6); + ctx.fillStyle = "orange"; + ctx.beginPath(); + ctx.lineTo(this.x + 23, this.y + 21); + ctx.lineTo(this.x + 6, this.y + 21); + ctx.lineTo(this.x + 14, this.y + 6); + ctx.fill(); + } ctx.strokeStyle = "#8E8E8E"; ctx.lineWidth = 3; ctx.strokeRect(ms.offset.x + this.x, ms.offset.y + this.y, this.width, this.height); @@ -469,9 +480,10 @@ var MouseState = /** @class */ (function () { return MouseState; }()); var Diagrams = /** @class */ (function () { - function Diagrams(canvasId, editNodeCallback, deleteNodeCallback) { + function Diagrams(canvasId, editNodeCallback, deleteNodeCallback, logNodeCallback) { if (editNodeCallback === void 0) { editNodeCallback = function () { }; } if (deleteNodeCallback === void 0) { deleteNodeCallback = function () { }; } + if (logNodeCallback === void 0) { logNodeCallback = function () { }; } this.shouldTick = true; this.nodes = new Map(); this.connections = new Array(); @@ -482,6 +494,7 @@ var Diagrams = /** @class */ (function () { this.newConnection = null; this.scale = 1.0; this.editNodeCallback = function () { }; + this.logNodeCallback = function () { }; this.deleteNodeCallback = function () { }; this.canvas = document.getElementById(canvasId); if (this.canvas === null) { @@ -494,6 +507,7 @@ var Diagrams = /** @class */ (function () { _diagram = this; this.ctx = ctx; this.editNodeCallback = editNodeCallback; + this.logNodeCallback = logNodeCallback; this.deleteNodeCallback = deleteNodeCallback; this.canvas.onmousemove = diagramOnMouseMove; this.canvas.onmousedown = diagramOnMouseDown; @@ -625,10 +639,11 @@ var Diagrams = /** @class */ (function () { }; Diagrams.prototype.draw = function () { }; - Diagrams.prototype.addNode = function (id, x, y, label, meta, results) { + Diagrams.prototype.addNode = function (id, x, y, label, meta, results, logs) { if (meta === void 0) { meta = {}; } if (results === void 0) { results = new Array(); } - var node = new DiagramNode(id, x, y, label, meta, this.ctx, results); + if (logs === void 0) { logs = new Array(); } + var node = new DiagramNode(id, x, y, label, meta, this.ctx, results, logs); this.nodes.set(id, node); }; Diagrams.prototype.addConnection = function (A, B) { diff --git a/static/diagram.ts b/static/diagram.ts index 32224cd..77f697a 100644 --- a/static/diagram.ts +++ b/static/diagram.ts @@ -311,6 +311,7 @@ class DiagramNode extends CanvasObject { meta: Object = {}; results: Array; + logs: Array; constructor( id: number, @@ -320,6 +321,7 @@ class DiagramNode extends CanvasObject { meta: Object = {}, ctx: CanvasRenderingContext2D, results: Array = new Array(), + logs: Array = new Array(), ){ super(x, y, 0, 0) this.id = id; @@ -330,11 +332,12 @@ class DiagramNode extends CanvasObject { this.deleteButton = new Button(0, 0, "Del", ctx, _diagram.deleteNodeCallback, this); this.editButton = new Button(0, 0, "Edit", ctx, _diagram.editNodeCallback, this); - this.logButton = new Button(0, 0, "Log", ctx, _diagram.editNodeCallback, this); + this.logButton = new Button(0, 0, "Log", ctx, _diagram.logNodeCallback, this); this.input = new NodeIO(this, true); this.output = new NodeIO(this, false); this.results = results; + this.logs = logs; } update(ms: MouseState) { @@ -346,7 +349,7 @@ class DiagramNode extends CanvasObject { if (this.hover){ this.deleteButton.update(ms); this.editButton.update(ms); - this.logButton.update(ms) + this.logButton.update(ms); let onButtons = this.deleteButton.hover || this.editButton.hover || this.logButton.hover; if (!this.dragging && ms.leftDown && !ms.draggingNode && !ms.draggingConnection && !onButtons){ this.dragging = true; @@ -411,6 +414,16 @@ class DiagramNode extends CanvasObject { this.input.draw(ctx, ms); this.output.draw(ctx, ms); + + if(this.logs.length > 0){ + ctx.moveTo(this.x + 21, this.y + 6); + ctx.fillStyle = "orange"; + ctx.beginPath(); + ctx.lineTo(this.x + 23, this.y + 21); + ctx.lineTo(this.x + 6, this.y + 21); + ctx.lineTo(this.x + 14, this.y + 6); + ctx.fill(); + } ctx.strokeStyle = "#8E8E8E"; ctx.lineWidth = 3; @@ -550,12 +563,14 @@ class Diagrams { scale: number = 1.0; editNodeCallback: (node: DiagramNode) => void = function (){}; + logNodeCallback: (node: DiagramNode) => void = function (){}; deleteNodeCallback: (node: DiagramNode) => void = function (){}; constructor( canvasId: string, editNodeCallback: (node: DiagramNode) => void = function (){}, - deleteNodeCallback: (node: DiagramNode) => void = function (){} + deleteNodeCallback: (node: DiagramNode) => void = function (){}, + logNodeCallback: (node: DiagramNode) => void = function (){}, ){ this.canvas = document.getElementById(canvasId) as HTMLCanvasElement; if (this.canvas === null){ @@ -568,6 +583,7 @@ class Diagrams { _diagram = this; this.ctx = ctx; this.editNodeCallback = editNodeCallback; + this.logNodeCallback = logNodeCallback; this.deleteNodeCallback = deleteNodeCallback; this.canvas.onmousemove = diagramOnMouseMove; @@ -659,8 +675,16 @@ class Diagrams { } - addNode(id: number, x: number, y: number, label: string, meta: Object = {}, results: Array = new Array()){ - let node = new DiagramNode(id, x, y, label, meta, this.ctx, results); + addNode( + id: number, + x: number, + y: number, + label: string, + meta: Object = {}, + results: Array = new Array(), + logs: Array = new Array() + ){ + let node = new DiagramNode(id, x, y, label, meta, this.ctx, results, logs); this.nodes.set(id, node); } diff --git a/static/edit.js b/static/edit.js index 7344d53..440ac80 100644 --- a/static/edit.js +++ b/static/edit.js @@ -562,6 +562,35 @@ function editNode(node) { submitButton.innerHTML = "Save"; submitButton.onclick = function () { submitEditNode(node); }; } +function logNode(node) { + var e_1, _a; + var logButton = document.getElementById("logButton"); + logButton.click(); + var logTitle = document.getElementById("logModalLabel"); + logTitle.innerHTML = node.label; + var logBody = document.getElementById("logTableBody"); + logBody.innerHTML = ""; + var logTable = document.getElementById("logTable"); + try { + for (var _b = __values(node.logs), _c = _b.next(); !_c.done; _c = _b.next()) { + var log = _c.value; + var row = document.createElement("tr"); + var cell = document.createElement("td"); + var code = document.createElement("code"); + code.innerHTML = log; + cell.appendChild(code); + row.appendChild(cell); + logBody.appendChild(row); + } + } + catch (e_1_1) { e_1 = { error: e_1_1 }; } + finally { + try { + if (_c && !_c.done && (_a = _b["return"])) _a.call(_b); + } + finally { if (e_1) throw e_1.error; } + } +} function deleteNode(node) { _diagram.nodes["delete"](node.id); for (var i = 0; i < _diagram.connections.length; i++) { @@ -593,7 +622,7 @@ function submitEditNode(node) { node.resize(_diagram.ctx); } function saveWatch() { - var e_1, _a, e_2, _b; + var e_2, _a, e_3, _b; var watchIdInput = document.getElementById("watch_id"); var watchId = Number(watchIdInput.value); var filters = new Array(); @@ -617,12 +646,12 @@ function saveWatch() { }); } } - catch (e_1_1) { e_1 = { error: e_1_1 }; } + catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_d && !_d.done && (_a = _c["return"])) _a.call(_c); } - finally { if (e_1) throw e_1.error; } + finally { if (e_2) throw e_2.error; } } var filtersInput = document.getElementById("filtersInput"); filtersInput.value = JSON.stringify(filters); @@ -639,12 +668,12 @@ function saveWatch() { }); } } - catch (e_2_1) { e_2 = { error: e_2_1 }; } + catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_f && !_f.done && (_b = _e["return"])) _b.call(_e); } - finally { if (e_2) throw e_2.error; } + finally { if (e_3) throw e_3.error; } } var connectionsInput = document.getElementById("connectionsInput"); connectionsInput.value = JSON.stringify(connections); diff --git a/static/edit.ts b/static/edit.ts index 1fb9958..f8f549e 100644 --- a/static/edit.ts +++ b/static/edit.ts @@ -576,6 +576,26 @@ function editNode(node: DiagramNode){ submitButton.onclick = function() {submitEditNode(node);} } +function logNode(node: DiagramNode){ + let logButton = document.getElementById("logButton") as HTMLButtonElement; + logButton.click(); + + let logTitle = document.getElementById("logModalLabel") as HTMLHeadElement; + logTitle.innerHTML = node.label; + let logBody = document.getElementById("logTableBody") as HTMLElement; + logBody.innerHTML = ""; + let logTable = document.getElementById("logTable") as HTMLTableElement; + for (let log of node.logs){ + let row = document.createElement("tr"); + let cell = document.createElement("td"); + let code = document.createElement("code"); + code.innerHTML = log; + cell.appendChild(code); + row.appendChild(cell); + logBody.appendChild(row); + } +} + function deleteNode(node: DiagramNode){ _diagram.nodes.delete(node.id) for (let i = 0; i < _diagram.connections.length; i++){ diff --git a/templates/watch/view.html b/templates/watch/view.html index 042a30a..9d32900 100644 --- a/templates/watch/view.html +++ b/templates/watch/view.html @@ -29,6 +29,11 @@ Save Watch + + + @@ -133,6 +138,31 @@ + + {{ end }} @@ -141,7 +171,7 @@