44using System . IO ;
55using System . Linq ;
66using System . Net . Http ;
7+ using System . Security . Cryptography ;
78using System . Threading ;
89using System . Threading . Tasks ;
910using Microsoft . Extensions . Logging ;
@@ -67,6 +68,30 @@ public async Task<ImportedPresenterPlan> ImportProfileImageAsync(ImportedPresent
6768
6869 var importedSpeakersFolder = GetOrCreateImportedSpeakersFolder ( ) ;
6970 var media = GetOrCreateSpeakerImage ( importedSpeakersFolder . Id , presenter ) ;
71+ var profileImageUdi = new GuidUdi ( Constants . UdiEntityType . Media , media . Key ) . ToString ( ) ;
72+
73+ if ( media . HasIdentity )
74+ {
75+ try
76+ {
77+ using var existingStream = _mediaFileManager . GetFile ( media , out _ ) ;
78+ if ( ReferenceEquals ( existingStream , Stream . Null ) == false &&
79+ StreamsHaveEqualContent ( stream , existingStream ) )
80+ {
81+ return presenter with { ProfileImageUdi = profileImageUdi } ;
82+ }
83+ }
84+ catch ( Exception exception )
85+ {
86+ _logger . LogWarning (
87+ exception ,
88+ "Failed to compare the existing Sessionize speaker image for {SpeakerName} ({SpeakerId}); retaining it." ,
89+ presenter . Name ,
90+ presenter . SessionizeSpeakerId ) ;
91+ return presenter with { ProfileImageUdi = profileImageUdi } ;
92+ }
93+ }
94+
7095 var fileName = BuildFileName ( presenter ) ;
7196
7297 media . SetValue (
@@ -82,7 +107,7 @@ public async Task<ImportedPresenterPlan> ImportProfileImageAsync(ImportedPresent
82107
83108 return presenter with
84109 {
85- ProfileImageUdi = new GuidUdi ( Constants . UdiEntityType . Media , media . Key ) . ToString ( )
110+ ProfileImageUdi = profileImageUdi
86111 } ;
87112 }
88113 catch ( Exception exception )
@@ -178,4 +203,39 @@ private static string BuildFileName(ImportedPresenterPlan presenter)
178203
179204 return $ "{ baseName } { extension } ";
180205 }
206+
207+ internal static bool StreamsHaveEqualContent ( Stream first , Stream second )
208+ {
209+ var firstPosition = first . CanSeek ? first . Position : 0 ;
210+ var secondPosition = second . CanSeek ? second . Position : 0 ;
211+
212+ try
213+ {
214+ if ( first . CanSeek )
215+ {
216+ first . Position = 0 ;
217+ }
218+
219+ if ( second . CanSeek )
220+ {
221+ second . Position = 0 ;
222+ }
223+
224+ var firstHash = SHA256 . HashData ( first ) ;
225+ var secondHash = SHA256 . HashData ( second ) ;
226+ return firstHash . AsSpan ( ) . SequenceEqual ( secondHash ) ;
227+ }
228+ finally
229+ {
230+ if ( first . CanSeek )
231+ {
232+ first . Position = firstPosition ;
233+ }
234+
235+ if ( second . CanSeek )
236+ {
237+ second . Position = secondPosition ;
238+ }
239+ }
240+ }
181241}
0 commit comments