Skip to content

Commit

Permalink
add - doc - Implemented preferred cultures
Browse files Browse the repository at this point in the history
---

Just like how we've implemented preferred user language, we've also
implemented preferred cultures.

---

Type: add
Breaking: False
Doc Required: True
Backport Required: False
Part: 1/1
  • Loading branch information
AptiviCEO committed Dec 26, 2024
1 parent 8649938 commit d550354
Show file tree
Hide file tree
Showing 16 changed files with 218 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
changes!
-->
<NitrocidModAPIVersionMajor>3.0.27</NitrocidModAPIVersionMajor>
<NitrocidModAPIVersionChangeset>14</NitrocidModAPIVersionChangeset>
<NitrocidModAPIVersionChangeset>16</NitrocidModAPIVersionChangeset>

<!-- The above two properties are to be installed to the file version -->
<NitrocidModAPIVersion>$(NitrocidModAPIVersionMajor).$(NitrocidModAPIVersionChangeset)</NitrocidModAPIVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace Nitrocid.Tests.Security.Permissions
public class PermissionManagerTests
{

private static readonly UserInfo rootUser = new("root", Encryption.GetEncryptedString("", "SHA256"), [], "System account", "", [], UserFlags.Administrator, []);
private static readonly UserInfo rootUser = new("root", Encryption.GetEncryptedString("", "SHA256"), [], "System account", "", "", [], UserFlags.Administrator, []);

/// <summary>
/// Add necessary user for testing
Expand Down
2 changes: 2 additions & 0 deletions private/Nitrocid.Tests/Users/UserManagementTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ public void TestGetUser()
user.Groups.ShouldNotBeNull();
user.Groups.ShouldBeEmpty();
user.PreferredLanguage.ShouldBeNullOrEmpty();
user.PreferredCulture.ShouldBeNullOrEmpty();
user.Flags.HasFlag(UserFlags.Administrator).ShouldBeTrue();
user.Flags.HasFlag(UserFlags.Anonymous).ShouldBeFalse();
user.Flags.HasFlag(UserFlags.Disabled).ShouldBeFalse();
Expand Down Expand Up @@ -164,6 +165,7 @@ public void TestGetUserIndex()
user.Groups.ShouldNotBeNull();
user.Groups.ShouldBeEmpty();
user.PreferredLanguage.ShouldBeNullOrEmpty();
user.PreferredCulture.ShouldBeNullOrEmpty();
user.Flags.HasFlag(UserFlags.Administrator).ShouldBeTrue();
user.Flags.HasFlag(UserFlags.Anonymous).ShouldBeFalse();
user.Flags.HasFlag(UserFlags.Disabled).ShouldBeFalse();
Expand Down
2 changes: 1 addition & 1 deletion public/Nitrocid.Templates/templates/KSMod/ModName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class ModName : IMod
public string Name { get; set; } = "My Mod";
public string Version { get; set; } = "1.0.0";

public Version MinimumSupportedApiVersion => new(3, 0, 27, 14);
public Version MinimumSupportedApiVersion => new(3, 0, 27, 15);

public ReadOnlyDictionary<string, Delegate> PubliclyAvailableFunctions => null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ internal static class KernelExceptionMessages
{ KernelExceptionType.Alarm, Translate.DoTranslation("There was an error when trying to process an alarm system operation.") },
{ KernelExceptionType.Widget, Translate.DoTranslation("There was an error when trying to process a widget system operation. If you're sure that this widget is registered properly, please make sure that you've written the widget class name properly.") },
{ KernelExceptionType.Homepage, Translate.DoTranslation("The homepage tools has encountered an error when trying to process your request. Please make sure that you've entered all the necessary data correctly.") },
{ KernelExceptionType.NoSuchCulture, Translate.DoTranslation("There is no culture by this name.") },
};

internal static string GetFinalExceptionMessage(KernelExceptionType exceptionType, string message, Exception? e, params object[] vars)
Expand Down
4 changes: 4 additions & 0 deletions public/Nitrocid/Kernel/Exceptions/KernelExceptionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -500,5 +500,9 @@ public enum KernelExceptionType
/// The homepage tools has encountered an error when trying to process your request. Please make sure that you've entered all the necessary data correctly.
/// </summary>
Homepage,
/// <summary>
/// There is no culture by this name.
/// </summary>
NoSuchCulture,
}
}
3 changes: 2 additions & 1 deletion public/Nitrocid/Kernel/Starting/KernelInitializers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -575,10 +575,11 @@ internal static void ResetEverything()

