pull/144/head
Henrique Dias 2016-11-01 15:00:36 +00:00
parent 11b37114dc
commit d8d7502b1c
6 changed files with 145 additions and 26 deletions

View File

@ -558,7 +558,17 @@ header p i {
top: 100%;
}
#search div {
#search ul {
padding: 0;
margin: 0;
list-style: none;
}
#search li {
margin-bottom: .5em;
}
#search>div {
position: absolute;
top: 0;
width: 100%;
@ -577,6 +587,9 @@ header p i {
overflow-x: hidden;
overflow-y: auto;
max-height: 50vh;
}
#search>div div {
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
@ -584,6 +597,18 @@ header p i {
word-wrap: break-word;
}
#search>div p {
width: 100%;
text-align: center;
display: none;
margin: 0;
max-width: none;
}
#search.ongoing p {
display: block;
}
#search.active div i,
#sidebar #search.active div i {
color: #ccc;

View File

@ -466,10 +466,12 @@ var redefineDownloadURLs = function() {
var searchEvent = function(event) {
let value = this.value;
let box = document.querySelector('#search div');
let search = document.getElementById('search');
let scrollable = document.querySelector('#search > div');
let box = document.querySelector('#search > div div');
if (value.length == 0) {
box.innerHTML = "Write one of your supported commands: " + user.Commands.join(", ") + ".";
box.innerHTML = "Search or use one of your supported commands: " + user.Commands.join(", ") + ".";
return;
}
@ -483,27 +485,47 @@ var searchEvent = function(event) {
});
if (!supported) {
box.innerHTML = "Command not supported."
return;
box.innerHTML = "Press enter to search."
} else {
box.innerHTML = "Press enter to execute."
}
box.innerHTML = "Press enter to continue."
if (event.keyCode == 13) {
box.innerHTML = '<i class="material-icons spin">autorenew</i>';
box.innerHTML = '';
search.classList.add('ongoing');
var conn = new WebSocket('ws://' + window.location.host + window.location.pathname + '?command=true');
conn.onopen = function() {
conn.send(value);
};
if (supported) {
var conn = new WebSocket('ws://' + window.location.host + window.location.pathname + '?command=true');
conn.onopen = function() {
conn.send(value);
};
conn.onmessage = function(event) {
box.innerHTML = event.data
box.scrollTop = box.scrollHeight;
}
conn.onmessage = function(event) {
box.innerHTML = event.data;
scrollable.scrollTop = scrollable.scrollHeight;
}
conn.onclose = function(event) {
reloadListing();
conn.onclose = function(event) {
search.classList.remove('ongoing');
reloadListing();
}
} else {
box.innerHTML = '<ul></ul>';
let ul = box.querySelector('ul');
var conn = new WebSocket('ws://' + window.location.host + window.location.pathname + '?search=true');
conn.onopen = function() {
conn.send(value);
};
conn.onmessage = function(event) {
ul.innerHTML += '<li><a href="' + event.data + '">' + event.data + '</a></li>';
scrollable.scrollTop = scrollable.scrollHeight;
}
conn.onclose = function(event) {
search.classList.remove('ongoing');
}
}
}
}
@ -557,7 +579,7 @@ document.addEventListener('listing', event => {
document.getElementById('search').classList.remove('active');
});
document.querySelector('#search div').innerHTML = "Write one of yours suported commands: " + user.Commands.join(", ") + ".";
document.querySelector('#search > div div').innerHTML = "Search or use one of yours suported commands: " + user.Commands.join(", ") + ".";
document.querySelector('#search input').addEventListener('keyup', searchEvent);
}
@ -900,4 +922,4 @@ document.addEventListener("DOMContentLoaded", function(event) {
}
return false;
});
});

View File

@ -52,7 +52,10 @@
<div id="search">
<i class="material-icons" title="Storage">storage</i>
<input type="text" placeholder="Execute a command...">
<div>Write your git, mercurial or svn command and press enter.</div>
<div>
<div>Write your git, mercurial or svn command and press enter.</div>
<p><i class="material-icons spin">autorenew</i></p>
</div>
</div>
{{ end }}

View File

@ -67,10 +67,6 @@ func (f FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err
user = c.User
}
if r.URL.Query().Get("command") != "" {
return handlers.Command(w, r, c, user)
}
// Checks if the request URL is for the WebDav server
if strings.HasPrefix(r.URL.Path, c.WebDavURL) {
// Checks for user permissions relatively to this PATH
@ -112,6 +108,14 @@ func (f FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err
return http.StatusForbidden, nil
}
if r.URL.Query().Get("search") != "" {
return handlers.Search(w, r, c, user)
}
if r.URL.Query().Get("command") != "" {
return handlers.Command(w, r, c, user)
}
if r.Method == http.MethodGet {
// Gets the information of the directory/file
fi, code, err = file.GetInfo(r.URL, c, user)

65
handlers/search.go Normal file
View File

@ -0,0 +1,65 @@
package handlers
import (
"net/http"
"os"
"path/filepath"
"strings"
"github.com/gorilla/websocket"
"github.com/hacdias/caddy-filemanager/config"
)
func Search(w http.ResponseWriter, r *http.Request, c *config.Config, u *config.User) (int, error) {
// Upgrades the connection to a websocket and checks for errors.
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return 0, err
}
defer conn.Close()
var search string
// Starts an infinite loop until a valid command is captured.
for {
_, message, err := conn.ReadMessage()
if err != nil {
return http.StatusInternalServerError, err
}
if len(message) != 0 {
search = string(message)
break
}
}
scope := strings.Replace(r.URL.Path, c.BaseURL, "", 1)
scope = strings.TrimPrefix(scope, "/")
scope = "/" + scope
scope = u.Scope + scope
scope = strings.Replace(scope, "\\", "/", -1)
scope = filepath.Clean(scope)
err = filepath.Walk(scope, func(path string, f os.FileInfo, err error) error {
// TODO: check user permissions?
if strings.Contains(path, search) {
path = strings.TrimPrefix(path, scope)
path = strings.Replace(path, "\\", "/", -1)
path = strings.TrimPrefix(path, "/")
err = conn.WriteMessage(websocket.TextMessage, []byte(path))
if err != nil {
return err
}
}
return nil
})
if err != nil {
return http.StatusInternalServerError, err
}
return http.StatusOK, nil
}

View File

@ -139,7 +139,7 @@ func (p Page) PrintAsHTML(w http.ResponseWriter, templates ...string) (int, erro
// PrintAsJSON prints the current Page infromation in JSON
func (p Page) PrintAsJSON(w http.ResponseWriter) (int, error) {
marsh, err := json.Marshal(p.Info.Data)
marsh, err := json.MarshalIndent(p.Info.Data, "", " ")
if err != nil {
return http.StatusInternalServerError, err
}