Commit 12fd3332 by murtaugh

rename, delete, and touch buttons, and no more cgi-bin!

1 parent 68719ef4
......@@ -10,6 +10,23 @@
form.target {
display: inline;
}
#filecontrols {
display: none;
position: absolute;
left: 0px;
top: 18px;
z-index: 1;
width: 360px;
border-top: 5px solid aqua;
background: aqua;
padding: 5px;
}
td.filecontrols {
position: relative;
}
td.filecontrols.active {
background: aqua;
}
</style>
</head>
<body>
......@@ -22,9 +39,9 @@ form.target {
{% endif %}
{% for item in items %}
{% if item.is_dir %}
<tr class="{{item.classes}}"><td valign="top"><img src="/__makeserver__/icons/directory.symbolic.png" alt="[DIR]"></td><td><a href="{{item.link}}">{{item.label}}</a>{{item.buttons}}</td><td align="right">{% if item.lasmod %}{{item.lastmod | strftime("%Y-%m-%d %H:%M")}}{%else%}&mdash;{%endif%}</td><td align="right"> - </td><td>&nbsp;</td></tr>
<tr class="{{item.classes}}"><td class="filecontrols" valign="top"><img src="/__makeserver__/icons/directory.symbolic.png" alt="[DIR]"></td><td><a href="{{item.link}}">{{item.label}}</a>{{item.buttons}}</td><td align="right">{% if item.lasmod %}{{item.lastmod | strftime("%Y-%m-%d %H:%M")}}{%else%}&mdash;{%endif%}</td><td align="right"> - </td><td>&nbsp;</td></tr>
{% else %}
<tr class="{{item.classes}}"><td valign="top"><a href="{{item.link}}?edit"><img src="/__makeserver__/icons/{% if item.is_text %}text{%else%}generic{%endif%}.symbolic.png" alt="[ ]" border="0"></a></td><td><a href="{{item.link}}{% if item.is_text and not (item.ext == "html" or item.ext == "svg")%}?edit{% endif %}">{{item.label}}</a>{{item.buttons}}</td><td align="right">{% if item.lastmod %}{{item.lastmod | strftime("%Y-%m-%d %H:%M")}}{%else%}&mdash;{%endif%} </td><td align="right">{{item.size|humanize_bytes}}</td><td>&nbsp;</td></tr>
<tr class="{{item.classes}}"><td class="filecontrols" valign="top"><a class="filecontrols" href="{{item.link}}?edit"><img src="/__makeserver__/icons/{% if item.is_text %}text{%else%}generic{%endif%}.symbolic.png" alt="[ ]" border="0"></a></td><td class="filename"><a href="{{item.link}}{% if item.is_text and not (item.ext == "html" or item.ext == "svg")%}?edit{% endif %}">{{item.label}}</a>{{item.buttons}}</td><td align="right">{% if item.lastmod %}{{item.lastmod | strftime("%Y-%m-%d %H:%M")}}{%else%}&mdash;{%endif%} </td><td align="right">{{item.size|humanize_bytes}}</td><td>&nbsp;</td></tr>
{% endif %}
{% endfor %}
</table>
......@@ -37,7 +54,19 @@ form.target {
<form class="target" action="{{rurl}}"><input type="submit" name="target" value="{{t}}"></form>{% endfor %}
</span>
</div>
<div id="filecontrols">
<button id="touchfile">touch</button>
<button id="renamefile">rename</button>
<button id="deletefile">delete</button>
<!-- <button id="remakefile">remake</button>
<div id="filecontrolsokbuttons">
<button id="filecontrolsok">OK</button>
<button id="filecontrolscancel">cancel</button>
</div>
-->
</div>
<script>
/*
function getjson (url, callback) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
......@@ -62,12 +91,46 @@ function getjson (url, callback) {
};
request.send();
}
*/
function post (url, data, callback) {
var request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
// request.setRequestHeader('Content-Type', 'application/octet-stream');
request.onload = function() {
if (request.readyState == XMLHttpRequest.DONE && request.status >= 200 && request.status < 400) {
// Success!
var resp = request.responseText;
callback(null, resp);
} else {
callback("server error");
}
};
request.onerror = function() {
callback("connection error");
};
var sdata = "";
for (var key in data) {
if (data.hasOwnProperty(key)) {
sdata += (sdata?"&":"") + key+"="+encodeURIComponent(data[key]);
}
}
request.send(sdata);
}
var touch = document.getElementById("touch");
touch.addEventListener("click", function () {
var name = prompt("touch");
if (name) {
var path = window.location.pathname + name;
post(path, {"touch": "1"}, function (err, data) {
if (err) {
alert("ERROR: " + err);
} else {
window.location.reload();
}
});
/*
getjson("/__makeserver__/cgi-bin/touch.cgi?path=" + encodeURIComponent(path),function (err, data) {
console.log("data", data);
if (data.result === 0) {
......@@ -77,8 +140,101 @@ touch.addEventListener("click", function () {
alert("that didn't work (" + data.result + ")");
}
});
*/
}
}, false);
var fc = document.getElementById("filecontrols");
Array.prototype.slice.call(document.querySelectorAll("a.filecontrols")).forEach(function (x) {
x.addEventListener("click", function (e) {
e.preventDefault();
console.log("click");
x.parentNode.appendChild(fc);
fc.style.display = "block";
x.parentNode.classList.add("active");
})
});
fc.addEventListener("mouseleave", function () {
fc.style.display = "none";
Array.prototype.slice.call(document.querySelectorAll("td.filecontrols.active")).forEach(function (x) {
x.classList.remove("active");
});
});
fc.querySelector("#touchfile").addEventListener("click", function () {
var td = document.querySelector("td.filecontrols.active"),
td2, td2a, originalPath;
if (td) {
td2 = td.parentNode.querySelector("td.filename");
td2a = td2.querySelector("a");
originalPath = td2a.textContent;
post(originalPath, {"touch": "1"}, function (err, response) {
if (err) {
alert("ERROR: " + err);
} else {
window.location.reload();
}
})
}
});
fc.querySelector("#deletefile").addEventListener("click", function () {
var td = document.querySelector("td.filecontrols.active"),
td2, td2a, originalPath;
if (td) {
td2 = td.parentNode.querySelector("td.filename");
td2a = td2.querySelector("a");
originalPath = td2a.textContent;
if (confirm("are you sure?")) {
post(originalPath, {"delete": "1"}, function (err, response) {
if (err) {
alert("ERROR: " + err);
} else {
window.location.reload();
}
})
}
}
});
fc.querySelector("#renamefile").addEventListener("click", function () {
var td = document.querySelector("td.filecontrols.active"),
td2, td2a, t, exit, originalPath;
if (td) {
exit = function () {
t.remove();
td2a.style.display = "inline";
}
td2 = td.parentNode.querySelector("td.filename");
td2a = td2.querySelector("a");
originalPath = td2a.textContent;
t = document.createElement("input");
td2a.style.display = "none";
t.value = originalPath;
td2.appendChild(t);
t.focus();
t.addEventListener("keypress", function (e) {
// console.log("keypress", e, e.keyCode);
if (e.keyCode == 13) {
console.log("ENTER");
var path = window.location.pathname + originalPath;
post(path, {"rename": "1", "to": t.value}, function (err, resp) {
if (err) {
exit();
alert("ERROR: " + err);
} else {
// exit();
window.location.reload();
}
});
// exit();
} else if (e.keyCode == 27) {
// console.log("ESCAPE");
exit();
}
});
}
});
</script>
</body>
</html>
......@@ -115,19 +115,41 @@ def maker (path, queue):
class FileSaver (Resource):
def __init__(self, path):
def __init__(self, path, docroot=None):
self.path = path
self.isLeaf = True
self.docroot = docroot
def render_POST(self, request):
# print ("FileSaver.POST", self.path, request)
data = request.content.read()
data = parse_qs(data)
# print ("data", data)
if "text" in data:
if "touch" in data:
# touch the file
with open(self.path, 'a'):
os.utime(self.path, None)
elif "rename" in data:
if "to" in data:
base = os.path.split(self.path)[0]
newpath = os.path.abspath(os.path.join(base, data['to'][0]))
if self.docroot and not newpath.startswith(self.docroot):
print (u"BAD Rename attempt '{0}' to '{1}'".format(self.path, newpath).encode("utf-8"))
return "BAD PATH"
# print (u"Renaming '{0}' to '{1}'".format(self.path, newpath).encode("utf-8"))
os.rename(self.path, newpath)
elif "text" in data:
text = data['text'][0]
with open(self.path, "w") as f:
f.write(text)
elif "data" in data:
data = data['text'][0]
with open(self.path, "wb") as f:
f.write(data)
elif "delete" in data:
# rm the file
# print (u"Deleting {0}".format(self.path).encode("utf-8"))
os.remove(self.path)
return "OK"
# if os.path.isdir(self.path) and not self.path.endswith("/"):
......@@ -171,7 +193,7 @@ class FileMaker (Resource):
query = parse_qs2(urlparse(request.uri).query)
if request.method == "POST":
return FileSaver(fpath)
return FileSaver(fpath, self.docroot)
if request.path == '/' or request.path.endswith("/"):
if 'target' in query:
# HANDLE a ?target=NAME request
......@@ -316,8 +338,8 @@ def main (args=None):
root_resource = FileMaker(docroot, make_requests, docroot, listing, makefile)
corehtdocs = File(corehtdocspath)
root_resource.putChild("__makeserver__", corehtdocs)
corecgibin = CGIDirectory(corecgibinpath)
corehtdocs.putChild("cgi-bin", corecgibin)
# corecgibin = CGIDirectory(corecgibinpath)
# corehtdocs.putChild("cgi-bin", corecgibin)
if args.alias:
for mnt, path in args.alias:
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!