forked from ddrilling/AsbCloudServer
176 lines
7.1 KiB
C#
176 lines
7.1 KiB
C#
using System;
|
|
using Google.Apis.Auth.OAuth2;
|
|
using Google.Apis.Auth.OAuth2.Flows;
|
|
using Google.Apis.Services;
|
|
using Google.Apis.Drive.v3;
|
|
using Google.Apis.Util.Store;
|
|
using Google.Apis.Drive.v3.Data;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using AsbCloudApp.Services;
|
|
using Google.Apis.Auth.OAuth2.Responses;
|
|
|
|
namespace AsbCloudInfrastructure.Services
|
|
{
|
|
public class GoogleDriveService : IFileShareService, IDisposable
|
|
{
|
|
private readonly DriveService service;
|
|
|
|
const string applicationName = "FileSharing";
|
|
const string username = "asbautodrilling@gmail.com";
|
|
const string redirectUri = "http://autodrilling.naftagaz.com/AuthCallback/IndexAsync";
|
|
const string clientId = "1020584579240-f7amqg35qg7j94ta1ntgitajq27cgh49.apps.googleusercontent.com";
|
|
const string clientSecret = "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";
|
|
const string authorizationCode = "4/0AX4XfWgwsZ5QIGwAbuyOyA9oGfcHVIhduERn3wUBVL04TPF1unHf5zWr58nWdLlDDlYBIA";
|
|
const string refreshToken = "1//04n0Xn0AxQbN6CgYIARAAGAQSNwF-L9Ir-Lo-3BAskEKuy-SmllhhjYrmAzmZ2h9GaUNqEQjTIpb9wOanarU2JPI3zOj_cyYVRm4";
|
|
|
|
static readonly IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
|
|
{
|
|
ClientSecrets = new ClientSecrets
|
|
{
|
|
ClientId = clientId,
|
|
ClientSecret = clientSecret
|
|
},
|
|
|
|
Scopes = new[] { DriveService.Scope.Drive },
|
|
DataStore = new FileDataStore(applicationName),//TODO: replace FileDataStore by thread safe static datastore service
|
|
});
|
|
|
|
public GoogleDriveService()
|
|
{
|
|
service = MakeDriveServiceAsync(CancellationToken.None).Result;
|
|
}
|
|
|
|
~GoogleDriveService()
|
|
{
|
|
Dispose();
|
|
}
|
|
|
|
private async Task<DriveService> MakeDriveServiceAsync(CancellationToken cancellationToken)
|
|
{
|
|
var token = await flow.LoadTokenAsync(username, cancellationToken).ConfigureAwait(false);
|
|
|
|
if (flow.ShouldForceTokenRetrieval() || token is null || token.IsExpired(flow.Clock))
|
|
{
|
|
token = await flow.RefreshTokenAsync(clientId, refreshToken, cancellationToken).ConfigureAwait(false);
|
|
//token = await flow.ExchangeCodeForTokenAsync(clientId, authorizationCode, redirectUri, cancellationToken).ConfigureAwait(false);
|
|
await flow.DataStore.StoreAsync(username, token).ConfigureAwait(false);
|
|
}
|
|
|
|
var credential = new UserCredential(flow, username, token);
|
|
|
|
var newService = new DriveService(new BaseClientService.Initializer
|
|
{
|
|
HttpClientInitializer = credential,
|
|
ApplicationName = applicationName
|
|
});
|
|
return newService;
|
|
}
|
|
|
|
public async Task<IEnumerable<string>> GetAllFileNames()
|
|
{
|
|
var fileList = service.Files.List();
|
|
fileList.Fields = "files(id, webViewLink, size)";
|
|
|
|
var result = new List<Google.Apis.Drive.v3.Data.File>();
|
|
string pageToken = null;
|
|
do
|
|
{
|
|
fileList.PageToken = pageToken;
|
|
var filesResult = await fileList.ExecuteAsync();
|
|
var files = filesResult.Files;
|
|
pageToken = filesResult.NextPageToken;
|
|
result.AddRange(files);
|
|
} while (pageToken != null);
|
|
|
|
return result.Select(r => r.Name);
|
|
}
|
|
|
|
public async Task<string> GetFileWebLinkAsync(string idFile,
|
|
CancellationToken token = default)
|
|
{
|
|
var fileList = service.Files.List();
|
|
fileList.Fields = "files(id, webViewLink, size)";
|
|
var filesResult = await fileList.ExecuteAsync(token)
|
|
.ConfigureAwait(false);
|
|
var file = filesResult.Files.FirstOrDefault(f => f.Id == idFile);
|
|
return file?.WebViewLink ?? string.Empty;
|
|
}
|
|
|
|
public async Task<string> CreateFolderAsync(string folderName,
|
|
CancellationToken token = default)
|
|
{
|
|
var driveFolder = new Google.Apis.Drive.v3.Data.File();
|
|
driveFolder.Name = folderName;
|
|
driveFolder.MimeType = "application/vnd.google-apps.folder";
|
|
//driveFolder.Parents = new string[] { parent };
|
|
var command = service.Files.Create(driveFolder);
|
|
var file = await command.ExecuteAsync(token)
|
|
.ConfigureAwait(false);
|
|
return file.Id;
|
|
}
|
|
|
|
public async Task CreatePublicPermissionForFileAsync(string idFile,
|
|
CancellationToken token = default)
|
|
{
|
|
var permission = new Permission() { Type = "anyone", Role = "reader"};
|
|
var addPermissionRequest = service.Permissions.Create(permission, idFile);
|
|
await addPermissionRequest.ExecuteAsync(token)
|
|
.ConfigureAwait(false);
|
|
}
|
|
|
|
public async Task<string> UploadFileAsync(Stream file, string fileName, string fileMime,
|
|
string fileDescription, CancellationToken token = default)
|
|
{
|
|
var driveFile = new Google.Apis.Drive.v3.Data.File();
|
|
driveFile.Name = fileName;
|
|
driveFile.Description = fileDescription;
|
|
driveFile.MimeType = fileMime;
|
|
//driveFile.Parents = new [] {folder};
|
|
|
|
var request = service.Files.Create(driveFile, file, fileMime);
|
|
request.Fields = "id";
|
|
|
|
var response = await request.UploadAsync(token)
|
|
.ConfigureAwait(false);
|
|
if (response.Status != Google.Apis.Upload.UploadStatus.Completed)
|
|
throw response.Exception;
|
|
|
|
return request.ResponseBody.Id;
|
|
}
|
|
|
|
public async Task DeleteFileAsync(string fileId,
|
|
CancellationToken token = default)
|
|
{
|
|
var command = service.Files.Delete(fileId);
|
|
await command.ExecuteAsync(token)
|
|
.ConfigureAwait(false);
|
|
}
|
|
|
|
#pragma warning disable CA1816 // Методы Dispose должны вызывать SuppressFinalize
|
|
public void Dispose()
|
|
{
|
|
service?.Dispose();
|
|
}
|
|
#pragma warning restore CA1816 // Методы Dispose должны вызывать SuppressFinalize
|
|
|
|
public async Task<string> PublishFileToCloudAsync(string filePath, string originalName, CancellationToken token)
|
|
{
|
|
await using var fileStream = System.IO.File.Open(filePath, FileMode.Open);
|
|
var uploadedFileId = await UploadFileAsync(fileStream, originalName,
|
|
"", "uploaded", token)
|
|
.ConfigureAwait(false);
|
|
|
|
await CreatePublicPermissionForFileAsync(uploadedFileId, token)
|
|
.ConfigureAwait(false);
|
|
|
|
var webLink = await GetFileWebLinkAsync(uploadedFileId, token)
|
|
.ConfigureAwait(false);
|
|
|
|
return webLink;
|
|
}
|
|
}
|
|
} |