Skip to content

Commit

Permalink
add basic serverside localisation
Browse files Browse the repository at this point in the history
  • Loading branch information
Apfelwurm committed Jan 11, 2023
1 parent 76e7026 commit cd29af7
Show file tree
Hide file tree
Showing 9 changed files with 773 additions and 321 deletions.
49 changes: 49 additions & 0 deletions NetEvent/Server/Extensions/DefaultCultureExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NetEvent.Server.Data;
using NetEvent.Server.Models;
using NetEvent.Shared;
using NetEvent.Shared.Config;

namespace NetEvent.Server.Extensions;

public static class DefaultCultureExtension
{
public static Task SetDefaultCulture(this WebApplication app)
{
var logger = app.Services.GetRequiredService<ILogger<WebApplication>>();

try
{
using (var scope = app.Services.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
using (var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>())
{
var organizationCulture = context.Set<SystemSettingValue>().Select(x => DtoMapper.Mapper.SystemSettingValueToSystemSettingValueDto(x)).ToList().Find(x => x.Key.Equals(SystemSettings.DataCultureInfo));

if (organizationCulture == null)
{
return Task.CompletedTask;
}

var culture = organizationCulture.Value;

var cultureInfo = new CultureInfo(culture);
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
}
}
}
catch (Exception ex)
{
logger.LogError(ex, "Unable to get Culture");
}

return Task.CompletedTask;
}
}
6 changes: 6 additions & 0 deletions NetEvent/Server/Localize.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace NetEvent.Server
{
public class Localize
{
}
}
153 changes: 82 additions & 71 deletions NetEvent/Server/Modules/System/Endpoints/GetSystemInfo.cs
Original file line number Diff line number Diff line change
@@ -1,71 +1,82 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using NetEvent.Shared.Dto;

namespace NetEvent.Server.Modules.System.Endpoints
{
public static class GetSystemInfo
{
public sealed class Handler : IRequestHandler<Request, Response>
{
public Handler()
{
}

public Task<Response> Handle(Request request, CancellationToken cancellationToken)
{
var systeminfocomponents = new List<SystemInfoComponentEntryDto>();
var systeminfohealth = new List<SystemInfoHealthEntryDto>();
var systeminfoversions = new List<SystemInfoVersionEntryDto>();

AppDomain currentDomain = AppDomain.CurrentDomain;
Assembly[] assems = currentDomain.GetAssemblies();
foreach (Assembly assem in assems)
{
systeminfocomponents.Add(new SystemInfoComponentEntryDto(assem.ManifestModule.Name, assem.ToString()));
}

systeminfoversions.Add(new SystemInfoVersionEntryDto("NETEVENT", Assembly.GetEntryAssembly()?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion));
systeminfoversions.Add(CreateSystemInfoVersionEntryFromEnv("BUILDNODE"));
systeminfoversions.Add(CreateSystemInfoVersionEntryFromEnv("BUILDID"));
systeminfoversions.Add(CreateSystemInfoVersionEntryFromEnv("BUILDNUMBER"));
systeminfoversions.Add(CreateSystemInfoVersionEntryFromEnv("SOURCE_COMMIT"));

// TODO: think about healthchecks and healthcheck modularity (to perform checks on various services like game servers, the mail server, payment apis ...) and remove dummy services
systeminfohealth.Add(new SystemInfoHealthEntryDto("NETEVENT Server", string.Empty, true));
systeminfohealth.Add(new SystemInfoHealthEntryDto("Email Service", "servername", false));

var systeminfo = new SystemInfoDto(systeminfocomponents, systeminfohealth, systeminfoversions);

return Task.FromResult(new Response(systeminfo));
}

private static SystemInfoVersionEntryDto CreateSystemInfoVersionEntryFromEnv(string envName)
{
return new SystemInfoVersionEntryDto(envName, string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName)) ? "dev" : Environment.GetEnvironmentVariable(envName));
}
}

public sealed class Request : IRequest<Response>
{
public Request()
{
}
}

public sealed class Response : ResponseBase<SystemInfoDto>
{
public Response(SystemInfoDto value) : base(value)
{
}

public Response(ReturnType returnType, string error) : base(returnType, error)
{
}
}
}
}
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using NetEvent.Shared.Dto;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using NetEvent.Server;

namespace NetEvent.Server.Modules.System.Endpoints
{
public static class GetSystemInfo
{
public sealed class Handler : IRequestHandler<Request, Response>
{
// TODO: remove localizer as soon as it is implemented somewhere where it makes sense
private IStringLocalizer<Localize> _Localizer { get; set; }

// TODO: remove localizer as soon as it is implemented somewhere where it makes sense
public Handler(IStringLocalizer<Localize> localizer)
{
_Localizer = localizer;
}

public Task<Response> Handle(Request request, CancellationToken cancellationToken)
{
var systeminfocomponents = new List<SystemInfoComponentEntryDto>();
var systeminfohealth = new List<SystemInfoHealthEntryDto>();
var systeminfoversions = new List<SystemInfoVersionEntryDto>();

AppDomain currentDomain = AppDomain.CurrentDomain;
Assembly[] assems = currentDomain.GetAssemblies();
foreach (Assembly assem in assems)
{
systeminfocomponents.Add(new SystemInfoComponentEntryDto(assem.ManifestModule.Name, assem.ToString()));
}

systeminfoversions.Add(new SystemInfoVersionEntryDto("NETEVENT", Assembly.GetEntryAssembly()?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion));
systeminfoversions.Add(CreateSystemInfoVersionEntryFromEnv("BUILDNODE"));
systeminfoversions.Add(CreateSystemInfoVersionEntryFromEnv("BUILDID"));
systeminfoversions.Add(CreateSystemInfoVersionEntryFromEnv("BUILDNUMBER"));
systeminfoversions.Add(CreateSystemInfoVersionEntryFromEnv("SOURCE_COMMIT"));

// TODO: think about healthchecks and healthcheck modularity (to perform checks on various services like game servers, the mail server, payment apis ...) and remove dummy services
systeminfohealth.Add(new SystemInfoHealthEntryDto("NETEVENT Server", string.Empty, true));
systeminfohealth.Add(new SystemInfoHealthEntryDto("Email Service", "servername", false));

var systeminfo = new SystemInfoDto(systeminfocomponents, systeminfohealth, systeminfoversions);

// TODO: remove localizer as soon as it is implemented somewhere where it makes sense
Console.WriteLine(_Localizer["test.test"]);

return Task.FromResult(new Response(systeminfo));
}

private static SystemInfoVersionEntryDto CreateSystemInfoVersionEntryFromEnv(string envName)
{
return new SystemInfoVersionEntryDto(envName, string.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName)) ? "dev" : Environment.GetEnvironmentVariable(envName));
}
}

