11using System ;
2+ using System . Collections . Generic ;
23using System . IO ;
34using System . Linq ;
45using System . Threading . Tasks ;
6+ using Azure ;
7+ using Azure . Storage . Blobs . Models ;
8+ using Azure . Storage . Blobs . Specialized ;
9+ using Azure . Storage . Sas ;
510using ContentReactor . Audio . Services . Models . Responses ;
611using ContentReactor . Audio . Services . Models . Results ;
712using ContentReactor . Shared ;
8- using ContentReactor . Shared . BlobRepository ;
13+ using ContentReactor . Shared . BlobHelper ;
914using ContentReactor . Shared . EventSchemas . Audio ;
10- using Microsoft . WindowsAzure . Storage . Blob ;
1115
1216namespace ContentReactor . Audio . Services
1317{
@@ -23,7 +27,7 @@ public interface IAudioService
2327
2428 public class AudioService : IAudioService
2529 {
26- protected IBlobRepository BlobRepository ;
30+ protected BlobHelper BlobHelper ;
2731 protected IAudioTranscriptionService AudioTranscriptionService ;
2832 protected IEventGridPublisherService EventGridPublisherService ;
2933
@@ -32,53 +36,52 @@ public class AudioService : IAudioService
3236 protected internal const string CategoryIdMetadataName = "categoryId" ;
3337 protected internal const string UserIdMetadataName = "userId" ;
3438 protected internal const int TranscriptPreviewLength = 100 ;
35-
36- public AudioService ( IBlobRepository blobRepository , IAudioTranscriptionService audioTranscriptionService , IEventGridPublisherService eventGridPublisherService )
39+
40+ public AudioService ( BlobHelper blobHelper , IAudioTranscriptionService audioTranscriptionService , IEventGridPublisherService eventGridPublisherService )
3741 {
38- BlobRepository = blobRepository ;
42+ BlobHelper = blobHelper ;
3943 AudioTranscriptionService = audioTranscriptionService ;
4044 EventGridPublisherService = eventGridPublisherService ;
4145 }
4246
4347 public ( string id , string url ) BeginAddAudioNote ( string userId )
4448 {
4549 // generate an ID for this image note
46- var audioId = Guid . NewGuid ( ) . ToString ( ) ;
50+ string audioId = Guid . NewGuid ( ) . ToString ( ) ;
4751
4852 // create a blob placeholder (which will not have any contents yet)
49- var blob = BlobRepository . CreatePlaceholderBlob ( AudioBlobContainerName , userId , audioId ) ;
53+ BlockBlobClient blob = BlobHelper . GetBlobClient ( AudioBlobContainerName , audioId ) ;
5054
51- // get a SAS token to allow the client to write the blob
52- var writePolicy = new SharedAccessBlobPolicy
53- {
54- SharedAccessStartTime = DateTime . UtcNow . AddMinutes ( - 5 ) , // to allow for clock skew
55- SharedAccessExpiryTime = DateTime . UtcNow . AddHours ( 24 ) ,
56- Permissions = SharedAccessBlobPermissions . Create | SharedAccessBlobPermissions . Write
57- } ;
58- var url = BlobRepository . GetSasTokenForBlob ( blob , writePolicy ) ;
5955
60- return ( audioId , url ) ;
56+ string urlAndSas = BlobHelper . GetSasUriForBlob ( blob , BlobSasPermissions . Create | BlobSasPermissions . Write ) ;
57+
58+ return ( audioId , urlAndSas ) ;
6159 }
6260
6361 public async Task < CompleteAddAudioNoteResult > CompleteAddAudioNoteAsync ( string audioId , string userId , string categoryId )
6462 {
65- var imageBlob = await BlobRepository . GetBlobAsync ( AudioBlobContainerName , userId , audioId , true ) ;
66- if ( imageBlob == null || ! await BlobRepository . BlobExistsAsync ( imageBlob ) )
63+ BlockBlobClient imageBlob = BlobHelper . GetBlobClient ( AudioBlobContainerName , audioId ) ;
64+ if ( imageBlob == null || ! await imageBlob . ExistsAsync ( ) )
6765 {
6866 // the blob hasn't actually been uploaded yet, so we can't process it
6967 return CompleteAddAudioNoteResult . AudioNotUploaded ;
7068 }
71-
69+
7270 // if the blob already contains metadata then that means it has already been added
73- if ( imageBlob . Metadata . ContainsKey ( CategoryIdMetadataName ) )
71+ Response < BlobProperties > response = await imageBlob . GetPropertiesAsync ( ) ;
72+ if ( response . Value . Metadata . ContainsKey ( CategoryIdMetadataName ) )
7473 {
7574 return CompleteAddAudioNoteResult . AudioAlreadyCreated ;
7675 }
7776
7877 // set the blob metadata
79- imageBlob . Metadata . Add ( CategoryIdMetadataName , categoryId ) ;
80- imageBlob . Metadata . Add ( UserIdMetadataName , userId ) ;
81- await BlobRepository . UpdateBlobMetadataAsync ( imageBlob ) ;
78+ var metadata = new Dictionary < string , string >
79+ {
80+ { CategoryIdMetadataName , categoryId } ,
81+ { UserIdMetadataName , userId }
82+ } ;
83+
84+ await imageBlob . SetMetadataAsync ( metadata ) ;
8285
8386 // publish an event into the Event Grid topic
8487 var subject = $ "{ userId } /{ audioId } ";
@@ -90,39 +93,33 @@ public async Task<CompleteAddAudioNoteResult> CompleteAddAudioNoteAsync(string a
9093 public async Task < AudioNoteDetails > GetAudioNoteAsync ( string id , string userId )
9194 {
9295 // get the blob, if it exists
93- var audioBlob = await BlobRepository . GetBlobAsync ( AudioBlobContainerName , userId , id , true ) ;
96+ BlockBlobClient audioBlob = BlobHelper . GetBlobClient ( AudioBlobContainerName , id ) ;
9497 if ( audioBlob == null )
9598 {
9699 return null ;
97100 }
98101
99- // get a SAS token for the blob
100- var readPolicy = new SharedAccessBlobPolicy
101- {
102- SharedAccessStartTime = DateTime . UtcNow . AddMinutes ( - 5 ) , // to allow for clock skew
103- SharedAccessExpiryTime = DateTime . UtcNow . AddHours ( 24 ) ,
104- Permissions = SharedAccessBlobPermissions . Read
105- } ;
106- var audioUrl = BlobRepository . GetSasTokenForBlob ( audioBlob , readPolicy ) ;
102+ string audioUrlAndSas = BlobHelper . GetSasUriForBlob ( audioBlob , BlobSasPermissions . Read ) ;
107103
108104 // get the transcript out of the blob metadata
109- audioBlob . Metadata . TryGetValue ( TranscriptMetadataName , out var transcript ) ;
110-
111- return new AudioNoteDetails
105+ Response < BlobProperties > response = await audioBlob . GetPropertiesAsync ( ) ;
106+ response . Value . Metadata . TryGetValue ( TranscriptMetadataName , out var transcript ) ;
107+
108+ return new AudioNoteDetails
112109 {
113- Id = id ,
114- AudioUrl = audioUrl ,
110+ Id = id ,
111+ AudioUrl = audioUrlAndSas ,
115112 Transcript = transcript
116113 } ;
117114 }
118115
119116 public async Task < AudioNoteSummaries > ListAudioNotesAsync ( string userId )
120117 {
121- var blobs = await BlobRepository . ListBlobsInFolderAsync ( AudioBlobContainerName , userId ) ;
118+ IList < BlobItem > blobs = await BlobHelper . ListBlobsAsync ( AudioBlobContainerName ) ;
122119 var blobSummaries = blobs
123120 . Select ( b => new AudioNoteSummary
124121 {
125- Id = b . Name . Split ( '/' ) [ 1 ] ,
122+ Id = b . Name . Split ( '/' ) [ 1 ] ,
126123 Preview = b . Metadata . ContainsKey ( TranscriptMetadataName ) ? b . Metadata [ TranscriptMetadataName ] . Truncate ( TranscriptPreviewLength ) : string . Empty
127124 } )
128125 . ToList ( ) ;
@@ -136,7 +133,8 @@ public async Task<AudioNoteSummaries> ListAudioNotesAsync(string userId)
136133 public async Task DeleteAudioNoteAsync ( string id , string userId )
137134 {
138135 // delete the blog
139- await BlobRepository . DeleteBlobAsync ( AudioBlobContainerName , userId , id ) ;
136+ BlockBlobClient blob = BlobHelper . GetBlobClient ( AudioBlobContainerName , id ) ;
137+ await blob . DeleteIfExistsAsync ( DeleteSnapshotsOption . IncludeSnapshots ) ;
140138
141139 // fire an event into the Event Grid topic
142140 var subject = $ "{ userId } /{ id } ";
@@ -146,7 +144,7 @@ public async Task DeleteAudioNoteAsync(string id, string userId)
146144 public async Task < string > UpdateAudioTranscriptAsync ( string id , string userId )
147145 {
148146 // get the blob
149- var audioBlob = await BlobRepository . GetBlobAsync ( AudioBlobContainerName , userId , id , true ) ;
147+ BlockBlobClient audioBlob = BlobHelper . GetBlobClient ( AudioBlobContainerName , id ) ;
150148 if ( audioBlob == null )
151149 {
152150 return null ;
@@ -156,18 +154,21 @@ public async Task<string> UpdateAudioTranscriptAsync(string id, string userId)
156154 string transcript ;
157155 using ( var audioBlobStream = new MemoryStream ( ) )
158156 {
159- await BlobRepository . DownloadBlobAsync ( audioBlob , audioBlobStream ) ;
157+ await audioBlob . DownloadToAsync ( audioBlobStream ) ;
160158
161159 // send to Cognitive Services and get back a transcript
162160 transcript = await AudioTranscriptionService . GetAudioTranscriptFromCognitiveServicesAsync ( audioBlobStream ) ;
163161 }
164-
162+
165163 // update the blob's metadata
166- audioBlob . Metadata [ TranscriptMetadataName ] = transcript ;
167- await BlobRepository . UpdateBlobMetadataAsync ( audioBlob ) ;
164+ var metadata = new Dictionary < string , string >
165+ {
166+ { TranscriptMetadataName , transcript }
167+ } ;
168168
169+ await audioBlob . SetMetadataAsync ( metadata ) ;
169170 // create a preview form of the transcript
170- var transcriptPreview = transcript . Truncate ( TranscriptPreviewLength ) ;
171+ string transcriptPreview = transcript . Truncate ( TranscriptPreviewLength ) ;
171172
172173 // fire an event into the Event Grid topic
173174 var subject = $ "{ userId } /{ id } ";
0 commit comments