Updates
Former-commit-id: 35d375188e7c700484d32a27eb48b30192e20537
This commit is contained in:
parent
5fc83eff7e
commit
f1f248e4d6
|
@ -15,7 +15,7 @@ charset = utf-8
|
||||||
|
|
||||||
# 4 space indentation
|
# 4 space indentation
|
||||||
[*.go]
|
[*.go]
|
||||||
indent_style = space
|
indent_style = tab
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
# Indentation override for all JS under lib directory
|
# Indentation override for all JS under lib directory
|
||||||
|
|
|
@ -4,7 +4,8 @@ var tempID = "_fm_internal_temporary_id",
|
||||||
buttons = {},
|
buttons = {},
|
||||||
templates = {},
|
templates = {},
|
||||||
selectedItems = [],
|
selectedItems = [],
|
||||||
overlay, clickOverlay;
|
overlay, clickOverlay,
|
||||||
|
webdav = {};
|
||||||
|
|
||||||
// Removes an element, if exists, from an array
|
// Removes an element, if exists, from an array
|
||||||
Array.prototype.removeElement = function(element) {
|
Array.prototype.removeElement = function(element) {
|
||||||
|
@ -112,6 +113,33 @@ function getCSSRule(rules) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* WEBDAV *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * */
|
||||||
|
// TODO: here, we should create an abstraction layer from the webdav.
|
||||||
|
// We must create functions that do the requests to the webdav backend.
|
||||||
|
// this functions will contain a 'callback' to be used withing the other function.
|
||||||
|
|
||||||
|
webdav.rename = function(oldLink, newLink, callback) {
|
||||||
|
let request = new XMLHttpRequest();
|
||||||
|
|
||||||
|
request.open('MOVE', toWebDavURL(oldLink));
|
||||||
|
request.setRequestHeader('Destination', toWebDavURL(newLink));
|
||||||
|
request.send();
|
||||||
|
request.onreadystatechange = function() {
|
||||||
|
if (request.readyState == 4) {
|
||||||
|
if (typeof callback == 'function') {
|
||||||
|
// This callback argument is a 'success'
|
||||||
|
callback(request.status == 201 || request.status == 204);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* EVENTS *
|
* EVENTS *
|
||||||
|
@ -176,11 +204,11 @@ function openEvent(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectMoveFolder(event) {
|
function selectMoveFolder(event) {
|
||||||
if(event.target.getAttribute("aria-selected") === "true") {
|
if (event.target.getAttribute("aria-selected") === "true") {
|
||||||
event.target.setAttribute("aria-selected", false);
|
event.target.setAttribute("aria-selected", false);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if(document.querySelector(".file-list li[aria-selected=true]")) {
|
if (document.querySelector(".file-list li[aria-selected=true]")) {
|
||||||
document.querySelector(".file-list li[aria-selected=true]").setAttribute("aria-selected", false);
|
document.querySelector(".file-list li[aria-selected=true]").setAttribute("aria-selected", false);
|
||||||
}
|
}
|
||||||
event.target.setAttribute("aria-selected", true);
|
event.target.setAttribute("aria-selected", true);
|
||||||
|
@ -189,71 +217,89 @@ function selectMoveFolder(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadNextFolder(event) {
|
function loadNextFolder(event) {
|
||||||
let request = new XMLHttpRequest(),
|
let request = new XMLHttpRequest(),
|
||||||
prompt = document.querySelector("form.prompt.active");
|
prompt = document.querySelector("form.prompt.active");
|
||||||
prompt.addEventListener("submit", moveSelected);
|
|
||||||
|
|
||||||
request.open("GET", "/" + event.target.innerHTML);
|
prompt.addEventListener("submit", moveSelected);
|
||||||
request.setRequestHeader("Accept", "application/json");
|
|
||||||
request.send();
|
|
||||||
request.onreadystatechange = function() {
|
|
||||||
if(request.readyState == 4 && request.status == 200) {
|
|
||||||
prompt.querySelector("ul").innerHTML = "";
|
|
||||||
for(let f of JSON.parse(request.response)) {
|
|
||||||
if(f.URL.substr(f.URL.length - 1) == "/") {
|
|
||||||
if(selectedItems.includes(btoa(f.URL.split("/")[1]))) continue;
|
|
||||||
let newNode = document.createElement("li");
|
|
||||||
newNode.innerHTML = (f.URL.replace("/" + event.target.innerHTML, "").split("/").join(""));
|
|
||||||
newNode.setAttribute("aria-selected", false);
|
|
||||||
|
|
||||||
newNode.addEventListener("dblclick", loadNextFolder);
|
request.open("GET", event.target.dataset.url);
|
||||||
newNode.addEventListener("click", selectMoveFolder);
|
request.setRequestHeader("Accept", "application/json");
|
||||||
|
request.send();
|
||||||
|
request.onreadystatechange = function() {
|
||||||
|
if (request.readyState == 4 && request.status == 200) {
|
||||||
|
let dirs = 0;
|
||||||
|
|
||||||
prompt.querySelector("ul").appendChild(newNode);
|
prompt.querySelector("ul").innerHTML = "";
|
||||||
|
prompt.querySelector('code').innerHTML = event.target.dataset.url;
|
||||||
|
|
||||||
|
for (let f of JSON.parse(request.response)) {
|
||||||
|
if (f.IsDir === true) {
|
||||||
|
dirs++;
|
||||||
|
|
||||||
|
let newNode = document.createElement("li");
|
||||||
|
newNode.dataset.url = f.URL;
|
||||||
|
newNode.innerHTML = f.Name;
|
||||||
|
newNode.setAttribute("aria-selected", false);
|
||||||
|
|
||||||
|
newNode.addEventListener("dblclick", loadNextFolder);
|
||||||
|
newNode.addEventListener("click", selectMoveFolder);
|
||||||
|
|
||||||
|
prompt.querySelector("div.file-list ul").appendChild(newNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirs === 0) {
|
||||||
|
prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveSelected(event) {
|
function moveSelected(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let request = new XMLHttpRequest(),
|
|
||||||
oldLink = toWebDavURL(window.location.pathname),
|
// TODO: this only works for ONE file. What if there are more files selected?
|
||||||
newLink = toWebDavURL(event.srcElement.querySelector("li[aria-selected=true]").innerHTML + "/");
|
// TODO: use webdav.rename
|
||||||
request.open("MOVE", oldLink);
|
|
||||||
request.setRequestHeader("Destination", newLink);
|
let request = new XMLHttpRequest(),
|
||||||
request.send();
|
oldLink = toWebDavURL(window.location.pathname),
|
||||||
request.onreadystatechange = function() {
|
newLink = toWebDavURL(event.srcElement.querySelector("li[aria-selected=true]").innerHTML + "/");
|
||||||
if(request.readyState == 4) {
|
|
||||||
if(request.status == 200 || request.status == 204) {
|
request.open("MOVE", oldLink);
|
||||||
window.reload();
|
request.setRequestHeader("Destination", newLink);
|
||||||
}
|
request.send();
|
||||||
|
request.onreadystatechange = function() {
|
||||||
|
if (request.readyState == 4) {
|
||||||
|
if (request.status == 200 || request.status == 204) {
|
||||||
|
window.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveEvent(event) {
|
function moveEvent(event) {
|
||||||
if(event.currentTarget.classList.contains("disabled")) return;
|
if (event.currentTarget.classList.contains("disabled")) return;
|
||||||
|
|
||||||
let request = new XMLHttpRequest();
|
let request = new XMLHttpRequest();
|
||||||
|
|
||||||
request.open("GET", window.location.pathname, true);
|
request.open("GET", window.location.pathname, true);
|
||||||
request.setRequestHeader("Accept", "application/json");
|
request.setRequestHeader("Accept", "application/json");
|
||||||
request.send();
|
request.send();
|
||||||
request.onreadystatechange = function() {
|
request.onreadystatechange = function() {
|
||||||
if(request.readyState == 4) {
|
if (request.readyState == 4) {
|
||||||
if(request.status == 200) {
|
if (request.status == 200) {
|
||||||
let prompt = document.importNode(templates.move.content, true);
|
let prompt = document.importNode(templates.move.content, true),
|
||||||
|
dirs = 0;
|
||||||
|
|
||||||
prompt.querySelector("p").innerHTML = `Choose new house for your file(s)/folder(s):`;
|
|
||||||
prompt.querySelector("form").addEventListener("submit", moveSelected);
|
prompt.querySelector("form").addEventListener("submit", moveSelected);
|
||||||
|
prompt.querySelector('code').innerHTML = window.location.pathname;
|
||||||
|
|
||||||
|
for (let f of JSON.parse(request.response)) {
|
||||||
|
if (f.IsDir === true) {
|
||||||
|
dirs++;
|
||||||
|
|
||||||
for(let f of JSON.parse(request.response)) {
|
|
||||||
if(f.URL.split("/").length == 3) {
|
|
||||||
if(selectedItems.includes(btoa(f.URL.split("/")[1]))) continue;
|
|
||||||
let newNode = document.createElement("li");
|
let newNode = document.createElement("li");
|
||||||
newNode.innerHTML = f.URL.split("/")[1];
|
newNode.dataset.url = f.URL;
|
||||||
|
newNode.innerHTML = f.Name;
|
||||||
newNode.setAttribute("aria-selected", false);
|
newNode.setAttribute("aria-selected", false);
|
||||||
|
|
||||||
newNode.addEventListener("dblclick", loadNextFolder);
|
newNode.addEventListener("dblclick", loadNextFolder);
|
||||||
|
@ -263,6 +309,10 @@ function moveEvent(event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dirs === 0) {
|
||||||
|
prompt.querySelector("p").innerHTML = `There aren't any folders in this directory.`;
|
||||||
|
}
|
||||||
|
|
||||||
document.body.appendChild(prompt);
|
document.body.appendChild(prompt);
|
||||||
document.querySelector(".overlay").classList.add("active");
|
document.querySelector(".overlay").classList.add("active");
|
||||||
document.querySelector(".prompt").classList.add("active");
|
document.querySelector(".prompt").classList.add("active");
|
||||||
|
@ -424,6 +474,7 @@ function searchEvent(event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function setupSearch() {
|
function setupSearch() {
|
||||||
let search = document.getElementById("search"),
|
let search = document.getElementById("search"),
|
||||||
searchInput = search.querySelector("input"),
|
searchInput = search.querySelector("input"),
|
||||||
|
|
|
@ -128,31 +128,24 @@ listing.rename = function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
let newName = event.currentTarget.querySelector('input').value,
|
let newName = event.currentTarget.querySelector('input').value,
|
||||||
newLink = removeLastDirectoryPartOf(toWebDavURL(link)) + "/" + newName,
|
newLink = removeLastDirectoryPartOf(link) + "/" + newName,
|
||||||
html = buttons.rename.querySelector('i').changeToLoading(),
|
html = buttons.rename.querySelector('i').changeToLoading();
|
||||||
request = new XMLHttpRequest();
|
|
||||||
|
|
||||||
request.open('MOVE', toWebDavURL(link));
|
webdav.rename(link, newLink, success => {
|
||||||
request.setRequestHeader('Destination', newLink);
|
if (success) {
|
||||||
request.send();
|
listing.reload(() => {
|
||||||
request.onreadystatechange = function() {
|
newName = btoa(newName);
|
||||||
if (request.readyState == 4) {
|
selectedItems = [newName];
|
||||||
if (request.status != 201 && request.status != 204) {
|
document.getElementById(newName).setAttribute("aria-selected", true);
|
||||||
span.innerHTML = name;
|
listing.handleSelectionChange();
|
||||||
} else {
|
});
|
||||||
closePrompt(event);
|
} else {
|
||||||
|
item.querySelector('.name').innerHTML = name;
|
||||||
listing.reload(() => {
|
|
||||||
newName = btoa(newName);
|
|
||||||
selectedItems = [newName];
|
|
||||||
document.getElementById(newName).setAttribute("aria-selected", true);
|
|
||||||
listing.handleSelectionChange();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons.rename.querySelector('i').changeToDone((request.status != 201 && request.status != 204), html);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
closePrompt(event);
|
||||||
|
buttons.rename.querySelector('i').changeToDone(!success, html);
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +310,6 @@ listing.updateColumns = function(event) {
|
||||||
items.style.width = `calc(${100/columns}% - 1em)`;
|
items.style.width = `calc(${100/columns}% - 1em)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
listing.addDoubleTapEvent = function() {
|
listing.addDoubleTapEvent = function() {
|
||||||
let items = document.getElementsByClassName('item'),
|
let items = document.getElementsByClassName('item'),
|
||||||
touches = {
|
touches = {
|
||||||
|
|
|
@ -193,17 +193,20 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template id="move-template">
|
<template id="move-template">
|
||||||
|
<!-- TODO: And the back button? :) -->
|
||||||
<form class="prompt">
|
<form class="prompt">
|
||||||
<h3>Move</h3>
|
<h3>Move</h3>
|
||||||
<p></p>
|
<p>Choose new house for your file(s)/folder(s):</p>
|
||||||
|
|
||||||
<div class="file-list">
|
<div class="file-list">
|
||||||
<ul>
|
<ul>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<p>Currently navigating on: <code></code>.</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button type="submit" autofocus class="ok">OK</button>
|
<button type="submit" autofocus class="ok">Move</button>
|
||||||
<button class="cancel" onclick="closePrompt(event);">Cancel</button>
|
<button class="cancel" onclick="closePrompt(event);">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
23
file/info.go
23
file/info.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
humanize "github.com/dustin/go-humanize"
|
humanize "github.com/dustin/go-humanize"
|
||||||
"github.com/hacdias/caddy-filemanager/config"
|
"github.com/hacdias/caddy-filemanager/config"
|
||||||
|
@ -16,8 +17,12 @@ import (
|
||||||
|
|
||||||
// Info contains the information about a particular file or directory
|
// Info contains the information about a particular file or directory
|
||||||
type Info struct {
|
type Info struct {
|
||||||
os.FileInfo
|
Name string
|
||||||
|
Size int64
|
||||||
URL string
|
URL string
|
||||||
|
ModTime time.Time
|
||||||
|
Mode os.FileMode
|
||||||
|
IsDir bool
|
||||||
Path string // Relative path to Caddyfile
|
Path string // Relative path to Caddyfile
|
||||||
VirtualPath string // Relative path to u.FileSystem
|
VirtualPath string // Relative path to u.FileSystem
|
||||||
Mimetype string
|
Mimetype string
|
||||||
|
@ -40,18 +45,24 @@ func GetInfo(url *url.URL, c *config.Config, u *config.User) (*Info, int, error)
|
||||||
i.Path = strings.Replace(i.Path, "\\", "/", -1)
|
i.Path = strings.Replace(i.Path, "\\", "/", -1)
|
||||||
i.Path = filepath.Clean(i.Path)
|
i.Path = filepath.Clean(i.Path)
|
||||||
|
|
||||||
i.FileInfo, err = os.Stat(i.Path)
|
info, err := os.Stat(i.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return i, errors.ErrorToHTTPCode(err, false), err
|
return i, errors.ErrorToHTTPCode(err, false), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i.Name = info.Name()
|
||||||
|
i.ModTime = info.ModTime()
|
||||||
|
i.Mode = info.Mode()
|
||||||
|
i.IsDir = info.IsDir()
|
||||||
|
i.Size = info.Size()
|
||||||
|
|
||||||
return i, 0, nil
|
return i, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveFileType obtains the mimetype and a simplified internal Type
|
// RetrieveFileType obtains the mimetype and a simplified internal Type
|
||||||
// using the first 512 bytes from the file.
|
// using the first 512 bytes from the file.
|
||||||
func (i *Info) RetrieveFileType() error {
|
func (i *Info) RetrieveFileType() error {
|
||||||
i.Mimetype = mime.TypeByExtension(filepath.Ext(i.Name()))
|
i.Mimetype = mime.TypeByExtension(filepath.Ext(i.Name))
|
||||||
|
|
||||||
if i.Mimetype == "" {
|
if i.Mimetype == "" {
|
||||||
err := i.Read()
|
err := i.Read()
|
||||||
|
@ -88,12 +99,12 @@ func (i Info) StringifyContent() string {
|
||||||
// HumanSize returns the size of the file as a human-readable string
|
// HumanSize returns the size of the file as a human-readable string
|
||||||
// in IEC format (i.e. power of 2 or base 1024).
|
// in IEC format (i.e. power of 2 or base 1024).
|
||||||
func (i Info) HumanSize() string {
|
func (i Info) HumanSize() string {
|
||||||
return humanize.IBytes(uint64(i.Size()))
|
return humanize.IBytes(uint64(i.Size))
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanModTime returns the modified time of the file as a human-readable string.
|
// HumanModTime returns the modified time of the file as a human-readable string.
|
||||||
func (i Info) HumanModTime(format string) string {
|
func (i Info) HumanModTime(format string) string {
|
||||||
return i.ModTime().Format(format)
|
return i.ModTime.Format(format)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanBeEdited checks if the extension of a file is supported by the editor
|
// CanBeEdited checks if the extension of a file is supported by the editor
|
||||||
|
@ -120,7 +131,7 @@ func (i Info) CanBeEdited() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, extension := range extensions {
|
for _, extension := range extensions {
|
||||||
if strings.HasSuffix(i.Name(), extension) {
|
if strings.HasSuffix(i.Name, extension) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,11 @@ func GetListing(u *config.User, filePath string, baseURL string) (*Listing, erro
|
||||||
url := url.URL{Path: baseURL + name}
|
url := url.URL{Path: baseURL + name}
|
||||||
|
|
||||||
i := Info{
|
i := Info{
|
||||||
FileInfo: f,
|
Name: f.Name(),
|
||||||
|
Size: f.Size(),
|
||||||
|
ModTime: f.ModTime(),
|
||||||
|
Mode: f.Mode(),
|
||||||
|
IsDir: f.IsDir(),
|
||||||
URL: url.String(),
|
URL: url.String(),
|
||||||
UserAllowed: allowed,
|
UserAllowed: allowed,
|
||||||
}
|
}
|
||||||
|
@ -138,15 +142,15 @@ func (l byName) Swap(i, j int) {
|
||||||
|
|
||||||
// Treat upper and lower case equally
|
// Treat upper and lower case equally
|
||||||
func (l byName) Less(i, j int) bool {
|
func (l byName) Less(i, j int) bool {
|
||||||
if l.Items[i].IsDir() && !l.Items[j].IsDir() {
|
if l.Items[i].IsDir && !l.Items[j].IsDir {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !l.Items[i].IsDir() && l.Items[j].IsDir() {
|
if !l.Items[i].IsDir && l.Items[j].IsDir {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.ToLower(l.Items[i].Name()) < strings.ToLower(l.Items[j].Name())
|
return strings.ToLower(l.Items[i].Name) < strings.ToLower(l.Items[j].Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// By Size
|
// By Size
|
||||||
|
@ -160,11 +164,11 @@ func (l bySize) Swap(i, j int) {
|
||||||
|
|
||||||
const directoryOffset = -1 << 31 // = math.MinInt32
|
const directoryOffset = -1 << 31 // = math.MinInt32
|
||||||
func (l bySize) Less(i, j int) bool {
|
func (l bySize) Less(i, j int) bool {
|
||||||
iSize, jSize := l.Items[i].Size(), l.Items[j].Size()
|
iSize, jSize := l.Items[i].Size, l.Items[j].Size
|
||||||
if l.Items[i].IsDir() {
|
if l.Items[i].IsDir {
|
||||||
iSize = directoryOffset + iSize
|
iSize = directoryOffset + iSize
|
||||||
}
|
}
|
||||||
if l.Items[j].IsDir() {
|
if l.Items[j].IsDir {
|
||||||
jSize = directoryOffset + jSize
|
jSize = directoryOffset + jSize
|
||||||
}
|
}
|
||||||
return iSize < jSize
|
return iSize < jSize
|
||||||
|
@ -178,5 +182,5 @@ func (l byTime) Swap(i, j int) {
|
||||||
l.Items[i], l.Items[j] = l.Items[j], l.Items[i]
|
l.Items[i], l.Items[j] = l.Items[j], l.Items[i]
|
||||||
}
|
}
|
||||||
func (l byTime) Less(i, j int) bool {
|
func (l byTime) Less(i, j int) bool {
|
||||||
return l.Items[i].ModTime().Before(l.Items[j].ModTime())
|
return l.Items[i].ModTime.Before(l.Items[j].ModTime)
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ func (f FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err
|
||||||
|
|
||||||
// If it's a dir and the path doesn't end with a trailing slash,
|
// If it's a dir and the path doesn't end with a trailing slash,
|
||||||
// redirect the user.
|
// redirect the user.
|
||||||
if fi.IsDir() && !strings.HasSuffix(r.URL.Path, "/") {
|
if fi.IsDir && !strings.HasSuffix(r.URL.Path, "/") {
|
||||||
http.Redirect(w, r, c.AddrPath+r.URL.Path+"/", http.StatusTemporaryRedirect)
|
http.Redirect(w, r, c.AddrPath+r.URL.Path+"/", http.StatusTemporaryRedirect)
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
@ -144,10 +144,10 @@ func (f FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err
|
||||||
switch {
|
switch {
|
||||||
case r.URL.Query().Get("download") != "":
|
case r.URL.Query().Get("download") != "":
|
||||||
code, err = handlers.Download(w, r, c, fi)
|
code, err = handlers.Download(w, r, c, fi)
|
||||||
case r.URL.Query().Get("raw") == "true" && !fi.IsDir():
|
case r.URL.Query().Get("raw") == "true" && !fi.IsDir:
|
||||||
http.ServeFile(w, r, fi.Path)
|
http.ServeFile(w, r, fi.Path)
|
||||||
code, err = 0, nil
|
code, err = 0, nil
|
||||||
case fi.IsDir():
|
case fi.IsDir:
|
||||||
code, err = handlers.ServeListing(w, r, c, user, fi)
|
code, err = handlers.ServeListing(w, r, c, user, fi)
|
||||||
default:
|
default:
|
||||||
code, err = handlers.ServeSingle(w, r, c, user, fi)
|
code, err = handlers.ServeSingle(w, r, c, user, fi)
|
||||||
|
|
|
@ -19,8 +19,8 @@ import (
|
||||||
func Download(w http.ResponseWriter, r *http.Request, c *config.Config, i *file.Info) (int, error) {
|
func Download(w http.ResponseWriter, r *http.Request, c *config.Config, i *file.Info) (int, error) {
|
||||||
query := r.URL.Query().Get("download")
|
query := r.URL.Query().Get("download")
|
||||||
|
|
||||||
if !i.IsDir() {
|
if !i.IsDir {
|
||||||
w.Header().Set("Content-Disposition", "attachment; filename="+i.Name())
|
w.Header().Set("Content-Disposition", "attachment; filename="+i.Name)
|
||||||
http.ServeFile(w, r, i.Path)
|
http.ServeFile(w, r, i.Path)
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ func Download(w http.ResponseWriter, r *http.Request, c *config.Config, i *file.
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
name := i.Name()
|
name := i.Name
|
||||||
if name == "." || name == "" {
|
if name == "." || name == "" {
|
||||||
name = "download"
|
name = "download"
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ type Editor struct {
|
||||||
func GetEditor(i *file.Info) (*Editor, error) {
|
func GetEditor(i *file.Info) (*Editor, error) {
|
||||||
// Create a new editor variable and set the mode
|
// Create a new editor variable and set the mode
|
||||||
editor := new(Editor)
|
editor := new(Editor)
|
||||||
editor.Mode = strings.TrimPrefix(filepath.Ext(i.Name()), ".")
|
editor.Mode = strings.TrimPrefix(filepath.Ext(i.Name), ".")
|
||||||
|
|
||||||
switch editor.Mode {
|
switch editor.Mode {
|
||||||
case "md", "markdown", "mdown", "mmark":
|
case "md", "markdown", "mdown", "mmark":
|
||||||
|
|
|
@ -26,7 +26,7 @@ func ServeSingle(w http.ResponseWriter, r *http.Request, c *config.Config, u *co
|
||||||
|
|
||||||
p := &page.Page{
|
p := &page.Page{
|
||||||
Info: &page.Info{
|
Info: &page.Info{
|
||||||
Name: i.Name(),
|
Name: i.Name,
|
||||||
Path: i.VirtualPath,
|
Path: i.VirtualPath,
|
||||||
IsDir: false,
|
IsDir: false,
|
||||||
Data: i,
|
Data: i,
|
||||||
|
|
Loading…
Reference in New Issue