public sealed class Request : IRequest<Response>
{
public Request()
{
}
}

public sealed class Response : ResponseBase<SystemInfoDto>
{
public Response(SystemInfoDto value) : base(value)
{
}

public Response(ReturnType returnType, string error) : base(returnType, error)
{
}
}
}
}
151 changes: 80 additions & 71 deletions NetEvent/Server/Modules/System/Endpoints/PostSystemSetting.cs
Original file line number Diff line number Diff line change
@@ -1,71 +1,80 @@
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using NetEvent.Server.Data;
using NetEvent.Server.Models;
using NetEvent.Shared;
using NetEvent.Shared.Config;
using NetEvent.Shared.Dto;

namespace NetEvent.Server.Modules.System.Endpoints
{
public static class PostSystemSetting
{
public sealed class Handler : IRequestHandler<Request, Response>
{
private readonly ApplicationDbContext _ApplicationDbContext;

public Handler(ApplicationDbContext applicationDbContext)
{
_ApplicationDbContext = applicationDbContext;
}

public async Task<Response> Handle(Request request, CancellationToken cancellationToken)
{
if (request.SystemSettingValue?.Key == null)
{
return new Response(ReturnType.Error, "Empty key is not allowed");
}

var data = await _ApplicationDbContext.FindAsync<SystemSettingValue>(new object[] { request.SystemSettingValue.Key }, cancellationToken);
if (data != null)
{
data.SerializedValue = request.SystemSettingValue.Value;
}
else
{
var serverData = request.SystemSettingValue.ToSystemSettingValue();
await _ApplicationDbContext.AddAsync(serverData, cancellationToken);
}

await _ApplicationDbContext.SaveChangesAsync(cancellationToken);

return new Response();
}
}

public sealed class Request : IRequest<Response>
{
public Request(SystemSettingGroup systemSettingGroup, SystemSettingValueDto systemSettingValue)
{
SystemSettingGroup = systemSettingGroup;
SystemSettingValue = systemSettingValue;
}

public SystemSettingGroup SystemSettingGroup { get; }

public SystemSettingValueDto SystemSettingValue { get; }
}

public sealed class Response : ResponseBase
{
public Response()
{
}

public Response(ReturnType returnType, string error) : base(returnType, error)
{
}
}
}
}
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using NetEvent.Server.Data;
using NetEvent.Server.Models;
using NetEvent.Shared;
using NetEvent.Shared.Config;
using NetEvent.Shared.Dto;
using System.Globalization;

namespace NetEvent.Server.Modules.System.Endpoints
{
public static class PostSystemSetting
{
public sealed class Handler : IRequestHandler<Request, Response>
{
private readonly ApplicationDbContext _ApplicationDbContext;

public Handler(ApplicationDbContext applicationDbContext)
{
_ApplicationDbContext = applicationDbContext;
}

public async Task<Response> Handle(Request request, CancellationToken cancellationToken)
{
if (request.SystemSettingValue?.Key == null)
{
return new Response(ReturnType.Error, "Empty key is not allowed");
}

var data = await _ApplicationDbContext.FindAsync<SystemSettingValue>(new object[] { request.SystemSettingValue.Key }, cancellationToken);
if (data != null)
{
data.SerializedValue = request.SystemSettingValue.Value;
}
else
{
var serverData = request.SystemSettingValue.ToSystemSettingValue();
await _ApplicationDbContext.AddAsync(serverData, cancellationToken);
}

await _ApplicationDbContext.SaveChangesAsync(cancellationToken);

// TODO: move special serverside handling to service
if (request.SystemSettingValue?.Key == SystemSettings.OrganizationData.DataCultureInfo)
{
var cultureInfo = new CultureInfo(request.SystemSettingValue.Value);
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
}

return new Response();
}
}

public sealed class Request : IRequest<Response>
{
public Request(SystemSettingGroup systemSettingGroup, SystemSettingValueDto systemSettingValue)
{
SystemSettingGroup = systemSettingGroup;
SystemSettingValue = systemSettingValue;
}

public SystemSettingGroup SystemSettingGroup { get; }

public SystemSettingValueDto SystemSettingValue { get; }
}

public sealed class Response : ResponseBase
{
public Response()
{
}

public Response(ReturnType returnType, string error) : base(returnType, error)
{
}
}
}
}
6 changes: 6 additions & 0 deletions NetEvent/Server/NetEvent.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,10 @@
<Folder Include="Migrations\" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Resources\Localize.resx">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>

</Project>
Loading

0 comments on commit cd29af7

Please sign in to comment.