some ui features for uploading
This commit is contained in:
@@ -168,6 +168,9 @@ func (ch *CaddyHugo) ServeHTTPWithNext(next httpserver.Handler, c *caddy.Control
|
|||||||
if strings.HasPrefix(r.URL.Path, "/hugo/media") {
|
if strings.HasPrefix(r.URL.Path, "/hugo/media") {
|
||||||
return ch.serveMediaPage(w, r)
|
return ch.serveMediaPage(w, r)
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(r.URL.Path, "/hugo/upload") {
|
||||||
|
return ch.uploadMedia(w, r)
|
||||||
|
}
|
||||||
if strings.HasPrefix(r.URL.Path, "/media/") {
|
if strings.HasPrefix(r.URL.Path, "/media/") {
|
||||||
return ch.serveMedia(w, r)
|
return ch.serveMedia(w, r)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ package caddyhugo
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
_ "image/gif"
|
||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
|
_ "image/png"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -24,6 +26,21 @@ func (ms *MediaSource) LocationOrig(m Media) string {
|
|||||||
return path.Join(ms.StorageDir, m.Name)
|
return path.Join(ms.StorageDir, m.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ms *MediaSource) receiveNewMedia(name string, r io.Reader) error {
|
||||||
|
dest := path.Join(ms.StorageDir, name)
|
||||||
|
f, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(f, r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return f.Close()
|
||||||
|
}
|
||||||
|
|
||||||
type Media struct {
|
type Media struct {
|
||||||
Type string
|
Type string
|
||||||
Name string
|
Name string
|
||||||
@@ -122,6 +139,38 @@ func (ms *MediaSource) Walk() ([]*Media, error) {
|
|||||||
return media, err
|
return media, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ch *CaddyHugo) uploadMedia(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
if ch.Media == nil {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return 404, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mr, err := r.MultipartReader()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return 400, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
part, err := mr.NextPart()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return 400, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
name := part.FileName()
|
||||||
|
if name != "" {
|
||||||
|
err = ch.Media.receiveNewMedia(name, part)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return 500, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 200, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ch *CaddyHugo) serveMediaPage(w http.ResponseWriter, r *http.Request) (int, error) {
|
func (ch *CaddyHugo) serveMediaPage(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
if ch.Media == nil {
|
if ch.Media == nil {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
@@ -131,7 +180,11 @@ func (ch *CaddyHugo) serveMediaPage(w http.ResponseWriter, r *http.Request) (int
|
|||||||
io.WriteString(w, `<html>
|
io.WriteString(w, `<html>
|
||||||
<head><style>.img { float: left; text-align: center; }</style></head>
|
<head><style>.img { float: left; text-align: center; }</style></head>
|
||||||
<body>
|
<body>
|
||||||
|
<div style="position: fixed; top: 0; height: 10vh; width: 100%;">
|
||||||
|
<div style="float: left; width: 100%; height: 10vh;">
|
||||||
`)
|
`)
|
||||||
|
io.WriteString(w, UploadPage("media"))
|
||||||
|
io.WriteString(w, "</div>")
|
||||||
if ch.Media != nil {
|
if ch.Media != nil {
|
||||||
media, err := ch.Media.Walk()
|
media, err := ch.Media.Walk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -140,10 +193,12 @@ func (ch *CaddyHugo) serveMediaPage(w http.ResponseWriter, r *http.Request) (int
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range media {
|
for _, m := range media {
|
||||||
|
fmt.Fprintf(w, `<div class="img">`)
|
||||||
|
|
||||||
src, width, height, err := ch.Media.ThumbMax(*m, 100)
|
src, width, height, err := ch.Media.ThumbMax(*m, 100)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
fmt.Fprintf(w, `<div class="img">error rendering %q: %v</div>`, m.Name, err)
|
||||||
return 500, nil
|
continue
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, `<div class="img"><img width=%d height=%d src=%q /><br /><input type="text" disabled value=%q /></div>`, width, height, src, src)
|
fmt.Fprintf(w, `<div class="img"><img width=%d height=%d src=%q /><br /><input type="text" disabled value=%q /></div>`, width, height, src, src)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -392,3 +392,78 @@ var AuthorPage = `<html>
|
|||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>`
|
</html>`
|
||||||
|
|
||||||
|
func UploadPage(elemName string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
<input type="file" style="display: hidden;" id="%s" />
|
||||||
|
<div id="%s_dropzone" ondrop="dropHandler(event);" ondragover="draghandler(event);" ondragenter="draghandler(event);" ondragleave="draghandler(event);" style="background-color: rgba(0,0,0,0.5); visibility: hidden; opacity:0; position: fixed; top: 0; bottom: 0; left: 0; right: 0; width: 100%; height: 100%; ; transition: visibility 175ms, opacity 175ms; z-index: 9999999;"></div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
var fileInput = document.getElementById('%s');
|
||||||
|
var dropzone = document.getElementById('%s_dropzone');
|
||||||
|
|
||||||
|
fileInput.onchange = function () {
|
||||||
|
var formData = new FormData();
|
||||||
|
fileInput.files.forEach(function (file) {
|
||||||
|
formData.append(file.name, file);
|
||||||
|
});
|
||||||
|
upload(formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastTarget = null;
|
||||||
|
|
||||||
|
window.addEventListener("dragenter", function(e)
|
||||||
|
{
|
||||||
|
lastTarget = e.target; // cache the last target here
|
||||||
|
// unhide our dropzone overlay
|
||||||
|
dropzone.style.visibility = "";
|
||||||
|
dropzone.style.opacity = 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("dragleave", function(e)
|
||||||
|
{
|
||||||
|
// this is the magic part. when leaving the window,
|
||||||
|
// e.target happens to be exactly what we want: what we cached
|
||||||
|
// at the start, the dropzone we dragged into.
|
||||||
|
// so..if dragleave target matches our cache, we hide the dropzone.
|
||||||
|
if(e.target === lastTarget)
|
||||||
|
{
|
||||||
|
dropzone.style.visibility = "hidden";
|
||||||
|
dropzone.style.opacity = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function draghandler(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dropHandler(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
|
var files = evt.dataTransfer.files;
|
||||||
|
var formData = new FormData();
|
||||||
|
|
||||||
|
for (var i = 0; i < files.length; i++) {
|
||||||
|
formData.append(files[i].name, files[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
upload(formData);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function upload(formData) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.onreadystatechange = function(e) {
|
||||||
|
if ( 4 == this.readyState ) {
|
||||||
|
window.location.reload(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhr.open('POST', '/hugo/upload');
|
||||||
|
xhr.send(formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
`, elemName, elemName, elemName, elemName, elemName, elemName)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user