feat: add lazy loading folder size
This commit is contained in:
parent
04e03a83b4
commit
123f44d1c8
@ -95,6 +95,37 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
|
|||||||
return file, err
|
return file, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewFolderInfo(opts FileOptions) (*FileInfo, error) {
|
||||||
|
file, err := NewFileInfo(opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
size, err := GetFolderSize(file.RealPath())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
file.Size = size
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFolderSize(path string) (int64, error) {
|
||||||
|
var size int64
|
||||||
|
err := filepath.WalkDir(path, func(_ string, d os.DirEntry, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !d.IsDir() {
|
||||||
|
info, err := d.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
size += info.Size()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
return size, err
|
||||||
|
}
|
||||||
|
|
||||||
func stat(opts FileOptions) (*FileInfo, error) {
|
func stat(opts FileOptions) (*FileInfo, error) {
|
||||||
var file *FileInfo
|
var file *FileInfo
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,16 @@ async function resourceAction(url, method, content) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function resourceSizeAction(url, method, content) {
|
||||||
|
url = removePrefix(url);
|
||||||
|
let opts = { method };
|
||||||
|
if (content) {
|
||||||
|
opts.body = content;
|
||||||
|
}
|
||||||
|
const res = await fetchURL(`/api/resources/size${url}`, opts);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
export async function remove(url) {
|
export async function remove(url) {
|
||||||
return resourceAction(url, "DELETE");
|
return resourceAction(url, "DELETE");
|
||||||
}
|
}
|
||||||
@ -163,6 +173,11 @@ export async function checksum(url, algo) {
|
|||||||
return (await data.json()).checksums[algo];
|
return (await data.json()).checksums[algo];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function foldersize(url) {
|
||||||
|
const data = await resourceSizeAction(`${url}`, "GET");
|
||||||
|
return (await data.json()).size;
|
||||||
|
}
|
||||||
|
|
||||||
export function getDownloadURL(file, inline) {
|
export function getDownloadURL(file, inline) {
|
||||||
const params = {
|
const params = {
|
||||||
...(inline && { inline: "true" }),
|
...(inline && { inline: "true" }),
|
||||||
|
|||||||
@ -13,11 +13,20 @@
|
|||||||
<strong>{{ $t("prompts.displayName") }}</strong> {{ name }}
|
<strong>{{ $t("prompts.displayName") }}</strong> {{ name }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p v-if="!dir || selected.length > 1">
|
<p v-if="!dir && selected.length === 1">
|
||||||
<strong>{{ $t("prompts.size") }}:</strong>
|
<strong>{{ $t("prompts.size") }}:</strong>
|
||||||
<span id="content_length"></span> {{ humanSize }}
|
<span id="content_length"></span> {{ humanSize }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p v-if="dir || selected.length > 1">
|
||||||
|
<strong>Size: </strong
|
||||||
|
><code
|
||||||
|
><a @click="foldersize($event)">{{
|
||||||
|
$t("prompts.show")
|
||||||
|
}}</a></code
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
|
||||||
<div v-if="resolution">
|
<div v-if="resolution">
|
||||||
<strong>{{ $t("prompts.resolution") }}:</strong>
|
<strong>{{ $t("prompts.resolution") }}:</strong>
|
||||||
{{ resolution.width }} x {{ resolution.height }}
|
{{ resolution.width }} x {{ resolution.height }}
|
||||||
@ -166,6 +175,26 @@ export default {
|
|||||||
this.$showError(e);
|
this.$showError(e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
foldersize: async function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
try {
|
||||||
|
let totalSize = 0;
|
||||||
|
|
||||||
|
for (let selected of this.selected) {
|
||||||
|
let item = this.req.items[selected]
|
||||||
|
if (!item.isDir) {
|
||||||
|
totalSize += item.size;
|
||||||
|
} else {
|
||||||
|
totalSize += await api.foldersize(item.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
event.target.innerHTML = filesize(totalSize);
|
||||||
|
} catch (e) {
|
||||||
|
this.$showError(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -60,6 +60,7 @@ func NewHandler(
|
|||||||
users.Handle("/{id:[0-9]+}", monkey(userGetHandler, "")).Methods("GET")
|
users.Handle("/{id:[0-9]+}", monkey(userGetHandler, "")).Methods("GET")
|
||||||
users.Handle("/{id:[0-9]+}", monkey(userDeleteHandler, "")).Methods("DELETE")
|
users.Handle("/{id:[0-9]+}", monkey(userDeleteHandler, "")).Methods("DELETE")
|
||||||
|
|
||||||
|
api.PathPrefix("/resources/size").Handler(monkey(resourceGetSizeHandler, "/api/resources/size")).Methods("GET")
|
||||||
api.PathPrefix("/resources").Handler(monkey(resourceGetHandler, "/api/resources")).Methods("GET")
|
api.PathPrefix("/resources").Handler(monkey(resourceGetHandler, "/api/resources")).Methods("GET")
|
||||||
api.PathPrefix("/resources").Handler(monkey(resourceDeleteHandler(fileCache), "/api/resources")).Methods("DELETE")
|
api.PathPrefix("/resources").Handler(monkey(resourceDeleteHandler(fileCache), "/api/resources")).Methods("DELETE")
|
||||||
api.PathPrefix("/resources").Handler(monkey(resourcePostHandler(fileCache), "/api/resources")).Methods("POST")
|
api.PathPrefix("/resources").Handler(monkey(resourcePostHandler(fileCache), "/api/resources")).Methods("POST")
|
||||||
|
|||||||
@ -19,6 +19,23 @@ import (
|
|||||||
"github.com/filebrowser/filebrowser/v2/fileutils"
|
"github.com/filebrowser/filebrowser/v2/fileutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var resourceGetSizeHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||||
|
folder, err := files.NewFolderInfo(files.FileOptions{
|
||||||
|
Fs: d.user.Fs,
|
||||||
|
Path: r.URL.Path,
|
||||||
|
Modify: d.user.Perm.Modify,
|
||||||
|
Expand: true,
|
||||||
|
ReadHeader: d.server.TypeDetectionByHeader,
|
||||||
|
Checker: d,
|
||||||
|
Content: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errToStatus(err), err
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderJSON(w, r, folder)
|
||||||
|
})
|
||||||
|
|
||||||
var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||||
file, err := files.NewFileInfo(files.FileOptions{
|
file, err := files.NewFileInfo(files.FileOptions{
|
||||||
Fs: d.user.Fs,
|
Fs: d.user.Fs,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user