87 lines
3.1 KiB
C#
87 lines
3.1 KiB
C#
using Azure.Identity;
|
|
using Microsoft.Graph;
|
|
using Microsoft.Graph.Drives.Item.Items.Item.CreateUploadSession;
|
|
using Microsoft.Graph.Models;
|
|
|
|
namespace OneDriveBackupService;
|
|
|
|
public class OneDriveClient {
|
|
|
|
private readonly ConfigData _config;
|
|
private readonly GraphServiceClient _client;
|
|
|
|
public OneDriveClient(ConfigData config) {
|
|
_config = config;
|
|
|
|
var options = new DeviceCodeCredentialOptions {
|
|
TenantId = "consumers",
|
|
DeviceCodeCallback = (code, _) => {
|
|
Console.WriteLine(code.Message);
|
|
return Task.CompletedTask;
|
|
}
|
|
};
|
|
|
|
_client = new GraphServiceClient(new DeviceCodeCredential(options), ["Files.ReadWrite.All"]);
|
|
}
|
|
|
|
public async Task EnsureAuthenticated(CancellationToken token) {
|
|
await _client.Me.Drive.GetAsync(cancellationToken: token);
|
|
}
|
|
|
|
public async Task<UploadResult<DriveItem>> UploadFile(string filePath, CancellationToken token) {
|
|
var fileName = Path.GetFileName(filePath);
|
|
var remoteFilePath = _config.BackupUploadRoot.Trim('/') + '/' + fileName;
|
|
|
|
var defaultDrive = await _client.Me.Drive.GetAsync(cancellationToken: token);
|
|
|
|
var driveFile = _client.Drives[defaultDrive!.Id].Items[$"root:/{remoteFilePath}:"]!;
|
|
var uploadSession = await driveFile.CreateUploadSession.PostAsync(new CreateUploadSessionPostRequestBody {
|
|
Item = new DriveItemUploadableProperties {
|
|
AdditionalData = new Dictionary<string, object> {
|
|
{ "@microsoft.graph.conflictBehavior", "replace" }
|
|
}
|
|
}
|
|
}, cancellationToken: token);
|
|
|
|
await using var stream = File.OpenRead(filePath);
|
|
var uploader = new LargeFileUploadTask<DriveItem>(uploadSession, stream);
|
|
var result = await uploader.UploadAsync(cancellationToken: token);
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<int> DeleteOldFiles(CancellationToken token) {
|
|
var defaultDrive = await _client.Me.Drive.GetAsync(cancellationToken: token);
|
|
|
|
var remoteFolder = _config.BackupUploadRoot.Trim('/');
|
|
var backupFiles = await _client.Drives[defaultDrive!.Id]
|
|
.Items[$"root:/{remoteFolder}:"]
|
|
.Children.GetAsync(cancellationToken: token);
|
|
|
|
if (backupFiles == null || backupFiles.Value == null || backupFiles.Value.Count == 0)
|
|
return 0;
|
|
|
|
var sortedFiles = backupFiles.Value
|
|
.Where(i =>
|
|
i.File != null &&
|
|
i.Name != null &&
|
|
i.Name.StartsWith("backup_") &&
|
|
i.Name.EndsWith(".tar.gz"))
|
|
.OrderByDescending(i => i.CreatedDateTime)
|
|
.ToList();
|
|
|
|
if (sortedFiles.Count < _config.KeepLast)
|
|
return 0;
|
|
|
|
int deletedCount = 0;
|
|
foreach (var backupFile in sortedFiles.Skip(_config.KeepLast)) {
|
|
if (backupFile.Id == null) continue;
|
|
|
|
await _client.Drives[defaultDrive.Id].Items[backupFile.Id].DeleteAsync(cancellationToken: token);
|
|
deletedCount++;
|
|
}
|
|
|
|
return deletedCount;
|
|
}
|
|
|
|
} |