aboutsummaryrefslogtreecommitdiff
path: root/internal/assets/public/public.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/assets/public/public.go')
1 files changed, 143 insertions, 0 deletions
diff --git a/internal/assets/public/public.go b/internal/assets/public/public.go
new file mode 100644
index 00000000..2bce7c7a
--- /dev/null
+++ b/internal/assets/public/public.go
@@ -0,0 +1,143 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package public
+
+import (
+ "bytes"
+ "net/http"
+ "os"
+ "path/filepath"
+ "time"
+
+ "gogs.io/gogs/internal/assets"
+)
+
+//go:generate go-bindata -nomemcopy -pkg=public -ignore="\\.DS_Store|less" -prefix=../../../public -debug=false -o=public_gen.go ../../../public/...
+
+/*
+ This file is a modified version of https://github.com/go-bindata/go-bindata/pull/18.
+*/
+
+type fileInfo struct {
+ name string
+ size int64
+}
+
+func (d fileInfo) Name() string {
+ return d.name
+}
+
+func (d fileInfo) Size() int64 {
+ return d.size
+}
+
+func (d fileInfo) Mode() os.FileMode {
+ return os.FileMode(0644) | os.ModeDir
+}
+
+func (d fileInfo) ModTime() time.Time {
+ return time.Time{}
+}
+
+// IsDir return file whether a directory
+func (d *fileInfo) IsDir() bool {
+ return true
+}
+
+func (d fileInfo) Sys() interface{} {
+ return nil
+}
+
+// file implements the http.File interface.
+type file struct {
+ name string
+ *bytes.Reader
+
+ children []os.FileInfo
+ childrenOffset int
+}
+
+func (f *file) Close() error {
+ return nil
+}
+
+// ⚠️ WARNING: This method is not concurrent-safe.
+func (f *file) Readdir(count int) ([]os.FileInfo, error) {
+ if len(f.children) == 0 {
+ return nil, os.ErrNotExist
+ }
+
+ if count <= 0 {
+ return f.children, nil
+ }
+
+ if f.childrenOffset+count > len(f.children) {
+ count = len(f.children) - f.childrenOffset
+ }
+ offset := f.childrenOffset
+ f.childrenOffset += count
+ return f.children[offset : offset+count], nil
+}
+
+func (f *file) Stat() (os.FileInfo, error) {
+ childCount := len(f.children)
+ if childCount != 0 {
+ return &fileInfo{
+ name: f.name,
+ size: int64(childCount),
+ }, nil
+ }
+ return AssetInfo(f.name)
+}
+
+// fileSystem implements the http.FileSystem interface.
+type fileSystem struct{}
+
+func (f *fileSystem) Open(name string) (http.File, error) {
+ if len(name) > 0 && name[0] == '/' {
+ name = name[1:]
+ }
+
+ // Attempt to get it as a file
+ p, err := Asset(name)
+ if err != nil && !assets.IsErrNotFound(err) {
+ return nil, err
+ } else if err == nil {
+ return &file{
+ name: name,
+ Reader: bytes.NewReader(p),
+ }, nil
+ }
+
+ // Attempt to get it as a directory
+ paths, err := AssetDir(name)
+ if err != nil && !assets.IsErrNotFound(err) {
+ return nil, err
+ }
+
+ infos := make([]os.FileInfo, len(paths))
+ for i, path := range paths {
+ path = filepath.Join(name, path)
+ info, err := AssetInfo(path)
+ if err != nil {
+ if !assets.IsErrNotFound(err) {
+ return nil, err
+ }
+ // Not found as a file, assume it's a directory.
+ infos[i] = &fileInfo{name: path}
+ } else {
+ infos[i] = info
+ }
+ }
+ return &file{
+ name: name,
+ children: infos,
+ }, nil
+}
+
+// NewFileSystem returns an http.FileSystem instance backed by embedded assets.
+func NewFileSystem() http.FileSystem {
+ return &fileSystem{}
+}