Skip to content

Commit

Permalink
Merge branch 'main' of github.com:notifo-io/notifo
Browse files Browse the repository at this point in the history
# Conflicts:
#	backend/src/Notifo.Domain/Channels/Email/Formatting/MjmlRenderer.cs
#	backend/src/Notifo.Domain/Notifo.Domain.csproj
  • Loading branch information
SebastianStehle committed Sep 4, 2023
2 parents 192809f + 6d8398e commit 7378bc3
Show file tree
Hide file tree
Showing 24 changed files with 498 additions and 316 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.62">
<PackageReference Include="Meziantou.Analyzer" Version="2.0.83">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,31 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.7.100.147" />
<PackageReference Include="Confluent.Kafka" Version="2.1.1" />
<PackageReference Include="FirebaseAdmin" Version="2.3.0" />
<PackageReference Include="FluentValidation" Version="11.5.2" />
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.7.200.32" />
<PackageReference Include="Confluent.Kafka" Version="2.2.0" />
<PackageReference Include="FirebaseAdmin" Version="2.4.0" />
<PackageReference Include="FluentValidation" Version="11.7.1" />
<PackageReference Include="Fluid.Core" Version="2.4.0" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.48" />
<PackageReference Include="libphonenumber-csharp" Version="8.13.14" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.52" />
<PackageReference Include="libphonenumber-csharp" Version="8.13.19" />
<PackageReference Include="Mailjet.Api" Version="3.0.0" />
<PackageReference Include="MailKit" Version="4.1.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.62">
<PackageReference Include="MailKit" Version="4.2.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.83">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.1" />
<PackageReference Include="MongoDB.Driver" Version="2.20.0" />
<PackageReference Include="MongoDB.Driver" Version="2.21.0" />
<PackageReference Include="NodaTime" Version="3.1.9" />
<PackageReference Include="OpenNotifications" Version="0.3.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="System.Collections" Version="4.3.0" />
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="Telegram.Bot" Version="19.0.0" />
<PackageReference Include="Twilio" Version="6.9.0" />
<PackageReference Include="Twilio" Version="6.11.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ private static string BuildErrorMessage(IEnumerable<EmailFormattingError> errors
foreach (var error in errors)
{
sb.Append(" * ");
sb.Append("Line: ");
sb.Append(error.Error.Line);
sb.Append("Position: ");
sb.Append(error.Error.LineNumber);
sb.Append(", ");
sb.Append(error.Error.LinePosition);
sb.Append(", ");
sb.Append("Template: ");
sb.Append(error.Template);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal static class MjmlRenderer

private static readonly MjmlOptions OptionsStrict = new MjmlOptions
{
ValidatorFactory = StrictValidatorFactory.Instance,
Validator = StrictValidator.Instance,
};

private static readonly IMjmlRenderer Renderer = new Mjml.Net.MjmlRenderer();
Expand All @@ -42,11 +42,18 @@ public static (string? Html, List<TemplateError>? Errors) Render(string? mjml, b
{
try
{
var options = strict ? OptionsStrict : OptionsOptimized;
var options =
strict ?
OptionsStrict :
OptionsOptimized;

(rendered, var mjmlErrors) = Renderer.Render(mjml, options);

errors = mjmlErrors?.Select(x => new TemplateError(x.Error, x.Line ?? -1, x.Column ?? -1)).ToList();
errors = mjmlErrors?.Select(x => new TemplateError(
x.Error,
x.Position.LineNumber,
x.Position.LinePosition)
).ToList();
}
catch (Exception ex)
{
Expand Down
12 changes: 9 additions & 3 deletions backend/src/Notifo.Domain/Log/Internal/LogCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,18 @@ private async Task StoreAsync(
return;
}

commands = updateQueue.Select(x => (x.Key, x.Value, now)).ToList();
commands = new List<(LogWrite, int, Instant)>();

// Use a normal loop to avoid the allocations of the closure.
foreach (var (key, value) in updateQueue)
{
commands.Add((key, value, now));
}

updateQueue.Clear();
}
finally
{
updateQueue.Clear();

readerWriterLock.ExitWriteLock();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public async Task EnhanceAsync(MetadataRequest request)
{
await using (var tempStream = tempFile.OpenWrite())
{
await assetThumbnailGenerator.FixOrientationAsync(uploadStream, mimeType, tempStream);
await assetThumbnailGenerator.FixAsync(uploadStream, mimeType, tempStream);
}
}

Expand Down
10 changes: 5 additions & 5 deletions backend/src/Notifo.Domain/Notifo.Domain.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentValidation" Version="11.5.2" />
<PackageReference Include="FluentValidation" Version="11.7.1" />
<PackageReference Include="Fluid.Core" Version="2.4.0" />
<PackageReference Include="Jint" Version="3.0.0-beta-2037" />
<PackageReference Include="libphonenumber-csharp" Version="8.13.14" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.62">
<PackageReference Include="libphonenumber-csharp" Version="8.13.19" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.83">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.1" />
<PackageReference Include="Mjml.Net" Version="2.0.0" />
<PackageReference Include="MongoDB.Driver" Version="2.20.0" />
<PackageReference Include="Mjml.Net" Version="3.0.0" />
<PackageReference Include="MongoDB.Driver" Version="2.21.0" />
<PackageReference Include="NodaTime" Version="3.1.9" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="System.Collections" Version="4.3.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,7 @@ public async Task BatchWriteAsync(List<((string AppId, string UserId) Key, Count
updates.Add(Update.Inc($"d.Counters.{key}", value));
}

var model = new UpdateOneModel<MongoDbUser>(Filter.Eq(x => x.DocId, docId), Update.Combine(updates))
{
IsUpsert = true
};
var model = new UpdateOneModel<MongoDbUser>(Filter.Eq(x => x.DocId, docId), Update.Combine(updates));

writes.Add(model);
}
Expand Down
2 changes: 1 addition & 1 deletion backend/src/Notifo.Domain/Utils/TemplateError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

namespace Notifo.Domain.Utils;

public sealed record TemplateError(string Message, int Line = -1, int Column = -1, Exception? Exception = null);
public sealed record TemplateError(string Message, int LineNumber = -1, int LinePosition = -1, Exception? Exception = null);
8 changes: 4 additions & 4 deletions backend/src/Notifo.Identity/Notifo.Identity.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AspNet.Security.OAuth.GitHub" Version="7.0.2" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.62">
<PackageReference Include="AspNet.Security.OAuth.GitHub" Version="7.0.4" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.83">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="7.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="7.0.10" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.1" />
<PackageReference Include="OpenIddict.AspNetCore" Version="4.5.0" />
<PackageReference Include="OpenIddict.AspNetCore" Version="4.7.0" />
<PackageReference Include="Squidex.OpenIddict.MongoDb" Version="4.0.1-dev" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
Expand Down
38 changes: 19 additions & 19 deletions backend/src/Notifo.Infrastructure/Notifo.Infrastructure.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentValidation" Version="11.5.2" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.62">
<PackageReference Include="FluentValidation" Version="11.7.1" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.83">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand All @@ -20,29 +20,29 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.8" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.10" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="7.0.0" />
<PackageReference Include="MongoDB.Driver" Version="2.20.0" />
<PackageReference Include="MongoDB.Driver" Version="2.21.0" />
<PackageReference Include="MongoDB.Driver.Core.Extensions.OpenTelemetry" Version="1.0.0" />
<PackageReference Include="NodaTime" Version="3.1.9" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.0.0" />
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.1.2" />
<PackageReference Include="OpenTelemetry" Version="1.5.1" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.Assets" Version="5.9.0" />
<PackageReference Include="Squidex.Assets.Azure" Version="5.9.0" />
<PackageReference Include="Squidex.Assets.FTP" Version="5.9.0" />
<PackageReference Include="Squidex.Assets.GoogleCloud" Version="5.9.0" />
<PackageReference Include="Squidex.Assets.ImageMagick" Version="5.9.0" />
<PackageReference Include="Squidex.Assets.ImageSharp" Version="5.9.0" />
<PackageReference Include="Squidex.Assets.Mongo" Version="5.9.0" />
<PackageReference Include="Squidex.Assets.S3" Version="5.9.0" />
<PackageReference Include="Squidex.Caching" Version="5.9.0" />
<PackageReference Include="Squidex.Hosting" Version="5.9.0" />
<PackageReference Include="Squidex.Hosting.Abstractions" Version="5.9.0" />
<PackageReference Include="Squidex.Log" Version="5.9.0" />
<PackageReference Include="Squidex.Messaging" Version="5.9.0" />
<PackageReference Include="Squidex.Text" Version="5.9.0" />
<PackageReference Include="Squidex.Assets" Version="5.18.0" />
<PackageReference Include="Squidex.Assets.Azure" Version="5.18.0" />
<PackageReference Include="Squidex.Assets.FTP" Version="5.18.0" />
<PackageReference Include="Squidex.Assets.GoogleCloud" Version="5.18.0" />
<PackageReference Include="Squidex.Assets.ImageMagick" Version="5.18.0" />
<PackageReference Include="Squidex.Assets.ImageSharp" Version="5.18.0" />
<PackageReference Include="Squidex.Assets.Mongo" Version="5.18.0" />
<PackageReference Include="Squidex.Assets.S3" Version="5.18.0" />
<PackageReference Include="Squidex.Caching" Version="5.18.0" />
<PackageReference Include="Squidex.Hosting" Version="5.18.0" />
<PackageReference Include="Squidex.Hosting.Abstractions" Version="5.18.0" />
<PackageReference Include="Squidex.Log" Version="5.18.0" />
<PackageReference Include="Squidex.Messaging" Version="5.18.0" />
<PackageReference Include="Squidex.Text" Version="5.18.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="7.0.0" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,78 +6,98 @@
// ==========================================================================

using System.Reflection;
using System.Reflection.Emit;

namespace Notifo.Infrastructure.Reflection.Internal;

public sealed class PropertyAccessor
public static class PropertyAccessor
{
private interface IPropertyAccessor
{
object? Get(object target);
public delegate TValue Getter<TSource, TValue>(TSource source);

void Set(object target, object? value);
}
public delegate void Setter<TSource, TValue>(TSource source, TValue value);

private sealed class PropertyWrapper<TObject, TValue> : IPropertyAccessor
public static Getter<TSource, TValue> CreateGetter<TSource, TValue>(PropertyInfo propertyInfo)
{
private readonly Func<TObject, TValue> getMethod;
private readonly Action<TObject, TValue> setMethod;

public PropertyWrapper(PropertyInfo propertyInfo)
if (!propertyInfo.CanRead)
{
if (propertyInfo.CanRead)
{
getMethod = (Func<TObject, TValue>)propertyInfo.GetGetMethod(true)!.CreateDelegate(typeof(Func<TObject, TValue>));
}
else
{
getMethod = x => throw new NotSupportedException();
}

if (propertyInfo.CanWrite)
{
setMethod = (Action<TObject, TValue>)propertyInfo.GetSetMethod(true)!.CreateDelegate(typeof(Action<TObject, TValue>));
}
else
{
setMethod = (x, y) => throw new NotSupportedException();
}
return x => throw new NotSupportedException();
}

public object? Get(object source)
var bakingField =
propertyInfo.DeclaringType!.GetField($"<{propertyInfo.Name}>k__BackingField",
BindingFlags.NonPublic |
BindingFlags.Instance);

var propertyGetMethod = propertyInfo.GetGetMethod()!;

var getMethod = new DynamicMethod(propertyGetMethod.Name, typeof(TValue), new[] { typeof(TSource) }, true);
var getGenerator = getMethod.GetILGenerator();

// Load this to stack.
getGenerator.Emit(OpCodes.Ldarg_0);

if (bakingField != null && !propertyGetMethod.IsVirtual)
{
return getMethod((TObject)source);
// Get field directly.
getGenerator.Emit(OpCodes.Ldfld, bakingField);
}

public void Set(object source, object? value)
else if (propertyGetMethod.IsVirtual)
{
setMethod((TObject)source, (TValue)value!);
// Call the virtual property.
getGenerator.Emit(OpCodes.Callvirt, propertyGetMethod);
}
else
{
// Call the non virtual property.
getGenerator.Emit(OpCodes.Call, propertyGetMethod);
}
}

private readonly IPropertyAccessor internalAccessor;
getGenerator.Emit(OpCodes.Ret);

public PropertyAccessor(Type targetType, PropertyInfo propertyInfo)
return getMethod.CreateDelegate<Getter<TSource, TValue>>();
}

public static Setter<TSource, TValue> CreateSetter<TSource, TValue>(PropertyInfo propertyInfo)
{
Guard.NotNull(targetType);
Guard.NotNull(propertyInfo);
if (!propertyInfo.CanWrite)
{
return (x, y) => throw new NotSupportedException();
}

var type = typeof(PropertyWrapper<,>).MakeGenericType(propertyInfo.DeclaringType!, propertyInfo.PropertyType);
var bakingField =
propertyInfo.DeclaringType!.GetField($"<{propertyInfo.Name}>k__BackingField",
BindingFlags.NonPublic |
BindingFlags.Instance);

internalAccessor = (IPropertyAccessor)Activator.CreateInstance(type, propertyInfo)!;
}
var propertySetMethod = propertyInfo.GetSetMethod()!;

public object? Get(object target)
{
Guard.NotNull(target);
var setMethod = new DynamicMethod(propertySetMethod.Name, null, new[] { typeof(TSource), typeof(TValue) }, true);
var setGenerator = setMethod.GetILGenerator();

return internalAccessor.Get(target);
}
// Load this to stack.
setGenerator.Emit(OpCodes.Ldarg_0);

public void Set(object target, object? value)
{
Guard.NotNull(target);
// Load argument to stack.
setGenerator.Emit(OpCodes.Ldarg_1);

if (bakingField != null && !propertySetMethod.IsVirtual)
{
// Set the baking field directly.
setGenerator.Emit(OpCodes.Stfld, bakingField);
}
else if (propertySetMethod.IsVirtual)
{
// Call the virtual property.
setGenerator.Emit(OpCodes.Callvirt, propertySetMethod);
}
else
{
// Call the non virtual property.
setGenerator.Emit(OpCodes.Call, propertySetMethod);
}

setGenerator.Emit(OpCodes.Ret);

internalAccessor.Set(target, value);
return setMethod.CreateDelegate<Setter<TSource, TValue>>();
}
}
Loading

0 comments on commit 7378bc3

Please sign in to comment.