Spaces:
Runtime error
Runtime error
package google_photo | |
import ( | |
"fmt" | |
"net/http" | |
"github.com/alist-org/alist/v3/drivers/base" | |
"github.com/go-resty/resty/v2" | |
) | |
// do others that not defined in Driver interface | |
const ( | |
FETCH_ALL = "all" | |
FETCH_ALBUMS = "albums" | |
FETCH_ROOT = "root" | |
FETCH_SHARE_ALBUMS = "share_albums" | |
) | |
func (d *GooglePhoto) refreshToken() error { | |
url := "https://www.googleapis.com/oauth2/v4/token" | |
var resp base.TokenResp | |
var e TokenError | |
_, err := base.RestyClient.R().SetResult(&resp).SetError(&e). | |
SetFormData(map[string]string{ | |
"client_id": d.ClientID, | |
"client_secret": d.ClientSecret, | |
"refresh_token": d.RefreshToken, | |
"grant_type": "refresh_token", | |
}).Post(url) | |
if err != nil { | |
return err | |
} | |
if e.Error != "" { | |
return fmt.Errorf(e.Error) | |
} | |
d.AccessToken = resp.AccessToken | |
return nil | |
} | |
func (d *GooglePhoto) request(url string, method string, callback base.ReqCallback, resp interface{}, headers map[string]string) ([]byte, error) { | |
req := base.RestyClient.R() | |
req.SetHeader("Authorization", "Bearer "+d.AccessToken) | |
req.SetHeader("Accept-Encoding", "gzip") | |
if headers != nil { | |
req.SetHeaders(headers) | |
} | |
if callback != nil { | |
callback(req) | |
} | |
if resp != nil { | |
req.SetResult(resp) | |
} | |
var e Error | |
req.SetError(&e) | |
res, err := req.Execute(method, url) | |
if err != nil { | |
return nil, err | |
} | |
if e.Error.Code != 0 { | |
if e.Error.Code == 401 { | |
err = d.refreshToken() | |
if err != nil { | |
return nil, err | |
} | |
return d.request(url, method, callback, resp, headers) | |
} | |
return nil, fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors) | |
} | |
return res.Body(), nil | |
} | |
func (d *GooglePhoto) getFiles(id string) ([]MediaItem, error) { | |
switch id { | |
case FETCH_ALL: | |
return d.getAllMedias() | |
case FETCH_ALBUMS: | |
return d.getAlbums() | |
case FETCH_SHARE_ALBUMS: | |
return d.getShareAlbums() | |
case FETCH_ROOT: | |
return d.getFakeRoot() | |
default: | |
return d.getMedias(id) | |
} | |
} | |
func (d *GooglePhoto) getFakeRoot() ([]MediaItem, error) { | |
return []MediaItem{ | |
{ | |
Id: FETCH_ALL, | |
Title: "全部媒体", | |
}, | |
{ | |
Id: FETCH_ALBUMS, | |
Title: "全部影集", | |
}, | |
{ | |
Id: FETCH_SHARE_ALBUMS, | |
Title: "共享影集", | |
}, | |
}, nil | |
} | |
func (d *GooglePhoto) getAlbums() ([]MediaItem, error) { | |
return d.fetchItems( | |
"https://photoslibrary.googleapis.com/v1/albums", | |
map[string]string{ | |
"fields": "albums(id,title,coverPhotoBaseUrl),nextPageToken", | |
"pageSize": "50", | |
"pageToken": "first", | |
}, | |
http.MethodGet) | |
} | |
func (d *GooglePhoto) getShareAlbums() ([]MediaItem, error) { | |
return d.fetchItems( | |
"https://photoslibrary.googleapis.com/v1/sharedAlbums", | |
map[string]string{ | |
"fields": "sharedAlbums(id,title,coverPhotoBaseUrl),nextPageToken", | |
"pageSize": "50", | |
"pageToken": "first", | |
}, | |
http.MethodGet) | |
} | |
func (d *GooglePhoto) getMedias(albumId string) ([]MediaItem, error) { | |
return d.fetchItems( | |
"https://photoslibrary.googleapis.com/v1/mediaItems:search", | |
map[string]string{ | |
"fields": "mediaItems(id,baseUrl,mimeType,mediaMetadata,filename),nextPageToken", | |
"pageSize": "100", | |
"albumId": albumId, | |
"pageToken": "first", | |
}, http.MethodPost) | |
} | |
func (d *GooglePhoto) getAllMedias() ([]MediaItem, error) { | |
return d.fetchItems( | |
"https://photoslibrary.googleapis.com/v1/mediaItems", | |
map[string]string{ | |
"fields": "mediaItems(id,baseUrl,mimeType,mediaMetadata,filename),nextPageToken", | |
"pageSize": "100", | |
"pageToken": "first", | |
}, | |
http.MethodGet) | |
} | |
func (d *GooglePhoto) getMedia(id string) (MediaItem, error) { | |
var resp MediaItem | |
query := map[string]string{ | |
"fields": "mediaMetadata,baseUrl,mimeType", | |
} | |
_, err := d.request(fmt.Sprintf("https://photoslibrary.googleapis.com/v1/mediaItems/%s", id), http.MethodGet, func(req *resty.Request) { | |
req.SetQueryParams(query) | |
}, &resp, nil) | |
if err != nil { | |
return resp, err | |
} | |
return resp, nil | |
} | |
func (d *GooglePhoto) fetchItems(url string, query map[string]string, method string) ([]MediaItem, error){ | |
res := make([]MediaItem, 0) | |
for query["pageToken"] != "" { | |
if query["pageToken"] == "first" { | |
query["pageToken"] = "" | |
} | |
var resp Items | |
_, err := d.request(url, method, func(req *resty.Request) { | |
req.SetQueryParams(query) | |
}, &resp, nil) | |
if err != nil { | |
return nil, err | |
} | |
query["pageToken"] = resp.NextPageToken | |
res = append(res, resp.MediaItems...) | |
res = append(res, resp.Albums...) | |
res = append(res, resp.SharedAlbums...) | |
} | |
return res, nil | |
} | |