Better handling of serving files, frontend tweaks.

Implemented a few new functions to handle the differences between local
and remote files - local files will be served (best it can be) with
ServeContent(), while remote files will be passed through from the
response body directly to the response writer. This isn't a very elegant
solution right now, but hoping to refactor this approach and simplify
the decision logic. However, serving files from local disks is much
better, including improvements to video files and generally better
handling of metadata.

Also some small tweaks to the frontned to align things a little nicer.
This commit is contained in:
Gabriel Simmer 2020-04-15 12:16:27 +01:00
parent e1b8c50d55
commit 8db4a35994
No known key found for this signature in database
GPG key ID: 33BA4D83B160A0A9
7 changed files with 63 additions and 53 deletions

View file

@ -102,16 +102,6 @@ body, h1 a {
} }
} }
.forms {
margin: 0 auto;
width: 40%;
}
form {
display: inline-block;
width: 30%;
}
@media only screen and (max-width: 1170px) { @media only screen and (max-width: 1170px) {
.grid-lg { .grid-lg {
display: block; display: block;
@ -200,7 +190,14 @@ button {
background-color: var(--blue); background-color: var(--blue);
} }
.item { .item, .forms {
display: flex; display: flex;
}
.item {
justify-content: center; justify-content: center;
} }
.forms {
width: 40%;
margin: 0 auto;
justify-content: space-around;
}

View file

@ -27,7 +27,7 @@ function getFileListing(provider, path = "") {
</form> </form>
<form id="createdir" action="#" method="post"> <form id="createdir" action="#" method="post">
<input type="text" id="newdir" data-dir="${provider}${path}"> <input type="text" id="newdir" data-dir="${provider}${path}">
<input type="submit" value="mkdir" id="newdir_submit"> <input type="submit" value="Create Directory" id="newdir_submit">
</form> </form>
</div> </div>
<div class="list"> <div class="list">
@ -81,7 +81,6 @@ function getProviders() {
// Dumb router function for passing around values from the hash. // Dumb router function for passing around values from the hash.
function router(event = null) { function router(event = null) {
let hash = location.hash.replace("#", "") let hash = location.hash.replace("#", "")
console.log(hash)
// If hash is empty, "redirect" to index. // If hash is empty, "redirect" to index.
if (hash === "") { if (hash === "") {
getProviders() getProviders()

View file

@ -138,7 +138,11 @@ func (bp *BackblazeProvider) GetDirectory(path string) Directory {
return finalDir return finalDir
} }
func (bp *BackblazeProvider) ViewFile(path string, w io.Writer) { func (bp *BackblazeProvider) ViewFile(path string) string {
return ""
}
func (bp *BackblazeProvider) RemoteFile(path string, w io.Writer) {
client := &http.Client{} client := &http.Client{}
// Get bucket name >:( // Get bucket name >:(
bucketIdPayload := fmt.Sprintf(`{"accountId": "%s", "bucketId": "%s"}`, bp.Name, bp.Bucket) bucketIdPayload := fmt.Sprintf(`{"accountId": "%s", "bucketId": "%s"}`, bp.Name, bp.Bucket)
@ -244,7 +248,6 @@ func (bp *BackblazeProvider) SaveFile(file io.Reader, filename string, path stri
req.Header.Add("X-Bz-Content-Sha1", fmt.Sprintf("%x", fileSha.Sum(nil))) req.Header.Add("X-Bz-Content-Sha1", fmt.Sprintf("%x", fileSha.Sum(nil)))
req.ContentLength = int64(len(bodyBytes)) req.ContentLength = int64(len(bodyBytes))
// Upload in background.
res, err = client.Do(req) res, err = client.Do(req)
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
@ -254,10 +257,10 @@ func (bp *BackblazeProvider) SaveFile(file io.Reader, filename string, path stri
return true return true
} }
func (bp *BackblazeProvider) DetermineType(path string) string { func (bp *BackblazeProvider) ObjectInfo(path string) (string, string) {
// B2 is really a "flat" filesystem, with directories being virtual. // B2 is really a "flat" filesystem, with directories being virtual.
// Therefore, we can assume everything is a file ;) // Therefore, we can assume everything is a file ;)
return "file" return "file", "remote"
} }
func (bp *BackblazeProvider) CreateDirectory(path string) bool { func (bp *BackblazeProvider) CreateDirectory(path string) bool {

View file

@ -42,16 +42,13 @@ func (dp *DiskProvider) GetDirectory(path string) Directory {
} }
} }
func (dp *DiskProvider) ViewFile(path string, w io.Writer) { func (dp *DiskProvider) ViewFile(path string) string {
file := strings.Join([]string{dp.Location,path}, "/") rp := strings.Join([]string{dp.Location,path}, "/")
fileReader, err := os.Open(file) return rp
if err != nil { }
return
} func (dp *DiskProvider) RemoteFile(path string, writer io.Writer) {
_, err = io.Copy(w, fileReader) return
if err != nil {
return
}
} }
func (dp *DiskProvider) SaveFile(file io.Reader, filename string, path string) bool { func (dp *DiskProvider) SaveFile(file io.Reader, filename string, path string) bool {
@ -71,17 +68,18 @@ func (dp *DiskProvider) SaveFile(file io.Reader, filename string, path string) b
return true return true
} }
func (dp *DiskProvider) DetermineType(path string) string { func (dp *DiskProvider) ObjectInfo(path string) (string, string) {
rp := strings.Join([]string{dp.Location,path}, "/") rp := strings.Join([]string{dp.Location,path}, "/")
file, err := os.Stat(rp) fileStat, err := os.Stat(rp)
if err != nil { if err != nil {
return "" fmt.Printf("error stat'ing file %v: %v", rp, err.Error())
} return "", ""
if file.IsDir() {
return "directory"
} }
return "file" if fileStat.IsDir() {
return "directory", ""
}
return "file", "local"
} }
func (dp *DiskProvider) CreateDirectory(path string) bool { func (dp *DiskProvider) CreateDirectory(path string) bool {

View file

@ -31,9 +31,10 @@ type FileContents struct {
type FileProviderInterface interface { type FileProviderInterface interface {
Setup(args map[string]string) bool Setup(args map[string]string) bool
GetDirectory(path string) Directory GetDirectory(path string) Directory
ViewFile(path string, w io.Writer) ViewFile(path string) string
RemoteFile(path string, writer io.Writer)
SaveFile(file io.Reader, filename string, path string) bool SaveFile(file io.Reader, filename string, path string) bool
DetermineType(path string) string ObjectInfo(path string) (string, string)
CreateDirectory(path string) bool CreateDirectory(path string) bool
Delete(path string) bool Delete(path string) bool
} }
@ -47,7 +48,11 @@ func (f FileProvider) GetDirectory(path string) Directory {
return Directory{} return Directory{}
} }
func (f FileProvider) ViewFile(path string, w io.Writer) { func (f FileProvider) ViewFile(path string) string {
return ""
}
func (f FileProvider) RemoteFile(path string, writer io.Writer) {
return return
} }
@ -55,8 +60,8 @@ func (f FileProvider) SaveFile(file io.Reader, filename string, path string) boo
return false return false
} }
func (f FileProvider) DetermineType(path string) string { func (f FileProvider) ObjectInfo(path string) (string, string) {
return "" return "", ""
} }
func (f FileProvider) CreateDirectory(path string) bool { func (f FileProvider) CreateDirectory(path string) bool {
@ -66,4 +71,3 @@ func (f FileProvider) CreateDirectory(path string) bool {
func (f FileProvider) Delete(path string) bool { func (f FileProvider) Delete(path string) bool {
return false return false
} }

View file

@ -24,8 +24,7 @@ func TestFileProvider(t *testing.T) {
t.Errorf("Default FileProvider GetDirectory() files returned %v, expected none.", getdirectory.Files) t.Errorf("Default FileProvider GetDirectory() files returned %v, expected none.", getdirectory.Files)
} }
var w bytes.Buffer viewfile := fp.ViewFile(""); if viewfile != "" {
fp.ViewFile("", &w); if len(w.Bytes()) > 0 {
t.Errorf("Default FileProvider ViewFile() %v, expected nothing.", w) t.Errorf("Default FileProvider ViewFile() %v, expected nothing.", w)
} }
@ -33,8 +32,8 @@ func TestFileProvider(t *testing.T) {
t.Errorf("Default FileProvider SaveFile() attempted to save a file.") t.Errorf("Default FileProvider SaveFile() attempted to save a file.")
} }
determinetype := fp.DetermineType(""); if determinetype != "" { determinetype := fp.ObjectInfo(""); if determinetype != "" {
t.Errorf("Default FileProvider DetermineType() did not return an empty string.") t.Errorf("Default FileProvider ObjectInfo() did not return an empty string.")
} }
createdirectory := fp.CreateDirectory(""); if createdirectory { createdirectory := fp.CreateDirectory(""); if createdirectory {
@ -88,10 +87,8 @@ func TestDiskProvider(t *testing.T) {
t.Errorf("DiskProvider GetDirectory() files returned %v, expected 1.", getdirectory.Files) t.Errorf("DiskProvider GetDirectory() files returned %v, expected 1.", getdirectory.Files)
} }
var w bytes.Buffer viewfile := dp.ViewFile("testing.txt"); if viewfile != DISK_TESTING_GROUNDS + "testing.txt"{
dp.ViewFile("testing.txt", &w); if w.String() != "testing file!" { t.Errorf("DiskProvider ViewFile() returned %v, expected path.", viewfile)
fmt.Println(w)
t.Errorf("DiskProvider ViewFile() returned %v, expected \"testing file!\".", w.String())
} }
testfile := bytes.NewReader([]byte("second test file!")) testfile := bytes.NewReader([]byte("second test file!"))
@ -99,8 +96,8 @@ func TestDiskProvider(t *testing.T) {
t.Errorf("DiskProvider SaveFile() could not save a file.") t.Errorf("DiskProvider SaveFile() could not save a file.")
} }
determinetype := dp.DetermineType("second_test.txt"); if determinetype != "file" { determinetype := dp.ObjectInfo("second_test.txt"); if determinetype != "file" {
t.Errorf("DiskProvider DetermineType() returned %v, expected \"file\".", determinetype) t.Errorf("DiskProvider ObjectInfo() returned %v, expected \"file\".", determinetype)
} }
createdirectory := dp.CreateDirectory("test_dir"); if !createdirectory { createdirectory := dp.CreateDirectory("test_dir"); if !createdirectory {

View file

@ -7,8 +7,10 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"net/http" "net/http"
"net/url" "net/url"
"os"
"sort" "sort"
"strings" "strings"
"time"
) )
func HandleProvider() Handler { func HandleProvider() Handler {
@ -29,7 +31,8 @@ func HandleProvider() Handler {
StatusCode: http.StatusInternalServerError, StatusCode: http.StatusInternalServerError,
} }
} }
fileType := provider.DetermineType(filename) fileType, location := provider.ObjectInfo(filename)
if fileType == "" { if fileType == "" {
return &HTTPError{ return &HTTPError{
Message: fmt.Sprintf("error determining filetype for %s\n", filename), Message: fmt.Sprintf("error determining filetype for %s\n", filename),
@ -37,7 +40,16 @@ func HandleProvider() Handler {
} }
} }
if fileType == "file" { if fileType == "file" {
provider.ViewFile(filename, w) if location == "local" {
rp := provider.ViewFile(filename)
if rp != "" {
f, _ := os.Open(rp)
http.ServeContent(w, r, filename, time.Time{}, f)
}
}
if location == "remote" {
provider.RemoteFile(filename, w)
}
return nil return nil
} }
fileList = provider.GetDirectory(filename) fileList = provider.GetDirectory(filename)