try
{
// Reset languages
// Reset languages and cultures
SplashManager.BeginSplashOut(context);
LanguageManager.SetLangDry(Config.MainConfig.CurrentLanguage);
LanguageManager.currentUserLanguage = LanguageManager.Languages[Config.MainConfig.CurrentLanguage];
CultureManager.currentUserCulture = CultureManager.GetCulturesDictionary()[Config.MainConfig.CurrentCultureName];
SplashManager.EndSplashOut(context);
}
catch (Exception exc)
Expand Down
26 changes: 19 additions & 7 deletions public/Nitrocid/Languages/CultureManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using System.Linq;
using Nitrocid.Kernel.Configuration;
using Nitrocid.Kernel.Debugging;
using Nitrocid.Users.Login;

namespace Nitrocid.Languages
{
Expand All @@ -30,37 +31,41 @@ namespace Nitrocid.Languages
/// </summary>
public static class CultureManager
{
internal static CultureInfo currentCulture = GetCulturesDictionary()[Config.MainConfig.CurrentCultureName];
internal static CultureInfo currentUserCulture = GetCulturesDictionary()[Config.MainConfig.CurrentCultureName];

/// <summary>
/// Current culture
/// </summary>
public static CultureInfo CurrentCulture =>
new(Config.MainConfig.CurrentCultureName);
Login.LoggedIn ? currentUserCulture : currentCulture;

/// <summary>
/// Updates current culture based on current language and custom culture
/// Updates current culture based on selected culture
/// </summary>
/// <param name="culture">Full culture name</param>
/// <param name="culture">Full culture name or code</param>
public static void UpdateCultureDry(string culture)
{
var cultures = GetCultures();
foreach (CultureInfo cultureInfo in cultures)
{
if (cultureInfo.EnglishName == culture)
if (cultureInfo.EnglishName == culture || cultureInfo.Name == culture)
{
DebugWriter.WriteDebug(DebugLevel.I, "Found. Changing culture...");
Config.MainConfig.CurrentCultureName = cultureInfo.Name;
currentCulture = cultureInfo;
break;
}
}
}

/// <summary>
/// Updates current culture based on current language and custom culture
/// Updates current culture based on selected culture
/// </summary>
/// <param name="Culture">Full culture name</param>
/// <param name="Culture">Full culture name or code</param>
public static void UpdateCulture(string Culture)
{
UpdateCultureDry(Culture);
Config.MainConfig.CurrentCultureName = currentCulture.Name;
Config.CreateConfig();
DebugWriter.WriteDebug(DebugLevel.I, "Saved new culture.");
}
Expand Down Expand Up @@ -88,5 +93,12 @@ public static string[] GetCultureNames() =>
/// <returns>An array of culture codes</returns>
public static string[] GetCultureCodes() =>
GetCultures().Select((ci) => ci.Name).ToArray();

/// <summary>
/// Gets the culture dictionary
/// </summary>
/// <returns>An array of culture codes</returns>
public static Dictionary<string, CultureInfo> GetCulturesDictionary() =>
GetCultures().ToDictionary((ci) => ci.Name, (ci) => ci);
}
}
9 changes: 9 additions & 0 deletions public/Nitrocid/Shell/Shells/Admin/AdminShellInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@ internal class AdminShellInfo : BaseShellInfo, IShellInfo
new CommandArgumentPart(true, "lang/clear")
})
], new UserLangCommand()),

new CommandInfo("userculture", /* Localizable */ "Changes the preferred user culture",

Check warning on line 130 in public/Nitrocid/Shell/Shells/Admin/AdminShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

This string, "Changes the preferred user culture", is unlocalized

Check warning on line 130 in public/Nitrocid/Shell/Shells/Admin/AdminShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This string, "Changes the preferred user culture", is unlocalized

Check warning on line 130 in public/Nitrocid/Shell/Shells/Admin/AdminShellInfo.cs

View workflow job for this annotation

GitHub Actions / Make API Reference

This string, "Changes the preferred user culture", is unlocalized

Check warning on line 130 in public/Nitrocid/Shell/Shells/Admin/AdminShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This string, "Changes the preferred user culture", is unlocalized

Check warning on line 130 in public/Nitrocid/Shell/Shells/Admin/AdminShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

This string, "Changes the preferred user culture", is unlocalized

Check warning on line 130 in public/Nitrocid/Shell/Shells/Admin/AdminShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This string, "Changes the preferred user culture", is unlocalized

Check warning on line 130 in public/Nitrocid/Shell/Shells/Admin/AdminShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This string, "Changes the preferred user culture", is unlocalized
[
new CommandArgumentInfo(new[]
{
new CommandArgumentPart(true, "user"),
new CommandArgumentPart(true, "culture/clear")
})
], new UserCultureCommand()),
];

