Files
Kenneth Skovhede 243cb62975 Improve license flexibility
This changes the way license usage is calculated. Previously the licenses would prohibit enumerating more than what was licensed. This had the benefit that the backup engine was unaware that more items exists.

However, this also prevented filtering items, as the enumeration happens before the filters are applied.

With the new approach, enumeration is applied without imposing limitations, but actually reading the items are limited. This allows filtering unwanted items, and they will not count towards usage.

The downside of this approach is that the backup will contain empty "folders" that could, at a glance, appear to contain everything, but are in fact just empty folders.

To mitigate this, the warning message now explictly mentions that some folders may be empty.
2026-06-12 13:34:04 +02:00

42 lines
1.9 KiB
C#

// Copyright (c) 2026 Duplicati Inc. All rights reserved.
using Duplicati.Library.Common.IO;
using Duplicati.Library.Interface;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Drive.v3;
using System.Runtime.CompilerServices;
namespace Duplicati.Proprietary.GoogleWorkspace.SourceItems;
internal class SharedDriveSourceEntry(SourceProvider provider, string parentPath, string userId, Drive drive, DriveService driveService)
: MetaEntryBase(Util.AppendDirSeparator(SystemIO.IO_OS.PathCombine(parentPath, drive.Id)), drive.CreatedTimeDateTimeOffset.HasValue ? drive.CreatedTimeDateTimeOffset.Value.UtcDateTime : DateTime.UnixEpoch, DateTime.UnixEpoch)
{
public override async IAsyncEnumerable<ISourceProviderEntry> Enumerate([EnumeratorCancellation] CancellationToken cancellationToken)
{
if (!provider.LicenseApprovedForEntry(parentPath, GoogleRootType.SharedDrives, drive.Id, true))
yield break;
if (cancellationToken.IsCancellationRequested) yield break;
yield return new SharedDriveMetadataSourceEntry(this.Path, drive);
if (cancellationToken.IsCancellationRequested) yield break;
yield return new SharedDrivePermissionsSourceEntry(this.Path, drive, driveService);
if (cancellationToken.IsCancellationRequested) yield break;
yield return new DriveFolderSourceEntry(this.Path, userId, "Content", drive.Id, driveService);
}
public override Task<Dictionary<string, string?>> GetMinorMetadata(CancellationToken cancellationToken)
{
return Task.FromResult(new Dictionary<string, string?>
{
{ "gsuite:v", "1" },
{ "gsuite:Type", SourceItemType.SharedDrives.ToString() }, // Or specific type?
{ "gsuite:Name", drive.Name },
{ "gsuite:Id", drive.Id },
{ "gsuite:Kind", drive.Kind }
}
.Where(kv => !string.IsNullOrEmpty(kv.Value))
.ToDictionary(kv => kv.Key, kv => kv.Value));
}
}