From 56c27c00906fbb1367c6729f4c0e683164aa9ef5 Mon Sep 17 00:00:00 2001 From: unknown <924417424@qq.com> Date: Tue, 22 Nov 2022 17:03:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0unzip=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E5=92=8C=E5=90=8E=E7=AB=AF=E7=9B=B8=E5=85=B3=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=8C=E5=B7=B2=E6=94=AF=E6=8C=81=E6=9D=83=E9=99=90=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auth/hook.go | 1 + cmd/root.go | 1 + frontend/src/api/files.js | 12 ++- frontend/src/components/prompts/Prompts.vue | 3 + frontend/src/components/prompts/Unzip.vue | 80 +++++++++++++++++++ .../src/components/settings/Permissions.vue | 4 + frontend/src/i18n/en.json | 5 +- frontend/src/i18n/zh-cn.json | 5 +- frontend/src/i18n/zh-tw.json | 5 +- frontend/src/views/files/Listing.vue | 18 +++++ go.mod | 3 + go.sum | 4 + http/resource.go | 19 ++++- storage/bolt/importer/conf.go | 1 + storage/bolt/importer/users.go | 1 + users/permissions.go | 1 + 16 files changed, 155 insertions(+), 8 deletions(-) create mode 100644 frontend/src/components/prompts/Unzip.vue diff --git a/auth/hook.go b/auth/hook.go index 3e57560e..f2960be1 100644 --- a/auth/hook.go +++ b/auth/hook.go @@ -215,6 +215,7 @@ func (a *HookAuth) GetUser(d *users.User) *users.User { Delete: isAdmin || a.Fields.GetBoolean("user.perm.delete", d.Perm.Delete), Share: isAdmin || a.Fields.GetBoolean("user.perm.share", d.Perm.Share), Download: isAdmin || a.Fields.GetBoolean("user.perm.download", d.Perm.Download), + Unzip: isAdmin || a.Fields.GetBoolean("user.perm.unzip", d.Perm.Unzip), } user := users.User{ ID: d.ID, diff --git a/cmd/root.go b/cmd/root.go index 5b314b61..cedef4ca 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -329,6 +329,7 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) { Delete: true, Share: true, Download: true, + Unzip: true, }, }, AuthMethod: "", diff --git a/frontend/src/api/files.js b/frontend/src/api/files.js index a91ba4b2..668a91f9 100644 --- a/frontend/src/api/files.js +++ b/frontend/src/api/files.js @@ -119,21 +119,27 @@ export async function post(url, content = "", overwrite = false, onupload) { }); } -function moveCopy(items, copy = false, overwrite = false, rename = false) { +function moveCopy(items, copy = false, overwrite = false, rename = false, unzip = false) { let promises = []; for (let item of items) { const from = item.from; const to = encodeURIComponent(removePrefix(item.to)); const url = `${from}?action=${ - copy ? "copy" : "rename" - }&destination=${to}&override=${overwrite}&rename=${rename}`; + unzip ? "unzip" : copy ? "copy" : "rename" + }&destination=${to}&override=${overwrite}&rename=${rename}&unzip=${unzip}`; + console.log(url); promises.push(resourceAction(url, "PATCH")); } return Promise.all(promises); } +export function unzip(items) { + console.log("unzip fn") + return moveCopy(items, false, false,false, true); +} + export function move(items, overwrite = false, rename = false) { return moveCopy(items, false, overwrite, rename); } diff --git a/frontend/src/components/prompts/Prompts.vue b/frontend/src/components/prompts/Prompts.vue index 36cb0349..0bc5b92d 100644 --- a/frontend/src/components/prompts/Prompts.vue +++ b/frontend/src/components/prompts/Prompts.vue @@ -20,6 +20,7 @@ import ReplaceRename from "./ReplaceRename"; import Share from "./Share"; import Upload from "./Upload"; import ShareDelete from "./ShareDelete"; +import Unzip from "./Unzip"; import { mapState } from "vuex"; import buttons from "@/utils/buttons"; @@ -40,6 +41,7 @@ export default { ReplaceRename, Upload, ShareDelete, + Unzip, }, data: function () { return { @@ -100,6 +102,7 @@ export default { "share", "upload", "share-delete", + "unzip", ].indexOf(this.show) >= 0; return (matched && this.show) || null; diff --git a/frontend/src/components/prompts/Unzip.vue b/frontend/src/components/prompts/Unzip.vue new file mode 100644 index 00000000..da46a09b --- /dev/null +++ b/frontend/src/components/prompts/Unzip.vue @@ -0,0 +1,80 @@ + + + \ No newline at end of file diff --git a/frontend/src/components/settings/Permissions.vue b/frontend/src/components/settings/Permissions.vue index 13d2b936..37400e12 100644 --- a/frontend/src/components/settings/Permissions.vue +++ b/frontend/src/components/settings/Permissions.vue @@ -36,6 +36,10 @@ {{ $t("settings.perm.share") }}

+

+ + {{ $t("settings.perm.unzip") }} +

diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index a1fccdb5..3c9b89a7 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -1,5 +1,6 @@ { "buttons": { + "unzip": "unzip", "cancel": "Cancel", "close": "Close", "copy": "Copy", @@ -120,6 +121,7 @@ }, "permanent": "Permanent", "prompts": { + "unzip": "Unzip", "copy": "Copy", "copyMessage": "Choose the place to copy your files:", "currentlyNavigating": "Currently navigating on:", @@ -214,7 +216,8 @@ "execute": "Execute commands", "modify": "Edit files", "rename": "Rename or move files and directories", - "share": "Share files" + "share": "Share files", + "unzip": "unzip" }, "permissions": "Permissions", "permissionsHelp": "You can set the user to be an administrator or choose the permissions individually. If you select \"Administrator\", all of the other options will be automatically checked. The management of users remains a privilege of an administrator.\n", diff --git a/frontend/src/i18n/zh-cn.json b/frontend/src/i18n/zh-cn.json index 89054142..68e0de1f 100644 --- a/frontend/src/i18n/zh-cn.json +++ b/frontend/src/i18n/zh-cn.json @@ -1,5 +1,6 @@ { "buttons": { + "unzip": "解压", "cancel": "取消", "close": "关闭", "copy": "复制", @@ -120,6 +121,7 @@ }, "permanent": "永久", "prompts": { + "unzip":"解压文件", "copy": "复制", "copyMessage": "请选择欲复制至的目录:", "currentlyNavigating": "当前目录:", @@ -210,7 +212,8 @@ "execute": "执行命令", "modify": "编辑", "rename": "重命名或移动文件和文件夹", - "share": "分享文件" + "share": "分享文件", + "unzip": "解压文件" }, "permissions": "权限", "permissionsHelp": "您可以将该用户设置为管理员或单独选择各项权限。如果您选择了“管理员”,则其他的选项会被自动选中,同时该用户可以管理其他用户。\n", diff --git a/frontend/src/i18n/zh-tw.json b/frontend/src/i18n/zh-tw.json index 1b51eb49..ad47166a 100644 --- a/frontend/src/i18n/zh-tw.json +++ b/frontend/src/i18n/zh-tw.json @@ -1,5 +1,6 @@ { "buttons": { + "unzip": "解压", "cancel": "取消", "close": "關閉", "copy": "複製", @@ -114,6 +115,7 @@ }, "permanent": "永久", "prompts": { + "unzip":"解壓檔案", "copy": "複製", "copyMessage": "請選擇欲複製至的目錄:", "currentlyNavigating": "目前目錄:", @@ -202,7 +204,8 @@ "execute": "執行命令", "modify": "編輯檔案", "rename": "重命名或移動檔案/資料夾", - "share": "分享檔案" + "share": "分享檔案", + "unzip": "解壓檔案" }, "permissions": "權限", "permissionsHelp": "您可以將該使用者設置為管理員,也可以單獨選擇各項權限。如果選擇了“管理員”,則其他的選項會被自動勾上,同時該使用者可以管理其他使用者。", diff --git a/frontend/src/views/files/Listing.vue b/frontend/src/views/files/Listing.vue index bdf4806b..ea931e2a 100644 --- a/frontend/src/views/files/Listing.vue +++ b/frontend/src/views/files/Listing.vue @@ -44,6 +44,13 @@ :label="$t('buttons.delete')" show="delete" /> + +
@@ -382,6 +395,7 @@ export default { share: this.selectedCount === 1 && this.user.perm.share, move: this.selectedCount > 0 && this.user.perm.rename, copy: this.selectedCount > 0 && this.user.perm.create, + unzip: this.selectedCount === 1 && this.isArchive(this.req.items[this.selected[0]].extension) && this.user.perm.unzip, }; }, isMobile() { @@ -881,6 +895,10 @@ export default { // Set the number of displayed items this.showLimit = showQuantity > totalItems ? totalItems : showQuantity; }, + isArchive(ext) { + const zip_exts = [".zip",".bz2",".br",".tbz2",".gz",".xz",".rar",".tar"]; //可扩展 + return zip_exts.indexOf(ext) > -1; + } }, }; diff --git a/go.mod b/go.mod index 3a8b2fab..e90a3f88 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,8 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) +require github.com/pierrec/lz4 v2.6.1+incompatible // indirect + require ( github.com/andybalholm/brotli v1.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -46,6 +48,7 @@ require ( github.com/klauspost/compress v1.11.4 // indirect github.com/klauspost/pgzip v1.2.5 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mholt/archiver v3.1.1+incompatible github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/nwaples/rardecode v1.1.0 // indirect github.com/pelletier/go-toml v1.9.4 // indirect diff --git a/go.sum b/go.sum index 30cd6a99..2d0f457f 100644 --- a/go.sum +++ b/go.sum @@ -194,6 +194,8 @@ github.com/maruel/natural v1.0.0 h1:C1GqgYygkdnwD1H1psoEVsPazXyUqRooEvX/XyWFFDg= github.com/maruel/natural v1.0.0/go.mod h1:eFVhYCcUOfZFxXoDZam8Ktya72wa79fNC3lc/leA0DQ= github.com/marusama/semaphore/v2 v2.5.0 h1:o/1QJD9DBYOWRnDhPwDVAXQn6mQYD0gZaS1Tpx6DJGM= github.com/marusama/semaphore/v2 v2.5.0/go.mod h1:z9nMiNUekt/LTpTUQdpp+4sJeYqUGpwMHfW0Z8V8fnQ= +github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU= +github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU= github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -206,6 +208,8 @@ github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhEC github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.0 h1:P7Bq0SaI8nsexyay5UAyDo+ICWy5MQPgEZ5+l8JQTKo= github.com/pelletier/go-toml/v2 v2.0.0/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/http/resource.go b/http/resource.go index 3a12538a..11a59604 100644 --- a/http/resource.go +++ b/http/resource.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "log" "net/http" "net/url" "os" @@ -17,6 +18,7 @@ import ( "github.com/filebrowser/filebrowser/v2/errors" "github.com/filebrowser/filebrowser/v2/files" "github.com/filebrowser/filebrowser/v2/fileutils" + "github.com/mholt/archiver" ) var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { @@ -178,6 +180,7 @@ var resourcePutHandler = withUser(func(w http.ResponseWriter, r *http.Request, d }) func resourcePatchHandler(fileCache FileCache) handleFunc { + log.SetFlags(log.Llongfile) return withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { src := r.URL.Path dst := r.URL.Query().Get("destination") @@ -189,7 +192,7 @@ func resourcePatchHandler(fileCache FileCache) handleFunc { if err != nil { return errToStatus(err), err } - if dst == "/" || src == "/" { + if dst == "/" || src == "/" || action != "unzip" { return http.StatusForbidden, nil } @@ -200,7 +203,8 @@ func resourcePatchHandler(fileCache FileCache) handleFunc { override := r.URL.Query().Get("override") == "true" rename := r.URL.Query().Get("rename") == "true" - if !override && !rename { + unzip := r.URL.Query().Get("unzip") == "true" + if !override && !rename && !unzip { if _, err = d.user.Fs.Stat(dst); err == nil { return http.StatusConflict, nil } @@ -327,6 +331,17 @@ func patchAction(ctx context.Context, action, src, dst string, d *data, fileCach } return fileutils.MoveFile(d.user.Fs, src, dst) + case "unzip": + if !d.user.Perm.Unzip { + return errors.ErrPermissionDenied + } + if strings.HasPrefix(src, "/") { + src = "." + src + } + if strings.HasPrefix(dst, "/") { + dst = "." + dst + } + return archiver.Unarchive(src, dst) default: return fmt.Errorf("unsupported action %s: %w", action, errors.ErrInvalidRequestParams) } diff --git a/storage/bolt/importer/conf.go b/storage/bolt/importer/conf.go index bafeb452..febb5fe4 100644 --- a/storage/bolt/importer/conf.go +++ b/storage/bolt/importer/conf.go @@ -134,6 +134,7 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error { Delete: cfg.Defaults.AllowEdit, Share: true, Download: true, + Unzip: true, }, }, } diff --git a/storage/bolt/importer/users.go b/storage/bolt/importer/users.go index 0483402d..dc56575f 100644 --- a/storage/bolt/importer/users.go +++ b/storage/bolt/importer/users.go @@ -73,6 +73,7 @@ func convertUsersToNew(old []*oldUser) ([]*users.User, error) { Delete: oldUser.AllowEdit, Share: true, Download: true, + Unzip: true, }, } diff --git a/users/permissions.go b/users/permissions.go index 29e0a5b9..7d69e9e4 100644 --- a/users/permissions.go +++ b/users/permissions.go @@ -10,4 +10,5 @@ type Permissions struct { Delete bool `json:"delete"` Share bool `json:"share"` Download bool `json:"download"` + Unzip bool `json:"unzip"` }