public override Dictionary<string, PromptPresetBase> ShellPresets => new()
Expand Down
74 changes: 74 additions & 0 deletions public/Nitrocid/Shell/Shells/Admin/Commands/UserCulture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// Nitrocid KS Copyright (C) 2018-2025 Aptivi
//
// This file is part of Nitrocid KS
//
// Nitrocid KS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Nitrocid KS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY, without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

using Terminaux.Writer.ConsoleWriters;
using Nitrocid.Kernel.Exceptions;
using Nitrocid.Languages;
using Nitrocid.Shell.ShellBase.Commands;
using Nitrocid.Users;
using System.Globalization;

namespace Nitrocid.Shell.Shells.Admin.Commands
{
class UserCultureCommand : BaseCommand, ICommand
{

public override int Execute(CommandParameters parameters, ref string variableValue)
{
string userName = parameters.ArgumentsList[0];
string culture = parameters.ArgumentsList[1];
int userIndex = UserManagement.GetUserIndex(userName);
if (culture == "clear")
{
// If we're doing this on ourselves, change the kernel culture to the system culture
culture = CultureManager.currentCulture.Name;
if (UserManagement.CurrentUser.Username == userName)
{
CultureManager.currentUserCulture = CultureManager.currentCulture;
UserManagement.CurrentUser.PreferredCulture = culture;
}

// Now, change the culture in the user config
UserManagement.Users[userIndex].PreferredCulture = null;
UserManagement.SaveUsers();
TextWriterColor.Write(Translate.DoTranslation("Preferred user culture set to {0}. You may want to log in again."), culture);
}
else if (CultureManager.GetCulturesDictionary().TryGetValue(culture, out CultureInfo? cultureInfo))
{
// Do it locally
if (UserManagement.CurrentUser.Username == userName)
{
CultureManager.currentUserCulture = cultureInfo;
UserManagement.CurrentUser.PreferredCulture = culture;
}

// Now, change the culture in the user config
UserManagement.Users[userIndex].PreferredCulture = culture;
UserManagement.SaveUsers();
TextWriterColor.Write(Translate.DoTranslation("Preferred user culture set to {0}. You may want to log in again."), culture);
}
else
{
TextWriterColor.Write(Translate.DoTranslation("Invalid culture") + " {0}", culture);
return KernelExceptionTools.GetErrorCode(KernelExceptionType.NoSuchCulture);
}
return 0;
}
}
}
2 changes: 2 additions & 0 deletions public/Nitrocid/Shell/Shells/Admin/Commands/UserInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public override int Execute(CommandParameters parameters, ref string variableVal
TextWriters.Write(user.FullName, true, KernelColorType.ListValue);
TextWriters.Write(Translate.DoTranslation("Preferred language") + ": ", false, KernelColorType.ListEntry);
TextWriters.Write(user.PreferredLanguage ?? "", true, KernelColorType.ListValue);
TextWriters.Write(Translate.DoTranslation("Preferred culture") + ": ", false, KernelColorType.ListEntry);
TextWriters.Write(user.PreferredCulture ?? "", true, KernelColorType.ListValue);
TextWriters.Write(Translate.DoTranslation("Flags") + ": ", false, KernelColorType.ListEntry);
TextWriters.Write(string.Join(", ", user.Flags), true, KernelColorType.ListValue);
TextWriterRaw.Write();
Expand Down
71 changes: 71 additions & 0 deletions public/Nitrocid/Shell/Shells/UESH/Commands/ChCulture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// Nitrocid KS Copyright (C) 2018-2025 Aptivi
//
// This file is part of Nitrocid KS
//
// Nitrocid KS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Nitrocid KS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY, without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

using Nitrocid.ConsoleBase.Colors;
using Nitrocid.ConsoleBase.Writers;
using Terminaux.Writer.ConsoleWriters;
using Nitrocid.Kernel.Exceptions;
using Nitrocid.Shell.ShellBase.Commands;
using Nitrocid.Shell.ShellBase.Switches;
using Nitrocid.Users;
using Terminaux.Inputs.Styles.Choice;
using System.Linq;
using Terminaux.Inputs.Styles;
using Nitrocid.Languages;

namespace Nitrocid.Shell.Shells.UESH.Commands
{
/// <summary>
/// Changes your kernel culture
/// </summary>
/// <remarks>
/// If you want to change your kernel culture without having to go to Settings (for scripting purposes), you can use this command.
/// <br></br>
/// The user must have at least the administrative privileges before they can run the command.
/// </remarks>
class ChCultureCommand : BaseCommand, ICommand
{

public override int Execute(CommandParameters parameters, ref string variableValue)
{
bool useUser = SwitchManager.ContainsSwitch(parameters.SwitchesList, "-user");

// Culture selection takes only one culture
string culture = parameters.ArgumentsList[0];
var cultures = CultureManager.GetCultureCodes();
if (!cultures.Contains(culture))
{
TextWriters.Write(Translate.DoTranslation("Invalid culture") + $" {culture}", true, KernelColorType.Error);
return KernelExceptionTools.GetErrorCode(KernelExceptionType.NoSuchLanguage);
}

// Change the culture
if (useUser)
{
UserManagement.CurrentUser.PreferredCulture = culture;
UserManagement.SaveUsers();
}
else
CultureManager.UpdateCulture(culture);
TextWriterColor.Write(Translate.DoTranslation("You may need to log out and log back in for changes to take effect."));
return 0;
}

}
}
14 changes: 14 additions & 0 deletions public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,20 @@ internal class UESHShellInfo : BaseShellInfo, IShellInfo
})
], new ChAttrCommand()),

