Skip to content

Commit 4331216

Browse files
committed
fix: avoid redundant speaker image saves
1 parent 9515a2b commit 4331216

2 files changed

Lines changed: 109 additions & 1 deletion

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System.IO;
2+
using System.Text;
3+
using SgfDevs.Dev.EventSync;
4+
using Xunit;
5+
6+
namespace SgfDevs.Tests;
7+
8+
public class SessionizeSpeakerMediaServiceTests
9+
{
10+
[Fact]
11+
public void StreamsHaveEqualContent_ReturnsTrueForIdenticalContent()
12+
{
13+
using var first = CreateStream("same image");
14+
using var second = CreateStream("same image");
15+
16+
var result = SessionizeSpeakerMediaService.StreamsHaveEqualContent(first, second);
17+
18+
Assert.True(result);
19+
}
20+
21+
[Fact]
22+
public void StreamsHaveEqualContent_ReturnsFalseForDifferentContent()
23+
{
24+
using var first = CreateStream("first image");
25+
using var second = CreateStream("second image");
26+
27+
var result = SessionizeSpeakerMediaService.StreamsHaveEqualContent(first, second);
28+
29+
Assert.False(result);
30+
}
31+
32+
[Fact]
33+
public void StreamsHaveEqualContent_RestoresFirstStreamPosition()
34+
{
35+
using var first = CreateStream("same image");
36+
using var second = CreateStream("same image");
37+
first.Position = 2;
38+
second.Position = 4;
39+
40+
var result = SessionizeSpeakerMediaService.StreamsHaveEqualContent(first, second);
41+
42+
Assert.True(result);
43+
Assert.Equal(2, first.Position);
44+
Assert.Equal(4, second.Position);
45+
}
46+
47+
private static MemoryStream CreateStream(string content) => new(Encoding.UTF8.GetBytes(content));
48+
}

SgfDevs/Dev/EventSync/SessionizeSpeakerMediaService.cs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO;
55
using System.Linq;
66
using System.Net.Http;
7+
using System.Security.Cryptography;
78
using System.Threading;
89
using System.Threading.Tasks;
910
using 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

Comments
 (0)