feat: add lazy loading folder size

This commit is contained in:
Suacrbah 2023-12-31 18:34:43 +08:00
parent 04e03a83b4
commit 123f44d1c8
5 changed files with 94 additions and 1 deletions

View File

@ -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

View File

@ -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" }),

View File

@ -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>

View File

@ -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")

View File

@ -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,