Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!doctype html>
- <html>
- <head>
- <!--
- MechanicDB v1.0.1. AGPL v3. February 2022.
- https://www.reddit.com/user/jcunews1
- https://greasyfork.org/en/users/85671-jcunews
- https://pastebin.com/u/jcunews
- Context:
- https://www.reddit.com/r/Batch/comments/sji28h/batch_script_for_mechanic/
- Database file is in CSV format and in stored at:
- %USERPROFILE%\MechanicDB.csv
- e.g.: C:\Users\myusername\MechanicDB.csv
- Save this code as `MechanicDB.hta`. NOT as `MechanicDB.html` or `MechanicDB.htm`.
- -->
- <meta charset=utf-8 />
- <meta http-equiv="x-ua-compatible" content="IE=9" />
- <title>MechanicDB</title>
- <style>
- body { margin: 3.5em 0 0 0; overflow-y: scroll; text-align: center }
- body, input, button { min-width: 3em; font: 16pt/normal sans-serif }
- input, button { padding: 0 .2em; width: auto; font: inherit }
- #form {
- display: block; position: fixed; left: 0; top: 0; right: 0;
- border-bottom: .1em solid #000; padding: .5em 0; background: #dde;
- }
- #lTime { position: absolute; left: .5em; top: .3em; font-size: 10pt }
- #tList td { padding: .5em .2em; max-width: 75vw }
- #tList a {
- display: inline-block; margin: .3em; border: 1px solid #aaa;
- padding: .1em .2em 0 .2em; background: #eee; text-decoration: none;
- }
- #tList a:hover { background: #00c; color: #cc0 }
- #bList { position: absolute; top: .5em; right: .5em }
- #eQuery { margin-right: .5em; padding: 0 .3em; width: 7.7em }
- #tList, #tNewRecord, #tMileages {
- display: none; margin: 1em auto 0 auto; border: .1em solid #ddd
- }
- #pRecord { display: none; margin: 0 auto }
- #tMileages {
- display: table; margin-top: .5em; border: none; border-spacing: .2em;
- }
- th, td { padding: .1em .2em; font-weight: normal }
- #tRecord tr:nth-child(4) td { padding: 1em .2em .5em .2em }
- #eAddMileage, #eNewMileage { width: 4em }
- #bAddMileage { margin-left: .5em }
- #tMileages tr:nth-child(2) th { background: #666 }
- #tMileages td { background: #ddd }
- #tMileages td:first-child { padding-right: 1em; text-align: right }
- #tMileages tr:nth-child(2n+1) td { background: #fff }
- #tMileages button {
- display: none; position:absolute; margin-left: 1em; min-width: 1.5em;
- font-size: 13pt
- }
- #tMileages tr:last-child button { display: inline-block }
- #tNewRecord { border-spacing: .3em; width: 25.5em }
- th { background: #000; color: #fff }
- td { text-align: left }
- #tNewRecord td:first-child { width: 5em; white-space: nowrap }
- #tNewRecord tr:last-child td { padding-top: 1em; text-align:center }
- </style>
- <style id=ls></style>
- </head>
- <body>
- <hta:application qwindowstate=maximize></hta:application>
- <div id=form>
- <form id=fQuery onsubmit="return query()">
- <div id=lTime></div>
- License Plate:
- <input id=eQuery tabindex=1 onkeydown="setTimeout(qinput,0)" />
- <button id=bQuery type=submit tabindex=2>Query</button>
- </form>
- <button id=bList tabindex=3 onclick="return list()">List</button>
- </div>
- <p id=lMessage>Please enter a license plate.</p>
- <table id=tList>
- <tr><th>License Plates</th></tr>
- <tr><td></td></tr>
- </table>
- <div id=pRecord>
- <form id=fMileage onsubmit="return addMileage()">
- <table id=tRecord>
- <tr><td>License Plate:</td><td id=lLicensePlate></td></tr>
- <tr><td>Created:</td><td id=lCreated></td></tr>
- <tr><td>Last Updated:</td><td id=lUpdated></td></tr>
- <tr>
- <td>Add Mileage:</td>
- <td>
- <input id=eAddMileage /> miles
- <button id=bAddMileage type=submit>Add</button>
- </td>
- </tr>
- </table>
- </form>
- <table id=tMileages>
- <tr><th colspan=3>Mileages</th></tr>
- <tr><th>Number</th><th>Time</th><th>Mileage</th></tr>
- </table>
- </div>
- <form id=fNewRecord onsubmit="return newRecord()">
- <table id=tNewRecord>
- <tr><td>License Plate:</td><td id=lNewLicensePlate></td></tr>
- <tr><td>Mileage:</td><td><input id=eNewMileage /> miles</td></tr>
- <tr>
- <td colspan=2>
- <button id=bNewRecord type=submit>OK</button>
- </td>
- </tr>
- </table>
- </form>
- <script>
- function qinput() {
- if (!tList.style.display) return;
- if (s = eQuery.value.trim()) {
- ls.innerHTML = '\
- #tList a { display: none }\
- #tList a[plate*="' + s.toUpperCase() + '"] { display:inline-block }'
- } else ls.innerHTML = ""
- }
- function dispRec() {
- query(this.getAttribute("plate"));
- return false
- }
- function list() {
- eQuery.value = "";
- (c = tList.rows[1].cells[0]).innerHTML = "";
- ks = Object.keys(data).sort();
- for (i = 0; i < arr.length; i++) {
- (e = document.createElement("A")).innerText = ks[i];
- e.href = "#";
- e.setAttribute("plate", ks[i]);
- e.onclick = dispRec;
- c.appendChild(e);
- }
- lMessage.style.display = "none";
- tList.style.display = "table";
- pRecord.style.display = "";
- tNewRecord.style.display = "";
- eQuery.focus();
- return false
- }
- function query(s) {
- if (s = s || eQuery.value.trim().toUpperCase()) {
- tList.style.display = "";
- if (rec = data[s]) {
- lMessage.style.display = "none";
- lLicensePlate.innerText = s;
- lCreated.innerText = (new Date(rec.created)).toLocaleString();
- lUpdated.innerText = (new Date(rec.lastUpdated)).toLocaleString();
- b = tMileages.tBodies[0].cloneNode(true);
- while (b.rows.length > 2) b.deleteRow(2);
- for (i = 0; i < rec.mileages.length; i++) {
- r = b.insertRow();
- r.insertCell().innerText = i + 1;
- r.insertCell().innerText =
- (new Date(parseInt(rec.mileages[i].time))).toLocaleString();
- (c = r.insertCell()).innerHTML =
- rec.mileages[i].mileage + " miles<button>X</button>";
- c.firstElementChild.rec = rec;
- c.firstElementChild.mIndex = i;
- c.firstElementChild.onclick = delMileage;
- }
- tMileages.replaceChild(b, tMileages.tBodies[0]);
- eAddMileage.value = "";
- lMessage.innerText = "License plate found.";
- pRecord.style.display = "table";
- tNewRecord.style.display = "";
- eAddMileage.focus()
- } else {
- lNewLicensePlate.innerText = s;
- eNewMileage.value = "";
- lMessage.style.display = "";
- lMessage.innerText = "\
- No matching license plate found.\n\
- Enter other license plate above, or enter data for a new license plate below.";
- pRecord.style.display = "";
- tNewRecord.style.display = "table";
- eNewMileage.focus()
- }
- } else {
- alert("License plate must not be empty.");
- eQuery.focus()
- }
- return false
- }
- function saveData() {
- fs.copyFile(dataFile, dataFile.replace(".csv", ".bak"), true);
- fData = fs.createTextFile(dataFile, true);
- ks = Object.keys(data);
- buf = [];
- for (i = ks.length - 1; i >= 0; i--) {
- rec = data[ks[i]];
- ms = [];
- for (j = 0; j < rec.mileages.length; j++) {
- ms.push(rec.mileages[j].time);
- ms.push(rec.mileages[j].mileage);
- }
- arr = [rec.licensePlate, rec.created, rec.lastUpdated];
- Array.prototype.push.apply(arr, ms);
- buf.push(arr.join(","))
- }
- fData.writeLine(buf.join("\n"));
- fData.close();
- }
- function addMileage() {
- if (s = eAddMileage.value.trim()) {
- if (/^\d+$/.test(s) && ((s = parseInt(s)) >= 0)) {
- t = Date.now();
- rec.mileages.push({time: t, mileage: s});
- rec.lastUpdated = t;
- saveData();
- lUpdated.innerText = (new Date(t)).toLocaleString();
- (r = tMileages.insertRow()).insertCell().innerText = rec.mileages.length;
- r.insertCell().innerText = (new Date(t)).toLocaleString();
- (c = r.insertCell()).innerHTML = s + " miles<button>X</button>";
- c.firstElementChild.mIndex = rec.mileages.length - 1;
- c.firstElementChild.onclick = delMileage
- } else alert("Mileage must be a positive integer number.")
- } else alert("Mileage must not be empty.");
- eAddMileage.select();
- eAddMileage.focus()
- return false
- }
- function delMileage() {
- if (!confirm("Delete this mileage entry?")) return;
- rec.mileages.pop();
- rec.lastUpdated = (t = Date.now());
- saveData();
- lUpdated.innerText = (new Date(t)).toLocaleString();
- (r = this.parentNode.parentNode).parentNode.removeChild(r);
- eAddMileage.focus()
- }
- function newRecord() {
- if (s = eNewMileage.value.trim()) {
- if (/^\d+$/.test(s) && ((s = parseInt(s)) >= 0)) {
- t = Date.now();
- data[lNewLicensePlate.innerText] = {
- licensePlate: lNewLicensePlate.innerText,
- created: t,
- lastUpdated: t,
- mileages: [{time: t, mileage: s}]
- };
- saveData();
- query(lNewLicensePlate.innerText)
- } else {
- alert("Mileage must be a positive integer number.");
- eNewMileage.select();
- eNewMileage.focus()
- }
- } else {
- alert("Mileage must not be empty.");
- eNewMileage.focus()
- }
- return false
- }
- String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g) };
- eQuery = fQuery.eQuery;
- eAddMileage = fMileage.eAddMileage;
- eNewMileage = fNewRecord.eNewMileage;
- setTimeout(function() { eQuery.focus() }, 0);
- fs = new ActiveXObject("scripting.filesystemobject");
- ws = new ActiveXObject("wscript.shell");
- dataFile = ws.environment("process")("userprofile") + "\\MechanicDB.csv";
- fData = fs.openTextFile(dataFile, 1, true);
- if (!fData.atEndOfStream) {
- buf = fData.readAll().split("\n")
- } else buf = [];
- fData.close();
- data = {};
- for (i = buf.length - 1; i >= 0; i--) {
- if (!(buf[i] = buf[i].trim())) continue;
- arr = buf[i].split(",");
- ms = [];
- for (j = 0; j < (arr.length - 3) / 2; j++) {
- ms.push({
- time: parseInt(arr[j * 2 + 3]), mileage: parseInt(arr[j * 2 + 4])
- })
- }
- rec = {
- licensePlate: arr[0],
- created: parseInt(arr[1]),
- lastUpdated: parseInt(arr[2]),
- mileages: ms
- };
- data[rec.licensePlate] = rec
- }
- (function updTime(t) {
- lTime.innerText =
- (t = new Date).toLocaleDateString().replace(", ", "\n") + "\n" + t.toLocaleTimeString();
- setTimeout(updTime, 50)
- })()
- </script>
- </body>
- </html>
Add Comment
Please, Sign In to add comment