Skip to content

Commit 0a8bd96

Browse files
committed
feat: support baidu.photo
1 parent 68f37fc commit 0a8bd96

5 files changed

Lines changed: 920 additions & 0 deletions

File tree

drivers/all.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
_ "github.com/Xhofe/alist/drivers/webdav"
2626
_ "github.com/Xhofe/alist/drivers/xunlei"
2727
_ "github.com/Xhofe/alist/drivers/yandex"
28+
_ "github.com/Xhofe/alist/drivers/baiduphoto"
2829
log "github.com/sirupsen/logrus"
2930
"strings"
3031
)

drivers/baiduphoto/baidu.go

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
package baiduphoto
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
7+
"github.com/Xhofe/alist/drivers/base"
8+
"github.com/Xhofe/alist/model"
9+
"github.com/Xhofe/alist/utils"
10+
"github.com/go-resty/resty/v2"
11+
log "github.com/sirupsen/logrus"
12+
)
13+
14+
func (driver Baidu) RefreshToken(account *model.Account) error {
15+
err := driver.refreshToken(account)
16+
if err != nil && err == base.ErrEmptyToken {
17+
err = driver.refreshToken(account)
18+
}
19+
if err != nil {
20+
account.Status = err.Error()
21+
}
22+
_ = model.SaveAccount(account)
23+
return err
24+
}
25+
26+
func (driver Baidu) refreshToken(account *model.Account) error {
27+
u := "https://openapi.baidu.com/oauth/2.0/token"
28+
var resp base.TokenResp
29+
var e TokenErrResp
30+
_, err := base.RestyClient.R().
31+
SetResult(&resp).
32+
SetError(&e).
33+
SetQueryParams(map[string]string{
34+
"grant_type": "refresh_token",
35+
"refresh_token": account.RefreshToken,
36+
"client_id": account.ClientId,
37+
"client_secret": account.ClientSecret,
38+
}).Get(u)
39+
if err != nil {
40+
return err
41+
}
42+
if e.ErrorMsg != "" {
43+
return &e
44+
}
45+
if resp.RefreshToken == "" {
46+
return base.ErrEmptyToken
47+
}
48+
account.Status = "work"
49+
account.AccessToken, account.RefreshToken = resp.AccessToken, resp.RefreshToken
50+
return nil
51+
}
52+
53+
func (driver Baidu) Request(method string, url string, callback func(*resty.Request), account *model.Account) (*resty.Response, error) {
54+
req := base.RestyClient.R()
55+
req.SetQueryParam("access_token", account.AccessToken)
56+
if callback != nil {
57+
callback(req)
58+
}
59+
60+
res, err := req.Execute(method, url)
61+
if err != nil {
62+
return nil, err
63+
}
64+
log.Debug(res.String())
65+
66+
var erron Erron
67+
if err = utils.Json.Unmarshal(res.Body(), &erron); err != nil {
68+
return nil, err
69+
}
70+
71+
switch erron.Errno {
72+
case 0:
73+
return res, nil
74+
case -6:
75+
if err = driver.RefreshToken(account); err != nil {
76+
return nil, err
77+
}
78+
default:
79+
return nil, fmt.Errorf("errno: %d, refer to https://photo.baidu.com/union/doc", erron.Errno)
80+
}
81+
return driver.Request(method, url, callback, account)
82+
}
83+
84+
// 获取所有根文件
85+
func (driver Baidu) GetAllFile(account *model.Account) (files []File, err error) {
86+
var cursor string
87+
88+
for {
89+
var resp FileListResp
90+
_, err = driver.Request(http.MethodGet, FILE_API_URL+"/list", func(r *resty.Request) {
91+
r.SetQueryParams(map[string]string{
92+
"need_thumbnail": "1",
93+
"need_filter_hidden": "0",
94+
"cursor": cursor,
95+
})
96+
r.SetResult(&resp)
97+
}, account)
98+
if err != nil {
99+
return
100+
}
101+
102+
cursor = resp.Cursor
103+
files = append(files, resp.List...)
104+
105+
if !resp.HasNextPage() {
106+
return
107+
}
108+
}
109+
}
110+
111+
// 获取所有相册
112+
func (driver Baidu) GetAllAlbum(account *model.Account) (albums []Album, err error) {
113+
var cursor string
114+
for {
115+
var resp AlbumListResp
116+
_, err = driver.Request(http.MethodGet, ALBUM_API_URL+"/list", func(r *resty.Request) {
117+
r.SetQueryParams(map[string]string{
118+
"need_amount": "1",
119+
"limit": "100",
120+
"cursor": cursor,
121+
})
122+
r.SetResult(&resp)
123+
}, account)
124+
if err != nil {
125+
return
126+
}
127+
if albums == nil {
128+
albums = make([]Album, 0, resp.TotalCount)
129+
}
130+
131+
cursor = resp.Cursor
132+
albums = append(albums, resp.List...)
133+
134+
if !resp.HasNextPage() {
135+
return
136+
}
137+
}
138+
}
139+
140+
// 获取相册中所有文件
141+
func (driver Baidu) GetAllAlbumFile(albumID string, account *model.Account) (files []AlbumFile, err error) {
142+
var cursor string
143+
for {
144+
var resp AlbumFileListResp
145+
_, err = driver.Request(http.MethodGet, ALBUM_API_URL+"/listfile", func(r *resty.Request) {
146+
r.SetQueryParams(map[string]string{
147+
"album_id": splitID(albumID)[0],
148+
"need_amount": "1",
149+
"limit": "1000",
150+
"cursor": cursor,
151+
})
152+
r.SetResult(&resp)
153+
}, account)
154+
if err != nil {
155+
return
156+
}
157+
if files == nil {
158+
files = make([]AlbumFile, 0, resp.TotalCount)
159+
}
160+
161+
cursor = resp.Cursor
162+
files = append(files, resp.List...)
163+
164+
if !resp.HasNextPage() {
165+
return
166+
}
167+
}
168+
}
169+
170+
// 创建相册
171+
func (driver Baidu) CreateAlbum(name string, account *model.Account) error {
172+
if !checkName(name) {
173+
return ErrNotSupportName
174+
}
175+
_, err := driver.Request(http.MethodPost, ALBUM_API_URL+"/create", func(r *resty.Request) {
176+
r.SetQueryParams(map[string]string{
177+
"title": name,
178+
"tid": getTid(),
179+
"source": "0",
180+
})
181+
}, account)
182+
return err
183+
}
184+
185+
// 相册改名
186+
func (driver Baidu) SetAlbumName(albumID string, name string, account *model.Account) error {
187+
if !checkName(name) {
188+
return ErrNotSupportName
189+
}
190+
191+
e := splitID(albumID)
192+
_, err := driver.Request(http.MethodPost, ALBUM_API_URL+"/settitle", func(r *resty.Request) {
193+
r.SetFormData(map[string]string{
194+
"title": name,
195+
"album_id": e[0],
196+
"tid": e[1],
197+
})
198+
}, account)
199+
return err
200+
}
201+
202+
// 删除相册
203+
func (driver Baidu) DeleteAlbum(albumID string, account *model.Account) error {
204+
e := splitID(albumID)
205+
_, err := driver.Request(http.MethodPost, ALBUM_API_URL+"/delete", func(r *resty.Request) {
206+
r.SetFormData(map[string]string{
207+
"album_id": e[0],
208+
"tid": e[1],
209+
"delete_origin_image": "0", // 是否删除原图 0 不删除
210+
})
211+
}, account)
212+
return err
213+
}
214+
215+
// 删除相册文件
216+
func (driver Baidu) DeleteAlbumFile(albumID string, account *model.Account, fileIDs ...string) error {
217+
e := splitID(albumID)
218+
_, err := driver.Request(http.MethodPost, ALBUM_API_URL+"/delfile", func(r *resty.Request) {
219+
r.SetFormData(map[string]string{
220+
"album_id": e[0],
221+
"tid": e[1],
222+
"list": fsidsFormat(fileIDs...),
223+
"del_origin": "0", // 是否删除原图 0 不删除 1 删除
224+
})
225+
}, account)
226+
return err
227+
}
228+
229+
// 增加相册文件
230+
func (driver Baidu) AddAlbumFile(albumID string, account *model.Account, fileIDs ...string) error {
231+
e := splitID(albumID)
232+
_, err := driver.Request(http.MethodGet, ALBUM_API_URL+"/addfile", func(r *resty.Request) {
233+
r.SetQueryParams(map[string]string{
234+
"album_id": e[0],
235+
"tid": e[1],
236+
"list": fsidsFormatNotUk(fileIDs...),
237+
})
238+
}, account)
239+
return err
240+
}
241+
242+
// 保存相册文件为根文件
243+
func (driver Baidu) CopyAlbumFile(albumID string, account *model.Account, fileID string) (*CopyFile, error) {
244+
var resp CopyFileResp
245+
e := splitID(fileID)
246+
_, err := driver.Request(http.MethodPost, ALBUM_API_URL+"/copyfile", func(r *resty.Request) {
247+
r.SetFormData(map[string]string{
248+
"album_id": splitID(albumID)[0],
249+
"tid": e[2],
250+
"uk": e[1],
251+
"list": fsidsFormatNotUk(fileID),
252+
})
253+
r.SetResult(&resp)
254+
}, account)
255+
if err != nil {
256+
return nil, err
257+
}
258+
return &resp.List[0], err
259+
}

0 commit comments

Comments
 (0)