diff options
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | debian/README.Debian | 3 | ||||
-rw-r--r-- | debian/changelog | 7 | ||||
-rw-r--r-- | html/index.html | 14 | ||||
-rw-r--r-- | html/webbox.css | 16 | ||||
-rw-r--r-- | html/webbox.js | 95 | ||||
-rw-r--r-- | src/webbox.cpp | 64 |
7 files changed, 188 insertions, 16 deletions
@@ -1,9 +1,9 @@ Prio 1 (for next version) ====== -rename function gallery - +logout +login page Prio 2 (for future versions) ====== @@ -15,3 +15,4 @@ player sandclock during operations i18n forward/back button +list: more info if appropriate diff --git a/debian/README.Debian b/debian/README.Debian index fac423e..413b4e7 100644 --- a/debian/README.Debian +++ b/debian/README.Debian @@ -129,9 +129,6 @@ VirtualHost configuration: AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch - # Order allow,deny - # Allow from all - Require all granted AuthType Basic AuthName "Webbox" diff --git a/debian/changelog b/debian/changelog index db2e3e2..b59b8d7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +webbox (1.1) unstable; urgency=medium + + * New version + * Implement renaming, UI update + + -- Roland Reichwein <mail@reichwein.it> Thu, 11 Jan 2018 15:31:06 +0100 + webbox (1.0) unstable; urgency=medium * Initial release diff --git a/html/index.html b/html/index.html index 580e415..904d5e0 100644 --- a/html/index.html +++ b/html/index.html @@ -11,7 +11,7 @@ <div> <table> <tr> - <td class="title"> </td> + <td class="title">Webbox</td> <td class="menusymbol" onclick="showMenu();"><img src="menu.png"/></td> </tr> </table> @@ -44,8 +44,10 @@ <tr class="writecommand"><td class="entry" onclick="hideMenu(); upload();">Upload</td></tr> <tr class="writecommand"><td class="entry" onclick="hideMenu(); deleteItems();">Delete</td></tr> <tr class="writecommand"><td class="entry" onclick="hideMenu(); move();">Move</td></tr> + <tr class="writecommand"><td class="entry" onclick="hideMenu(); rename();">Rename</td></tr> <tr><td class="entry" onclick="hideMenu(); info();">Info</td></tr> <tr><td class="entry" onclick="hideMenu(); selectAll();">Select/Unselect All</td></tr> + <tr><td class="entry" onclick="hideMenu(); logout();">Logout</td></tr> <tr><td class="entry" onclick="hideMenu();">Close Menu</td></tr> </table> </div> @@ -69,6 +71,16 @@ <div id="movefiles"></div> </div> + <div id="rename-dialog" hidden> + Old name: + <br/> + <div id="renameold"></div> + <br/> + New name:<br> + <input type="text" id="renamenew" class="textinput"></input> + <br/> + </div> + <a download="webbox-download.zip" id="download-a" hidden></a> <div class="footer"> diff --git a/html/webbox.css b/html/webbox.css index ffb16cc..67d87b4 100644 --- a/html/webbox.css +++ b/html/webbox.css @@ -157,6 +157,7 @@ table.list { border: 0; /* 1px solid #000000; */ cursor: pointer; background-color: #FFFFFF; + border-collapse: collapse; } table.list tr { @@ -167,15 +168,21 @@ table.list tr.selectedrow { background-color: #CCCCFF; } +table.list td { + border-width: 0; + border-bottom-width: 1px; + border-style: solid; + border-color: #808080; +} + table.list td.type { width: 50px; - border: 0; /* 1px solid #000000; */ } table.list td.name { width: 100%; - border: 0; /* 1px solid #000000; */ color: #0000FF; + white-space: pre; } @media only screen and (min-width: 1px) and (max-width: 630px) { @@ -196,4 +203,9 @@ table.list td.name { height: 100%; margin: 0; } + + table.list td { + padding: 5px; + } } + diff --git a/html/webbox.js b/html/webbox.js index 40a7a1a..7c1b43f 100644 --- a/html/webbox.js +++ b/html/webbox.js @@ -2,6 +2,16 @@ var currentDir = "/"; var listElements; var numberOfSelectedRows = 0; +function clearContents() { + var result = "<table class=\"list\">"; + result += "<tr><td class=\"type\"></td><td class=\"name\">(empty)</td></tr>"; + result += "</table>" + + var listElement = document.getElementById("list"); + + listElement.innerHTML = result; +} + function loadContents(dir) { numberOfSelectedRows = 0; @@ -39,7 +49,7 @@ function loadContents(dir) { result += "</table>" - listElement = document.getElementById("list"); + var listElement = document.getElementById("list"); listElement.innerHTML = result; @@ -301,10 +311,16 @@ function setCurrentDir(newDir) { } function download(filename) { + var files = getSelectedFiles(); + + // if activated via menu, download directly (not as zip) + if (files.length == 1 && filename === undefined) { + filename = files[0]; + } + if (filename === undefined) { // download selection as ZIP showDialog(); - var files = getSelectedFiles(); if (files.length == 0) { document.getElementById("dialog").innerHTML = "No files selected."; document.getElementById("okbutton").onclick = hideDialog; @@ -558,6 +574,70 @@ function move() { xhr.send(xmlDocument); } } +function rename() { + showDialog(); + + var files = getSelectedFiles(); + if (files.length == 0) { + document.getElementById("dialog").innerHTML = "No files selected."; + document.getElementById("okbutton").onclick = hideDialog; + return; + } + if (files.length > 1) { + document.getElementById("dialog").innerHTML = "Only one file can be renamed at once."; + document.getElementById("okbutton").onclick = hideDialog; + return; + } + + document.getElementById("renameold").innerHTML = files[0]; + + document.getElementById("dialog").innerHTML = document.getElementById("rename-dialog").innerHTML; + document.getElementById("renamenew").value = files[0]; + document.getElementById("renamenew").focus(); + document.getElementById("renamenew").onkeydown = function(evt) { + if (evt.key == "Enter") { + document.getElementById("okbutton").click(); + } + } + + document.getElementById("okbutton").onclick = function() { + + var xhr = new XMLHttpRequest(); + + xhr.onreadystatechange = function() { + if (this.readyState != 4) { + return; + } + if (this.status != 200) { + document.getElementById("dialog").innerHTML = "HTTP error"; + } else { + document.getElementById("dialog").innerHTML = xhr.responseText; + } + + document.getElementById("okbutton").onclick = hideDialog; + document.getElementById("okbutton").focus(); + loadContents(currentDir); // load new file list with deleted items + } + + var filename = getSelectedFiles()[0]; + + var parser = new DOMParser(); + var xmlDocument = parser.parseFromString("<request></request>", "text/xml"); + var filesElement = xmlDocument.getElementsByTagName("request")[0]; + + var oldnameElement = xmlDocument.createElement("oldname"); + oldnameElement.appendChild(document.createTextNode(document.getElementById("renameold").childNodes[0].nodeValue)); + filesElement.appendChild(oldnameElement); + + var newnameElement = xmlDocument.createElement("newname"); + newnameElement.appendChild(document.createTextNode(document.getElementById("renamenew").value)); + filesElement.appendChild(newnameElement); + + xhr.open("POST", "/bin/query" + currentDir + "?command=rename", true); + xhr.setRequestHeader("Content-type", "text/xml"); + xhr.send(xmlDocument); + } +} // File info: date, size, type function info() { @@ -630,3 +710,14 @@ function refresh() { loadContents(currentDir); // load new file list } +function logout() { + var menu = document.getElementsByClassName("menu")[0]; + var firsttd = menu.getElementsByClassName("firsttd")[0]; + firsttd.innerHTML = "/"; + + clearContents(); + + var p = window.location.protocol + '//' + // current location must return 200 OK for this GET + window.location = window.location.href.replace(p, p + 'logout:password@') +} diff --git a/src/webbox.cpp b/src/webbox.cpp index d0cfebc..51b6436 100644 --- a/src/webbox.cpp +++ b/src/webbox.cpp @@ -343,12 +343,16 @@ class InfoCommand: public PostCommand { QFileInfo fileInfo(m_path + "/" + filename); qint64 size = fileInfo.size(); QString date = fileInfo.lastModified().toString(); - QString type = fileInfo.isDir() ? "directory" : "file"; - FCGX_PutS(QString("%1, %2 bytes, %3 (%4)<br>") - .arg(filename) - .arg(size) - .arg(date) - .arg(type).toUtf8().data(), p.request.out); + if (fileInfo.isDir()) { + FCGX_PutS(QString("%1, %2 (folder)<br>") + .arg(filename) + .arg(date).toUtf8().data(), p.request.out); + } else { + FCGX_PutS(QString("%1, %2 bytes, %3 (file)<br>") + .arg(filename) + .arg(size) + .arg(date).toUtf8().data(), p.request.out); + } } } } @@ -547,6 +551,51 @@ class MoveCommand: public PostCommand { } }; +class RenameCommand: public PostCommand { + public: + RenameCommand() { + m_commandName = "rename"; + m_isWriteCommand = true; + } + + protected: + virtual void start(CommandParameters& p) { + if (!readContent(p)) + return; + + QXmlStreamReader xml(m_content); + + QString oldname; + QString newname; + + while (!xml.atEnd()) { + while (xml.readNextStartElement()) { + if (xml.name() == "request") { + while (xml.readNextStartElement()) { + if (xml.name() == "oldname") { + oldname = xml.readElementText(); + } else + if (xml.name() == "newname") { + newname = xml.readElementText(); + } + } + } + } + } + + QDir dir(m_path); + QString response; + if (!dir.rename(oldname, newname)) { + response = QString("Error renaming %1 to %2<br/>").arg(oldname).arg(newname); + } else { + response = "OK"; + } + + FCGX_PutS("Content-Type: text/plain\r\n\r\n", p.request.out); + FCGX_PutS(response.toUtf8().data(), p.request.out); + } +}; + class UploadCommand: public PostCommand { public: UploadCommand() { @@ -712,6 +761,9 @@ int main(int argc, char* argv[]) { MoveCommand moveCommand; commands.registerCommand(moveCommand); + RenameCommand renameCommand; + commands.registerCommand(renameCommand); + UploadCommand uploadCommand; commands.registerCommand(uploadCommand); |