65 Star 395 Fork 128

admpub/nging

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
sftpmanager.go 5.46 KB
一键复制 编辑 原始数据 按行查看 历史
admpub 提交于 2019-09-07 17:18 . improved filemanager
/*
Nging is a toolbox for webmasters
Copyright (C) 2018-present Wenhui Shen <swh@admpub.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package sftpmanager
import (
"bytes"
"io"
"io/ioutil"
"os"
"path"
"sort"
"strings"
"github.com/admpub/nging/application/library/charset"
"github.com/admpub/nging/application/library/filemanager"
"github.com/pkg/sftp"
"github.com/webx-top/com"
"github.com/webx-top/echo"
)
func New(client *sftp.Client, editableMaxSize int64, ctx echo.Context) *sftpManager {
return &sftpManager{
Context: ctx,
client: client,
EditableMaxSize: editableMaxSize,
}
}
type sftpManager struct {
echo.Context
client *sftp.Client
EditableMaxSize int64
}
func (s *sftpManager) Edit(ppath string, content string, encoding string) (interface{}, error) {
f, err := s.client.Open(ppath)
if err != nil {
return nil, err
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
return nil, err
}
if fi.IsDir() {
return nil, s.E(`不能编辑文件夹`)
}
if s.EditableMaxSize > 0 && fi.Size() > s.EditableMaxSize {
return nil, s.E(`很抱歉,不支持编辑超过%v的文件`, com.FormatByte(s.EditableMaxSize))
}
encoding = strings.ToLower(encoding)
isUTF8 := len(encoding) == 0 || encoding == `utf-8`
if s.IsPost() {
b := []byte(content)
if !isUTF8 {
b, err = charset.Convert(`utf-8`, encoding, b)
if err != nil {
return nil, err
}
}
f.Close()
r := bytes.NewReader(b)
f, err = s.client.OpenFile(ppath, os.O_CREATE|os.O_RDWR|os.O_TRUNC)
if err != nil {
return nil, err
}
_, err = io.Copy(f, r)
if err != nil {
return nil, s.E(ppath + `:` + err.Error())
}
return nil, err
}
dat, err := ioutil.ReadAll(f)
if err == nil && !isUTF8 {
dat, err = charset.Convert(encoding, `utf-8`, dat)
}
return string(dat), err
}
func (s *sftpManager) Mkdir(ppath, newName string) error {
dirPath := path.Join(ppath, newName)
f, err := s.client.Open(dirPath)
if err == nil {
finfo, err := f.Stat()
if err != nil {
return err
}
if finfo.IsDir() {
return s.E(`已经存在相同名称的文件夹`)
}
return s.E(`已经存在相同名称的文件`)
}
if !os.IsNotExist(err) {
return err
}
err = s.client.Mkdir(dirPath)
return err
}
func (s *sftpManager) Rename(ppath, newName string) error {
return s.client.Rename(ppath, newName)
}
func (s *sftpManager) Chown(ppath string, uid, gid int) error {
return s.client.Chown(ppath, uid, gid)
}
func (s *sftpManager) Chmod(ppath string, mode os.FileMode) error {
return s.client.Chmod(ppath, mode)
}
func (s *sftpManager) Search(ppath string, prefix string, num int) []string {
var paths []string
dirs, _ := s.client.ReadDir(ppath)
for _, d := range dirs {
if len(paths) >= num {
break
}
name := d.Name()
if strings.HasPrefix(name, prefix) {
paths = append(paths, name)
continue
}
}
return paths
}
func (s *sftpManager) Remove(ppath string) error {
return s.client.Remove(ppath)
}
func (s *sftpManager) Upload(ppath string) error {
d, err := s.client.Open(ppath)
if err != nil {
return err
}
defer d.Close()
fi, err := d.Stat()
if !fi.IsDir() {
return s.E(`路径不正确`)
}
fileSrc, fileHdr, err := s.Request().FormFile(`file`)
if err != nil {
return err
}
defer fileSrc.Close()
// Destination
fileName := fileHdr.Filename
fileDst, err := s.client.Create(path.Join(ppath, fileName))
if err != nil {
return err
}
defer fileDst.Close()
// Copy
_, err = io.Copy(fileDst, fileSrc)
return err
}
func (s *sftpManager) List(ppath string, sortBy ...string) (err error, exit bool, dirs []os.FileInfo) {
d, err := s.client.Open(ppath)
if err != nil {
return err, false, nil
}
defer d.Close()
fi, err := d.Stat()
if !fi.IsDir() {
fileName := path.Base(ppath)
inline := s.Formx(`inline`).Bool()
return s.Attachment(d, fileName, inline), true, nil
}
dirs, err = s.client.ReadDir(ppath)
if len(sortBy) > 0 {
switch sortBy[0] {
case `time`:
sort.Sort(filemanager.SortByModTime(dirs))
case `-time`:
sort.Sort(filemanager.SortByModTimeDesc(dirs))
case `name`:
case `-name`:
sort.Sort(filemanager.SortByNameDesc(dirs))
case `type`:
fallthrough
default:
sort.Sort(filemanager.SortByFileType(dirs))
}
}
if s.Format() == "json" {
dirList, fileList := s.ListTransfer(dirs)
data := s.Data()
data.SetData(echo.H{
`dirList`: dirList,
`fileList`: fileList,
})
return s.JSON(data), true, nil
}
return
}
func (s *sftpManager) ListTransfer(dirs []os.FileInfo) (dirList []echo.H, fileList []echo.H) {
dirList = []echo.H{}
fileList = []echo.H{}
for _, d := range dirs {
item := echo.H{
`name`: d.Name(),
`size`: d.Size(),
`mode`: d.Mode().String(),
`mtime`: d.ModTime().Format(`2006-01-02 15:04:05`),
//`sys`: d.Sys(),
}
if d.IsDir() {
dirList = append(dirList, item)
continue
}
fileList = append(fileList, item)
}
return
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/admpub/nging.git
git@gitee.com:admpub/nging.git
admpub
nging
nging
v2.2.1

搜索帮助