// Copyright (c) 2026 Duplicati Inc. All rights reserved. using Duplicati.Library.Common.IO; using Duplicati.Library.Interface; using Google.Apis.Drive.v3; using System.Runtime.CompilerServices; using File = Google.Apis.Drive.v3.Data.File; namespace Duplicati.Proprietary.GoogleWorkspace.SourceItems; internal class DriveFileSourceEntry(string parentPath, File file, DriveService driveService) : MetaEntryBase(Util.AppendDirSeparator(SystemIO.IO_OS.PathCombine(parentPath, file.Id)), file.CreatedTimeDateTimeOffset.HasValue ? file.CreatedTimeDateTimeOffset.Value.UtcDateTime : DateTime.UnixEpoch, file.ModifiedTimeDateTimeOffset.HasValue ? file.ModifiedTimeDateTimeOffset.Value.UtcDateTime : DateTime.UnixEpoch) { public override async IAsyncEnumerable Enumerate([EnumeratorCancellation] CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) yield break; yield return new DriveFileMetadataSourceEntry(this.Path, file); if (cancellationToken.IsCancellationRequested) yield break; yield return new DriveFilePermissionsSourceEntry(this.Path, file, driveService); if (cancellationToken.IsCancellationRequested) yield break; yield return new DriveFileContentSourceEntry(this.Path, file, driveService); if (cancellationToken.IsCancellationRequested) yield break; yield return new DriveFileCommentsSourceEntry(this.Path, file, driveService); // Skip revisions for Google Workspace files (Docs, Sheets, Slides, Sites, Shortcuts) as they cannot be exported if (!GoogleMimeTypes.IsGoogleSite(file.MimeType) && !GoogleMimeTypes.IsShortcut(file.MimeType) && !GoogleMimeTypes.IsGoogleDoc(file.MimeType)) { if (cancellationToken.IsCancellationRequested) yield break; yield return new DriveFileRevisionsSourceEntry(this.Path, file, driveService); } } public override Task> GetMinorMetadata(CancellationToken cancellationToken) { return Task.FromResult(new Dictionary { { "gsuite:v", "1" }, { "gsuite:Type", SourceItemType.DriveFile.ToString() }, { "gsuite:Name", file.Name }, { "gsuite:Id", file.Id }, { "gsuite:MimeType", file.MimeType } } .Where(kv => !string.IsNullOrEmpty(kv.Value)) .ToDictionary(kv => kv.Key, kv => kv.Value)); } }