- folder
- insert_photo
- insert_drive_file
+ {{ item.isDir ? 'folder' : (item.type==='image') ? 'insert_photo' : 'insert_drive_file' }}
-
@@ -46,6 +49,8 @@
diff --git a/http/http.go b/http/http.go
index a4b3c2d2..95747794 100644
--- a/http/http.go
+++ b/http/http.go
@@ -51,6 +51,7 @@ func NewHandler(imgSvc ImgService, fileCache FileCache, store *storage.Storage,
api.PathPrefix("/resources").Handler(monkey(resourcePostPutHandler, "/api/resources")).Methods("PUT")
api.PathPrefix("/resources").Handler(monkey(resourcePatchHandler, "/api/resources")).Methods("PATCH")
+ api.Path("/shares").Handler(monkey(shareListHandler, "/api/shares")).Methods("GET")
api.PathPrefix("/share").Handler(monkey(shareGetsHandler, "/api/share")).Methods("GET")
api.PathPrefix("/share").Handler(monkey(sharePostHandler, "/api/share")).Methods("POST")
api.PathPrefix("/share").Handler(monkey(shareDeleteHandler, "/api/share")).Methods("DELETE")
diff --git a/http/share.go b/http/share.go
index 2c01ca26..853a178e 100644
--- a/http/share.go
+++ b/http/share.go
@@ -5,6 +5,7 @@ import (
"encoding/base64"
"net/http"
"path"
+ "sort"
"strconv"
"strings"
"time"
@@ -23,6 +24,34 @@ func withPermShare(fn handleFunc) handleFunc {
})
}
+var shareListHandler = withPermShare(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
+ var (
+ s []*share.Link
+ err error
+ )
+ if d.user.Perm.Admin {
+ s, err = d.store.Share.All()
+ } else {
+ s, err = d.store.Share.FindByUserID(d.user.ID)
+ }
+ if err == errors.ErrNotExist {
+ return renderJSON(w, r, []*share.Link{})
+ }
+
+ if err != nil {
+ return http.StatusInternalServerError, err
+ }
+
+ sort.Slice(s, func(i, j int) bool {
+ if s[i].UserID != s[j].UserID {
+ return s[i].UserID < s[j].UserID
+ }
+ return s[i].Expire < s[j].Expire
+ })
+
+ return renderJSON(w, r, s)
+})
+
var shareGetsHandler = withPermShare(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
s, err := d.store.Share.Gets(r.URL.Path, d.user.ID)
if err == errors.ErrNotExist {
diff --git a/share/storage.go b/share/storage.go
index 6073cbcc..4cd263de 100644
--- a/share/storage.go
+++ b/share/storage.go
@@ -8,6 +8,8 @@ import (
// StorageBackend is the interface to implement for a share storage.
type StorageBackend interface {
+ All() ([]*Link, error)
+ FindByUserID(id uint) ([]*Link, error)
GetByHash(hash string) (*Link, error)
GetPermanent(path string, id uint) (*Link, error)
Gets(path string, id uint) ([]*Link, error)
@@ -25,6 +27,46 @@ func NewStorage(back StorageBackend) *Storage {
return &Storage{back: back}
}
+// All wraps a StorageBackend.All.
+func (s *Storage) All() ([]*Link, error) {
+ links, err := s.back.All()
+
+ if err != nil {
+ return nil, err
+ }
+
+ for i, link := range links {
+ if link.Expire != 0 && link.Expire <= time.Now().Unix() {
+ if err := s.Delete(link.Hash); err != nil {
+ return nil, err
+ }
+ links = append(links[:i], links[i+1:]...)
+ }
+ }
+
+ return links, nil
+}
+
+// FindByUserID wraps a StorageBackend.FindByUserID.
+func (s *Storage) FindByUserID(id uint) ([]*Link, error) {
+ links, err := s.back.FindByUserID(id)
+
+ if err != nil {
+ return nil, err
+ }
+
+ for i, link := range links {
+ if link.Expire != 0 && link.Expire <= time.Now().Unix() {
+ if err := s.Delete(link.Hash); err != nil {
+ return nil, err
+ }
+ links = append(links[:i], links[i+1:]...)
+ }
+ }
+
+ return links, nil
+}
+
// GetByHash wraps a StorageBackend.GetByHash.
func (s *Storage) GetByHash(hash string) (*Link, error) {
link, err := s.back.GetByHash(hash)
diff --git a/storage/bolt/share.go b/storage/bolt/share.go
index f74247ec..78940c34 100644
--- a/storage/bolt/share.go
+++ b/storage/bolt/share.go
@@ -12,6 +12,26 @@ type shareBackend struct {
db *storm.DB
}
+func (s shareBackend) All() ([]*share.Link, error) {
+ var v []*share.Link
+ err := s.db.All(&v)
+ if err == storm.ErrNotFound {
+ return v, errors.ErrNotExist
+ }
+
+ return v, err
+}
+
+func (s shareBackend) FindByUserID(id uint) ([]*share.Link, error) {
+ var v []*share.Link
+ err := s.db.Select(q.Eq("UserID", id)).Find(&v)
+ if err == storm.ErrNotFound {
+ return v, errors.ErrNotExist
+ }
+
+ return v, err
+}
+
func (s shareBackend) GetByHash(hash string) (*share.Link, error) {
var v share.Link
err := s.db.One("Hash", hash, &v)
From fb5b28d9cbdee10d38fcd719b9fd832121be58ef Mon Sep 17 00:00:00 2001
From: WeidiDeng
Date: Tue, 29 Dec 2020 00:35:29 +0800
Subject: [PATCH 0045/1102] feat: download shared subdirectory (#1184)
Co-authored-by: Oleg Lobanov
---
frontend/src/api/files.js | 2 +-
frontend/src/api/utils.js | 2 +
frontend/src/components/Header.vue | 17 +-
frontend/src/components/buttons/Download.vue | 4 +-
frontend/src/components/files/ListingItem.vue | 22 +-
frontend/src/css/_share.css | 8 +-
frontend/src/i18n/en.json | 3 +-
frontend/src/i18n/zh-cn.json | 3 +-
frontend/src/store/getters.js | 1 +
frontend/src/store/index.js | 3 +-
frontend/src/store/mutations.js | 3 +-
frontend/src/views/Share.vue | 220 +++++++++++++-----
http/public.go | 40 +++-
13 files changed, 240 insertions(+), 88 deletions(-)
diff --git a/frontend/src/api/files.js b/frontend/src/api/files.js
index 2b5cf540..d12a4237 100644
--- a/frontend/src/api/files.js
+++ b/frontend/src/api/files.js
@@ -58,7 +58,7 @@ export async function put (url, content = '') {
}
export function download (format, ...files) {
- let url = `${baseURL}/api/raw`
+ let url = store.getters['isSharing'] ? `${baseURL}/api/public/dl/${store.state.hash}` : `${baseURL}/api/raw`
if (files.length === 1) {
url += removePrefix(files[0]) + '?'
diff --git a/frontend/src/api/utils.js b/frontend/src/api/utils.js
index 617e2258..68337d10 100644
--- a/frontend/src/api/utils.js
+++ b/frontend/src/api/utils.js
@@ -36,6 +36,8 @@ export async function fetchJSON (url, opts) {
export function removePrefix (url) {
if (url.startsWith('/files')) {
url = url.slice(6)
+ } else if (store.getters['isSharing']) {
+ url = url.slice(7 + store.state.hash.length)
}
if (url === '') url = '/'
diff --git a/frontend/src/components/Header.vue b/frontend/src/components/Header.vue
index b9278d10..6d9a1270 100644
--- a/frontend/src/components/Header.vue
+++ b/frontend/src/components/Header.vue
@@ -8,8 +8,8 @@