docxTemplater/gdisk/api.go
2022-12-31 14:46:28 +00:00

390 lines
8.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}