Files
duplicati/proprietary/GoogleWorkspace/RestoreProvider/RestoreProvider.cs
T
Kenneth Skovhede da246874ec Initial implementation of Google Workspace backup.
This is a WIP and still needs the restore part implemented.

Not all resources are fully tested but basic elements work.
2026-02-04 15:44:23 +01:00

150 lines
4.9 KiB
C#

// Copyright (c) 2026 Duplicati Inc. All rights reserved.
using Duplicati.Library.Interface;
namespace Duplicati.Proprietary.GoogleWorkspace;
public sealed class RestoreProvider : IRestoreDestinationProviderModule, IDisposable
{
private readonly APIHelper _apiHelper;
private readonly string _restorePath;
private readonly OptionsHelper.GoogleWorkspaceOptions _options;
private readonly string _tempPath;
private readonly Dictionary<string, string> _tempFiles = new();
private readonly Dictionary<string, Dictionary<string, string?>> _metadata = new();
public RestoreProvider()
{
_apiHelper = null!;
_restorePath = null!;
_options = null!;
_tempPath = null!;
}
public RestoreProvider(string url, string restorePath, Dictionary<string, string?> options)
{
_restorePath = restorePath;
_options = OptionsHelper.ParseOptions(options);
_apiHelper = new APIHelper(_options);
_tempPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "Duplicati-GoogleWorkspace-Restore-" + Guid.NewGuid().ToString());
System.IO.Directory.CreateDirectory(_tempPath);
}
public string Key => OptionsHelper.ModuleKey;
public string DisplayName => Strings.Common.DisplayName;
public string Description => Strings.Common.Description;
public IList<ICommandLineArgument> SupportedCommands => OptionsHelper.SupportedCommands;
public string TargetDestination => _restorePath;
public void Dispose()
{
if (!string.IsNullOrEmpty(_tempPath) && System.IO.Directory.Exists(_tempPath))
{
try
{
System.IO.Directory.Delete(_tempPath, true);
}
catch { }
}
}
public Task Initialize(CancellationToken cancellationToken)
{
_apiHelper.Initialize();
return Task.CompletedTask;
}
public Task Test(CancellationToken cancellationToken)
{
_apiHelper.TestConnection();
return Task.CompletedTask;
}
public Task<bool> CreateFolderIfNotExists(string path, CancellationToken cancellationToken)
{
return Task.FromResult(true);
}
public Task<bool> FileExists(string path, CancellationToken cancellationToken)
{
return Task.FromResult(_tempFiles.ContainsKey(path));
}
public Task<Stream> OpenWrite(string path, CancellationToken cancellationToken)
{
var tempFile = System.IO.Path.Combine(_tempPath, Guid.NewGuid().ToString());
_tempFiles[path] = tempFile;
return Task.FromResult<Stream>(new FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None));
}
public Task<Stream> OpenRead(string path, CancellationToken cancellationToken)
{
if (_tempFiles.TryGetValue(path, out var tempFile) && System.IO.File.Exists(tempFile))
{
return Task.FromResult<Stream>(new FileStream(tempFile, FileMode.Open, FileAccess.Read, FileShare.Read));
}
throw new FileNotFoundException("File not found in temp storage", path);
}
public Task<Stream> OpenReadWrite(string path, CancellationToken cancellationToken)
{
if (_tempFiles.TryGetValue(path, out var tempFile) && System.IO.File.Exists(tempFile))
{
return Task.FromResult<Stream>(new FileStream(tempFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None));
}
throw new FileNotFoundException("File not found in temp storage", path);
}
public Task<long> GetFileLength(string path, CancellationToken cancellationToken)
{
if (_tempFiles.TryGetValue(path, out var tempFile) && System.IO.File.Exists(tempFile))
{
return Task.FromResult(new FileInfo(tempFile).Length);
}
return Task.FromResult(-1L);
}
public Task<bool> HasReadOnlyAttribute(string path, CancellationToken cancellationToken)
{
return Task.FromResult(false);
}
public Task ClearReadOnlyAttribute(string path, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
public Task<bool> WriteMetadata(string path, Dictionary<string, string?> metadata, bool isFolder, bool isRoot, CancellationToken cancellationToken)
{
_metadata[path] = metadata;
return Task.FromResult(true);
}
public Task DeleteFolder(string path, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
public Task DeleteFile(string path, CancellationToken cancellationToken)
{
if (_tempFiles.TryGetValue(path, out var tempFile))
{
if (System.IO.File.Exists(tempFile))
System.IO.File.Delete(tempFile);
_tempFiles.Remove(path);
}
return Task.CompletedTask;
}
public Task Finalize(Action<double>? progress, CancellationToken cancellationToken)
{
// TODO: Implement restore logic based on _tempFiles and _metadata
return Task.CompletedTask;
}
}