Initial commit
This commit is contained in:
74
alidrive/auth.go
Normal file
74
alidrive/auth.go
Normal file
@ -0,0 +1,74 @@
|
||||
package alidrive
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/Xhofe/alist/conf"
|
||||
"github.com/Xhofe/alist/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func TokenLogin() (*TokenLoginResp, error) {
|
||||
log.Infof("尝试使用token登录...")
|
||||
url:="https://auth.aliyundrive.com/v2/oauth/token_login"
|
||||
req:=TokenLoginReq{Token:conf.Conf.AliDrive.LoginToken}
|
||||
log.Debugf("token_login_req:%v",req)
|
||||
var tokenLogin TokenLoginResp
|
||||
if body, err := DoPost(url, req,false); err != nil {
|
||||
log.Errorf("tokenLogin-doPost出错:%s",err.Error())
|
||||
return nil,err
|
||||
}else {
|
||||
if err = json.Unmarshal(body,&tokenLogin);err!=nil {
|
||||
log.Errorf("解析json[%s]出错:%s",string(body),err.Error())
|
||||
return nil,err
|
||||
}
|
||||
}
|
||||
if tokenLogin.IsAvailable() {
|
||||
return &tokenLogin,nil
|
||||
}
|
||||
return nil,fmt.Errorf("登录token失效,请更换:%s",tokenLogin.Message)
|
||||
}
|
||||
|
||||
func GetToken(tokenLogin *TokenLoginResp) (*TokenResp,error) {
|
||||
log.Infof("获取API token...")
|
||||
url:="https://websv.aliyundrive.com/token/get"
|
||||
code:=utils.GetCode(tokenLogin.Goto)
|
||||
if code == "" {
|
||||
return nil,fmt.Errorf("获取code出错")
|
||||
}
|
||||
req:=GetTokenReq{Code:code}
|
||||
var token TokenResp
|
||||
if body, err := DoPost(url, req,false); err != nil {
|
||||
log.Errorf("tokenLogin-doPost出错:%s",err.Error())
|
||||
return nil,err
|
||||
}else {
|
||||
if err = json.Unmarshal(body,&token);err!=nil {
|
||||
log.Errorf("解析json[%s]出错:%s",string(body),err.Error())
|
||||
log.Errorf("此处json解析失败应该是code失效")
|
||||
return nil,fmt.Errorf("code失效")
|
||||
}
|
||||
}
|
||||
return &token,nil
|
||||
}
|
||||
|
||||
func RefreshToken() bool {
|
||||
log.Infof("刷新token...")
|
||||
url:="https://websv.aliyundrive.com/token/refresh"
|
||||
req:=RefreshTokenReq{RefreshToken:conf.Conf.AliDrive.RefreshToken}
|
||||
var token TokenResp
|
||||
if body, err := DoPost(url, req,false); err != nil {
|
||||
log.Errorf("tokenLogin-doPost出错:%s",err.Error())
|
||||
return false
|
||||
}else {
|
||||
if err = json.Unmarshal(body,&token);err!=nil {
|
||||
log.Errorf("解析json[%s]出错:%s",string(body),err.Error())
|
||||
log.Errorf("此处json解析失败应该是refresh_token失效")
|
||||
return false
|
||||
}
|
||||
}
|
||||
//刷新成功 更新token
|
||||
conf.Conf.AliDrive.AccessToken=token.AccessToken
|
||||
conf.Conf.AliDrive.RefreshToken=token.RefreshToken
|
||||
conf.Authorization=token.TokenType+"\t"+token.AccessToken
|
||||
return true
|
||||
}
|
5
alidrive/const.go
Normal file
5
alidrive/const.go
Normal file
@ -0,0 +1,5 @@
|
||||
package alidrive
|
||||
|
||||
var (
|
||||
User *UserInfo
|
||||
)
|
46
alidrive/req_bean.go
Normal file
46
alidrive/req_bean.go
Normal file
@ -0,0 +1,46 @@
|
||||
package alidrive
|
||||
|
||||
type ListReq struct {
|
||||
DriveId string `json:"drive_id"`
|
||||
Fields string `json:"fields"`
|
||||
ImageThumbnailProcess string `json:"image_thumbnail_process"`
|
||||
ImageUrlProcess string `json:"image_url_process"`
|
||||
Limit int `json:"limit"`
|
||||
Marker string `json:"marker"`
|
||||
OrderBy string `json:"order_by"`
|
||||
OrderDirection string `json:"order_direction"`
|
||||
ParentFileId string `json:"parent_file_id"`
|
||||
VideoThumbnailProcess string `json:"video_thumbnail_process"`
|
||||
}
|
||||
|
||||
type GetReq struct {
|
||||
DriveId string `json:"drive_id"`
|
||||
FileId string `json:"file_id"`
|
||||
ImageThumbnailProcess string `json:"image_thumbnail_process"`
|
||||
VideoThumbnailProcess string `json:"video_thumbnail_process"`
|
||||
}
|
||||
|
||||
type SearchReq struct {
|
||||
DriveId string `json:"drive_id"`
|
||||
ImageThumbnailProcess string `json:"image_thumbnail_process"`
|
||||
ImageUrlProcess string `json:"image_url_process"`
|
||||
Limit int `json:"limit"`
|
||||
Marker string `json:"marker"`
|
||||
OrderBy string `json:"order_by"`//"type ASC,updated_at DESC"
|
||||
|
||||
Query string `json:"query"`// "name match '测试文件'"
|
||||
|
||||
VideoThumbnailProcess string `json:"video_thumbnail_process"`
|
||||
}
|
||||
|
||||
type TokenLoginReq struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type GetTokenReq struct {
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
type RefreshTokenReq struct {
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
200
alidrive/request.go
Normal file
200
alidrive/request.go
Normal file
@ -0,0 +1,200 @@
|
||||
package alidrive
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/Xhofe/alist/conf"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GetFile(fileId string) (*File, error) {
|
||||
url:=conf.Conf.AliDrive.ApiUrl+"/file/get"
|
||||
req:=GetReq{
|
||||
DriveId: User.DefaultDriveId,
|
||||
FileId: fileId,
|
||||
ImageThumbnailProcess: conf.ImageThumbnailProcess,
|
||||
VideoThumbnailProcess: conf.VideoThumbnailProcess,
|
||||
}
|
||||
var file File
|
||||
if body, err := DoPost(url, req,true); err != nil {
|
||||
log.Errorf("doPost出错:%s",err.Error())
|
||||
return nil,err
|
||||
}else {
|
||||
if err = json.Unmarshal(body,&file);err !=nil {
|
||||
log.Errorf("解析json[%s]出错:%s",string(body),err.Error())
|
||||
return nil,err
|
||||
}
|
||||
}
|
||||
if file.IsAvailable() {
|
||||
return &file,nil
|
||||
}
|
||||
if file.Code==conf.AccessTokenInvalid {
|
||||
if RefreshToken() {
|
||||
return GetFile(fileId)
|
||||
}
|
||||
}
|
||||
return nil,fmt.Errorf(file.Message)
|
||||
}
|
||||
|
||||
func Search(key string,limit int, marker string) (*Files, error) {
|
||||
url:=conf.Conf.AliDrive.ApiUrl+"/file/search"
|
||||
req:=SearchReq{
|
||||
DriveId: User.DefaultDriveId,
|
||||
ImageThumbnailProcess: conf.ImageThumbnailProcess,
|
||||
ImageUrlProcess: conf.ImageUrlProcess,
|
||||
Limit: limit,
|
||||
Marker: marker,
|
||||
OrderBy: conf.OrderSearch,
|
||||
Query: fmt.Sprintf("name match '%s'",key),
|
||||
VideoThumbnailProcess: conf.VideoThumbnailProcess,
|
||||
}
|
||||
var files Files
|
||||
if body, err := DoPost(url, req,true); err != nil {
|
||||
log.Errorf("doPost出错:%s",err.Error())
|
||||
return nil,err
|
||||
}else {
|
||||
if err = json.Unmarshal(body,&files);err !=nil {
|
||||
log.Errorf("解析json[%s]出错:%s",string(body),err.Error())
|
||||
return nil,err
|
||||
}
|
||||
}
|
||||
if files.IsAvailable() {
|
||||
return &files,nil
|
||||
}
|
||||
if files.Code==conf.AccessTokenInvalid {
|
||||
if RefreshToken() {
|
||||
return Search(key,limit,marker)
|
||||
}
|
||||
}
|
||||
return nil,fmt.Errorf(files.Message)
|
||||
}
|
||||
|
||||
func GetRoot(limit int,marker string,orderBy string,orderDirection string) (*Files,error) {
|
||||
return GetList(conf.Conf.AliDrive.RootFolder,limit,marker,orderBy,orderDirection)
|
||||
}
|
||||
|
||||
func GetList(parent string,limit int,marker string,orderBy string,orderDirection string) (*Files,error) {
|
||||
url:=conf.Conf.AliDrive.ApiUrl+"/file/list"
|
||||
req:=ListReq{
|
||||
DriveId: User.DefaultDriveId,
|
||||
Fields: "*",
|
||||
ImageThumbnailProcess: conf.ImageThumbnailProcess,
|
||||
ImageUrlProcess: conf.ImageUrlProcess,
|
||||
Limit: limit,
|
||||
Marker: marker,
|
||||
OrderBy: orderBy,
|
||||
OrderDirection: orderDirection,
|
||||
ParentFileId: parent,
|
||||
VideoThumbnailProcess: conf.VideoThumbnailProcess,
|
||||
}
|
||||
var files Files
|
||||
if body, err := DoPost(url, req,true); err != nil {
|
||||
log.Errorf("doPost出错:%s",err.Error())
|
||||
return nil,err
|
||||
}else {
|
||||
if err = json.Unmarshal(body,&files);err !=nil {
|
||||
log.Errorf("解析json[%s]出错:%s",string(body),err.Error())
|
||||
return nil,err
|
||||
}
|
||||
}
|
||||
if files.IsAvailable() {
|
||||
return &files,nil
|
||||
}
|
||||
if files.Code==conf.AccessTokenInvalid {
|
||||
if RefreshToken() {
|
||||
return GetRoot(limit,marker,orderBy,orderDirection)
|
||||
}
|
||||
}
|
||||
return nil,fmt.Errorf(files.Message)
|
||||
}
|
||||
|
||||
func GetUserInfo() (*UserInfo,error) {
|
||||
url:=conf.Conf.AliDrive.ApiUrl+"/user/get"
|
||||
var user UserInfo
|
||||
if body, err := DoPost(url, map[string]interface{}{},true); err != nil {
|
||||
log.Errorf("doPost出错:%s",err.Error())
|
||||
return nil,err
|
||||
}else {
|
||||
if err = json.Unmarshal(body,&user);err !=nil {
|
||||
log.Errorf("解析json[%s]出错:%s",string(body),err.Error())
|
||||
return nil,err
|
||||
}
|
||||
}
|
||||
if user.IsAvailable() {
|
||||
return &user,nil
|
||||
}
|
||||
if user.Code==conf.AccessTokenInvalid {
|
||||
if RefreshToken() {
|
||||
return GetUserInfo()
|
||||
}
|
||||
}
|
||||
return nil,fmt.Errorf(user.Message)
|
||||
}
|
||||
|
||||
func DoPost(url string,request interface{},auth bool) (body []byte, err error) {
|
||||
var(
|
||||
resp *http.Response
|
||||
)
|
||||
requestBody := new(bytes.Buffer)
|
||||
err = json.NewEncoder(requestBody).Encode(request)
|
||||
if err !=nil {
|
||||
log.Errorf("创建requestBody出错:%s",err.Error())
|
||||
}
|
||||
req,err:=http.NewRequest("POST",url,requestBody)
|
||||
log.Debugf("do_post_req:%v",req)
|
||||
if err != nil {
|
||||
log.Errorf("创建request出错:%s",err.Error())
|
||||
return
|
||||
}
|
||||
if auth {
|
||||
req.Header.Set("authorization",conf.Authorization)
|
||||
}
|
||||
req.Header.Add("content-type","application/json")
|
||||
req.Header.Add("user-agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36")
|
||||
req.Header.Add("origin","https://aliyundrive.com")
|
||||
req.Header.Add("accept","*/*")
|
||||
req.Header.Add("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")
|
||||
req.Header.Add("Connection", "keep-alive")
|
||||
|
||||
for retryCount := 3; retryCount >= 0; retryCount-- {
|
||||
if resp,err=conf.Client.Do(req);err!=nil&&strings.Contains(err.Error(),"timeout") {
|
||||
<- time.After(time.Second)
|
||||
}else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err!=nil {
|
||||
log.Errorf("请求阿里云盘api时出错:%s",err.Error())
|
||||
return
|
||||
}
|
||||
if body, err = ioutil.ReadAll(resp.Body); err != nil {
|
||||
log.Errorf("读取api返回内容失败")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetPaths(fileId string) (*[]Path,error) {
|
||||
paths:=make([]Path,0)
|
||||
for fileId != conf.Conf.AliDrive.RootFolder && fileId != "root" {
|
||||
file,err:=GetFile(fileId)
|
||||
if err !=nil {
|
||||
log.Errorf("获取path出错:%s",err.Error())
|
||||
return nil,err
|
||||
}
|
||||
paths=append(paths,Path{
|
||||
Name: file.Name,
|
||||
FileId: file.FileId,
|
||||
})
|
||||
fileId=file.ParentFileId
|
||||
}
|
||||
paths=append(paths, Path{
|
||||
Name: "Root",
|
||||
FileId: "root",
|
||||
})
|
||||
return &paths,nil
|
||||
}
|
135
alidrive/resp_bean.go
Normal file
135
alidrive/resp_bean.go
Normal file
@ -0,0 +1,135 @@
|
||||
package alidrive
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RespError struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type UserInfo struct {
|
||||
RespError
|
||||
DomainId string `json:"domain_id"`
|
||||
UserId string `json:"user_id"`
|
||||
Avatar string `json:"avatar"`
|
||||
CreatedAt int `json:"created_at"`
|
||||
UpdatedAt int `json:"updated_at"`
|
||||
Email string `json:"email"`
|
||||
NickName string `json:"nick_name"`
|
||||
Phone string `json:"phone"`
|
||||
Role string `json:"role"`
|
||||
Status string `json:"status"`
|
||||
UserName string `json:"user_name"`
|
||||
Description string `json:"description"`
|
||||
DefaultDriveId string `json:"default_drive_id"`
|
||||
UserData map[string]interface{} `json:"user_data"`
|
||||
}
|
||||
|
||||
type Files struct {
|
||||
RespError
|
||||
Items []File `json:"items"`
|
||||
NextMarker string `json:"next_marker"`
|
||||
Readme string `json:"readme"`
|
||||
Paths []Path `json:"paths"`
|
||||
}
|
||||
|
||||
type Path struct {
|
||||
Name string `json:"name"`
|
||||
FileId string `json:"file_id"`
|
||||
}
|
||||
|
||||
type File struct {
|
||||
RespError
|
||||
DriveId string `json:"drive_id"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
DomainId string `json:"domain_id"`
|
||||
EncryptMode string `json:"encrypt_mode"`
|
||||
FileExtension string `json:"file_extension"`
|
||||
FileId string `json:"file_id"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Name string `json:"name"`
|
||||
ParentFileId string `json:"parent_file_id"`
|
||||
Starred bool `json:"starred"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
// 文件多出部分
|
||||
Category string `json:"category"`
|
||||
ContentHash string `json:"content_hash"`
|
||||
ContentHashName string `json:"content_hash_name"`
|
||||
ContentType string `json:"content_type"`
|
||||
Crc64Hash string `json:"crc_64_hash"`
|
||||
DownloadUrl string `json:"download_url"`
|
||||
PunishFlag int `json:"punish_flag"`
|
||||
Size int `json:"size"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
Url string `json:"url"`
|
||||
ImageMediaMetadata map[string]interface{} `json:"image_media_metadata"`
|
||||
|
||||
Paths []Path `json:"paths"`
|
||||
}
|
||||
|
||||
func (resp *RespError) IsAvailable() bool {
|
||||
return resp.Code == ""
|
||||
}
|
||||
|
||||
type TokenLoginResp struct {
|
||||
RespError
|
||||
Goto string `json:"goto"`
|
||||
}
|
||||
|
||||
type TokenResp struct {
|
||||
RespError
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
TokenType string `json:"token_type"`
|
||||
|
||||
UserInfo
|
||||
|
||||
DefaultSboxDriveId string `json:"default_sbox_drive_id"`
|
||||
ExpireTime *time.Time `json:"expire_time"`
|
||||
State string `json:"state"`
|
||||
ExistLink []interface{} `json:"exist_link"`
|
||||
NeedLink bool `json:"need_link"`
|
||||
PinSetup bool `json:"pin_setup"`
|
||||
IsFirstLogin bool `json:"is_first_login"`
|
||||
NeedRpVerify bool `json:"need_rp_verify"`
|
||||
DeviceId string `json:"device_id"`
|
||||
}
|
||||
|
||||
func HasPassword(files *Files) string {
|
||||
fileList := files.Items
|
||||
for _, file := range fileList {
|
||||
if strings.HasPrefix(file.Name, ".password-") {
|
||||
return file.Name[10:]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func HasReadme(files *Files) string {
|
||||
fileList := files.Items
|
||||
for _, file := range fileList {
|
||||
if file.Name == "Readme.md" {
|
||||
resp, err := http.Get(file.Url)
|
||||
if err != nil {
|
||||
log.Errorf("Get Readme出错:%s", err.Error())
|
||||
return ""
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Errorf("读取 Readme出错:%s", err.Error())
|
||||
return ""
|
||||
}
|
||||
return string(data)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
Reference in New Issue
Block a user