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 credential = new ClientSecretCredential(_config.TenantId, _config.ClientId, _config.ClientSecret); _client = new GraphServiceClient(credential); } public async Task> UploadFile(string filePath, CancellationToken token) { var fileName = Path.GetFileName(filePath); var remoteFilePath = _config.BackupUploadRoot.Trim('/') + '/' + fileName; var defaultDrive = await _client.Users[_config.UserId].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 { { "@microsoft.graph.conflictBehavior", "replace" } } } }, cancellationToken: token); await using var stream = File.OpenRead(filePath); var uploader = new LargeFileUploadTask(uploadSession, stream); var result = await uploader.UploadAsync(cancellationToken: token); return result; } public async Task DeleteOldFiles(CancellationToken token) { var defaultDrive = await _client.Users[_config.UserId].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; } }