Files
OneDriveBackupService/OneDriveClient.cs

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;
}
}