2022-01-09 14:44:43 +00:00
package _39
import (
"bytes"
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers/base"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
log "github.com/sirupsen/logrus"
"io"
"math"
"net/http"
"path/filepath"
"strconv"
)
type Cloud139 struct { }
func ( driver Cloud139 ) Config ( ) base . DriverConfig {
return base . DriverConfig {
Name : "139Yun" ,
LocalSort : true ,
}
}
func ( driver Cloud139 ) Items ( ) [ ] base . Item {
return [ ] base . Item {
{
Name : "username" ,
Label : "phone" ,
Type : base . TypeString ,
Required : true ,
Description : "phone number" ,
} ,
{
Name : "access_token" ,
Label : "Cookie" ,
Type : base . TypeString ,
Required : true ,
Description : "Unknown expiration time" ,
} ,
{
Name : "internal_type" ,
Label : "139yun type" ,
Type : base . TypeSelect ,
Required : true ,
Values : "Personal,Family" ,
} ,
{
Name : "root_folder" ,
Label : "root folder file_id" ,
Type : base . TypeString ,
Required : true ,
} ,
2022-01-11 15:43:55 +00:00
{
Name : "site_id" ,
Label : "cloud_id" ,
Type : base . TypeString ,
Required : false ,
} ,
2022-01-09 14:44:43 +00:00
}
}
func ( driver Cloud139 ) Save ( account * model . Account , old * model . Account ) error {
2022-01-15 11:36:37 +00:00
if account == nil {
return nil
}
2022-01-09 14:44:43 +00:00
_ , err := driver . Request ( "/orchestration/personalCloud/user/v1.0/qryUserExternInfo" , base . Post , nil , nil , nil , base . Json {
"qryUserExternInfoReq" : base . Json {
"commonAccountInfo" : base . Json {
"account" : account . Username ,
"accountType" : 1 ,
} ,
} ,
} , nil , account )
return err
}
func ( driver Cloud139 ) File ( path string , account * model . Account ) ( * model . File , error ) {
path = utils . ParsePath ( path )
if path == "/" {
return & model . File {
Id : account . RootFolder ,
Name : account . Name ,
Size : 0 ,
Type : conf . FOLDER ,
Driver : driver . Config ( ) . Name ,
UpdatedAt : account . UpdatedAt ,
} , nil
}
dir , name := filepath . Split ( path )
files , err := driver . Files ( dir , account )
if err != nil {
return nil , err
}
for _ , file := range files {
if file . Name == name {
return & file , nil
}
}
return nil , base . ErrPathNotFound
}
func ( driver Cloud139 ) Files ( path string , account * model . Account ) ( [ ] model . File , error ) {
path = utils . ParsePath ( path )
var files [ ] model . File
cache , err := base . GetCache ( path , account )
if err == nil {
files , _ = cache . ( [ ] model . File )
} else {
file , err := driver . File ( path , account )
if err != nil {
return nil , err
}
2022-01-11 15:43:55 +00:00
if isFamily ( account ) {
files , err = driver . familyGetFiles ( file . Id , account )
} else {
files , err = driver . GetFiles ( file . Id , account )
}
2022-01-09 14:44:43 +00:00
if err != nil {
return nil , err
}
if len ( files ) > 0 {
_ = base . SetCache ( path , files , account )
}
}
return files , nil
}
func ( driver Cloud139 ) Link ( args base . Args , account * model . Account ) ( * base . Link , error ) {
file , err := driver . File ( args . Path , account )
if err != nil {
return nil , err
}
2022-01-13 10:01:54 +00:00
var u string
//if isFamily(account) {
// u, err = driver.familyLink(file.Id, account)
//} else {
u , err = driver . GetLink ( file . Id , account )
//}
2022-01-09 14:44:43 +00:00
if err != nil {
return nil , err
}
return & base . Link { Url : u } , nil
}
func ( driver Cloud139 ) Path ( path string , account * model . Account ) ( * model . File , [ ] model . File , error ) {
path = utils . ParsePath ( path )
log . Debugf ( "139 path: %s" , path )
file , err := driver . File ( path , account )
if err != nil {
return nil , nil , err
}
if ! file . IsDir ( ) {
return file , nil , nil
}
files , err := driver . Files ( path , account )
if err != nil {
return nil , nil , err
}
return nil , files , nil
}
2022-02-02 10:03:54 +00:00
//func (driver Cloud139) Proxy(r *http.Request, account *model.Account) {
//
//}
2022-01-09 14:44:43 +00:00
func ( driver Cloud139 ) Preview ( path string , account * model . Account ) ( interface { } , error ) {
return nil , base . ErrNotSupport
}
func ( driver Cloud139 ) MakeDir ( path string , account * model . Account ) error {
parentFile , err := driver . File ( utils . Dir ( path ) , account )
if err != nil {
return err
}
data := base . Json {
"createCatalogExtReq" : base . Json {
"parentCatalogID" : parentFile . Id ,
"newCatalogName" : utils . Base ( path ) ,
"commonAccountInfo" : base . Json {
"account" : account . Username ,
"accountType" : 1 ,
} ,
} ,
}
pathname := "/orchestration/personalCloud/catalog/v1.0/createCatalogExt"
2022-01-11 15:43:55 +00:00
if isFamily ( account ) {
data = base . Json {
"cloudID" : account . SiteId ,
"commonAccountInfo" : base . Json {
"account" : account . Username ,
"accountType" : 1 ,
} ,
"docLibName" : utils . Base ( path ) ,
}
pathname = "/orchestration/familyCloud/cloudCatalog/v1.0/createCloudDoc"
}
2022-01-09 14:44:43 +00:00
_ , err = driver . Post ( pathname ,
data , nil , account )
return err
}
func ( driver Cloud139 ) Move ( src string , dst string , account * model . Account ) error {
2022-01-11 15:43:55 +00:00
if isFamily ( account ) {
return base . ErrNotSupport
}
2022-01-09 14:44:43 +00:00
srcFile , err := driver . File ( src , account )
if err != nil {
return err
}
dstParentFile , err := driver . File ( utils . Dir ( dst ) , account )
if err != nil {
return err
}
var contentInfoList [ ] string
var catalogInfoList [ ] string
if srcFile . IsDir ( ) {
catalogInfoList = append ( catalogInfoList , srcFile . Id )
} else {
contentInfoList = append ( contentInfoList , srcFile . Id )
}
data := base . Json {
"createBatchOprTaskReq" : base . Json {
"taskType" : 3 ,
"actionType" : "304" ,
"taskInfo" : base . Json {
"contentInfoList" : contentInfoList ,
"catalogInfoList" : catalogInfoList ,
"newCatalogID" : dstParentFile . Id ,
} ,
"commonAccountInfo" : base . Json {
2022-01-15 11:44:22 +00:00
"account" : account . Username ,
2022-01-09 14:44:43 +00:00
"accountType" : 1 ,
} ,
} ,
}
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
_ , err = driver . Post ( pathname , data , nil , account )
return err
}
func ( driver Cloud139 ) Rename ( src string , dst string , account * model . Account ) error {
2022-01-11 15:43:55 +00:00
if isFamily ( account ) {
return base . ErrNotSupport
}
2022-01-09 14:44:43 +00:00
srcFile , err := driver . File ( src , account )
if err != nil {
return err
}
var data base . Json
var pathname string
if srcFile . IsDir ( ) {
data = base . Json {
"catalogID" : srcFile . Id ,
"catalogName" : utils . Base ( dst ) ,
"commonAccountInfo" : base . Json {
2022-01-15 11:44:22 +00:00
"account" : account . Username ,
2022-01-09 14:44:43 +00:00
"accountType" : 1 ,
} ,
}
pathname = "/orchestration/personalCloud/catalog/v1.0/updateCatalogInfo"
} else {
data = base . Json {
"contentID" : srcFile . Id ,
"contentName" : utils . Base ( dst ) ,
"commonAccountInfo" : base . Json {
2022-01-15 11:44:22 +00:00
"account" : account . Username ,
2022-01-09 14:44:43 +00:00
"accountType" : 1 ,
} ,
}
pathname = "/orchestration/personalCloud/catalog/v1.0/updateContentInfo"
}
_ , err = driver . Post ( pathname , data , nil , account )
return err
}
func ( driver Cloud139 ) Copy ( src string , dst string , account * model . Account ) error {
2022-01-11 15:43:55 +00:00
if isFamily ( account ) {
return base . ErrNotSupport
}
2022-01-09 14:44:43 +00:00
srcFile , err := driver . File ( src , account )
if err != nil {
return err
}
dstParentFile , err := driver . File ( utils . Dir ( dst ) , account )
if err != nil {
return err
}
2022-01-11 15:43:55 +00:00
var contentInfoList [ ] string
var catalogInfoList [ ] string
2022-01-09 14:44:43 +00:00
if srcFile . IsDir ( ) {
2022-01-11 15:43:55 +00:00
catalogInfoList = append ( catalogInfoList , srcFile . Id )
} else {
contentInfoList = append ( contentInfoList , srcFile . Id )
2022-01-09 14:44:43 +00:00
}
data := base . Json {
"createBatchOprTaskReq" : base . Json {
"taskType" : 3 ,
"actionType" : 309 ,
"taskInfo" : base . Json {
2022-01-11 15:43:55 +00:00
"contentInfoList" : contentInfoList ,
"catalogInfoList" : catalogInfoList ,
2022-01-09 14:44:43 +00:00
"newCatalogID" : dstParentFile . Id ,
} ,
"commonAccountInfo" : base . Json {
2022-01-15 11:44:22 +00:00
"account" : account . Username ,
2022-01-09 14:44:43 +00:00
"accountType" : 1 ,
} ,
} ,
}
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
_ , err = driver . Post ( pathname , data , nil , account )
return err
}
func ( driver Cloud139 ) Delete ( path string , account * model . Account ) error {
file , err := driver . File ( path , account )
if err != nil {
return err
}
2022-01-11 15:43:55 +00:00
var contentInfoList [ ] string
var catalogInfoList [ ] string
2022-01-09 14:44:43 +00:00
if file . IsDir ( ) {
2022-01-11 15:43:55 +00:00
catalogInfoList = append ( catalogInfoList , file . Id )
} else {
contentInfoList = append ( contentInfoList , file . Id )
2022-01-09 14:44:43 +00:00
}
data := base . Json {
"createBatchOprTaskReq" : base . Json {
"taskType" : 2 ,
"actionType" : 201 ,
"taskInfo" : base . Json {
2022-01-11 15:43:55 +00:00
"newCatalogID" : "" ,
"contentInfoList" : contentInfoList ,
2022-02-17 09:37:45 +00:00
"catalogInfoList" : catalogInfoList ,
2022-01-09 14:44:43 +00:00
} ,
"commonAccountInfo" : base . Json {
2022-01-15 11:44:22 +00:00
"account" : account . Username ,
2022-01-09 14:44:43 +00:00
"accountType" : 1 ,
} ,
} ,
}
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
2022-01-11 15:43:55 +00:00
if isFamily ( account ) {
data = base . Json {
"catalogList" : catalogInfoList ,
"contentList" : contentInfoList ,
"commonAccountInfo" : base . Json {
2022-01-15 11:44:22 +00:00
"account" : account . Username ,
2022-01-11 15:43:55 +00:00
"accountType" : 1 ,
} ,
"sourceCatalogType" : 1002 ,
"taskType" : 2 ,
}
pathname = "/orchestration/familyCloud/batchOprTask/v1.0/createBatchOprTask"
}
2022-01-09 14:44:43 +00:00
_ , err = driver . Post ( pathname , data , nil , account )
return err
}
func ( driver Cloud139 ) Upload ( file * model . FileStream , account * model . Account ) error {
if file == nil {
return base . ErrEmptyFile
}
parentFile , err := driver . File ( file . ParentPath , account )
if err != nil {
return err
}
if ! parentFile . IsDir ( ) {
return base . ErrNotFolder
}
data := base . Json {
"manualRename" : 2 ,
"operation" : 0 ,
"fileCount" : 1 ,
"totalSize" : file . Size ,
"uploadContentList" : [ ] base . Json { {
"contentName" : file . Name ,
"contentSize" : file . Size ,
// "digest": "5a3231986ce7a6b46e408612d385bafa"
} } ,
"parentCatalogID" : parentFile . Id ,
"newCatalogName" : "" ,
"commonAccountInfo" : base . Json {
2022-01-15 11:44:22 +00:00
"account" : account . Username ,
2022-01-09 14:44:43 +00:00
"accountType" : 1 ,
} ,
}
pathname := "/orchestration/personalCloud/uploadAndDownload/v1.0/pcUploadFileRequest"
2022-01-11 15:43:55 +00:00
if isFamily ( account ) {
data = newJson ( base . Json {
"fileCount" : 1 ,
"manualRename" : 2 ,
"operation" : 0 ,
"path" : "" ,
"seqNo" : "" ,
"totalSize" : file . Size ,
"uploadContentList" : [ ] base . Json { {
"contentName" : file . Name ,
"contentSize" : file . Size ,
// "digest": "5a3231986ce7a6b46e408612d385bafa"
} } ,
} , account )
pathname = "/orchestration/familyCloud/content/v1.0/getFileUploadURL"
return base . ErrNotSupport
}
2022-01-09 14:44:43 +00:00
var resp UploadResp
_ , err = driver . Post ( pathname , data , & resp , account )
if err != nil {
return err
}
var Default uint64 = 10485760
part := int ( math . Ceil ( float64 ( file . Size ) / float64 ( Default ) ) )
var start uint64 = 0
for i := 0 ; i < part ; i ++ {
byteSize := file . Size - start
if byteSize > Default {
byteSize = Default
}
byteData := make ( [ ] byte , byteSize )
_ , err = io . ReadFull ( file , byteData )
if err != nil {
return err
}
req , err := http . NewRequest ( "POST" , resp . Data . UploadResult . RedirectionURL , bytes . NewBuffer ( byteData ) )
if err != nil {
return err
}
headers := map [ string ] string {
"Accept" : "*/*" ,
"Content-Type" : "text/plain;name=" + unicode ( file . Name ) ,
"contentSize" : strconv . FormatUint ( file . Size , 10 ) ,
"range" : fmt . Sprintf ( "bytes=%d-%d" , start , start + byteSize - 1 ) ,
"content-length" : strconv . FormatUint ( byteSize , 10 ) ,
"uploadtaskID" : resp . Data . UploadResult . UploadTaskID ,
"rangeType" : "0" ,
"Referer" : "https://yun.139.com/" ,
"User-Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 Edg/95.0.1020.44" ,
"x-SvcType" : "1" ,
}
for k , v := range headers {
req . Header . Set ( k , v )
}
res , err := base . HttpClient . Do ( req )
if err != nil {
return err
}
log . Debugf ( "%+v" , res )
start += byteSize
}
return nil
}
var _ base . Driver = ( * Cloud139 ) ( nil )