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) {
.grid-lg {
display: block;
@ -200,7 +190,14 @@ button {
background-color: var(--blue);
}
.item {
.item, .forms {
display: flex;
}
.item {
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 id="createdir" action="#" method="post">
<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>
</div>
<div class="list">
@ -81,7 +81,6 @@ function getProviders() {
// Dumb router function for passing around values from the hash.
function router(event = null) {
let hash = location.hash.replace("#", "")
console.log(hash)
// If hash is empty, "redirect" to index.
if (hash === "") {
getProviders()

View file

@ -138,7 +138,11 @@ func (bp *BackblazeProvider) GetDirectory(path string) Directory {
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{}
// Get bucket name >:(
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.ContentLength = int64(len(bodyBytes))
// Upload in background.
res, err = client.Do(req)
if err != nil {
fmt.Println(err.Error())
@ -254,10 +257,10 @@ func (bp *BackblazeProvider) SaveFile(file io.Reader, filename string, path stri
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.
// Therefore, we can assume everything is a file ;)
return "file"
return "file", "remote"
}
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) {
file := strings.Join([]string{dp.Location,path}, "/")
fileReader, err := os.Open(file)
if err != nil {
return
}
_, err = io.Copy(w, fileReader)
if err != nil {
return
}
func (dp *DiskProvider) ViewFile(path string) string {
rp := strings.Join([]string{dp.Location,path}, "/")
return rp
}
func (dp *DiskProvider) RemoteFile(path string, writer io.Writer) {
return
}
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
}
func (dp *DiskProvider) DetermineType(path string) string {
func (dp *DiskProvider) ObjectInfo(path string) (string, string) {
rp := strings.Join([]string{dp.Location,path}, "/")
file, err := os.Stat(rp)
fileStat, err := os.Stat(rp)
if err != nil {
return ""
}
if file.IsDir() {
return "directory"
fmt.Printf("error stat'ing file %v: %v", rp, err.Error())
return "", ""
}
return "file"
if fileStat.IsDir() {
return "directory", ""
}
return "file", "local"
}
func (dp *DiskProvider) CreateDirectory(path string) bool {

View file

@ -31,9 +31,10 @@ type FileContents struct {
type FileProviderInterface interface {
Setup(args map[string]string) bool
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
DetermineType(path string) string
ObjectInfo(path string) (string, string)
CreateDirectory(path string) bool
Delete(path string) bool
}
@ -47,7 +48,11 @@ func (f FileProvider) GetDirectory(path string) 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
}
@ -55,8 +60,8 @@ func (f FileProvider) SaveFile(file io.Reader, filename string, path string) boo
return false
}
func (f FileProvider) DetermineType(path string) string {
return ""
func (f FileProvider) ObjectInfo(path string) (string, string) {
return "", ""
}
func (f FileProvider) CreateDirectory(path string) bool {
@ -65,5 +70,4 @@ func (f FileProvider) CreateDirectory(path string) bool {
func (f FileProvider) Delete(path string) bool {
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)
}
var w bytes.Buffer
fp.ViewFile("", &w); if len(w.Bytes()) > 0 {
viewfile := fp.ViewFile(""); if viewfile != "" {
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.")
}
determinetype := fp.DetermineType(""); if determinetype != "" {
t.Errorf("Default FileProvider DetermineType() did not return an empty string.")
determinetype := fp.ObjectInfo(""); if determinetype != "" {
t.Errorf("Default FileProvider ObjectInfo() did not return an empty string.")
}
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)
}
var w bytes.Buffer
dp.ViewFile("testing.txt", &w); if w.String() != "testing file!" {
fmt.Println(w)
t.Errorf("DiskProvider ViewFile() returned %v, expected \"testing file!\".", w.String())
viewfile := dp.ViewFile("testing.txt"); if viewfile != DISK_TESTING_GROUNDS + "testing.txt"{
t.Errorf("DiskProvider ViewFile() returned %v, expected path.", viewfile)
}
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.")
}
determinetype := dp.DetermineType("second_test.txt"); if determinetype != "file" {
t.Errorf("DiskProvider DetermineType() returned %v, expected \"file\".", determinetype)
determinetype := dp.ObjectInfo("second_test.txt"); if determinetype != "file" {
t.Errorf("DiskProvider ObjectInfo() returned %v, expected \"file\".", determinetype)
}
createdirectory := dp.CreateDirectory("test_dir"); if !createdirectory {

View file

@ -7,8 +7,10 @@ import (
"github.com/gorilla/mux"
"net/http"
"net/url"
"os"
"sort"
"strings"
"time"
)
func HandleProvider() Handler {
@ -29,7 +31,8 @@ func HandleProvider() Handler {
StatusCode: http.StatusInternalServerError,
}
}
fileType := provider.DetermineType(filename)
fileType, location := provider.ObjectInfo(filename)
if fileType == "" {
return &HTTPError{
Message: fmt.Sprintf("error determining filetype for %s\n", filename),
@ -37,7 +40,16 @@ func HandleProvider() Handler {
}
}
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
}
fileList = provider.GetDirectory(filename)