diff options
author | tomsmeding <tom.smeding@gmail.com> | 2017-12-24 17:19:24 +0100 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2017-12-24 17:19:24 +0100 |
commit | 6fbce51f49502c5ff5f45cef9e58973fa0f3a90c (patch) | |
tree | 4753eac41ec161a118f329c5284dc4e3ecd2d3e2 | |
parent | 77d73b37116c44a13962cd1676ea457c37d7cf96 (diff) |
Add 'save' module
-rw-r--r-- | modules/save/index.html | 41 | ||||
-rw-r--r-- | modules/save/read.html | 131 | ||||
-rw-r--r-- | modules/save/save.js | 84 |
3 files changed, 256 insertions, 0 deletions
diff --git a/modules/save/index.html b/modules/save/index.html new file mode 100644 index 0000000..d8c55ca --- /dev/null +++ b/modules/save/index.html @@ -0,0 +1,41 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>Save</title> +<script> +function doSave(){ + var text=document.getElementById("text").value.trim(); + if(text==""){ + alert("Please enter some text"); + return; + } + + var xhr=new XMLHttpRequest(); + xhr.onreadystatechange=function(){ + if(xhr.readyState==4){ + if(xhr.status!=200){ + alert("Error saving text\n"+xhr.responseText); + } else { + alert("Successfully saved!") + document.getElementById("text").value=""; + } + } + }; + xhr.open("POST","/save"); + xhr.send(text); +} +</script> +<style> +body { + font-family: sans-serif; +} +</style> +</head> +<body> +<h2>Save some text for Tom</h2> +<textarea id="text" style="width:500px;height:100px"></textarea><br> +<br> +<input type="button" value="Save" onclick="doSave()"> +</body> +</html> diff --git a/modules/save/read.html b/modules/save/read.html new file mode 100644 index 0000000..c359dd5 --- /dev/null +++ b/modules/save/read.html @@ -0,0 +1,131 @@ +<!doctype html> +<html> +<head> +<meta charset="utf-8"> +<title>Save: Read</title> +<script> +var currentFname=null; + +function populateList(arr){ + var ul=document.getElementById("ul"); + ul.innerHTML=""; + + if(arr.length==0){ + document.getElementById("nosaves").classList.remove("invisible"); + return; + } + document.getElementById("nosaves").classList.add("invisible"); + + for(var i=0;i<arr.length;i++){ + var li=document.createElement("li"); + var a=document.createElement("a"); + a.appendChild(document.createTextNode(arr[i])); + a.href="javascript:void 0"; + a.addEventListener("click",(function(i,li){return function(){ + var xhr=new XMLHttpRequest(); + xhr.onreadystatechange=function(){ + if(xhr.readyState==4){ + if(xhr.status!=200){ + alert("Error reading save '"+arr[i]+"'\n"+xhr.responseText); + } else { + var l=ul.getElementsByClassName("selected"); + for(var i=0;i<l.length;i++)l[i].classList.remove("selected"); + li.classList.add("selected"); + displaySave(arr[i],xhr.responseText); + } + } + }; + xhr.open("GET","/save/read/file/"+encodeURIComponent(arr[i])); + xhr.send(); + };})(i,li)); + li.appendChild(a); + ul.appendChild(li); + } +} + +function displaySave(fname,text){ + var e; + e=document.getElementById("filename"); + e.innerHTML=""; e.appendChild(document.createTextNode(fname)); + + e=document.getElementById("contents"); + e.innerHTML=""; e.appendChild(document.createTextNode(text)); + + document.getElementById("container").classList.remove("invisible"); + + currentFname=fname; +} + +function deleteCurrent(){ + if(!currentFname){ + alert("No save selected"); + return; + } + + if(!confirm("Really delete this save?"))return; + + var xhr=new XMLHttpRequest(); + xhr.onreadystatechange=function(){ + if(xhr.readyState==4){ + if(xhr.status!=200){ + alert("Error deleting saves\n"+xhr.responseText); + } else { + currentFname=null; + document.getElementById("container").classList.add("invisible"); + loadSaves(); + } + } + }; + xhr.open("DELETE","/save/read/file/"+encodeURIComponent(currentFname)); + xhr.send(); +} + +function loadSaves(){ + var xhr=new XMLHttpRequest(); + xhr.onreadystatechange=function(){ + if(xhr.readyState==4){ + if(xhr.status!=200){ + alert("Error listing saves\n"+xhr.responseText); + } else { + populateList(JSON.parse(xhr.responseText)); + } + } + }; + xhr.open("GET","/save/read/files"); + xhr.send(); +} + +window.addEventListener("load",function(){ + loadSaves(); +}); +</script> +<style> +body { + font-family: sans-serif; + font-size: 16px; +} +#contents { + border: 1px gray solid; + padding: 5px; + display: inline-block; +} +li.selected { + font-weight: bold; +} +.invisible { + display: none; +} +</style> +</head> +<body> +<h2>Save: Read</h2> +<div id="nosaves"><i>No saves found!</i></div> +<ul id="ul"></ul> +<br> +<div id="container" class="invisible"> + <b id="filename"></b><br> + <a href="javascript:void 0" onclick="deleteCurrent()">Delete</a><br> + <pre id="contents"></pre> +</div> +</body> +</html> diff --git a/modules/save/save.js b/modules/save/save.js new file mode 100644 index 0000000..d64e66e --- /dev/null +++ b/modules/save/save.js @@ -0,0 +1,84 @@ +var cmn=require("../$common.js"), + fs=require("fs"), + mkdirp=require("mkdirp"); + +var moddir; +var directory; + +var filenameRegex=/[^a-zA-Z0-9._-]/g; + +function pad(s,n){ + s=s+""; + var p=""; + while(s.length+p.length<n)p+="0"; + return p+s; +} + +function makefilename(){ + var d=new Date(); + var s=[ + pad(d.getFullYear(),4), pad(d.getMonth()+1,2), pad(d.getDate(),2), + pad(d.getHours(),2), pad(d.getMinutes(),2), pad(d.getSeconds(),2), + pad(d.getMilliseconds(),3) + ].join("-"); + return s+".txt"; +} + +module.exports=function(app,io,_moddir){ + moddir=_moddir; + directory=moddir+"/saves"; + + mkdirp.sync(directory); + + app.get("/save",function(req,res){ + res.sendFile(moddir+"/index.html"); + }); + app.post("/save",function(req,res){ + var s=req.body.trim(); + if(s=="")res.status(400).send("No text sent"); + fs.writeFile(directory+"/"+makefilename(),s,function(err){ + if(err){ + console.log(err); + res.status(500).send("An error occurred"); + return; + } + res.send(); + }); + }); + + app.all(["/save/read","/save/read/*"],cmn.authgen()); + + app.get("/save/read",function(req,res){ + res.sendFile(moddir+"/read.html"); + }); + app.get("/save/read/files",function(req,res){ + fs.readdir(directory,function(err,files){ + if(err){ + console.log(err); + res.status(500).send(err); + return; + } + res.send(JSON.stringify(files)); + }); + }); + app.get("/save/read/file/:fname",function(req,res){ + var fname=req.params.fname.replace(filenameRegex,""); + fs.readFile(directory+"/"+fname,function(err,text){ + if(err){ + res.status(404).send("File not found"); + return; + } + res.send(text); + }); + }); + app.delete("/save/read/file/:fname",function(req,res){ + var fname=req.params.fname.replace(filenameRegex,""); + fs.unlink(directory+"/"+fname,function(err){ + if(err){ + res.status(404).send("File not found"); + return; + } + res.send(); + }); + }); +}; |