11using System ;
22using System . Collections . Generic ;
33using System . IO ;
4+ using System . Linq ;
5+ using System . Net ;
46using System . Threading ;
57using System . Threading . Tasks ;
8+ using Google ;
69using Google . Cloud . Storage . V1 ;
710using SharpGrip . FileSystem . Exceptions ;
811using SharpGrip . FileSystem . Extensions ;
912using SharpGrip . FileSystem . Models ;
13+ using SharpGrip . FileSystem . Utilities ;
1014using DirectoryNotFoundException = SharpGrip . FileSystem . Exceptions . DirectoryNotFoundException ;
1115using FileNotFoundException = SharpGrip . FileSystem . Exceptions . FileNotFoundException ;
16+ using Object = Google . Apis . Storage . v1 . Data . Object ;
1217
1318namespace SharpGrip . FileSystem . Adapters . GoogleCloudStorage
1419{
@@ -51,6 +56,10 @@ public override async Task<IFile> GetFileAsync(string virtualPath, CancellationT
5156
5257 return ModelFactory . CreateFile ( file , path , virtualPath ) ;
5358 }
59+ catch ( GoogleApiException googleApiException ) when ( googleApiException . HttpStatusCode == HttpStatusCode . NotFound )
60+ {
61+ throw new FileNotFoundException ( path , Prefix ) ;
62+ }
5463 catch ( Exception exception )
5564 {
5665 throw Exception ( exception ) ;
@@ -59,11 +68,16 @@ public override async Task<IFile> GetFileAsync(string virtualPath, CancellationT
5968
6069 public override async Task < IDirectory > GetDirectoryAsync ( string virtualPath , CancellationToken cancellationToken = default )
6170 {
62- var path = GetPath ( virtualPath ) . EnsureLeadingForwardSlash ( ) . EnsureTrailingForwardSlash ( ) ;
71+ var path = GetPath ( virtualPath ) . RemoveLeadingForwardSlash ( ) . EnsureTrailingForwardSlash ( ) ;
6372 var parentPath = GetParentPathPart ( path ) . EnsureTrailingForwardSlash ( ) ;
6473
6574 try
6675 {
76+ if ( path . IsNullOrEmpty ( ) || path == "/" )
77+ {
78+ return ModelFactory . CreateDirectory ( "/" , path , virtualPath ) ;
79+ }
80+
6781 var request = client . Service . Objects . List ( bucketName ) ;
6882
6983 request . Prefix = parentPath == "/" ? null : parentPath ;
@@ -73,13 +87,16 @@ public override async Task<IDirectory> GetDirectoryAsync(string virtualPath, Can
7387 {
7488 var objects = await request . ExecuteAsync ( cancellationToken : cancellationToken ) ;
7589
76- foreach ( var directoryName in objects . Prefixes )
90+ if ( objects . Prefixes != null )
7791 {
78- var directoryPath = parentPath + directoryName ;
79-
80- if ( directoryPath == path )
92+ foreach ( var directoryPath in objects . Prefixes )
8193 {
82- return ModelFactory . CreateDirectory ( directoryName . RemoveTrailingForwardSlash ( ) , directoryPath , GetVirtualPath ( directoryPath ) ) ;
94+ if ( directoryPath == path )
95+ {
96+ var directoryName = GetLastPathPart ( directoryPath ) ;
97+
98+ return ModelFactory . CreateDirectory ( directoryName . RemoveTrailingForwardSlash ( ) , directoryPath . EnsureTrailingForwardSlash ( ) , GetVirtualPath ( directoryPath ) ) ;
99+ }
83100 }
84101 }
85102
@@ -88,6 +105,10 @@ public override async Task<IDirectory> GetDirectoryAsync(string virtualPath, Can
88105
89106 throw new DirectoryNotFoundException ( path , Prefix ) ;
90107 }
108+ catch ( GoogleApiException googleApiException ) when ( googleApiException . HttpStatusCode == HttpStatusCode . NotFound )
109+ {
110+ throw new DirectoryNotFoundException ( path , Prefix ) ;
111+ }
91112 catch ( Exception exception )
92113 {
93114 throw Exception ( exception ) ;
@@ -113,11 +134,12 @@ public override async Task<IEnumerable<IFile>> GetFilesAsync(string virtualPath
113134 {
114135 var objects = await request . ExecuteAsync ( cancellationToken : cancellationToken ) ;
115136
116- foreach ( var file in objects . Items )
137+ if ( objects . Items != null )
117138 {
118- var filePath = path + file . Name ;
119-
120- files . Add ( ModelFactory . CreateFile ( file , filePath . RemoveTrailingForwardSlash ( ) , GetVirtualPath ( filePath ) ) ) ;
139+ foreach ( var file in objects . Items . Where ( item => item . ContentType != null ) )
140+ {
141+ files . Add ( ModelFactory . CreateFile ( file , file . Name . RemoveTrailingForwardSlash ( ) , GetVirtualPath ( file . Name ) ) ) ;
142+ }
121143 }
122144
123145 request . PageToken = objects . NextPageToken ;
@@ -150,11 +172,14 @@ public override async Task<IEnumerable<IDirectory>> GetDirectoriesAsync(string v
150172 {
151173 var objects = await request . ExecuteAsync ( cancellationToken : cancellationToken ) ;
152174
153- foreach ( var directoryName in objects . Prefixes )
175+ if ( objects . Prefixes != null )
154176 {
155- var directoryPath = path + directoryName ;
177+ foreach ( var directoryPath in objects . Prefixes )
178+ {
179+ var directoryName = GetLastPathPart ( directoryPath ) ;
156180
157- directories . Add ( ModelFactory . CreateDirectory ( directoryName . RemoveTrailingForwardSlash ( ) , directoryPath . EnsureTrailingForwardSlash ( ) , GetVirtualPath ( directoryPath ) ) ) ;
181+ directories . Add ( ModelFactory . CreateDirectory ( directoryName . RemoveTrailingForwardSlash ( ) , directoryPath . EnsureTrailingForwardSlash ( ) , GetVirtualPath ( directoryPath ) ) ) ;
182+ }
158183 }
159184
160185 request . PageToken = objects . NextPageToken ;
@@ -179,9 +204,7 @@ public override async Task CreateDirectoryAsync(string virtualPath, Cancellation
179204
180205 try
181206 {
182- // client.Service.
183-
184- await client . UploadObjectAsync ( bucketName , GetLastPathPart ( path ) . EnsureTrailingForwardSlash ( ) , null , Stream . Null , cancellationToken : cancellationToken ) ;
207+ await client . UploadObjectAsync ( bucketName , path . EnsureTrailingForwardSlash ( ) , null , Stream . Null , cancellationToken : cancellationToken ) ;
185208 }
186209 catch ( Exception exception )
187210 {
@@ -191,22 +214,98 @@ public override async Task CreateDirectoryAsync(string virtualPath, Cancellation
191214
192215 public override async Task DeleteDirectoryAsync ( string virtualPath , CancellationToken cancellationToken = default )
193216 {
194- throw new NotImplementedException ( ) ;
217+ await GetDirectoryAsync ( virtualPath , cancellationToken ) ;
218+
219+ var path = GetPath ( virtualPath ) . RemoveLeadingForwardSlash ( ) . EnsureTrailingForwardSlash ( ) ;
220+
221+ try
222+ {
223+ var files = await GetFilesAsync ( virtualPath , cancellationToken ) ;
224+
225+ foreach ( var file in files )
226+ {
227+ await DeleteFileAsync ( file . VirtualPath , cancellationToken ) ;
228+ }
229+
230+ var subDirectories = await GetDirectoriesAsync ( virtualPath , cancellationToken ) ;
231+
232+ foreach ( var subDirectory in subDirectories )
233+ {
234+ await DeleteDirectoryAsync ( subDirectory . VirtualPath , cancellationToken ) ;
235+ }
236+
237+ await client . DeleteObjectAsync ( bucketName , path , cancellationToken : cancellationToken ) ;
238+ }
239+ catch ( Exception exception )
240+ {
241+ throw Exception ( exception ) ;
242+ }
195243 }
196244
197245 public override async Task DeleteFileAsync ( string virtualPath , CancellationToken cancellationToken = default )
198246 {
199- throw new NotImplementedException ( ) ;
247+ await GetFileAsync ( virtualPath , cancellationToken ) ;
248+
249+ var path = GetPath ( virtualPath ) . RemoveLeadingForwardSlash ( ) . RemoveTrailingForwardSlash ( ) ;
250+
251+ try
252+ {
253+ await client . DeleteObjectAsync ( bucketName , path , cancellationToken : cancellationToken ) ;
254+ }
255+ catch ( Exception exception )
256+ {
257+ throw Exception ( exception ) ;
258+ }
200259 }
201260
202261 public override async Task < Stream > ReadFileStreamAsync ( string virtualPath , CancellationToken cancellationToken = default )
203262 {
204- throw new NotImplementedException ( ) ;
263+ await GetFileAsync ( virtualPath , cancellationToken ) ;
264+
265+ var path = GetPath ( virtualPath ) . RemoveLeadingForwardSlash ( ) . RemoveTrailingForwardSlash ( ) ;
266+
267+ try
268+ {
269+ var file = await client . GetObjectAsync ( bucketName , path , new GetObjectOptions ( ) , cancellationToken ) ;
270+
271+ var memoryStream = new MemoryStream ( ) ;
272+
273+ await client . DownloadObjectAsync ( file , memoryStream , new DownloadObjectOptions ( ) , cancellationToken ) ;
274+
275+ memoryStream . Position = 0 ;
276+
277+ return memoryStream ;
278+ }
279+ catch ( Exception exception )
280+ {
281+ throw Exception ( exception ) ;
282+ }
205283 }
206284
207285 public override async Task WriteFileAsync ( string virtualPath , Stream contents , bool overwrite = false , CancellationToken cancellationToken = default )
208286 {
209- throw new NotImplementedException ( ) ;
287+ if ( ! overwrite && await FileExistsAsync ( virtualPath , cancellationToken ) )
288+ {
289+ throw new FileExistsException ( GetPath ( virtualPath ) , Prefix ) ;
290+ }
291+
292+ var path = GetPath ( virtualPath ) . RemoveLeadingForwardSlash ( ) . RemoveTrailingForwardSlash ( ) ;
293+
294+ try
295+ {
296+ var file = new Object
297+ {
298+ Bucket = bucketName ,
299+ Name = path ,
300+ ContentType = ContentTypeProvider . GetContentType ( path )
301+ } ;
302+
303+ await client . UploadObjectAsync ( file , contents , new UploadObjectOptions ( ) , cancellationToken ) ;
304+ }
305+ catch ( Exception exception )
306+ {
307+ throw Exception ( exception ) ;
308+ }
210309 }
211310
212311 protected override Exception Exception ( Exception exception )
0 commit comments