diff --git a/FileSystem.Adapters.GoogleCloudStorage/FileSystem.Adapters.GoogleCloudStorage.csproj b/FileSystem.Adapters.GoogleCloudStorage/FileSystem.Adapters.GoogleCloudStorage.csproj new file mode 100644 index 0000000..e36621b --- /dev/null +++ b/FileSystem.Adapters.GoogleCloudStorage/FileSystem.Adapters.GoogleCloudStorage.csproj @@ -0,0 +1,27 @@ + + + + SharpGrip.FileSystem.Adapters.GoogleCloudStorage + + + + SharpGrip.FileSystem.Adapters.GoogleCloudStorage + SharpGrip.FileSystem.Adapters.GoogleCloudStorage + SharpGrip FileSystem Google Cloud Storage adapter + The SharpGrip FileSystem Google Cloud Storage adapter. + sharpgrip;file-system;google-cloud-storage + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapter.cs b/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapter.cs new file mode 100644 index 0000000..f8f2d62 --- /dev/null +++ b/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapter.cs @@ -0,0 +1,321 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using Google; +using Google.Cloud.Storage.V1; +using SharpGrip.FileSystem.Exceptions; +using SharpGrip.FileSystem.Extensions; +using SharpGrip.FileSystem.Models; +using SharpGrip.FileSystem.Utilities; +using DirectoryNotFoundException = SharpGrip.FileSystem.Exceptions.DirectoryNotFoundException; +using FileNotFoundException = SharpGrip.FileSystem.Exceptions.FileNotFoundException; +using Object = Google.Apis.Storage.v1.Data.Object; + +namespace SharpGrip.FileSystem.Adapters.GoogleCloudStorage +{ + public class GoogleCloudStorageAdapter : Adapter + { + private readonly StorageClient client; + private readonly string bucketName; + + public GoogleCloudStorageAdapter(string prefix, string rootPath, StorageClient client, string bucketName, Action? configuration = null) + : base(prefix, rootPath, configuration) + { + this.client = client; + this.bucketName = bucketName; + } + + public override void Dispose() + { + client.Dispose(); + } + + public override async Task ConnectAsync(CancellationToken cancellationToken = default) + { + Logger.LogStartConnectingAdapter(this); + await Task.CompletedTask; + Logger.LogFinishedConnectingAdapter(this); + } + + public override async Task GetFileAsync(string virtualPath, CancellationToken cancellationToken = default) + { + var path = GetPath(virtualPath).RemoveLeadingForwardSlash().RemoveTrailingForwardSlash(); + + try + { + var file = await client.GetObjectAsync(bucketName, path, new GetObjectOptions(), cancellationToken); + + if (file == null) + { + throw new FileNotFoundException(path, Prefix); + } + + return ModelFactory.CreateFile(file, path, virtualPath); + } + catch (GoogleApiException googleApiException) when (googleApiException.HttpStatusCode == HttpStatusCode.NotFound) + { + throw new FileNotFoundException(path, Prefix); + } + catch (Exception exception) + { + throw Exception(exception); + } + } + + public override async Task GetDirectoryAsync(string virtualPath, CancellationToken cancellationToken = default) + { + var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash(); + var parentPath = GetParentPathPart(path).EnsureTrailingForwardSlash(); + + try + { + if (path.IsNullOrEmpty() || path == "/") + { + return ModelFactory.CreateDirectory("/", path, virtualPath); + } + + var request = client.Service.Objects.List(bucketName); + + request.Prefix = parentPath == "/" ? null : parentPath; + request.Delimiter = "/"; + + do + { + var objects = await request.ExecuteAsync(cancellationToken: cancellationToken); + + if (objects.Prefixes != null) + { + foreach (var directoryPath in objects.Prefixes) + { + if (directoryPath == path) + { + var directoryName = GetLastPathPart(directoryPath); + + return ModelFactory.CreateDirectory(directoryName.RemoveTrailingForwardSlash(), directoryPath.EnsureTrailingForwardSlash(), GetVirtualPath(directoryPath)); + } + } + } + + request.PageToken = objects.NextPageToken; + } while (request.PageToken != null); + + throw new DirectoryNotFoundException(path, Prefix); + } + catch (GoogleApiException googleApiException) when (googleApiException.HttpStatusCode == HttpStatusCode.NotFound) + { + throw new DirectoryNotFoundException(path, Prefix); + } + catch (Exception exception) + { + throw Exception(exception); + } + } + + public override async Task> GetFilesAsync(string virtualPath = "", CancellationToken cancellationToken = default) + { + await GetDirectoryAsync(virtualPath, cancellationToken); + + var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash(); + + try + { + var files = new List(); + + var request = client.Service.Objects.List(bucketName); + + request.Prefix = path == "/" ? null : path; + request.Delimiter = "/"; + + do + { + var objects = await request.ExecuteAsync(cancellationToken: cancellationToken); + + if (objects.Items != null) + { + foreach (var file in objects.Items.Where(item => item.ContentType != null)) + { + files.Add(ModelFactory.CreateFile(file, file.Name.RemoveTrailingForwardSlash(), GetVirtualPath(file.Name))); + } + } + + request.PageToken = objects.NextPageToken; + } while (request.PageToken != null); + + return files; + } + catch (Exception exception) + { + throw Exception(exception); + } + } + + public override async Task> GetDirectoriesAsync(string virtualPath = "", CancellationToken cancellationToken = default) + { + await GetDirectoryAsync(virtualPath, cancellationToken); + + var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash(); + + try + { + var directories = new List(); + + var request = client.Service.Objects.List(bucketName); + + request.Prefix = path == "/" ? null : path; + request.Delimiter = "/"; + + do + { + var objects = await request.ExecuteAsync(cancellationToken: cancellationToken); + + if (objects.Prefixes != null) + { + foreach (var directoryPath in objects.Prefixes) + { + var directoryName = GetLastPathPart(directoryPath); + + directories.Add(ModelFactory.CreateDirectory(directoryName.RemoveTrailingForwardSlash(), directoryPath.EnsureTrailingForwardSlash(), GetVirtualPath(directoryPath))); + } + } + + request.PageToken = objects.NextPageToken; + } while (request.PageToken != null); + + return directories; + } + catch (Exception exception) + { + throw Exception(exception); + } + } + + public override async Task CreateDirectoryAsync(string virtualPath, CancellationToken cancellationToken = default) + { + if (await DirectoryExistsAsync(virtualPath, cancellationToken)) + { + throw new DirectoryExistsException(GetPath(virtualPath), Prefix); + } + + var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash(); + + try + { + await client.UploadObjectAsync(bucketName, path.EnsureTrailingForwardSlash(), null, Stream.Null, cancellationToken: cancellationToken); + } + catch (Exception exception) + { + throw Exception(exception); + } + } + + public override async Task DeleteDirectoryAsync(string virtualPath, CancellationToken cancellationToken = default) + { + await GetDirectoryAsync(virtualPath, cancellationToken); + + var path = GetPath(virtualPath).RemoveLeadingForwardSlash().EnsureTrailingForwardSlash(); + + try + { + var files = await GetFilesAsync(virtualPath, cancellationToken); + + foreach (var file in files) + { + await DeleteFileAsync(file.VirtualPath, cancellationToken); + } + + var subDirectories = await GetDirectoriesAsync(virtualPath, cancellationToken); + + foreach (var subDirectory in subDirectories) + { + await DeleteDirectoryAsync(subDirectory.VirtualPath, cancellationToken); + } + + await client.DeleteObjectAsync(bucketName, path, cancellationToken: cancellationToken); + } + catch (Exception exception) + { + throw Exception(exception); + } + } + + public override async Task DeleteFileAsync(string virtualPath, CancellationToken cancellationToken = default) + { + await GetFileAsync(virtualPath, cancellationToken); + + var path = GetPath(virtualPath).RemoveLeadingForwardSlash().RemoveTrailingForwardSlash(); + + try + { + await client.DeleteObjectAsync(bucketName, path, cancellationToken: cancellationToken); + } + catch (Exception exception) + { + throw Exception(exception); + } + } + + public override async Task ReadFileStreamAsync(string virtualPath, CancellationToken cancellationToken = default) + { + await GetFileAsync(virtualPath, cancellationToken); + + var path = GetPath(virtualPath).RemoveLeadingForwardSlash().RemoveTrailingForwardSlash(); + + try + { + var file = await client.GetObjectAsync(bucketName, path, new GetObjectOptions(), cancellationToken); + + var memoryStream = new MemoryStream(); + + await client.DownloadObjectAsync(file, memoryStream, new DownloadObjectOptions(), cancellationToken); + + memoryStream.Position = 0; + + return memoryStream; + } + catch (Exception exception) + { + throw Exception(exception); + } + } + + public override async Task WriteFileAsync(string virtualPath, Stream contents, bool overwrite = false, CancellationToken cancellationToken = default) + { + if (!overwrite && await FileExistsAsync(virtualPath, cancellationToken)) + { + throw new FileExistsException(GetPath(virtualPath), Prefix); + } + + var path = GetPath(virtualPath).RemoveLeadingForwardSlash().RemoveTrailingForwardSlash(); + + try + { + var file = new Object + { + Bucket = bucketName, + Name = path, + ContentType = ContentTypeProvider.GetContentType(path) + }; + + await client.UploadObjectAsync(file, contents, new UploadObjectOptions(), cancellationToken); + } + catch (Exception exception) + { + throw Exception(exception); + } + } + + protected override Exception Exception(Exception exception) + { + if (exception is FileSystemException) + { + return exception; + } + + return new AdapterRuntimeException(exception); + } + } +} \ No newline at end of file diff --git a/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapterConfiguration.cs b/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapterConfiguration.cs new file mode 100644 index 0000000..dc83161 --- /dev/null +++ b/FileSystem.Adapters.GoogleCloudStorage/src/GoogleCloudStorageAdapterConfiguration.cs @@ -0,0 +1,8 @@ +using SharpGrip.FileSystem.Configuration; + +namespace SharpGrip.FileSystem.Adapters.GoogleCloudStorage +{ + public class GoogleCloudStorageAdapterConfiguration : AdapterConfiguration + { + } +} \ No newline at end of file diff --git a/FileSystem.Adapters.GoogleCloudStorage/src/ModelFactory.cs b/FileSystem.Adapters.GoogleCloudStorage/src/ModelFactory.cs new file mode 100644 index 0000000..6a49dab --- /dev/null +++ b/FileSystem.Adapters.GoogleCloudStorage/src/ModelFactory.cs @@ -0,0 +1,44 @@ +using Google.Apis.Storage.v1.Data; +using SharpGrip.FileSystem.Models; +using SharpGrip.FileSystem.Utilities; + +namespace SharpGrip.FileSystem.Adapters.GoogleCloudStorage +{ + public static class ModelFactory + { + public static FileModel CreateFile(Object file, string path, string virtualPath) + { + return new FileModel + { + Name = PathUtilities.GetLastPathPart(file.Name), + Path = path, + VirtualPath = virtualPath, + Length = (long?) file.Size, + LastModifiedDateTime = file.UpdatedDateTimeOffset?.DateTime, + CreatedDateTime = file.TimeCreatedDateTimeOffset?.DateTime + }; + } + + public static DirectoryModel CreateDirectory(string name, string path, string virtualPath) + { + return new DirectoryModel + { + Name = name, + Path = path, + VirtualPath = virtualPath + }; + } + + public static DirectoryModel CreateDirectory(Object directory, string path, string virtualPath) + { + return new DirectoryModel + { + Name = directory.Name, + Path = path, + VirtualPath = virtualPath, + LastModifiedDateTime = directory.UpdatedDateTimeOffset?.DateTime, + CreatedDateTime = directory.TimeCreatedDateTimeOffset?.DateTime + }; + } + } +} \ No newline at end of file diff --git a/FileSystem.sln b/FileSystem.sln index 46362fa..b34ff32 100644 --- a/FileSystem.sln +++ b/FileSystem.sln @@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.Dropbox EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.Ftp", "FileSystem.Adapters.Ftp\FileSystem.Adapters.Ftp.csproj", "{ED38402A-3667-4701-A974-4D7710E1544A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.GoogleCloudStorage", "FileSystem.Adapters.GoogleCloudStorage\FileSystem.Adapters.GoogleCloudStorage.csproj", "{0E6E0F36-55C4-49FF-9298-99D5B3309381}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.GoogleDrive", "FileSystem.Adapters.GoogleDrive\FileSystem.Adapters.GoogleDrive.csproj", "{CB1F411C-3FB5-4441-9541-423951C17BAF}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileSystem.Adapters.MicrosoftOneDrive", "FileSystem.Adapters.MicrosoftOneDrive\FileSystem.Adapters.MicrosoftOneDrive.csproj", "{9955422E-4A50-43CD-BC2B-91E6820F206C}" @@ -50,6 +52,10 @@ Global {ED38402A-3667-4701-A974-4D7710E1544A}.Debug|Any CPU.Build.0 = Debug|Any CPU {ED38402A-3667-4701-A974-4D7710E1544A}.Release|Any CPU.ActiveCfg = Release|Any CPU {ED38402A-3667-4701-A974-4D7710E1544A}.Release|Any CPU.Build.0 = Release|Any CPU + {0E6E0F36-55C4-49FF-9298-99D5B3309381}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E6E0F36-55C4-49FF-9298-99D5B3309381}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E6E0F36-55C4-49FF-9298-99D5B3309381}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E6E0F36-55C4-49FF-9298-99D5B3309381}.Release|Any CPU.Build.0 = Release|Any CPU {CB1F411C-3FB5-4441-9541-423951C17BAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CB1F411C-3FB5-4441-9541-423951C17BAF}.Debug|Any CPU.Build.0 = Debug|Any CPU {CB1F411C-3FB5-4441-9541-423951C17BAF}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/FileSystem/FileSystem.csproj b/FileSystem/FileSystem.csproj index 2285baa..0bd12ae 100644 --- a/FileSystem/FileSystem.csproj +++ b/FileSystem/FileSystem.csproj @@ -9,7 +9,7 @@ SharpGrip.FileSystem SharpGrip FileSystem SharpGrip FileSystem is a file system abstraction supporting multiple adapters. - sharpgrip;file-system;amazon-s3;azure-blob-storage;azure-file-storage;dropbox;ftp;google-drive;microsoft-onedrive;sftp + sharpgrip;file-system;amazon-s3;azure-blob-storage;azure-file-storage;dropbox;ftp;google-cloud-storage;google-drive;microsoft-onedrive;sftp diff --git a/FileSystem/src/Adapters/Adapter.cs b/FileSystem/src/Adapters/Adapter.cs index a977c21..265445f 100644 --- a/FileSystem/src/Adapters/Adapter.cs +++ b/FileSystem/src/Adapters/Adapter.cs @@ -129,9 +129,9 @@ public virtual async Task AppendFileAsync(string virtualPath, Stream contents, C public abstract Task WriteFileAsync(string virtualPath, Stream contents, bool overwrite = false, CancellationToken cancellationToken = default); protected abstract Exception Exception(Exception exception); - protected string GetPath(string path) + protected string GetPath(string virtualPath) { - return PathUtilities.GetPath(path, RootPath); + return PathUtilities.GetPath(virtualPath, RootPath); } protected string GetVirtualPath(string path) diff --git a/README.md b/README.md index aeb6ee4..656a5d2 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,10 @@ ## Introduction -SharpGrip FileSystem is a .NET file system abstraction supporting multiple adapters. +SharpGrip FileSystem is a versatile .NET file system abstraction that supports multiple storage adapters. +It empowers developers to manage various file systems and services through a unified and easily comprehensible API. +By coding against the abstractions provided by this library, developers can sidestep vendor-specific APIs, effectively avoiding vendor lock-ins. +This flexibility enhances the portability and maintainability of the codebase, allowing for smoother transitions between different file systems. ## Installation @@ -22,17 +25,18 @@ For adapters other than the local file system (included in the `SharpGrip.FileSy ## Supported adapters -| Adapter | Package | NuGet | -|:------------------------------------------------|:--------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Local adapter](#local-adapter) | `SharpGrip.FileSystem` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem)](https://www.nuget.org/packages/SharpGrip.FileSystem) | -| [AmazonS3](#amazons3-adapter) | `SharpGrip.FileSystem.Adapters.AmazonS3` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AmazonS3)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AmazonS3) | -| [AzureBlobStorage](#azureblobstorage-adapter) | `SharpGrip.FileSystem.Adapters.AzureBlobStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AzureBlobStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureBlobStorage) | -| [AzureFileStorage](#azurefilestorage-adapter) | `SharpGrip.FileSystem.Adapters.AzureFileStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AzureFileStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureFileStorage) | -| [Dropbox](#dropbox-adapter) | `SharpGrip.FileSystem.Adapters.Dropbox` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Dropbox)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Dropbox) | -| [FTP](#ftp-adapter) | `SharpGrip.FileSystem.Adapters.Ftp` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Ftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Ftp) | -| [GoogleDrive](#googledrive-adapter) | `SharpGrip.FileSystem.Adapters.GoogleDrive` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.GoogleDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleDrive) | -| [MicrosoftOneDrive](#microsoftonedrive-adapter) | `SharpGrip.FileSystem.Adapters.MicrosoftOneDrive` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive) | -| [SFTP](#sftp-adapter) | `SharpGrip.FileSystem.Adapters.Sftp` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Sftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Sftp) | +| Adapter | Package | NuGet | +|:--------------------------------------------------|:---------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Local adapter](#local-adapter) | `SharpGrip.FileSystem` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem)](https://www.nuget.org/packages/SharpGrip.FileSystem) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem)](https://www.nuget.org/packages/SharpGrip.FileSystem) | +| [AmazonS3](#amazons3-adapter) | `SharpGrip.FileSystem.Adapters.AmazonS3` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AmazonS3)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AmazonS3) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.AmazonS3)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AmazonS3) | +| [AzureBlobStorage](#azureblobstorage-adapter) | `SharpGrip.FileSystem.Adapters.AzureBlobStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AzureBlobStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureBlobStorage) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.AzureBlobStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureBlobStorage) | +| [AzureFileStorage](#azurefilestorage-adapter) | `SharpGrip.FileSystem.Adapters.AzureFileStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.AzureFileStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureFileStorage) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.AzureFileStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.AzureFileStorage) | +| [Dropbox](#dropbox-adapter) | `SharpGrip.FileSystem.Adapters.Dropbox` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Dropbox)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Dropbox) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.Dropbox)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Dropbox) | +| [FTP](#ftp-adapter) | `SharpGrip.FileSystem.Adapters.Ftp` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Ftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Ftp) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.Ftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Ftp) | +| [GoogleCloudStorage](#googlecloudstorage-adapter) | `SharpGrip.FileSystem.Adapters.GoogleCloudStorage` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.GoogleCloudStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleCloudStorage) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.GoogleCloudStorage)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleCloudStorage) | +| [GoogleDrive](#googledrive-adapter) | `SharpGrip.FileSystem.Adapters.GoogleDrive` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.GoogleDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleDrive) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.GoogleDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.GoogleDrive) | +| [MicrosoftOneDrive](#microsoftonedrive-adapter) | `SharpGrip.FileSystem.Adapters.MicrosoftOneDrive` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.MicrosoftOneDrive) | +| [SFTP](#sftp-adapter) | `SharpGrip.FileSystem.Adapters.Sftp` | [![NuGet](https://img.shields.io/nuget/v/SharpGrip.FileSystem.Adapters.Sftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Sftp) [![NuGet](https://img.shields.io/nuget/dt/SharpGrip.FileSystem.Adapters.Sftp)](https://www.nuget.org/packages/SharpGrip.FileSystem.Adapters.Sftp) | ## Supported operations @@ -144,6 +148,22 @@ var adapters = new List var fileSystem = new FileSystem(adapters); ``` +### GoogleCloudStorage adapter + +``` +// Google connection. +var credential = GoogleCredential.FromFile("path/to/credential/file"); +var storageClient = await StorageClient.CreateAsync(credential); + +var adapters = new List +{ + new LocalAdapter("local", "/var/files"), + new GoogleCloudStorageAdapter(prefix, rootPath, storageClient, "bucketName", configuration); +}; + +var fileSystem = new FileSystem(adapters); +``` + ### GoogleDrive adapter ```