add vcs command

pull/144/head
Henrique Dias 2016-06-26 18:30:08 +01:00
parent fff716b2b3
commit 0f18f74848
6 changed files with 140 additions and 148 deletions

View File

@ -431,6 +431,23 @@ header form input {
background-color: rgba(0, 0, 0, .1);
}
.floating {
position: fixed;
bottom: 1em;
right: 1em;
}
.floating .action {
background-color: #68EFAD;
color: #306e50;
box-shadow: 0 1px 3px rgba(0, 0, 0, .06), 0 1px 2px rgba(0, 0, 0, .12);
}
#newfolder i {
transform: rotate(45deg);
}
/* LISTING */
#listing {

View File

@ -1,106 +1,95 @@
<!DOCTYPE html>
<html>
<head>
<title>{{.Name}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Roboto:400,500' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="{{ .Config.BaseURL }}/_filemanagerinternal/css/styles.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.3/ace.js"></script>
<script src="{{ .Config.BaseURL }}/_filemanagerinternal/js/application.js"></script>
{{ if ne .Config.StyleSheet "" }}
<style>
{{.Config.StyleSheet}}
</style>
{{ end }}
</head>
<body>
<header>
<div>
{{ $lnk := .PreviousLink }}
{{ if ne $lnk ""}}
<a href="{{ $lnk }}">
<div class="action" id="prev">
<i class="material-icons">subdirectory_arrow_left</i>
</div>
</a>
{{ else }}
<div class="action disabled" id="prev">
<head>
<title>{{.Name}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Roboto:400,500' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="{{ .Config.BaseURL }}/_filemanagerinternal/css/styles.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.3/ace.js"></script>
<script src="{{ .Config.BaseURL }}/_filemanagerinternal/js/application.js"></script>
{{ if ne .Config.StyleSheet "" }}<style>{{.Config.StyleSheet}}</style>{{ end }}
</head>
<body>
<header>
<div>
{{ $lnk := .PreviousLink }}
{{ if ne $lnk ""}}<a href="{{ $lnk }}">{{ end }}
<div class="action{{ if eq $lnk ""}} disabled{{ end }}" id="prev">
<i class="material-icons">subdirectory_arrow_left</i>
</div>
{{ end }}
<p>
<a href="{{ if eq .Config.BaseURL " " }}/{{ else }}{{ .Config.BaseURL }}{{ end }}">
{{ if .Config.HugoEnabled }}Hugo{{ else }}File Manager{{ end }}
{{ if ne $lnk ""}}</a>{{ end }}
<p>
<a href="{{ if eq .Config.BaseURL "" }}/{{ else }}{{ .Config.BaseURL }}{{ end }}">
{{ if .Config.HugoEnabled }}Hugo{{ else }}File Manager{{ end }}
</a>
{{ if ne .Name "/"}}
<i class="material-icons">chevron_right</i>
{{ .Name }}</p>
{{ end }}
{{ if ne .Name "/"}}<i class="material-icons">chevron_right</i>{{ .Name }}
</p>
{{ end }}
</div>
<div>
{{ if .IsDir}}
<form>
<i class="material-icons">search</i>
<input type="text" placeholder="Search or command">
</form>
<div class="action" id="view">
<i class="material-icons">view_headline</i>
</div>
<div class="action" id="upload">
<i class="material-icons">file_upload</i>
</div>
{{ else }}
{{ template "actions" . }}
{{ end }}
{{ if .Config.HugoEnabled }}
<a href="{{ .Config.BaseURL }}/settings">
<div class="action">
<i class="material-icons">settings</i>
</div>
</a>
{{ end }}
<div class="action" id="logout">
<i class="material-icons">exit_to_app</i>
</div>
</div>
</header>
{{ if .IsDir }}
<div id="toolbar">
<div>
{{ if .IsDir}}
<form>
<i class="material-icons">search</i>
<input type="text" placeholder="Search">
</form>
<div class="action" id="view">
<i class="material-icons">view_headline</i>
<div class="action" id="back">
<i class="material-icons">arrow_back</i>
</div>
<p><span id="selected-number">0</span> selected.</p>
</div>
<div class="action" id="upload">
<i class="material-icons">file_upload</i>
</div>
{{ else }}
<div>
{{ template "actions" . }}
{{ end }}
</div>
</div>
{{ end }}
{{ if .Config.HugoEnabled }}
<!-- Hugo plugin stuff -->
<a href="{{ .Config.BaseURL }}/settings">
<div class="action">
<i class="material-icons">settings</i>
</div>
</a>
<main>
{{ template "content" .Data }}
</main>
{{ end }}
<div class="action" id="logout">
<i class="material-icons">exit_to_app</i>
{{ if .IsDir }}
<div class="floating">
<div class="action" id="newfolder">
<i class="material-icons">close</i>
</div>
</div>
</header>
</div>
{{ end }}
{{ if .IsDir }}
<div id="toolbar">
<div>
<div class="action" id="back">
<i class="material-icons">arrow_back</i>
</div>
<p>
<span id="selected-number">0</span>
selected.</p>
</div>
<div>
{{ template "actions" . }}
</div>
</div>
{{ end }}
<main>
{{ .Path }}
{{ template "content" .Data }}
</main>
<footer>
Served with
<a rel="noopener noreferrer" href="https://caddyserver.com">Caddy</a>
and
<a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">File Manager</a>.
{{ if .Config.HugoEnabled }}With a flavour of
<a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">Hugo</a>.{{ end }}
</footer>
</body>
<footer>
Served with <a rel="noopener noreferrer" href="https://caddyserver.com">Caddy</a> and
<a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">File Manager</a>.
{{ if .Config.HugoEnabled }}With a flavour of
<a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">Hugo</a>.{{ end }}
</footer>
</body>
</html>

View File

@ -14,6 +14,7 @@ import (
a "github.com/hacdias/caddy-filemanager/internal/assets"
"github.com/hacdias/caddy-filemanager/internal/config"
"github.com/hacdias/caddy-filemanager/internal/file"
"github.com/hacdias/caddy-filemanager/internal/vcs"
"github.com/mholt/caddy/caddyhttp/httpserver"
)
@ -79,7 +80,11 @@ func (f FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err
}
// Search and git commands
if r.Header.Get("Search") == "true" {
// TODO: search and git commands
// TODO: search commands
}
// VCS commands
if r.Header.Get("Command") != "" {
vcs.Handle(w, r, c)
}
// Creates a new folder
// TODO: not implemented on frontend

View File

@ -15,7 +15,7 @@ type Config struct {
Root http.FileSystem
BaseURL string
StyleSheet string // Costum stylesheet
HugoEnabled bool // This must be only used by Hugo plugin
HugoEnabled bool // Enables the Hugo plugin for File Manager
}
// Parse parses the configuration set by the user so it can

View File

@ -1,55 +0,0 @@
package git
import (
"bytes"
"encoding/json"
"net/http"
"os/exec"
"strings"
"github.com/hacdias/caddy-filemanager/internal/config"
"github.com/hacdias/caddy-filemanager/internal/page"
)
// Handle handles the POST method on GIT page which is only an API.
func Handle(w http.ResponseWriter, r *http.Request, c *config.Config) (int, error) {
// Check if git is installed on the computer
if _, err := exec.LookPath("git"); err != nil {
return http.StatusNotImplemented, nil
}
// Get the JSON information sent using a buffer
buff := new(bytes.Buffer)
buff.ReadFrom(r.Body)
// Creates the raw file "map" using the JSON
var info map[string]interface{}
json.Unmarshal(buff.Bytes(), &info)
// Check if command was sent
if _, ok := info["command"]; !ok {
return http.StatusBadRequest, nil
}
command := info["command"].(string)
args := strings.Split(command, " ")
if len(args) > 0 && args[0] == "git" {
args = append(args[:0], args[1:]...)
}
if len(args) == 0 {
return http.StatusBadRequest, nil
}
cmd := exec.Command("git", args...)
cmd.Dir = c.PathScope
output, err := cmd.CombinedOutput()
if err != nil {
return http.StatusInternalServerError, err
}
page := &page.Page{Info: &page.Info{Data: string(output)}}
return page.PrintAsJSON(w)
}

36
internal/vcs/vcs.go Normal file
View File

@ -0,0 +1,36 @@
package vcs
import (
"net/http"
"os/exec"
"strings"
"github.com/hacdias/caddy-filemanager/internal/config"
"github.com/hacdias/caddy-filemanager/internal/page"
)
// Handle handles the POST method on GIT page which is only an API.
func Handle(w http.ResponseWriter, r *http.Request, c *config.Config) (int, error) {
command := strings.Split(r.Header.Get("command"), " ")
// Check if the command is for git, mercurial or svn
if command[0] != "git" && command[0] != "hg" && command[0] != "svn" {
return http.StatusForbidden, nil
}
// Check if the program is talled is installed on the computer
if _, err := exec.LookPath(command[0]); err != nil {
return http.StatusNotImplemented, nil
}
cmd := exec.Command(command[0], command[1:len(command)]...)
cmd.Dir = c.PathScope
output, err := cmd.CombinedOutput()
if err != nil {
return http.StatusInternalServerError, err
}
page := &page.Page{Info: &page.Info{Data: string(output)}}
return page.PrintAsJSON(w)
}