390 lines
8.4 KiB
Go
390 lines
8.4 KiB
Go
package GDisk
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"fmt"
|
||
"golang.org/x/oauth2"
|
||
"golang.org/x/oauth2/google"
|
||
"google.golang.org/api/drive/v3"
|
||
"google.golang.org/api/option"
|
||
"io"
|
||
"net/http"
|
||
"os"
|
||
"penahub.gitlab.yandexcloud.net/backend/templategen/tools"
|
||
"strings"
|
||
)
|
||
|
||
const (
|
||
DefaultDir = "TemplateGenerator"
|
||
TemplateDir = "templates"
|
||
SaveDir = "saved"
|
||
MimeTypeDocx = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
||
)
|
||
|
||
type Client struct {
|
||
App *ClientApp
|
||
HTTPClient *http.Client
|
||
Service *drive.Service
|
||
Token *oauth2.Token
|
||
}
|
||
|
||
type ClientApp struct {
|
||
Config *oauth2.Config
|
||
}
|
||
|
||
func NewClientApp(credentials string) (*ClientApp, error) {
|
||
b, err := os.ReadFile(credentials)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
config, err := google.ConfigFromJSON(b,
|
||
drive.DriveScope,
|
||
drive.DriveMetadataScope,
|
||
)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return &ClientApp{Config: config}, nil
|
||
}
|
||
|
||
func (ca *ClientApp) GenerateOAuthUrl(userId, redirectUrl string) (string, error) {
|
||
state, err := tools.EncryptTokenRC4(tools.StateToken{
|
||
UserID: userId,
|
||
Service: "google",
|
||
RedirectUrl: redirectUrl,
|
||
})
|
||
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
return ca.Config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.ApprovalForce), nil
|
||
}
|
||
|
||
func (ca *ClientApp) RefreshToken(ctx context.Context, oldToken *oauth2.Token) (*oauth2.Token, error) {
|
||
token, err := ca.Config.TokenSource(ctx, oldToken).Token()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return token, nil
|
||
}
|
||
|
||
func (ca *ClientApp) NewClient(ctx context.Context, token *oauth2.Token) (*Client, error) {
|
||
client := ca.Config.Client(ctx, token)
|
||
srv, err := drive.NewService(ctx, option.WithHTTPClient(client))
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return &Client{
|
||
App: ca,
|
||
HTTPClient: client,
|
||
Service: srv,
|
||
Token: token,
|
||
}, nil
|
||
}
|
||
|
||
func (ca *ClientApp) GetToken(ctx context.Context, authCode string) (*oauth2.Token, error) {
|
||
return ca.Config.Exchange(ctx, authCode)
|
||
}
|
||
|
||
func (c *Client) SetToken(token oauth2.Token) {
|
||
c.Token = &token
|
||
}
|
||
|
||
func (c *Client) GetDisk() {
|
||
srv, err := drive.NewService(context.Background(), option.WithHTTPClient(c.HTTPClient))
|
||
|
||
if err != nil {
|
||
fmt.Println("err123", err)
|
||
return
|
||
}
|
||
|
||
about, err := srv.About.Get().Fields("storageQuota", "user", "exportFormats", "maxImportSizes", "maxUploadSize").Do()
|
||
if err != nil {
|
||
fmt.Println("err1234", err)
|
||
return
|
||
}
|
||
fmt.Printf("srv.About %+v \r\n", about.User)
|
||
|
||
dl, err := srv.Drives.List().Do()
|
||
if err != nil {
|
||
fmt.Println("err12345", err)
|
||
return
|
||
}
|
||
|
||
fmt.Println("DRIVES ________________________")
|
||
for _, drive := range dl.Drives {
|
||
fmt.Println(drive)
|
||
}
|
||
}
|
||
|
||
// GetUserInfo - получить информацию о пользователе Google
|
||
func (c *Client) GetUserInfo() (*drive.User, error) {
|
||
srv, err := drive.NewService(context.Background(), option.WithHTTPClient(c.HTTPClient))
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
about, err := srv.About.Get().Fields("user").Do()
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
if about == nil {
|
||
return nil, errors.New("got empty about")
|
||
}
|
||
|
||
if about.User == nil {
|
||
return nil, errors.New("got empty about.User")
|
||
}
|
||
|
||
return about.User, nil
|
||
}
|
||
|
||
// GetResourcesByName - получить информацию о ресурсе
|
||
func (c *Client) GetResourcesByName(name, parentID string) (*drive.FileList, error) {
|
||
query := "name = '" + name + "' and trashed = false"
|
||
|
||
if parentID != "" {
|
||
query += "and '" + parentID + "' in parents"
|
||
}
|
||
|
||
fl, err := c.Service.Files.List().
|
||
Q(query).
|
||
Do()
|
||
if err != nil {
|
||
if strings.Contains(err.Error(), "404") {
|
||
return nil, nil
|
||
}
|
||
return nil, err
|
||
}
|
||
|
||
return fl, nil
|
||
}
|
||
|
||
// GetResources - получить список файлов и папок ресурса по его id
|
||
// Если id не указан, то принимается значение 'root'
|
||
func (c *Client) GetResources(id string) (*drive.FileList, error) {
|
||
if id == "" {
|
||
id = "root"
|
||
}
|
||
query := fmt.Sprintf("trashed = false and '%v' in parents", id)
|
||
|
||
fl, err := c.Service.Files.List().
|
||
Q(query).
|
||
Do()
|
||
if err != nil {
|
||
if strings.Contains(err.Error(), "404") {
|
||
return nil, nil
|
||
}
|
||
return nil, err
|
||
}
|
||
|
||
return fl, nil
|
||
}
|
||
|
||
// PutResources - создание папки
|
||
func (c *Client) PutResources(name, parentID string) (*drive.File, error) {
|
||
q := &drive.File{Name: name, MimeType: "application/vnd.google-apps.folder", IsAppAuthorized: true}
|
||
if parentID != "" {
|
||
q.Parents = []string{parentID}
|
||
}
|
||
f, err := c.Service.Files.Create(q).Do()
|
||
|
||
if err != nil {
|
||
fmt.Println("3", err.Error())
|
||
fmt.Println("")
|
||
return nil, err
|
||
}
|
||
|
||
return f, nil
|
||
}
|
||
|
||
func (c *Client) DeleteResources(id string) error {
|
||
return c.Service.Files.Delete(id).Do()
|
||
}
|
||
|
||
// UploadFile - отправить файл в диск
|
||
func (c *Client) UploadFile(filepath, mimetype, parentID string) (string, string, error) {
|
||
file, err := os.Open(filepath)
|
||
defer file.Close()
|
||
|
||
if err != nil {
|
||
return "", "", err
|
||
}
|
||
|
||
filename := strings.Split(file.Name(), "/")
|
||
|
||
q := &drive.File{
|
||
Name: filename[len(filename)-1],
|
||
MimeType: mimetype,
|
||
IsAppAuthorized: true,
|
||
}
|
||
|
||
if parentID != "" {
|
||
q.Parents = []string{parentID}
|
||
}
|
||
|
||
fileData, err := c.Service.Files.Create(q).Media(file).Do()
|
||
|
||
if err != nil {
|
||
return "", "", err
|
||
}
|
||
|
||
return fileData.Id, fileData.ExportLinks[mimetype], nil
|
||
}
|
||
|
||
func (c *Client) DownloadFile(filepath, fileID string) error {
|
||
file, err := c.Service.Files.Get(fileID).Do()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
var resp *http.Response
|
||
fmt.Println("mimeType", file.MimeType)
|
||
if file.MimeType == "application/vnd.google-apps.document" {
|
||
resp, err = c.Service.Files.Export(fileID, MimeTypeDocx).
|
||
Fields("exportFormat", "docx").
|
||
Download()
|
||
} else {
|
||
resp, err = c.Service.Files.Get(fileID).Download()
|
||
}
|
||
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
defer resp.Body.Close()
|
||
|
||
out, err := os.Create(filepath)
|
||
defer out.Close()
|
||
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
_, err = io.Copy(out, resp.Body)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// MakeDefaultDirs - проверяет диск на наличие папок DefaultDir, TemplateDir и SaveDir.
|
||
// Если папки не существуют, то создает их
|
||
func (c *Client) MakeDefaultDirs(defaultId, defaultName, templateId, templateName, saveId,
|
||
saveName string) (*drive.File, *drive.File, *drive.File, error) {
|
||
var defaultDir, templateDir, saveDir *drive.File
|
||
|
||
if defaultName == "" {
|
||
defaultName = DefaultDir
|
||
}
|
||
|
||
if templateName == "" {
|
||
templateName = TemplateDir
|
||
}
|
||
|
||
if saveName == "" {
|
||
saveName = SaveDir
|
||
}
|
||
|
||
var err error
|
||
|
||
// Check Default directory
|
||
if defaultId == "" {
|
||
fl, err := c.GetResourcesByName(defaultName, "")
|
||
if err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
|
||
if len(fl.Files) == 0 {
|
||
defaultDir, err = c.PutResources(defaultName, "")
|
||
if err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
} else {
|
||
defaultDir = fl.Files[0]
|
||
}
|
||
} else {
|
||
defaultDir, err = c.Service.Files.Get(defaultId).Do()
|
||
if err != nil {
|
||
if strings.Contains(err.Error(), "404") {
|
||
defaultDir, err = c.PutResources(defaultName, "")
|
||
if err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
} else {
|
||
return nil, nil, nil, err
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check Template Directory
|
||
if templateId == "" {
|
||
fl, err := c.GetResourcesByName(templateName, defaultDir.Id)
|
||
if err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
|
||
if len(fl.Files) == 0 {
|
||
templateDir, err = c.PutResources(templateName, defaultDir.Id)
|
||
if err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
} else {
|
||
templateDir = fl.Files[0]
|
||
}
|
||
} else {
|
||
templateDir, err = c.Service.Files.Get(templateId).Do()
|
||
if err != nil {
|
||
if strings.Contains(err.Error(), "404") {
|
||
templateDir, err = c.PutResources(templateName, defaultDir.Id)
|
||
if err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
} else {
|
||
return nil, nil, nil, err
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check Save Directory
|
||
if saveId == "" {
|
||
fl, err := c.GetResourcesByName(saveName, defaultDir.Id)
|
||
if err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
|
||
if len(fl.Files) == 0 {
|
||
saveDir, err = c.PutResources(saveName, defaultDir.Id)
|
||
if err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
} else {
|
||
saveDir = fl.Files[0]
|
||
}
|
||
} else {
|
||
saveDir, err = c.Service.Files.Get(templateId).Do()
|
||
if err != nil {
|
||
if strings.Contains(err.Error(), "404") {
|
||
saveDir, err = c.PutResources(saveName, defaultDir.Id)
|
||
if err != nil {
|
||
return nil, nil, nil, err
|
||
}
|
||
} else {
|
||
return nil, nil, nil, err
|
||
}
|
||
}
|
||
}
|
||
|
||
return defaultDir, templateDir, saveDir, nil
|
||
}
|