mirror of https://github.com/Xhofe/alist
🚧 123pan write
parent
a7e9bb9e9a
commit
fe79f9518b
|
@ -1,12 +1,17 @@
|
||||||
package _23
|
package _23
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Xhofe/alist/conf"
|
"github.com/Xhofe/alist/conf"
|
||||||
"github.com/Xhofe/alist/drivers/base"
|
"github.com/Xhofe/alist/drivers/base"
|
||||||
"github.com/Xhofe/alist/model"
|
"github.com/Xhofe/alist/model"
|
||||||
"github.com/Xhofe/alist/utils"
|
"github.com/Xhofe/alist/utils"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
"math/rand"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
@ -122,6 +127,20 @@ func (driver Pan123) GetFiles(parentId string, account *model.Account) ([]Pan123
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (driver Pan123) Post(url string, data base.Json, account *model.Account) ([]byte, error) {
|
||||||
|
res, err := pan123Client.R().
|
||||||
|
SetHeader("authorization", "Bearer "+account.AccessToken).
|
||||||
|
SetBody(data).Post(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body := res.Body()
|
||||||
|
if jsoniter.Get(body, "code").ToInt() != 0 {
|
||||||
|
return nil, errors.New(jsoniter.Get(body, "message").ToString())
|
||||||
|
}
|
||||||
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (driver Pan123) GetFile(path string, account *model.Account) (*Pan123File, error) {
|
func (driver Pan123) GetFile(path string, account *model.Account) (*Pan123File, error) {
|
||||||
dir, name := filepath.Split(path)
|
dir, name := filepath.Split(path)
|
||||||
dir = utils.ParsePath(dir)
|
dir = utils.ParsePath(dir)
|
||||||
|
@ -143,6 +162,28 @@ func (driver Pan123) GetFile(path string, account *model.Account) (*Pan123File,
|
||||||
return nil, base.ErrPathNotFound
|
return nil, base.ErrPathNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RandStr(length int) string {
|
||||||
|
str := "123456789abcdefghijklmnopqrstuvwxyz"
|
||||||
|
bytes := []byte(str)
|
||||||
|
var result []byte
|
||||||
|
rand.Seed(time.Now().UnixNano()+ int64(rand.Intn(100)))
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
result = append(result, bytes[rand.Intn(len(bytes))])
|
||||||
|
}
|
||||||
|
return string(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HMAC(message string, secret string) string {
|
||||||
|
key := []byte(secret)
|
||||||
|
h := hmac.New(sha256.New, key)
|
||||||
|
h.Write([]byte(message))
|
||||||
|
// fmt.Println(h.Sum(nil))
|
||||||
|
//sha := hex.EncodeToString(h.Sum(nil))
|
||||||
|
// fmt.Println(sha)
|
||||||
|
//return sha
|
||||||
|
return string(h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
base.RegisterDriver(&Pan123{})
|
base.RegisterDriver(&Pan123{})
|
||||||
pan123Client.SetRetryCount(3)
|
pan123Client.SetRetryCount(3)
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
package _23
|
package _23
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Xhofe/alist/conf"
|
"github.com/Xhofe/alist/conf"
|
||||||
"github.com/Xhofe/alist/drivers/base"
|
"github.com/Xhofe/alist/drivers/base"
|
||||||
"github.com/Xhofe/alist/model"
|
"github.com/Xhofe/alist/model"
|
||||||
"github.com/Xhofe/alist/utils"
|
"github.com/Xhofe/alist/utils"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
url "net/url"
|
url "net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Pan123 struct{}
|
type Pan123 struct{}
|
||||||
|
@ -161,7 +167,7 @@ func (driver Pan123) Link(path string, account *model.Account) (*base.Link, erro
|
||||||
link := base.Link{}
|
link := base.Link{}
|
||||||
if res.StatusCode() == 302 {
|
if res.StatusCode() == 302 {
|
||||||
link.Url = res.Header().Get("location")
|
link.Url = res.Header().Get("location")
|
||||||
}else {
|
} else {
|
||||||
link.Url = resp.Data.DownloadUrl
|
link.Url = resp.Data.DownloadUrl
|
||||||
}
|
}
|
||||||
return &link, nil
|
return &link, nil
|
||||||
|
@ -198,22 +204,145 @@ func (driver Pan123) Preview(path string, account *model.Account) (interface{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (driver Pan123) MakeDir(path string, account *model.Account) error {
|
func (driver Pan123) MakeDir(path string, account *model.Account) error {
|
||||||
return base.ErrNotImplement
|
dir, name := filepath.Split(path)
|
||||||
|
parentFile, err := driver.File(dir, account)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !parentFile.IsDir() {
|
||||||
|
return base.ErrNotFolder
|
||||||
|
}
|
||||||
|
parentFileId, _ := strconv.Atoi(parentFile.Id)
|
||||||
|
data := base.Json{
|
||||||
|
"driveId": 0,
|
||||||
|
"etag": "",
|
||||||
|
"fileName": name,
|
||||||
|
"parentFileId": parentFileId,
|
||||||
|
"size": 0,
|
||||||
|
"type": 1,
|
||||||
|
}
|
||||||
|
_, err = driver.Post("https://www.123pan.com/api/file/upload_request", data, account)
|
||||||
|
if err == nil {
|
||||||
|
_ = base.DeleteCache(dir, account)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (driver Pan123) Move(src string, dst string, account *model.Account) error {
|
func (driver Pan123) Move(src string, dst string, account *model.Account) error {
|
||||||
return base.ErrNotImplement
|
srcDir, _ := filepath.Split(src)
|
||||||
|
dstDir, dstName := filepath.Split(dst)
|
||||||
|
srcFile, err := driver.File(src, account)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fileId, _ := strconv.Atoi(srcFile.Id)
|
||||||
|
// rename
|
||||||
|
if srcDir == dstDir {
|
||||||
|
data := base.Json{
|
||||||
|
"driveId": 0,
|
||||||
|
"fileId": fileId,
|
||||||
|
"fileName": dstName,
|
||||||
|
}
|
||||||
|
_, err = driver.Post("https://www.123pan.com/api/file/rename", data, account)
|
||||||
|
} else {
|
||||||
|
// move
|
||||||
|
dstDirFile, err := driver.File(dstDir, account)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
parentFileId, _ := strconv.Atoi(dstDirFile.Id)
|
||||||
|
data := base.Json{
|
||||||
|
"fileId": fileId,
|
||||||
|
"parentFileId": parentFileId,
|
||||||
|
}
|
||||||
|
_, err = driver.Post("https://www.123pan.com/api/file/mod_pid", data, account)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
_ = base.DeleteCache(srcDir, account)
|
||||||
|
_ = base.DeleteCache(dstDir, account)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (driver Pan123) Copy(src string, dst string, account *model.Account) error {
|
func (driver Pan123) Copy(src string, dst string, account *model.Account) error {
|
||||||
return base.ErrNotImplement
|
return base.ErrNotSupport
|
||||||
}
|
}
|
||||||
|
|
||||||
func (driver Pan123) Delete(path string, account *model.Account) error {
|
func (driver Pan123) Delete(path string, account *model.Account) error {
|
||||||
return base.ErrNotImplement
|
file, err := driver.GetFile(path, account)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data := base.Json{
|
||||||
|
"driveId": 0,
|
||||||
|
"operation": true,
|
||||||
|
"fileTrashInfoList": file,
|
||||||
|
}
|
||||||
|
_, err = driver.Post("https://www.123pan.com/api/file/trash", data, account)
|
||||||
|
if err == nil {
|
||||||
|
_ = base.DeleteCache(utils.Dir(path), account)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UploadResp struct {
|
||||||
|
XMLName xml.Name `xml:"InitiateMultipartUploadResult"`
|
||||||
|
Bucket string `xml:"Bucket"`
|
||||||
|
Key string `xml:"Key"`
|
||||||
|
UploadId string `xml:"UploadId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO unfinished
|
||||||
func (driver Pan123) Upload(file *model.FileStream, account *model.Account) error {
|
func (driver Pan123) Upload(file *model.FileStream, account *model.Account) error {
|
||||||
|
parentFile, err := driver.File(file.ParentPath, account)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !parentFile.IsDir() {
|
||||||
|
return base.ErrNotFolder
|
||||||
|
}
|
||||||
|
parentFileId, _ := strconv.Atoi(parentFile.Id)
|
||||||
|
data := base.Json{
|
||||||
|
"driveId": 0,
|
||||||
|
"duplicate": true,
|
||||||
|
"etag": RandStr(32), //maybe file's md5
|
||||||
|
"fileName": file.GetFileName(),
|
||||||
|
"parentFileId": parentFileId,
|
||||||
|
"size": file.GetSize(),
|
||||||
|
"type": 0,
|
||||||
|
}
|
||||||
|
res, err := driver.Post("https://www.123pan.com/api/file/upload_request", data, account)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
baseUrl := fmt.Sprintf("https://file.123pan.com/%s/%s", jsoniter.Get(res, "data.Bucket").ToString(), jsoniter.Get(res, "data.Key").ToString())
|
||||||
|
var resp UploadResp
|
||||||
|
kSecret := jsoniter.Get(res, "data.SecretAccessKey").ToString()
|
||||||
|
nowTimeStr := time.Now().String()
|
||||||
|
Date := strings.ReplaceAll(strings.Split(nowTimeStr, "T")[0],"-","")
|
||||||
|
|
||||||
|
StringToSign := fmt.Sprintf("%s\n%s\n%s\n%s",
|
||||||
|
"AWS4-HMAC-SHA256",
|
||||||
|
nowTimeStr,
|
||||||
|
fmt.Sprintf("%s/us-east-1/s3/aws4_request", Date),
|
||||||
|
)
|
||||||
|
|
||||||
|
kDate := HMAC("AWS4"+kSecret, Date)
|
||||||
|
kRegion := HMAC(kDate, "us-east-1")
|
||||||
|
kService := HMAC(kRegion, "s3")
|
||||||
|
kSigning := HMAC(kService, "aws4_request")
|
||||||
|
_, err = pan123Client.R().SetResult(&resp).SetHeaders(map[string]string{
|
||||||
|
"Authorization": fmt.Sprintf("AWS4-HMAC-SHA256 Credential=%s/%s/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-security-token;x-amz-user-agent, Signature=%s",
|
||||||
|
jsoniter.Get(res, "data.AccessKeyId"),
|
||||||
|
Date,
|
||||||
|
hex.EncodeToString([]byte(HMAC(StringToSign, kSigning)))),
|
||||||
|
"X-Amz-Content-Sha256": "UNSIGNED-PAYLOAD",
|
||||||
|
"X-Amz-Date": nowTimeStr,
|
||||||
|
"x-amz-security-token": jsoniter.Get(res, "data.SessionToken").ToString(),
|
||||||
|
}).Post(fmt.Sprintf("%s?uploads", baseUrl))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return base.ErrNotImplement
|
return base.ErrNotImplement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue