feat(newsletter): Started to localize the newsletter (#4485)

* Abstract media servers content into interfaces

* Media server entities into abstract classes

* Abstract media server content repository

* First pass at newsletter refactoring

* Minor code clean up

* Attempt at abstracting repositories (WIP)

* Fixed cast issue

* Corrected the other properties

* A step towards newsletter refactoring

* Clean up leftovers

* Fix broken episodes db interaction

* Save absolute URL for Plex content

Let's be consistent with Emby and Jellyfin

* Fix broken integration with Plex libraries

* Fix error when multiple media servers configured

* Fix newsletter being sent if no movies or episodes

* Fix broken tests

* Remove unneccesary logs

* Allow for newsletter localization

* Generate file in English

* Fix unsubscribe text unlocalized by messy merge

* Fix indentation

Co-authored-by: tidusjar <tidusjar@gmail.com>
l10n_develop
sephrat 2 years ago committed by GitHub
parent 4f0bbfd451
commit b5ec556243
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -36,6 +36,7 @@
<ProjectReference Include="..\Ombi.Api.Trakt\Ombi.Api.Trakt.csproj" />
<ProjectReference Include="..\Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj" />
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
<ProjectReference Include="..\Ombi.I18n\Ombi.I18n.csproj" />
<ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" />
<ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" />
<ProjectReference Include="..\Ombi.Store\Ombi.Store.csproj" />

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AssemblyVersion>3.0.0.0</AssemblyVersion>
<FileVersion>3.0.0.0</FileVersion>
<Version></Version>
<PackageVersion></PackageVersion>
<LangVersion>8.0</LangVersion>
<Configurations>Debug;Release;NonUiBuild</Configurations>
</PropertyGroup>
<ItemGroup>
<Content Include="Resources\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\Texts.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Texts.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Update="Resources\Texts.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Texts.Designer.cs</LastGenOutput>
</Content>
</ItemGroup>
</Project>

@ -0,0 +1,144 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Ombi.I18n.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Texts {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Texts() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Ombi.I18n.Resources.Texts", typeof(Texts).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
public static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Type:.
/// </summary>
public static string AlbumTypeLabel {
get {
return ResourceManager.GetString("AlbumTypeLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Episodes:.
/// </summary>
public static string EpisodesLabel {
get {
return ResourceManager.GetString("EpisodesLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Genres:.
/// </summary>
public static string GenresLabel {
get {
return ResourceManager.GetString("GenresLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to New Albums.
/// </summary>
public static string NewAlbums {
get {
return ResourceManager.GetString("NewAlbums", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to New Movies.
/// </summary>
public static string NewMovies {
get {
return ResourceManager.GetString("NewMovies", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to New TV.
/// </summary>
public static string NewTV {
get {
return ResourceManager.GetString("NewTV", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Powered by.
/// </summary>
public static string PoweredBy {
get {
return ResourceManager.GetString("PoweredBy", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Season:.
/// </summary>
public static string SeasonLabel {
get {
return ResourceManager.GetString("SeasonLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unsubscribe.
/// </summary>
public static string Unsubscribe {
get {
return ResourceManager.GetString("Unsubscribe", resourceCulture);
}
}
}
}

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="NewAlbums" xml:space="preserve">
<value>Nouveaux Albums</value>
</data>
<data name="NewMovies" xml:space="preserve">
<value>Nouveaux Films</value>
</data>
<data name="NewTV" xml:space="preserve">
<value>Nouvelles séries</value>
</data>
<data name="GenresLabel" xml:space="preserve">
<value>Genres :</value>
</data>
<data name="AlbumTypeLabel" xml:space="preserve">
<value>Type :</value>
</data>
<data name="SeasonLabel" xml:space="preserve">
<value>Saison :</value>
</data>
<data name="EpisodesLabel" xml:space="preserve">
<value>Épisodes :</value>
</data>
<data name="PoweredBy" xml:space="preserve">
<value>Propulsé par</value>
</data>
<data name="Unsubscribe" xml:space="preserve">
<value>Se désinscrire</value>
</data>
</root>

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="NewAlbums" xml:space="preserve">
<value>New Albums</value>
</data>
<data name="NewMovies" xml:space="preserve">
<value>New Movies</value>
</data>
<data name="NewTV" xml:space="preserve">
<value>New TV</value>
</data>
<data name="GenresLabel" xml:space="preserve">
<value>Genres:</value>
</data>
<data name="AlbumTypeLabel" xml:space="preserve">
<value>Type:</value>
</data>
<data name="SeasonLabel" xml:space="preserve">
<value>Season:</value>
</data>
<data name="EpisodesLabel" xml:space="preserve">
<value>Episodes:</value>
</data>
<data name="PoweredBy" xml:space="preserve">
<value>Powered by</value>
</data>
<data name="Unsubscribe" xml:space="preserve">
<value>Unsubscribe</value>
</data>
</root>

@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Text;
using Ombi.I18n.Resources;
namespace Ombi.Notifications.Templates
{
@ -31,6 +32,7 @@ namespace Ombi.Notifications.Templates
private const string IntroText = "{@INTRO}";
private const string Unsubscribe = "{@UNSUBSCRIBE}";
private const string UnsubscribeText = "{@UNSUBSCRIBETEXT}";
private const string PoweredByText = "{@POWEREDBYTEXT}";
public string LoadTemplate(string subject, string intro, string tableHtml, string logo, string unsubscribeLink)
@ -42,7 +44,8 @@ namespace Ombi.Notifications.Templates
sb.Replace(DateKey, DateTime.Now.ToString("f"));
sb.Replace(Logo, string.IsNullOrEmpty(logo) ? OmbiLogo : logo);
sb.Replace(Unsubscribe, string.IsNullOrEmpty(unsubscribeLink) ? string.Empty : unsubscribeLink);
sb.Replace(UnsubscribeText, string.IsNullOrEmpty(unsubscribeLink) ? string.Empty : "Unsubscrible");
sb.Replace(UnsubscribeText, string.IsNullOrEmpty(unsubscribeLink) ? string.Empty : Texts.Unsubscribe);
sb.Replace(PoweredByText, Texts.PoweredBy);
return sb.ToString();
}

@ -17,6 +17,7 @@
<None Update="Templates\BasicTemplate.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<ProjectReference Include="..\Ombi.I18n\Ombi.I18n.csproj" />
</ItemGroup>
</Project>

@ -458,7 +458,7 @@
</tr>
<tr>
<td class="content-block powered-by" valign="top" align="center" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; color: #999999; font-size: 12px; text-align: center;">
Powered by <a href="https://github.com/Ombi-app/Ombi" style="font-weight: 400; font-size: 12px; text-align: center; text-decoration: none; color: #ff761b;">Ombi</a>
{@POWEREDBYTEXT} <a href="https://github.com/Ombi-app/Ombi" style="font-weight: 400; font-size: 12px; text-align: center; text-decoration: none; color: #ff761b;">Ombi</a>
</td>
</tr>
</tbody>

@ -16,6 +16,7 @@ using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
using Ombi.Hubs;
using Ombi.I18n.Resources;
using Ombi.Notifications;
using Ombi.Notifications.Models;
using Ombi.Notifications.Templates;
@ -440,7 +441,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (movies.Any() && !settings.DisableMovies)
{
sb.Append("<h1 style=\"text-align: center; max-width: 1042px;\">New Movies</h1><br /><br />");
sb.Append($"<h1 style=\"text-align: center; max-width: 1042px;\">{Texts.NewMovies}</h1><br /><br />");
sb.Append(
"<table class=\"movies-table\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">");
sb.Append("<tr>");
@ -457,7 +458,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (episodes.Any() && !settings.DisableTv)
{
sb.Append("<br /><br /><h1 style=\"text-align: center; max-width: 1042px;\">New TV</h1><br /><br />");
sb.Append($"<br /><br /><h1 style=\"text-align: center; max-width: 1042px;\">{Texts.NewTV}</h1><br /><br />");
sb.Append(
"<table class=\"tv-table\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">");
sb.Append("<tr>");
@ -475,7 +476,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (albums.Any() && !settings.DisableMusic)
{
sb.Append("<h1 style=\"text-align: center; max-width: 1042px;\">New Albums</h1><br /><br />");
sb.Append($"<h1 style=\"text-align: center; max-width: 1042px;\">{Texts.NewAlbums}</h1><br /><br />");
sb.Append(
"<table class=\"movies-table\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">");
sb.Append("<tr>");
@ -601,7 +602,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (info.Genres.Any())
{
AddGenres($"Genres: {string.Join(", ", info.Genres.Select(x => x.Name.ToString()).ToArray())}");
AddGenres($"{Texts.GenresLabel} {string.Join(", ", info.Genres.Select(x => x.Name.ToString()).ToArray())}");
}
}
@ -637,7 +638,7 @@ namespace Ombi.Schedule.Jobs.Ombi
}
AddParagraph(summary);
AddGenres($"Type: {info.albumType}");
AddGenres($"{Texts.AlbumTypeLabel} {info.albumType}");
}
private async Task ProcessTv(IEnumerable<IMediaServerEpisode> episodes, string languageCode)
@ -742,7 +743,7 @@ namespace Ombi.Schedule.Jobs.Ombi
var orderedEpisodes = epInformation.Episodes.OrderBy(x => x.EpisodeNumber).ToList();
var episodeString = StringHelper.BuildEpisodeList(orderedEpisodes.Select(x => x.EpisodeNumber));
var episodeAirDate = epInformation.EpisodeAirDate;
finalsb.Append($"Season: {epInformation.SeasonNumber} - Episodes: {episodeString} {episodeAirDate}");
finalsb.Append($"{Texts.SeasonLabel} {epInformation.SeasonNumber} - {Texts.EpisodesLabel} {episodeString} {episodeAirDate}");
finalsb.Append("<br />");
}
@ -794,7 +795,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (tvInfo.genres.Any())
{
AddGenres($"Genres: {string.Join(", ", tvInfo.genres.Select(x => x.name.ToString()).ToArray())}");
AddGenres($"{Texts.GenresLabel} {string.Join(", ", tvInfo.genres.Select(x => x.name.ToString()).ToArray())}");
}
}

@ -18,6 +18,7 @@
<ItemGroup>
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
<ProjectReference Include="..\Ombi.I18n\Ombi.I18n.csproj" />
<ProjectReference Include="..\Ombi.Store\Ombi.Store.csproj" />
</ItemGroup>

@ -1,7 +1,10 @@
namespace Ombi.Settings.Settings.Models
using Ombi.I18n.Resources;
using System.Globalization;
namespace Ombi.Settings.Settings.Models
{
public class OmbiSettings : Settings
{
private string defaultLanguageCode = "en";
public string BaseUrl { get; set; }
public bool CollectAnalyticData { get; set; }
public bool Wizard { get; set; }
@ -9,7 +12,14 @@
public bool DoNotSendNotificationsForAutoApprove { get; set; }
public bool HideRequestsUsers { get; set; }
public bool DisableHealthChecks { get; set; }
public string DefaultLanguageCode { get; set; } = "en";
public string DefaultLanguageCode
{
get => defaultLanguageCode;
set {
defaultLanguageCode = value;
Texts.Culture = new CultureInfo(value);
}
}
public bool AutoDeleteAvailableRequests { get; set; }
public int AutoDeleteAfterDays { get; set; }
public Branch Branch { get; set; }

Loading…
Cancel
Save