From e69279604ec2d265b2557e9e4affd7bde8cd1f11 Mon Sep 17 00:00:00 2001 From: mandragora-hub Date: Sun, 23 Jun 2024 13:23:06 -0400 Subject: [PATCH] feat: refinement --- README.md | 3 + static/custom.css | 43 --- static/index.html | 7 +- static/lib/jsonTree.css | 122 ------ static/lib/jsonTree.js | 837 ---------------------------------------- static/script.js | 39 +- static/site.webmanifest | 20 +- 7 files changed, 26 insertions(+), 1045 deletions(-) delete mode 100644 static/custom.css delete mode 100644 static/lib/jsonTree.css delete mode 100644 static/lib/jsonTree.js diff --git a/README.md b/README.md index 2260e3b..fc2e06a 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ The services will respond with the next JSON, given the URL - - - + + PDF Metadata Extractor @@ -104,7 +103,7 @@

PDF Metadata Extractor

diff --git a/static/lib/jsonTree.css b/static/lib/jsonTree.css deleted file mode 100644 index 5a17792..0000000 --- a/static/lib/jsonTree.css +++ /dev/null @@ -1,122 +0,0 @@ -/* - * JSON Tree Viewer - * http://github.com/summerstyle/jsonTreeViewer - * - * Copyright 2017 Vera Lobacheva (http://iamvera.com) - * Released under the MIT license (LICENSE.txt) - */ - -/* Background for the tree. May use for element */ -.jsontree_bg { - background: #fff; -} - -/* Styles for the container of the tree (e.g. fonts, margins etc.) */ -.jsontree_tree { - margin-left: 30px; - font-family: "PT Mono", monospace; - font-size: 14px; -} - -/* Styles for a list of child nodes */ -.jsontree_child-nodes { - display: none; - margin-left: 35px; - margin-bottom: 5px; - line-height: 2; -} -.jsontree_node_expanded - > .jsontree_value-wrapper - > .jsontree_value - > .jsontree_child-nodes { - display: block; -} - -/* Styles for labels */ -.jsontree_label-wrapper { - float: left; - margin-right: 8px; -} -.jsontree_label { - font-weight: normal; - vertical-align: top; - color: #000; - position: relative; - padding: 1px; - border-radius: 4px; - cursor: default; -} -.jsontree_node_marked > .jsontree_label-wrapper > .jsontree_label { - background: #fff2aa; -} - -/* Styles for values */ -.jsontree_value-wrapper { - display: block; - overflow: hidden; -} -.jsontree_node_complex > .jsontree_value-wrapper { - overflow: inherit; -} -.jsontree_value { - vertical-align: top; - display: inline; -} -.jsontree_value_null { - color: #777; - font-weight: bold; -} -.jsontree_value_string { - color: #025900; - font-weight: bold; -} -.jsontree_value_number { - color: #000e59; - font-weight: bold; -} -.jsontree_value_boolean { - color: #600100; - font-weight: bold; -} - -/* Styles for active elements */ -.jsontree_expand-button { - position: absolute; - top: 3px; - left: -15px; - display: block; - width: 11px; - height: 11px; - background-image: url("icons.svg"); -} -.jsontree_node_expanded - > .jsontree_label-wrapper - > .jsontree_label - > .jsontree_expand-button { - background-position: 0 -11px; -} -.jsontree_show-more { - cursor: pointer; -} -.jsontree_node_expanded - > .jsontree_value-wrapper - > .jsontree_value - > .jsontree_show-more { - display: none; -} -.jsontree_node_empty - > .jsontree_label-wrapper - > .jsontree_label - > .jsontree_expand-button, -.jsontree_node_empty - > .jsontree_value-wrapper - > .jsontree_value - > .jsontree_show-more { - display: none !important; -} -.jsontree_node_complex > .jsontree_label-wrapper > .jsontree_label { - cursor: pointer; -} -.jsontree_node_empty > .jsontree_label-wrapper > .jsontree_label { - cursor: default !important; -} diff --git a/static/lib/jsonTree.js b/static/lib/jsonTree.js deleted file mode 100644 index da62bcf..0000000 --- a/static/lib/jsonTree.js +++ /dev/null @@ -1,837 +0,0 @@ -/** - * JSON Tree library (a part of jsonTreeViewer) - * http://github.com/summerstyle/jsonTreeViewer - * - * Copyright 2017 Vera Lobacheva (http://iamvera.com) - * Released under the MIT license (LICENSE.txt) - */ - -var jsonTree = (function () { - /* ---------- Utilities ---------- */ - var utils = { - /* - * Returns js-"class" of value - * - * @param val {any type} - value - * @returns {string} - for example, "[object Function]" - */ - getClass: function (val) { - return Object.prototype.toString.call(val); - }, - - /** - * Checks for a type of value (for valid JSON data types). - * In other cases - throws an exception - * - * @param val {any type} - the value for new node - * @returns {string} ("object" | "array" | "null" | "boolean" | "number" | "string") - */ - getType: function (val) { - if (val === null) { - return "null"; - } - - switch (typeof val) { - case "number": - return "number"; - - case "string": - return "string"; - - case "boolean": - return "boolean"; - } - - switch (utils.getClass(val)) { - case "[object Array]": - return "array"; - - case "[object Object]": - return "object"; - } - - throw new Error("Bad type: " + utils.getClass(val)); - }, - - /** - * Applies for each item of list some function - * and checks for last element of the list - * - * @param obj {Object | Array} - a list or a dict with child nodes - * @param func {Function} - the function for each item - */ - forEachNode: function (obj, func) { - var type = utils.getType(obj), - isLast; - - switch (type) { - case "array": - isLast = obj.length - 1; - - obj.forEach(function (item, i) { - func(i, item, i === isLast); - }); - - break; - - case "object": - var keys = Object.keys(obj).sort(); - - isLast = keys.length - 1; - - keys.forEach(function (item, i) { - func(item, obj[item], i === isLast); - }); - - break; - } - }, - - /** - * Implements the kind of an inheritance by - * using parent prototype and - * creating intermediate constructor - * - * @param Child {Function} - a child constructor - * @param Parent {Function} - a parent constructor - */ - inherits: (function () { - var F = function () {}; - - return function (Child, Parent) { - F.prototype = Parent.prototype; - Child.prototype = new F(); - Child.prototype.constructor = Child; - }; - })(), - - /* - * Checks for a valid type of root node* - * - * @param {any type} jsonObj - a value for root node - * @returns {boolean} - true for an object or an array, false otherwise - */ - isValidRoot: function (jsonObj) { - switch (utils.getType(jsonObj)) { - case "object": - case "array": - return true; - default: - return false; - } - }, - - /** - * Extends some object - */ - extend: function (targetObj, sourceObj) { - for (var prop in sourceObj) { - if (sourceObj.hasOwnProperty(prop)) { - targetObj[prop] = sourceObj[prop]; - } - } - }, - }; - - /* ---------- Node constructors ---------- */ - - /** - * The factory for creating nodes of defined type. - * - * ~~~ Node ~~~ is a structure element of an onject or an array - * with own label (a key of an object or an index of an array) - * and value of any json data type. The root object or array - * is a node without label. - * {... - * [+] "label": value, - * ...} - * - * Markup: - *
  • - * - * - * - * "label" - * - * : - * - * <(div|span) class="jsontree_value jsontree_value_(object|array|boolean|null|number|string)"> - * ... - * - *
  • - * - * @param label {string} - key name - * @param val {Object | Array | string | number | boolean | null} - a value of node - * @param isLast {boolean} - true if node is last in list of siblings - * - * @return {Node} - */ - function Node(label, val, isLast) { - var nodeType = utils.getType(val); - - if (nodeType in Node.CONSTRUCTORS) { - return new Node.CONSTRUCTORS[nodeType](label, val, isLast); - } else { - throw new Error("Bad type: " + utils.getClass(val)); - } - } - - Node.CONSTRUCTORS = { - boolean: NodeBoolean, - number: NodeNumber, - string: NodeString, - null: NodeNull, - object: NodeObject, - array: NodeArray, - }; - - /* - * The constructor for simple types (string, number, boolean, null) - * {... - * [+] "label": value, - * ...} - * value = string || number || boolean || null - * - * Markup: - *
  • - * - * "age" - * : - * - * 25 - * , - *
  • - * - * @abstract - * @param label {string} - key name - * @param val {string | number | boolean | null} - a value of simple types - * @param isLast {boolean} - true if node is last in list of parent childNodes - */ - function _NodeSimple(label, val, isLast) { - if (this.constructor === _NodeSimple) { - throw new Error("This is abstract class"); - } - - var self = this, - el = document.createElement("div"), - labelEl, - template = function (label, val) { - var str = - '\ - \ - "' + - label + - '" : \ - \ - \ - ' + - val + - "" + - (!isLast ? "," : "") + - ""; - - return str; - }; - - self.label = label; - self.isComplex = false; - - el.classList.add("jsontree_node"); - el.innerHTML = template(label, val); - - self.el = el; - - labelEl = el.querySelector(".jsontree_label"); - - labelEl.addEventListener( - "click", - function (e) { - if (e.altKey) { - self.toggleMarked(); - return; - } - - if (e.shiftKey) { - document.getSelection().removeAllRanges(); - alert(self.getJSONPath()); - return; - } - }, - false - ); - } - - _NodeSimple.prototype = { - constructor: _NodeSimple, - - /** - * Mark node - */ - mark: function () { - this.el.classList.add("jsontree_node_marked"); - }, - - /** - * Unmark node - */ - unmark: function () { - this.el.classList.remove("jsontree_node_marked"); - }, - - /** - * Mark or unmark node - */ - toggleMarked: function () { - this.el.classList.toggle("jsontree_node_marked"); - }, - - /** - * Expands parent node of this node - * - * @param isRecursive {boolean} - if true, expands all parent nodes - * (from node to root) - */ - expandParent: function (isRecursive) { - if (!this.parent) { - return; - } - - this.parent.expand(); - this.parent.expandParent(isRecursive); - }, - - /** - * Returns JSON-path of this - * - * @param isInDotNotation {boolean} - kind of notation for returned json-path - * (by default, in bracket notation) - * @returns {string} - */ - getJSONPath: function (isInDotNotation) { - if (this.isRoot) { - return "$"; - } - - var currentPath; - - if (this.parent.type === "array") { - currentPath = "[" + this.label + "]"; - } else { - currentPath = isInDotNotation - ? "." + this.label - : "['" + this.label + "']"; - } - - return this.parent.getJSONPath(isInDotNotation) + currentPath; - }, - }; - - /* - * The constructor for boolean values - * {... - * [+] "label": boolean, - * ...} - * boolean = true || false - * - * @constructor - * @param label {string} - key name - * @param val {boolean} - value of boolean type, true or false - * @param isLast {boolean} - true if node is last in list of parent childNodes - */ - function NodeBoolean(label, val, isLast) { - this.type = "boolean"; - - _NodeSimple.call(this, label, val, isLast); - } - utils.inherits(NodeBoolean, _NodeSimple); - - /* - * The constructor for number values - * {... - * [+] "label": number, - * ...} - * number = 123 - * - * @constructor - * @param label {string} - key name - * @param val {number} - value of number type, for example 123 - * @param isLast {boolean} - true if node is last in list of parent childNodes - */ - function NodeNumber(label, val, isLast) { - this.type = "number"; - - _NodeSimple.call(this, label, val, isLast); - } - utils.inherits(NodeNumber, _NodeSimple); - - /* - * The constructor for string values - * {... - * [+] "label": string, - * ...} - * string = "abc" - * - * @constructor - * @param label {string} - key name - * @param val {string} - value of string type, for example "abc" - * @param isLast {boolean} - true if node is last in list of parent childNodes - */ - function NodeString(label, val, isLast) { - this.type = "string"; - - _NodeSimple.call(this, label, '"' + val + '"', isLast); - } - utils.inherits(NodeString, _NodeSimple); - - /* - * The constructor for null values - * {... - * [+] "label": null, - * ...} - * - * @constructor - * @param label {string} - key name - * @param val {null} - value (only null) - * @param isLast {boolean} - true if node is last in list of parent childNodes - */ - function NodeNull(label, val, isLast) { - this.type = "null"; - - _NodeSimple.call(this, label, val, isLast); - } - utils.inherits(NodeNull, _NodeSimple); - - /* - * The constructor for complex types (object, array) - * {... - * [+] "label": value, - * ...} - * value = object || array - * - * Markup: - *
  • - * - * - * - * "label" - * - * : - * - *
    - * { - *
      - * } - * , - *
    - *
  • - * - * @abstract - * @param label {string} - key name - * @param val {Object | Array} - a value of complex types, object or array - * @param isLast {boolean} - true if node is last in list of parent childNodes - */ - function _NodeComplex(label, val, isLast) { - if (this.constructor === _NodeComplex) { - throw new Error("This is abstract class"); - } - - var self = this, - el = document.createElement("div"), - template = function (label, sym) { - var comma = !isLast ? "," : "", - str = - '\ -
    \ -
    \ - ' + - sym[0] + - '\ - \ -
    \ - ' + - sym[1] + - "" + - "
    " + - comma + - "
    "; - - if (label !== null) { - str = - '\ - \ - ' + - '' + - '"' + - label + - '" : \ - ' + - str; - } - - return str; - }, - childNodesUl, - labelEl, - moreContentEl, - childNodes = []; - - self.label = label; - self.isComplex = true; - - el.classList.add("jsontree_node"); - el.classList.add("jsontree_node_complex"); - el.innerHTML = template(label, self.sym); - - childNodesUl = el.querySelector(".jsontree_child-nodes"); - - if (label !== null) { - labelEl = el.querySelector(".jsontree_label"); - moreContentEl = el.querySelector(".jsontree_show-more"); - - labelEl.addEventListener( - "click", - function (e) { - if (e.altKey) { - self.toggleMarked(); - return; - } - - if (e.shiftKey) { - document.getSelection().removeAllRanges(); - alert(self.getJSONPath()); - return; - } - - self.toggle(e.ctrlKey || e.metaKey); - }, - false - ); - - moreContentEl.addEventListener( - "click", - function (e) { - self.toggle(e.ctrlKey || e.metaKey); - }, - false - ); - - self.isRoot = false; - } else { - self.isRoot = true; - self.parent = null; - - el.classList.add("jsontree_node_expanded"); - } - - self.el = el; - self.childNodes = childNodes; - self.childNodesUl = childNodesUl; - - utils.forEachNode(val, function (label, node, isLast) { - self.addChild(new Node(label, node, isLast)); - }); - - self.isEmpty = !Boolean(childNodes.length); - if (self.isEmpty) { - el.classList.add("jsontree_node_empty"); - } - } - - utils.inherits(_NodeComplex, _NodeSimple); - - utils.extend(_NodeComplex.prototype, { - constructor: _NodeComplex, - - /* - * Add child node to list of child nodes - * - * @param child {Node} - child node - */ - addChild: function (child) { - this.childNodes.push(child); - this.childNodesUl.appendChild(child.el); - child.parent = this; - }, - - /* - * Expands this list of node child nodes - * - * @param isRecursive {boolean} - if true, expands all child nodes - */ - expand: function (isRecursive) { - if (this.isEmpty) { - return; - } - - if (!this.isRoot) { - this.el.classList.add("jsontree_node_expanded"); - } - - if (isRecursive) { - this.childNodes.forEach(function (item, i) { - if (item.isComplex) { - item.expand(isRecursive); - } - }); - } - }, - - /* - * Collapses this list of node child nodes - * - * @param isRecursive {boolean} - if true, collapses all child nodes - */ - collapse: function (isRecursive) { - if (this.isEmpty) { - return; - } - - if (!this.isRoot) { - this.el.classList.remove("jsontree_node_expanded"); - } - - if (isRecursive) { - this.childNodes.forEach(function (item, i) { - if (item.isComplex) { - item.collapse(isRecursive); - } - }); - } - }, - - /* - * Expands collapsed or collapses expanded node - * - * @param {boolean} isRecursive - Expand all child nodes if this node is expanded - * and collapse it otherwise - */ - toggle: function (isRecursive) { - if (this.isEmpty) { - return; - } - - this.el.classList.toggle("jsontree_node_expanded"); - - if (isRecursive) { - var isExpanded = this.el.classList.contains("jsontree_node_expanded"); - - this.childNodes.forEach(function (item, i) { - if (item.isComplex) { - item[isExpanded ? "expand" : "collapse"](isRecursive); - } - }); - } - }, - - /** - * Find child nodes that match some conditions and handle it - * - * @param {Function} matcher - * @param {Function} handler - * @param {boolean} isRecursive - */ - findChildren: function (matcher, handler, isRecursive) { - if (this.isEmpty) { - return; - } - - this.childNodes.forEach(function (item, i) { - if (matcher(item)) { - handler(item); - } - - if (item.isComplex && isRecursive) { - item.findChildren(matcher, handler, isRecursive); - } - }); - }, - }); - - /* - * The constructor for object values - * {... - * [+] "label": object, - * ...} - * object = {"abc": "def"} - * - * @constructor - * @param label {string} - key name - * @param val {Object} - value of object type, {"abc": "def"} - * @param isLast {boolean} - true if node is last in list of siblings - */ - function NodeObject(label, val, isLast) { - this.sym = ["{", "}"]; - this.type = "object"; - - _NodeComplex.call(this, label, val, isLast); - } - utils.inherits(NodeObject, _NodeComplex); - - /* - * The constructor for array values - * {... - * [+] "label": array, - * ...} - * array = [1,2,3] - * - * @constructor - * @param label {string} - key name - * @param val {Array} - value of array type, [1,2,3] - * @param isLast {boolean} - true if node is last in list of siblings - */ - function NodeArray(label, val, isLast) { - this.sym = ["[", "]"]; - this.type = "array"; - - _NodeComplex.call(this, label, val, isLast); - } - utils.inherits(NodeArray, _NodeComplex); - - /* ---------- The tree constructor ---------- */ - - /* - * The constructor for json tree. - * It contains only one Node (Array or Object), without property name. - * CSS-styles of .tree define main tree styles like font-family, - * font-size and own margins. - * - * Markup: - * - * - * @constructor - * @param jsonObj {Object | Array} - data for tree - * @param domEl {DOMElement} - DOM-element, wrapper for tree - */ - function Tree(jsonObj, domEl) { - this.wrapper = document.createElement("div"); - this.wrapper.className = "jsontree_tree clearfix"; - - this.rootNode = null; - - this.sourceJSONObj = jsonObj; - - this.loadData(jsonObj); - this.appendTo(domEl); - } - - Tree.prototype = { - constructor: Tree, - - /** - * Fill new data in current json tree - * - * @param {Object | Array} jsonObj - json-data - */ - loadData: function (jsonObj) { - if (!utils.isValidRoot(jsonObj)) { - alert("The root should be an object or an array"); - return; - } - - this.sourceJSONObj = jsonObj; - - this.rootNode = new Node(null, jsonObj, "last"); - this.wrapper.innerHTML = ""; - this.wrapper.appendChild(this.rootNode.el); - }, - - /** - * Appends tree to DOM-element (or move it to new place) - * - * @param {DOMElement} domEl - */ - appendTo: function (domEl) { - domEl.appendChild(this.wrapper); - }, - - /** - * Expands all tree nodes (objects or arrays) recursively - * - * @param {Function} filterFunc - 'true' if this node should be expanded - */ - expand: function (filterFunc) { - if (this.rootNode.isComplex) { - if (typeof filterFunc == "function") { - this.rootNode.childNodes.forEach(function (item, i) { - if (item.isComplex && filterFunc(item)) { - item.expand(); - } - }); - } else { - this.rootNode.expand("recursive"); - } - } - }, - - /** - * Collapses all tree nodes (objects or arrays) recursively - */ - collapse: function () { - if (typeof this.rootNode.collapse === "function") { - this.rootNode.collapse("recursive"); - } - }, - - /** - * Returns the source json-string (pretty-printed) - * - * @param {boolean} isPrettyPrinted - 'true' for pretty-printed string - * @returns {string} - for exemple, '{"a":2,"b":3}' - */ - toSourceJSON: function (isPrettyPrinted) { - if (!isPrettyPrinted) { - return JSON.stringify(this.sourceJSONObj); - } - - var DELIMETER = "[%^$#$%^%]", - jsonStr = JSON.stringify(this.sourceJSONObj, null, DELIMETER); - - jsonStr = jsonStr.split("\n").join("
    "); - jsonStr = jsonStr.split(DELIMETER).join("    "); - - return jsonStr; - }, - - /** - * Find all nodes that match some conditions and handle it - */ - findAndHandle: function (matcher, handler) { - this.rootNode.findChildren(matcher, handler, "isRecursive"); - }, - - /** - * Unmark all nodes - */ - unmarkAll: function () { - this.rootNode.findChildren( - function (node) { - return true; - }, - function (node) { - node.unmark(); - }, - "isRecursive" - ); - }, - }; - - /* ---------- Public methods ---------- */ - return { - /** - * Creates new tree by data and appends it to the DOM-element - * - * @param jsonObj {Object | Array} - json-data - * @param domEl {DOMElement} - the wrapper element - * @returns {Tree} - */ - create: function (jsonObj, domEl) { - return new Tree(jsonObj, domEl); - }, - }; -})(); diff --git a/static/script.js b/static/script.js index e28def6..1f199d2 100644 --- a/static/script.js +++ b/static/script.js @@ -43,13 +43,6 @@ function showResults(result) { // appendTextToNode(resultReadTime, msToTime(result.readTime || 0)); appendTextToNode(resultCode, JSON.stringify(result, null, 2)); - - //show json result - // container.textContent = ""; - // const tree = jsonTree.create(result, container); - // tree.expand(function (node) { - // return node.childNodes.length < 2 || node.label === "metadata"; - // }); console.log("result", result); } @@ -65,23 +58,9 @@ function showErrors(error) { form.addEventListener("submit", (e) => { e.preventDefault(); - const fileUrl = input.value; + const fileUrl = encodeURI(input.value.trim()); if (!fileUrl) return; - // const myHeaders = new Headers(); - // myHeaders.append("Content-Type", "application/json"); - - // const raw = JSON.stringify({ - // fileUrl: url, - // }); - - // const requestOptions = { - // method: "POST", - // headers: myHeaders, - // body: raw, - // redirect: "follow", - // }; - showLoading(); const baseURL = "https://pdfutils.redania.lat"; fetch(`${baseURL}/metadata/?url=${fileUrl}`) @@ -101,22 +80,6 @@ function appendTextToNode(node, text) { node.appendChild(textNode); } -function padTo2Digits(num) { - return num.toString().padStart(2, "0"); -} - -function msToTime(milliseconds) { - const seconds = padTo2Digits(Math.floor((milliseconds / 1000) % 60)); - const minutes = padTo2Digits(Math.floor((milliseconds / (1000 * 60)) % 60)); - const hours = padTo2Digits( - Math.floor((milliseconds / (1000 * 60 * 60)) % 24) - ); - - return `${padTo2Digits(hours)} hours, ${padTo2Digits( - minutes - )} minutes, ${padTo2Digits(seconds)} seconds`; -} - // * Automatically generate text // const textEl = document.getElementById("auto-text"); // const text = textEl.getAttribute("text"); diff --git a/static/site.webmanifest b/static/site.webmanifest index 2e1beea..cdf1f08 100644 --- a/static/site.webmanifest +++ b/static/site.webmanifest @@ -1 +1,19 @@ -{"name":"Api-Litterarum","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file +{ + "name": "PDF Metadata Extractor", + "short_name": "PdfUtils", + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +}