Skip to content
This repository was archived by the owner on Sep 11, 2023. It is now read-only.

Translations rework #118

Merged
merged 10 commits into from
Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Deploy/Compress_Beta.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ LiteralPath=
"sourcepawn/",
"lysis/",
"SPCode.exe",
"lang_0_spcode.xml",
"GPLv3.txt",
"License.txt"
DestinationPath = "SPCode.Beta.Portable.zip"
Expand Down
1 change: 0 additions & 1 deletion Deploy/Compress_Stable.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ LiteralPath=
"sourcepawn/",
"lysis/",
"SPCode.exe",
"lang_0_spcode.xml",
"GPLv3.txt",
"License.txt"
DestinationPath = "SPCode.Portable.zip"
Expand Down
1 change: 0 additions & 1 deletion Deploy/SPCode_Beta.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ SetOutPath $INSTDIR

File SPCode.exe

File lang_0_spcode.xml
File License.txt
File GPLv3.txt

Expand Down
1 change: 0 additions & 1 deletion Deploy/SPCode_Stable.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ SetOutPath $INSTDIR

File SPCode.exe

File lang_0_spcode.xml
File License.txt
File GPLv3.txt

Expand Down
1 change: 0 additions & 1 deletion Deploy/SpcodeUpdater/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
Expand Down
1 change: 0 additions & 1 deletion Interop/HotkeyControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using SPCode.Utils;
Expand Down
11 changes: 9 additions & 2 deletions Interop/OptionsControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace SPCode
[Serializable]
public class OptionsControl
{
public static int SVersion = 14;
public static int SVersion = 15;
public bool Editor_AgressiveIndentation = true;
public bool Editor_AutoCloseBrackets = true;
public bool Editor_AutoCloseStringChars = true;
Expand Down Expand Up @@ -87,6 +87,9 @@ public class OptionsControl
// Version 14
public ActionOnClose ActionOnClose;

// Version 15
public int TranslationsVersion;

public int Version = 11;

public void FillNullToDefaults()
Expand Down Expand Up @@ -174,9 +177,13 @@ public void FillNullToDefaults()
SearchOptions.MultilineRegex = false;
SearchOptions.ReplaceType = 0;
}
if (Version < 14)
{
TranslationsVersion = 0;
}

//new Optionsversion - reset new fields to default
Version = SVersion; //then Update Version afterwars
Version = SVersion; //then Update Version afterwards
}
}

Expand Down
207 changes: 154 additions & 53 deletions Interop/TranslationProvider.cs
Original file line number Diff line number Diff line change
@@ -1,98 +1,199 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Windows;
using System.Xml;
using Octokit;
using SPCode.Utils;
using static SPCode.Utils.DefaultTranslations;

namespace SPCode.Interop
{
public class TranslationProvider
{
public string[] AvailableLanguageIDs;
public string[] AvailableLanguages;

public List<string> AvailableLanguageIDs = new();
public List<string> AvailableLanguages = new();
public bool IsDefault = true;

private readonly Dictionary<string, string> LangDict = new(StringComparer.OrdinalIgnoreCase);
private readonly string _tempDir = Paths.GetTempDirectory();
private readonly string _translationsDir = Paths.GetTranslationsDirectory();
private static readonly Dictionary<string, string> _langDictionary = new(StringComparer.OrdinalIgnoreCase);
private Release _latestVersion;

public TranslationProvider()
{
// Make sure translations dir exists
if (!Directory.Exists(_translationsDir))
{
Directory.CreateDirectory(_translationsDir);
}

if (IsUpdateAvailable())
{
UpdateTranslations();
}

ParseTranslationFiles();
}

/// <summary>
/// Gets the translation of the specified phrase.
/// </summary>
/// <param name="phrase">The phrase to return translated</param>
/// <returns></returns>
public string Get(string phrase)
public static string Translate(string phrase)
{
return LangDict.ContainsKey(phrase) ? LangDict[phrase] : "<empty>";
return _langDictionary.ContainsKey(phrase) ? _langDictionary[phrase] : "<empty>";
}

/// <summary>
/// Loads the specified language.
/// </summary>
/// <param name="lang">The language to load</param>
/// <param name="Initial"></param>
public void LoadLanguage(string lang, bool Initial = false)
/// <param name="initial">Whether this was the startup initial method call</param>
public void LoadLanguage(string lang, bool initial = false)
{
DefaultLangDict.Keys.ToList().ForEach(x => LangDict[x] = DefaultLangDict[x]);
var languageList = new List<string>();
var languageIDList = new List<string>();
languageList.Add("English");
languageIDList.Add("");
// This is probably the first boot ever
if (lang == string.Empty)
{
lang = Constants.DefaultLanguageID;
Program.OptionsObject.Language = lang;
}
lang = lang.Trim().ToLowerInvariant();
IsDefault = (string.IsNullOrEmpty(lang) || lang.ToLowerInvariant() == "en") && Initial;
if (File.Exists(Constants.LanguagesFile))
IsDefault = (string.IsNullOrEmpty(lang) || lang.ToLowerInvariant() == Constants.DefaultLanguageID) && initial;
var doc = new XmlDocument();

try
{
try
// Fill with defaults first
if (initial)
{
var document = new XmlDocument();
document.Load(Constants.LanguagesFile);
if (document.ChildNodes.Count < 1)
doc.Load(Path.Combine(_translationsDir, Constants.DefaultTranslationsFile));
foreach (XmlNode node in doc.ChildNodes[0].ChildNodes)
{
throw new Exception("No Root-Node: \"translations\" found");
_langDictionary.Add(node.Name, node.InnerText);
}

XmlNode rootLangNode = null;
foreach (XmlNode childNode in document.ChildNodes[0].ChildNodes)
// Return if the attempted language to load is the default one
if (lang == Constants.DefaultLanguageID)
{
var lID = childNode.Name;
var lNm = lID;
if (childNode.Name.ToLowerInvariant() == lang)
{
rootLangNode = childNode;
}
if (childNode.FirstChild.Name.ToLowerInvariant() == "language")
{
lNm = childNode.FirstChild.InnerText;
}
languageList.Add(lNm);
languageIDList.Add(lID);
return;
}
if (rootLangNode != null)
}

var file = Path.Combine(_translationsDir, $"{lang}.xml");
if (!File.Exists(file))
{
UpdateTranslations();
LoadLanguage(lang);
return;
}
else
{
doc.Load(file);

// Replace existing keys with the ones available in this file
foreach (XmlNode node in doc.ChildNodes[0].ChildNodes)
{
foreach (XmlNode node in rootLangNode.ChildNodes)
{
if (node.NodeType == XmlNodeType.Comment)
{
continue;
}
var nn = node.Name.ToLowerInvariant();
var nv = node.InnerText;
LangDict[nn] = nv;
}
_langDictionary[node.Name] = node.InnerText;
}
}
catch (Exception e)
}
catch (Exception)
{
throw;
}
}

/// <summary>
/// Gets all of the translation files and adds them to the global available languages list.
/// </summary>
public void ParseTranslationFiles()
{
try
{
var filesDir = Directory.GetFiles(_translationsDir).Where(x => x.EndsWith(".xml"));
foreach (var file in filesDir)
{
// Create wrapper
var fInfo = new FileInfo(file);

// Parse content in an XML object
var doc = new XmlDocument();
doc.LoadXml(File.ReadAllText(fInfo.FullName));

// Get language name and ID
var langName = doc.ChildNodes[0].ChildNodes
.Cast<XmlNode>()
.Single(x => x.Name == "language")
.InnerText;
var langID = fInfo.Name.Substring(0, fInfo.Name.IndexOf('.'));

// Add file to the available languages lists
AvailableLanguages.Add(langName);
AvailableLanguageIDs.Add(langID);
}
}
catch (Exception ex)
{
MessageBox.Show($"There was a problem while updating the translations file.\n" +
$"Details: {ex.Message}");
}
}

/// <summary>
/// Downloads the latest translation files release from GitHub for SPCode to parse them.
/// </summary>
public void UpdateTranslations()
{
// Clear temp folder before beggining
DirUtils.ClearTempFolder();

// Download latest release zip file
var wc = new WebClient();
var downloadedFile = Path.Combine(_tempDir, "langs.zip");
wc.Headers.Add(HttpRequestHeader.UserAgent, Constants.ProductHeaderValueName);
wc.DownloadFile(_latestVersion.ZipballUrl, downloadedFile);

// Decompress and replace all of its files
ZipFile.ExtractToDirectory(downloadedFile, _tempDir);
var filesDir = Directory.GetFiles(Directory.GetDirectories(_tempDir)[0]).Where(x => x.EndsWith(".xml"));
foreach (var file in filesDir)
{
// Create wrapper
var fInfo = new FileInfo(file);

// Replace current file with this one
var destination = Path.Combine(_translationsDir, fInfo.Name);
if (File.Exists(destination))
{
MessageBox.Show("An error occured while reading the language-file. Without them, the editor wont show translations." + Environment.NewLine + "Details: " + e.Message
, "Error while reading configs."
, MessageBoxButton.OK
, MessageBoxImage.Warning);
File.Delete(destination);
}
File.Move(fInfo.FullName, destination);
}
AvailableLanguages = languageList.ToArray();
AvailableLanguageIDs = languageIDList.ToArray();

// Delete all temp folder contents
DirUtils.ClearTempFolder();

// Update version to options object
Program.OptionsObject.TranslationsVersion = int.Parse(_latestVersion.Name);
}

/// <summary>
/// Compares the stored version of the translations release with the one from GitHub
/// </summary>
/// <returns>Whether there's an update available</returns>
public bool IsUpdateAvailable()
{
var client = new GitHubClient(new ProductHeaderValue(Constants.ProductHeaderValueName));
var versionStored = Program.OptionsObject.TranslationsVersion;

_latestVersion = client.Repository.Release.GetAll(Constants.OrgName,
Constants.TranslationsRepoName).Result[0];

return versionStored < int.Parse(_latestVersion.Name);
}
}
}
4 changes: 2 additions & 2 deletions Interop/Updater/UpdateCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ private static async Task<IEnumerable<Release>> GetAllReleases()
PageSize = 10
};

var client = new GitHubClient(new ProductHeaderValue("spcode-client"));
var releases = await client.Repository.Release.GetAll("SPCodeOrg", "SPCode", apiOptions);
var client = new GitHubClient(new ProductHeaderValue(Constants.ProductHeaderValueName));
var releases = await client.Repository.Release.GetAll(Constants.OrgName, Constants.MainRepoName, apiOptions);
#if BETA
var finalReleasesList = releases.Where(x => x.Prerelease);
#else
Expand Down
17 changes: 9 additions & 8 deletions Interop/Updater/UpdateWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using MahApps.Metro.Controls.Dialogs;
using MdXaml;
using SPCode.Utils;
using static SPCode.Interop.TranslationProvider;

namespace SPCode.Interop.Updater
{
Expand Down Expand Up @@ -85,11 +86,11 @@ public void PrepareUpdateWindow(bool OnlyChangelog = false)
}
else
{
Title = string.Format(Program.Translations.Get("VersionAvailable"), updateInfo.AllReleases[0].TagName);
MainLine.Text = Program.Translations.Get("WantToUpdate");
ActionYesButton.Content = Program.Translations.Get("Yes");
ActionNoButton.Content = Program.Translations.Get("No");
ActionGithubButton.Content = Program.Translations.Get("ViewGithub");
Title = string.Format(Translate("VersionAvailable"), updateInfo.AllReleases[0].TagName);
MainLine.Text = Translate("WantToUpdate");
ActionYesButton.Content = Translate("Yes");
ActionNoButton.Content = Translate("No");
ActionGithubButton.Content = Translate("ViewGithub");
}

var releasesBody = new StringBuilder();
Expand Down Expand Up @@ -131,8 +132,8 @@ private void StartUpdate()
ActionYesButton.Visibility = Visibility.Hidden;
ActionNoButton.Visibility = Visibility.Hidden;
ActionGithubButton.Visibility = Visibility.Hidden;
MainLine.Text = string.Format(Program.Translations.Get("UpdatingTo"), updateInfo.AllReleases[0].TagName);
SubLine.Text = Program.Translations.Get("DownloadingUpdater");
MainLine.Text = string.Format(Translate("UpdatingTo"), updateInfo.AllReleases[0].TagName);
SubLine.Text = Translate("DownloadingUpdater");
var t = new Thread(UpdateDownloadWorker);
t.Start();
}
Expand Down Expand Up @@ -180,7 +181,7 @@ private void UpdateDownloadWorker()
/// </summary>
private void FinalizeUpdate()
{
SubLine.Text = Program.Translations.Get("StartingUpdater");
SubLine.Text = Translate("StartingUpdater");
UpdateLayout();
try
{
Expand Down
Loading