1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . IO ;
4+ using System . Threading ;
5+ using System . Threading . Tasks ;
6+ using Google . Cloud . Storage . V1 ;
7+ using SharpGrip . FileSystem . Exceptions ;
8+ using SharpGrip . FileSystem . Extensions ;
9+ using SharpGrip . FileSystem . Models ;
10+ using DirectoryNotFoundException = SharpGrip . FileSystem . Exceptions . DirectoryNotFoundException ;
11+ using FileNotFoundException = SharpGrip . FileSystem . Exceptions . FileNotFoundException ;
12+
13+ namespace SharpGrip . FileSystem . Adapters . GoogleCloudStorage
14+ {
15+ public class GoogleCloudStorageAdapter : Adapter < GoogleCloudStorageAdapterConfiguration , string , string >
16+ {
17+ private readonly StorageClient client ;
18+ private readonly string bucketName ;
19+
20+ public GoogleCloudStorageAdapter ( string prefix , string rootPath , StorageClient client , string bucketName , Action < GoogleCloudStorageAdapterConfiguration > ? configuration = null )
21+ : base ( prefix , rootPath , configuration )
22+ {
23+ this . client = client ;
24+ this . bucketName = bucketName ;
25+ }
26+
27+ public override void Dispose ( )
28+ {
29+ client . Dispose ( ) ;
30+ }
31+
32+ public override async Task ConnectAsync ( CancellationToken cancellationToken = default )
33+ {
34+ Logger . LogStartConnectingAdapter ( this ) ;
35+ await Task . CompletedTask ;
36+ Logger . LogFinishedConnectingAdapter ( this ) ;
37+ }
38+
39+ public override async Task < IFile > GetFileAsync ( string virtualPath , CancellationToken cancellationToken = default )
40+ {
41+ var path = GetPath ( virtualPath ) . RemoveLeadingForwardSlash ( ) . RemoveTrailingForwardSlash ( ) ;
42+
43+ try
44+ {
45+ var file = await client . GetObjectAsync ( bucketName , path , new GetObjectOptions ( ) , cancellationToken ) ;
46+
47+ if ( file == null )
48+ {
49+ throw new FileNotFoundException ( path , Prefix ) ;
50+ }
51+
52+ return ModelFactory . CreateFile ( file , path , virtualPath ) ;
53+ }
54+ catch ( Exception exception )
55+ {
56+ throw Exception ( exception ) ;
57+ }
58+ }
59+
60+ public override async Task < IDirectory > GetDirectoryAsync ( string virtualPath , CancellationToken cancellationToken = default )
61+ {
62+ var path = GetPath ( virtualPath ) . EnsureLeadingForwardSlash ( ) . EnsureTrailingForwardSlash ( ) ;
63+ var parentPath = GetParentPathPart ( path ) . EnsureTrailingForwardSlash ( ) ;
64+
65+ try
66+ {
67+ var request = client . Service . Objects . List ( bucketName ) ;
68+
69+ request . Prefix = parentPath == "/" ? null : parentPath ;
70+ request . Delimiter = "/" ;
71+
72+ do
73+ {
74+ var objects = await request . ExecuteAsync ( cancellationToken : cancellationToken ) ;
75+
76+ foreach ( var directoryName in objects . Prefixes )
77+ {
78+ var directoryPath = parentPath + directoryName ;
79+
80+ if ( directoryPath == path )
81+ {
82+ return ModelFactory . CreateDirectory ( directoryName . RemoveTrailingForwardSlash ( ) , directoryPath , GetVirtualPath ( directoryPath ) ) ;
83+ }
84+ }
85+
86+ request . PageToken = objects . NextPageToken ;
87+ } while ( request . PageToken != null ) ;
88+
89+ throw new DirectoryNotFoundException ( path , Prefix ) ;
90+ }
91+ catch ( Exception exception )
92+ {
93+ throw Exception ( exception ) ;
94+ }
95+ }
96+
97+ public override async Task < IEnumerable < IFile > > GetFilesAsync ( string virtualPath = "" , CancellationToken cancellationToken = default )
98+ {
99+ await GetDirectoryAsync ( virtualPath , cancellationToken ) ;
100+
101+ var path = GetPath ( virtualPath ) . RemoveLeadingForwardSlash ( ) . EnsureTrailingForwardSlash ( ) ;
102+
103+ try
104+ {
105+ var files = new List < IFile > ( ) ;
106+
107+ var request = client . Service . Objects . List ( bucketName ) ;
108+
109+ request . Prefix = path == "/" ? null : path ;
110+ request . Delimiter = "/" ;
111+
112+ do
113+ {
114+ var objects = await request . ExecuteAsync ( cancellationToken : cancellationToken ) ;
115+
116+ foreach ( var file in objects . Items )
117+ {
118+ var filePath = path + file . Name ;
119+
120+ files . Add ( ModelFactory . CreateFile ( file , filePath . RemoveTrailingForwardSlash ( ) , GetVirtualPath ( filePath ) ) ) ;
121+ }
122+
123+ request . PageToken = objects . NextPageToken ;
124+ } while ( request . PageToken != null ) ;
125+
126+ return files ;
127+ }
128+ catch ( Exception exception )
129+ {
130+ throw Exception ( exception ) ;
131+ }
132+ }
133+
134+ public override async Task < IEnumerable < IDirectory > > GetDirectoriesAsync ( string virtualPath = "" , CancellationToken cancellationToken = default )
135+ {
136+ await GetDirectoryAsync ( virtualPath , cancellationToken ) ;
137+
138+ var path = GetPath ( virtualPath ) . RemoveLeadingForwardSlash ( ) . EnsureTrailingForwardSlash ( ) ;
139+
140+ try
141+ {
142+ var directories = new List < IDirectory > ( ) ;
143+
144+ var request = client . Service . Objects . List ( bucketName ) ;
145+
146+ request . Prefix = path == "/" ? null : path ;
147+ request . Delimiter = "/" ;
148+
149+ do
150+ {
151+ var objects = await request . ExecuteAsync ( cancellationToken : cancellationToken ) ;
152+
153+ foreach ( var directoryName in objects . Prefixes )
154+ {
155+ var directoryPath = path + directoryName ;
156+
157+ directories . Add ( ModelFactory . CreateDirectory ( directoryName . RemoveTrailingForwardSlash ( ) , directoryPath . EnsureTrailingForwardSlash ( ) , GetVirtualPath ( directoryPath ) ) ) ;
158+ }
159+
160+ request . PageToken = objects . NextPageToken ;
161+ } while ( request . PageToken != null ) ;
162+
163+ return directories ;
164+ }
165+ catch ( Exception exception )
166+ {
167+ throw Exception ( exception ) ;
168+ }
169+ }
170+
171+ public override async Task CreateDirectoryAsync ( string virtualPath , CancellationToken cancellationToken = default )
172+ {
173+ if ( await DirectoryExistsAsync ( virtualPath , cancellationToken ) )
174+ {
175+ throw new DirectoryExistsException ( GetPath ( virtualPath ) , Prefix ) ;
176+ }
177+
178+ var path = GetPath ( virtualPath ) . RemoveLeadingForwardSlash ( ) . EnsureTrailingForwardSlash ( ) ;
179+
180+ try
181+ {
182+ // client.Service.
183+
184+ await client . UploadObjectAsync ( bucketName , GetLastPathPart ( path ) . EnsureTrailingForwardSlash ( ) , null , Stream . Null , cancellationToken : cancellationToken ) ;
185+ }
186+ catch ( Exception exception )
187+ {
188+ throw Exception ( exception ) ;
189+ }
190+ }
191+
192+ public override async Task DeleteDirectoryAsync ( string virtualPath , CancellationToken cancellationToken = default )
193+ {
194+ throw new NotImplementedException ( ) ;
195+ }
196+
197+ public override async Task DeleteFileAsync ( string virtualPath , CancellationToken cancellationToken = default )
198+ {
199+ throw new NotImplementedException ( ) ;
200+ }
201+
202+ public override async Task < Stream > ReadFileStreamAsync ( string virtualPath , CancellationToken cancellationToken = default )
203+ {
204+ throw new NotImplementedException ( ) ;
205+ }
206+
207+ public override async Task WriteFileAsync ( string virtualPath , Stream contents , bool overwrite = false , CancellationToken cancellationToken = default )
208+ {
209+ throw new NotImplementedException ( ) ;
210+ }
211+
212+ protected override Exception Exception ( Exception exception )
213+ {
214+ if ( exception is FileSystemException )
215+ {
216+ return exception ;
217+ }
218+
219+ return new AdapterRuntimeException ( exception ) ;
220+ }
221+ }
222+ }
0 commit comments