new CommandInfo("chculture", /* Localizable */ "Changes culture",

Check warning on line 194 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

This string, "Changes culture", is unlocalized

Check warning on line 194 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This string, "Changes culture", is unlocalized

Check warning on line 194 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / Make API Reference

This string, "Changes culture", is unlocalized

Check warning on line 194 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This string, "Changes culture", is unlocalized

Check warning on line 194 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

This string, "Changes culture", is unlocalized

Check warning on line 194 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This string, "Changes culture", is unlocalized

Check warning on line 194 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This string, "Changes culture", is unlocalized
[
new CommandArgumentInfo(
[
new CommandArgumentPart(true, "culture"),
],
[
new SwitchInfo("user", /* Localizable */ "Changes the user culture instead of the system culture", new SwitchOptions()

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / Make API Reference

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / Make API Reference

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (macos-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized

Check warning on line 201 in public/Nitrocid/Shell/Shells/UESH/UESHShellInfo.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This string, "Changes the user culture instead of the system culture", is unlocalized
{
AcceptsValues = false
}),
])
], new ChCultureCommand(), CommandFlags.Strict),

new CommandInfo("chdir", /* Localizable */ "Changes directory",
[
new CommandArgumentInfo(new[]
Expand Down
8 changes: 8 additions & 0 deletions public/Nitrocid/Users/Login/Login.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ internal static void SignIn(string signedInUser)
else
LanguageManager.currentUserLanguage = LanguageManager.currentLanguage;

// Set preferred culture
string preferredCulture = UserManagement.CurrentUser.PreferredCulture ?? "";
DebugWriter.WriteDebug(DebugLevel.I, "Preferred culture {0}. Trying to set dryly...", preferredCulture);
if (!string.IsNullOrWhiteSpace(preferredCulture))
CultureManager.currentUserCulture = CultureManager.GetCulturesDictionary()[preferredCulture];
else
CultureManager.currentUserCulture = CultureManager.currentCulture;

// Fire event PostLogin
EventsManager.FireEvent(EventType.PostLogin, UserManagement.CurrentUser.Username);
DebugWriter.WriteDebug(DebugLevel.I, "Out of login flow.");
Expand Down
7 changes: 6 additions & 1 deletion public/Nitrocid/Users/UserInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ public class UserInfo
/// The preferred language
/// </summary>
public string? PreferredLanguage { get; set; }
/// <summary>
/// The preferred culture
/// </summary>
public string? PreferredCulture { get; set; }
[JsonProperty]
internal string[] Groups { get; set; }
[JsonProperty]
Expand All @@ -55,13 +59,14 @@ public class UserInfo
/// Makes a new class instance of current user info
/// </summary>
[JsonConstructor]
internal UserInfo(string username, string password, string[] permissions, string fullName, string preferredLanguage, string[] groups, UserFlags flags, Dictionary<string, object[]> customSettings)
internal UserInfo(string username, string password, string[] permissions, string fullName, string preferredLanguage, string preferredCulture, string[] groups, UserFlags flags, Dictionary<string, object[]> customSettings)
{
Username = username;
Password = password;
Permissions = permissions;
FullName = fullName;
PreferredLanguage = preferredLanguage;
PreferredCulture = preferredCulture;
Groups = groups;
Flags = flags;
CustomSettings = customSettings;
Expand Down
Loading

0 comments on commit d550354

Please sign in to comment.