Greasy Fork is available in English.

IoTTalk Delete Device

Delete multiple devices in IoTTalk using regular expressions


Installer ce script?
  1. // ==UserScript==// @name IoTTalk Delete Device// @namespace Fractalism// @version 1.1.2// @description Delete multiple devices in IoTTalk using regular expressions// @author Fractalism// @match http*://*.iottalk.tw/list_all// @grant none// ==/UserScript==(function () {'use strict';// make find-and-delete UI(function CreateUI() {var MainUI = document.createElement('div');document.body.appendChild(MainUI);MainUI.id = 'main-UI';MainUI.innerHTML = `<form action='javascript:void(0)'><span>Find and delete</span><br><input type='text' id='d_name-input'><br><div id='search-div'><button id='search-btn'>Search</button><button id='hint-message' disabled><b>?</b></button></div><div id='delete-div' style='display:none'><button id='delete-btn'>Delete</button><button id='cancel-btn'>Cancel</button></div><div id='param-div'><label><input type='checkbox' id='case_sensitive'><small>Case-sensitive search</small></label><br><label><input type='checkbox' id='no_project' checked><small>Match unused devices only</small></label></div></form>`;MainUI.style.position = 'fixed';MainUI.style.top = '20px'; // pixelsMainUI.style.right = '20px'; // pixelsMainUI.style.backgroundColor = 'white';MainUI.style.border = '1px black solid';MainUI.style.padding = '5px 15px 5px 15px';MainUI.style.borderRadius = '10px';var d_name_Input = document.getElementById('d_name-input');d_name_Input.onkeydown = function () {if (!(event.which == 13 || event.keyCode == 13)) {switch_display(1);}}var SearchDiv = document.getElementById('search-div');SearchDiv.style.position = 'relative'; // to position HintButton correctlySearchDiv.style.width = d_name_Input.clientWidth;var DeleteDiv = document.getElementById('delete-div');DeleteDiv.style.position = 'relative';var ParamsDiv = document.getElementById('param-div');var SearchButton = document.getElementById('search-btn');SearchButton.onclick = function () {var params = {case_sensitive: document.getElementById('case_sensitive').checked,no_project: document.getElementById('no_project').checked,}find_devices(params);switch_display(2);d_name_Input.focus();};var DeleteButton = document.getElementById('delete-btn');DeleteButton.onclick = function () {var confirm = delete_devices();if (confirm) {switch_display(1);}};var CancelButton = document.getElementById('cancel-btn');CancelButton.onclick = function () {window.device_matches = [];switch_display(1);}var HintButton = document.getElementById('hint-message');HintButton.style.position = 'absolute';//HintButton.style.bottom = '10px';HintButton.style.right = '0px';HintButton.style.width = '1.5em';HintButton.style.height = '1.5em';HintButton.style.border = '1.5px black solid';HintButton.style.borderRadius = '50%';HintButton.style.color = 'black';HintButton.style.backgroundColor = 'white';HintButton.style.padding = '0px';HintButton.title = `Hint:\n> Type part of the d_name or use a regex, check the console for r###lts.\n> Search empty string to get all devices on the server.\n> Right click on an <a> element in a match and select "Scroll into view" to see the device on the webpage.`;var my_style = document.createElement('style');my_style.innerHTML = `div#main-UI * {text-align: center; margin: 5px 0px 5px 0px;}div#main-UI * {font-family: Arial, Helvetica, sans-serif;}div#main-UI div {margin: 0px auto 0px auto; padding: 0px 0px 0px 0px;}div#main-UI input[type=checkbox] {margin: 5px 5px 5px 5px;}div#main-UI #param-div {text-align: left;}`; // apply to everything inside divdocument.head.appendChild(my_style);// switch to display certain buttons// mode: 1=search mode, 2=delete modefunction switch_display(mode) {switch (mode) {case 1:SearchDiv.style.display = 'block';DeleteDiv.style.display = 'none';ParamsDiv.style.display = 'block';break;case 2:SearchDiv.style.display = 'none';DeleteDiv.style.display = 'block';ParamsDiv.style.display = 'none';break;default:}}})();// modify send_delete function for one-by-one deletions without refreshing pagewindow.send_delete = send_delete_single;function send_delete_single(url) {$.ajax({url: url,type: 'DELETE',success: (r###lt) => alert(`Device with MAC address ${url.substr(1)} deleted successfully.`),error: (jqXHR, textStatus, errorThrown) => alert(`Error deleting ${url.substr(1)}\ntextStatus: ${textStatus}\nerrorThrown: ${errorThrown}`)});event.preventDefault(); // don't scroll to top after deleting}// for batch deletions (send output to console instead)function send_delete_batch(url) {$.ajax({url: url,type: 'DELETE',success: (r###lt) => console.log(`Device with MAC address ${url.substr(1)} deleted successfully.`),error: (jqXHR, textStatus, errorThrown) => console.log(`Error deleting ${url.substr(1)}\ntextStatus: ${textStatus}\nerrorThrown: ${errorThrown}`)});event.preventDefault();}// find devices with d_name matching input regexfunction find_devices(params) {console.clear();var d_name = document.getElementById('d_name-input').value;console.log('Search d_name: ' + d_name);var index, node, matches = [],skipped = [];for ([index, node] of window.relevantNodes.entries()) {if (node.nodeType == node.TEXT_NODE && node.nodeValue.search(RegExp(`d_name: .*${d_name}`, params.case_sensitive ? '' : 'i')) != -1) {if (params.no_project && node.nodeValue.trim().search(/project:$/) != -1 && (node.nextSibling.getAttribute('onclick') && node.nextSibling.getAttribute('onclick').indexOf('open_project(') != -1)) {skipped.push([node, window.relevantNodes[index - 1]]);} else {matches.push([node, window.relevantNodes[index - 1]]); // text node and link to delete device}}}console.log(`Found ${matches.length+skipped.length} devices (${matches.length} matched, ${skipped.length} skipped)`);console.groupCollapsed(`Matched devices (${matches.length})`);for (let i = 0; i < matches.length; ++i) {let d_name, dm_name;let lines = matches[i][0].nodeValue.split('\n');for (let line of lines) {if (line.search('d_name:') != -1) d_name = line.trim();if (line.search('dm_name:') != -1) dm_name = line.trim();}console.log(`Match ${i+1}:\n ${d_name}\n ${dm_name}\n`, matches[i][1]);};console.groupEnd();console.groupCollapsed(`Skipped devices (${skipped.length})`);for (let i = 0; i < skipped.length; ++i) {let d_name, dm_name;let lines = skipped[i][0].nodeValue.split('\n');for (let line of lines) {if (line.search('d_name:') != -1) d_name = line.trim();if (line.search('dm_name:') != -1) dm_name = line.trim();}console.log(`Skip ${i+1}:\n ${d_name}\n ${dm_name}\n`, skipped[i][1]);}console.groupEnd();window.device_matches = matches;}function delete_devices() {var matches = window.device_matches;if (!confirm(`Delete all ${matches.length} matched devices?`)) return false;window.send_delete = send_delete_batch;var index, match;for ([index, match] of matches.entries()) {console.log(`Deleting match ${index+1}`);match[1].onclick();}window.send_delete = send_delete_single;return true;}// get all relevant nodes only once at start(function collect_nodes() {var relevantNodes = [];var walker = document.createTreeWalker(document.body.firstElementChild, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, function my_filter(node) {if (node.nodeType == node.TEXT_NODE && node.nodeValue.indexOf('d_name:') != -1 || node.nodeType == node.ELEMENT_NODE && node.nodeName == "A" && node.innerText == "Delete") {return NodeFilter.FILTER_ACCEPT;} else {return NodeFilter.FILTER_SKIP;}});let node;while (node = walker.nextNode()) {if (node.nodeName == "HR") break; // scan device part, skip DF-module partrelevantNodes.push(node);}window.relevantNodes = relevantNodes;})();})();