diff --git a/AltReaper/Checks.cs b/AltReaper/Checks.cs index a691f5e..525f353 100644 --- a/AltReaper/Checks.cs +++ b/AltReaper/Checks.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using System.Net; +using System.Net; using System.Net.NetworkInformation; using static System.Console; @@ -7,20 +6,19 @@ namespace Reaper { internal class Checks { - public static bool cfgChecker(JsonHandling.config config) + public static bool CfgChecker(JsonHandling.Config config) { - bool[] bools = { - String.IsNullOrEmpty(config.apiKey), - String.IsNullOrEmpty(config.senderMail), - String.IsNullOrEmpty(config.senderMailPassword), - String.IsNullOrEmpty(config.hostDomain), - String.IsNullOrEmpty(config.portNumber), - false, - String.IsNullOrEmpty(config.bcc) - }; + bool[] bools = [ + string.IsNullOrEmpty(config.ApiKey), + string.IsNullOrEmpty(config.SenderMail), + string.IsNullOrEmpty(config.SenderMailPassword), + string.IsNullOrEmpty(config.HostDomain), + string.IsNullOrEmpty(config.PortNumber), + false + ]; try { - if (int.Parse(config.portNumber) < 0 && int.Parse(config.portNumber) > 65535) + if (int.Parse(config.PortNumber) < 0 || int.Parse(config.PortNumber) > 65535) { bools[5] = true; } } catch { return true; } @@ -38,53 +36,60 @@ public static void DeviceIsOnline() PingReply googleReply = googlePing.Send("8.8.8.8"); if (cloudflareReply.Status == IPStatus.Success | googleReply.Status == IPStatus.Success) { - WriteLine("Device is online"); + WriteLine(Properties.Resources.DeviceOnline); } else { - WriteLine(@" -Your device is not connected to the internet. -This application needs internet access. -Please connect your device to the internet to use this application."); + WriteLine(Properties.Resources.DeviceOfflineDetails); Helper.Closer(); } } public static void APIisOnline() { - //force internal output to be english - Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); - Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US"); - IWebProxy defaultWebProxy = WebRequest.DefaultWebProxy; - defaultWebProxy.Credentials = CredentialCache.DefaultCredentials; + IWebProxy? defaultWebProxy = WebRequest.DefaultWebProxy; + defaultWebProxy?.Credentials = CredentialCache.DefaultCredentials; try { - HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.openweathermap.org/data/2.5/weather?q=London"); - request.Proxy = defaultWebProxy; - HttpWebResponse response = (HttpWebResponse)request.GetResponse(); - response.Close(); + var handler = new HttpClientHandler + { + Proxy = defaultWebProxy, + UseProxy = true, + DefaultProxyCredentials = CredentialCache.DefaultCredentials + }; + + using var client = new HttpClient(handler); + client.Timeout = TimeSpan.FromSeconds(10); + + HttpResponseMessage response = client.GetAsync("https://api.openweathermap.org/data/2.5/weather?q=London").GetAwaiter().GetResult(); + + // Treat HTTP 401 (Unauthorized) as online (API reachable but invalid key) + if (response.StatusCode == HttpStatusCode.Unauthorized) + { + WriteLine(Properties.Resources.ApiOnline); + return; + } + + // Any other HTTP response (including successful 200) is treated as offline for this check + WriteLine(Properties.Resources.ApiOffline); + Helper.Closer(); } - catch (WebException e) + catch (Exception e) when (e is HttpRequestException or TaskCanceledException) { - if (e.Message.Equals("The remote server returned an error: (401) Unauthorized.", StringComparison.InvariantCultureIgnoreCase)) - { WriteLine("API is online"); } - else { WriteLine("API is not online. Please try again later."); Helper.Closer(); } + // network-level error (DNS, connection failure) or HttpClient.Timeout, which surfaces as TaskCanceledException + WriteLine(string.Format(Properties.Resources.NetworkErrorFormat, e.Message)); + Helper.Closer(); } catch (Exception e) { - WriteLine("\nThe following Exception was raised : {0}", e.Message); + WriteLine(string.Format(Properties.Resources.ExceptionRaisedFormat, e.Message)); } } } - class Menu + class Menu(string inputPrompt, string[] options) { - private int Index; - private string[] Options; - private string InputPrompt; - public Menu(string inputPrompt, string[] options) - { - InputPrompt = inputPrompt; - Options = options; - Index = 0; - } + private int Index = 0; + private readonly string[] Options = options; + private readonly string InputPrompt = inputPrompt; + public void DisplayAvailableOptions() { Console.WriteLine(InputPrompt); @@ -95,28 +100,28 @@ public void DisplayAvailableOptions() if (counter == Index) { prefix = ">"; - Console.BackgroundColor = ConsoleColor.White; - Console.ForegroundColor = ConsoleColor.Black; + BackgroundColor = ConsoleColor.White; + ForegroundColor = ConsoleColor.Black; } else { prefix = " "; - Console.BackgroundColor = ConsoleColor.Black; - Console.ForegroundColor = ConsoleColor.White; + BackgroundColor = ConsoleColor.Black; + ForegroundColor = ConsoleColor.White; } - Console.WriteLine($"{prefix} {currentOption}"); + WriteLine($"{prefix} {currentOption}"); } - Console.BackgroundColor = ConsoleColor.Black; - Console.ForegroundColor = ConsoleColor.Green; + BackgroundColor = ConsoleColor.Black; + ForegroundColor = ConsoleColor.Green; } - public int IRExcecute() + public int IRExecute() { ConsoleKey pressedKey; do { - Console.Clear(); + Clear(); DisplayAvailableOptions(); - ConsoleKeyInfo keyInfo = Console.ReadKey(true); + ConsoleKeyInfo keyInfo = ReadKey(true); pressedKey = keyInfo.Key; if (pressedKey == ConsoleKey.UpArrow ^ pressedKey == ConsoleKey.W) @@ -138,14 +143,14 @@ public int IRExcecute() } while (pressedKey != ConsoleKey.Enter); return Index; } - public String SRExcecute() + public string SRExecute() { ConsoleKey pressedKey; do { - Console.Clear(); + Clear(); DisplayAvailableOptions(); - ConsoleKeyInfo keyInfo = Console.ReadKey(true); + ConsoleKeyInfo keyInfo = ReadKey(true); pressedKey = keyInfo.Key; if (pressedKey == ConsoleKey.UpArrow ^ pressedKey == ConsoleKey.W) diff --git a/AltReaper/Helper.cs b/AltReaper/Helper.cs index 7a27f37..79216c4 100644 --- a/AltReaper/Helper.cs +++ b/AltReaper/Helper.cs @@ -1,44 +1,57 @@ using Renci.SshNet; using System.Text.Json; -using System.Text.RegularExpressions; using static System.Console; +using Reaper.IO; namespace Reaper { - public static class globalVars + public static class GlobalVars { - public static string[] fullySupportedLanguages = { "afrikaans", "albanian", "arabic", "azerbaijani", "bulgarian", "catalan", "czech", "danish", "german", "greek", "english", "basque", "persian", "farsi", "finnish", "french", "galician", "Hebrew", "hindi", "croatian", "hungarian", "indonesian", "italian", "japanese", "korean", "latvian", "lithuanian", "macedonian", "norwegian", "dutch", "polish", "portuguese", "romanian", "russian", "swedish", "slovak", "slovenian", "spanish", "serbian", "thai", "turkish", "ukrainian", "vietnamese", "chinese simplified", "chinese traditional", "zulu" }; - public static string[] supportedShortCodes = { "af", "al", "ar", "az", "bg", "ca", "cz", "da", "de", "el", "en", "eu", "fa", "fa", "fi", "fr", "gl", "he", "hi", "hr", "hu", "id", "it", "ja", "kr", "la", "lt", "mk", "no", "nl", "pl", "pt", "pt_br", "ro", "ru", "se", "sk", "sl", "sr", "th", "tr", "ua", "vi", "zh_cn", "zh_tw", "zu" }; - public static string appName = "Reaper", devName = "WetterSenseDev", versionNumber = "0.9.1"; - public static string[] devData = { appName, devName }; - public static string baseLoc = $"{Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)}\\Reaper"; - public static string tree = $"{baseLoc}\\langFiles\\", cfgLoc = $"{baseLoc}\\config.json"; + // Load application metadata from resources + public static readonly string[] devData = [Properties.Resources.AppName, Properties.Resources.DevName]; + public static readonly string baseLoc = $"{Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)}\\Reaper"; + public static readonly string cfgLoc = $"{baseLoc}\\config.json"; + public static readonly string easterEgg = "https://bit.ly/3Gpgiyh"; + // App visible languages and mapping to OpenWeatherMap API codes / culture names. + // Keep small for now: English and German only. + public static readonly string[] appLanguages = ["English", "German"]; + public static readonly Dictionary appToApiCode = new() + { + { "English", "en" }, + { "German", "de" } + }; + // Map app language display -> culture name used for ResourceManager lookups (use BCP-47 style) + public static readonly Dictionary appToCulture = new() + { + { "English", "en" }, + { "German", "de" } + }; } internal class Helper { - public static void MailOption(JsonHandling.langVal langValue, JsonHandling.config config, String[] content) + public static void MailOption(JsonHandling.Config config, String[] content) { - string[] mailOptions = { langValue.yes, langValue.no }; - Menu mailMenu = new Menu(langValue.mailWanted, mailOptions); + string[] mailOptions = [Properties.Resources.YesOption, Properties.Resources.NoOption]; + Menu mailMenu = new(Properties.Resources.mailWanted, mailOptions); - if (mailMenu.IRExcecute() == 0) + if (mailMenu.IRExecute() == 0) { bool partSuccess = false; while (!partSuccess) { - if (Checks.cfgChecker(config)) + if (Checks.CfgChecker(config)) { - Inputs.configGen(langValue, config); - config = JsonSerializer.Deserialize(File.ReadAllText(globalVars.cfgLoc)); + Inputs.ConfigGen(config); + config = JsonSerializer.Deserialize(File.ReadAllText(GlobalVars.cfgLoc))!; } - Write($"\n{langValue.mailAddressQuery}\n>"); + Write($"\n{Properties.Resources.mailAddressQuery}\n>"); CursorVisible = true; ForegroundColor = ConsoleColor.White; ForegroundColor = ConsoleColor.Green; CursorVisible = false; - if (Outputs.MailOutput(ReadLine(), langValue.yourWeatherInfo, content, langValue, config)) + if (Outputs.MailOutput(ReadLine() ?? "", Properties.Resources.yourWeatherInfo, content, config)) { - Closer(config, langValue); + Closer(config); } else { throw new Exception(); } partSuccess = true; @@ -61,7 +74,7 @@ public static string PasswordMaker() { if (password.Length > 0) { - password = password.Remove(password.Length - 1); + password = password[..^1]; Write("\b \b"); } } @@ -78,64 +91,46 @@ public static string PasswordMaker() } public static void SuperUserMode(String superUserPwd, String appName, string directoryLoc) { - SftpClient sftp = new SftpClient("ssh.strato.de", $"sftp_{appName}@wettersense.de", superUserPwd); + SftpClient sftp = new("ssh.strato.de", 22, $"sftp_{appName}@wettersense.de", superUserPwd); sftp.Connect(); Stream configLoc = File.Create($"{directoryLoc}\\config.json"); sftp.DownloadFile(@"/config.json", configLoc); configLoc.Close(); - System.Collections.IEnumerator enumerator = sftp.ListDirectory("/langFiles/", null).GetEnumerator(); - List files = new List(); - while (enumerator.MoveNext()) - { - Renci.SshNet.Sftp.SftpFile sftpFile = (Renci.SshNet.Sftp.SftpFile)enumerator.Current; - string name = sftpFile.Name; - files.Add(name); - } - - Regex myRegex = new Regex(@"^[a-z]+Text\.json$"); - List downloadList = files.Where(f => myRegex.IsMatch(f)).ToList(); - foreach (string str in downloadList) - { - Stream langFileLoc = File.Create($"{directoryLoc}\\langFiles\\{str}"); - sftp.DownloadFile($"/langFiles/{str}", langFileLoc); - langFileLoc.Close(); - } sftp.Disconnect(); } public static void Closer() { Uninstaller(); - WriteLine($"\nThank you for using {globalVars.devData[0]}!"); - WriteLine("Weather data powered by openweathermap.org"); - WriteLine($"{globalVars.devData[0]} by {globalVars.devData[1]}"); - WriteLine("Press any key to exit."); + WriteLine(string.Format(Properties.Resources.ThankYouFormat, GlobalVars.devData[0])); + WriteLine(Properties.Resources.WeatherPoweredBy); + WriteLine(string.Format(Properties.Resources.BylineFormat, GlobalVars.devData[0], GlobalVars.devData[1])); + WriteLine(Properties.Resources.PressAnyKeyExit); ReadKey(true); Environment.Exit(0); } - public static void Closer(JsonHandling.config config, JsonHandling.langVal langValue) + public static void Closer(JsonHandling.Config config) { - WriteLine($"{langValue.mailSuccessMessage}"); + WriteLine($"{Properties.Resources.mailSuccessMessage}"); Uninstaller(); - WriteLine($"\nThank you for using {globalVars.devData[0]}!"); - WriteLine("Weather data powered by openweathermap.org"); - WriteLine($"Mail powered by htmlemail.io & {config.senderMail.Split('@')[1]}"); - WriteLine($"{globalVars.devData[0]} by {globalVars.devData[1]}"); - WriteLine("Press any key to exit."); + WriteLine(string.Format(Properties.Resources.ThankYouFormat, GlobalVars.devData[0])); + WriteLine(Properties.Resources.WeatherPoweredBy); + WriteLine(string.Format(Properties.Resources.MailPoweredByFormat, config.SenderMail.Split('@')[1])); + WriteLine(string.Format(Properties.Resources.BylineFormat, GlobalVars.devData[0], GlobalVars.devData[1])); + WriteLine(Properties.Resources.PressAnyKeyExit); ReadKey(true); Environment.Exit(0); } public static void Uninstaller() { - string baseLoc = $"{Environment.GetEnvironmentVariable("USERPROFILE")}\\Desktop\\Reaper"; - string uninstallPrompt = $"\nDo you want to unistall {globalVars.devData[0]}?"; - string[] uninstallOptions = { "yes", "no" }; + string uninstallPrompt = string.Format(Properties.Resources.UninstallPromptFormat, GlobalVars.devData[0]); + string[] uninstallOptions = [Properties.Resources.YesOption, Properties.Resources.NoOption]; Menu uninstallMenu = new(uninstallPrompt, uninstallOptions); - int uninstallChoice = uninstallMenu.IRExcecute(); + int uninstallChoice = uninstallMenu.IRExecute(); if (uninstallChoice == 0) { - Directory.Delete(baseLoc, true); + Directory.Delete(GlobalVars.baseLoc, true); } } } diff --git a/AltReaper/HtmlBody.cs b/AltReaper/HtmlBody.cs index 99aaf26..396cacf 100644 --- a/AltReaper/HtmlBody.cs +++ b/AltReaper/HtmlBody.cs @@ -1,17 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection.Metadata; -using System.Text; -using System.Threading.Tasks; -using static Reaper.JsonHandling; -using System.Xml.Linq; - -namespace Reaper +namespace Reaper { internal class HtmlBody { - public static string getBody(string[] content, string easterEgg, string name, config config) + public static string GetBody(string[] content, string easterEgg, string name, JsonHandling.Config config) { string htmlBody = $"\r\n" + @@ -28,7 +19,7 @@ public static string getBody(string[] content, string easterEgg, string name, co $"\r\n\r\n\r\n\r\n" + $"
\r\n\r\n\r\n\r\n \r\n \r\n " + - $"\r\n \r\n
\r\n" + $"
Don't like these emails? Unsubscribe.\r\n
\r\n Powered by htmlemail & {config.senderMail.Split('@')[1].Split('.')[0]}.\r\n
\r\n " + + $"\r\n Powered by htmlemail & {config.SenderMail.Split('@')[1].Split('.')[0]}.\r\n \r\n \r\n \r\n " + $"
\r\n \r\n\r\n\r\n" + $"\r\n  \r\n\r\n\r\n" + $"\r\n" + diff --git a/AltReaper/IO/Inputs.cs b/AltReaper/IO/Inputs.cs index 94a6ec3..5d4ad1b 100644 --- a/AltReaper/IO/Inputs.cs +++ b/AltReaper/IO/Inputs.cs @@ -12,116 +12,112 @@ * port * bcc */ -namespace Reaper +namespace Reaper.IO { internal class Inputs { - public static String configReader() - { - return File.ReadAllText(globalVars.cfgLoc); - } - public static String langHandler(String langPreferenceLong) - { - //importing selected language file - return File.ReadAllText($"{globalVars.tree}{langPreferenceLong}Text.json"); - } - public static async Task APICall(String city, String langPreferenceShort, String unitPreference, String APIKey) + public static async Task APICall(string city, string langPreferenceShort, string unitPreference, string APIKey) { //Use default system proxy settings - IWebProxy defaultWebProxy = WebRequest.DefaultWebProxy; - defaultWebProxy.Credentials = CredentialCache.DefaultCredentials; + IWebProxy? defaultWebProxy = WebRequest.DefaultWebProxy; + defaultWebProxy?.Credentials = CredentialCache.DefaultCredentials; HttpClientHandler handler = new() { Proxy = defaultWebProxy, }; - HttpClient client = new() + HttpClient client = new(handler) { BaseAddress = new Uri("https://api.openweathermap.org/data/2.5/"), }; - return await client.GetFromJsonAsync($"weather?q={city}&lang={langPreferenceShort}&units={unitPreference}&appid={APIKey}"); + return await client.GetFromJsonAsync($"weather?q={city}&lang={langPreferenceShort}&units={unitPreference}&appid={APIKey}") + ?? throw new InvalidOperationException("The weather API returned an empty response."); } - public static bool configGen(JsonHandling.langVal langValue, JsonHandling.config config) + public static bool ConfigGen(JsonHandling.Config config) { //checks if config file exists and if all lines have information - if (File.Exists(globalVars.cfgLoc) && Checks.cfgChecker(config) == false) { return true; } + if (File.Exists(GlobalVars.cfgLoc) && Checks.CfgChecker(config) == false) { return true; } - string apiKey = config.apiKey; + string apiKey = config.ApiKey; Write("\nEnter the mail address which you want use to send mails\n>"); CursorVisible = true; ForegroundColor = ConsoleColor.White; - string senderMail = ReadLine(); + string senderMail = ReadLine() ?? ""; ForegroundColor = ConsoleColor.Green; Write("\nEnter the password for the mail (won't be shown) letter by letter, then press enter\n>"); string senderMailPassword = Helper.PasswordMaker(); Write("\nEnter the smtp host domain\"\n>"); ForegroundColor = ConsoleColor.White; - string hostDomain = ReadLine(); + string hostDomain = ReadLine() ?? ""; ForegroundColor = ConsoleColor.Green; Write("\nEnter the smtp port Number\n>"); ForegroundColor = ConsoleColor.White; - string portNumber = ReadLine(); + string portNumber = ReadLine() ?? ""; ForegroundColor = ConsoleColor.Green; - Write($"\nEnter the mail address of the BCC archive mail or type \"{langValue.no}\" (without quotes) \n>"); - ForegroundColor = ConsoleColor.White; - string BCC = ReadLine(); + //empty bcc means no BCC mail + string BCC = ""; + string[] bccOptions = [Properties.Resources.YesOption, Properties.Resources.NoOption]; + Menu bccMenu = new(Properties.Resources.bccWanted, bccOptions); + if (bccMenu.IRExecute() == 0) + { + Write("\nEnter the mail address of the BCC archive mail\n>"); + CursorVisible = true; + ForegroundColor = ConsoleColor.White; + BCC = ReadLine() ?? ""; + ForegroundColor = ConsoleColor.Green; + } CursorVisible = false; - var json = new JsonHandling.config + var json = new JsonHandling.Config { - apiKey = apiKey, - senderMail = senderMail, - senderMailPassword = senderMailPassword, - hostDomain = hostDomain, - portNumber = portNumber, - bcc = BCC + ApiKey = apiKey, + SenderMail = senderMail, + SenderMailPassword = senderMailPassword, + HostDomain = hostDomain, + PortNumber = portNumber, + Bcc = BCC }; - File.WriteAllText(globalVars.cfgLoc, JsonSerializer.Serialize(json)); + File.WriteAllText(GlobalVars.cfgLoc, JsonSerializer.Serialize(json)); return true; } - public static string UnitPreference(JsonHandling.langVal langValue) + public static string UnitPreference() { //gets unit preference - string[] unitOptions = { langValue.metric, langValue.imperial }; - Menu unitMenu = new(langValue.unitQuery, unitOptions); - return unitMenu.IRExcecute() == 0 ? "metric" : "imperial"; + string[] unitOptions = [Properties.Resources.metric, Properties.Resources.imperial]; + Menu unitMenu = new(Properties.Resources.unitQuery, unitOptions); + return unitMenu.IRExecute() == 0 ? "metric" : "imperial"; } public static void ConfigGetter() { - JsonHandling.config test = null; - try { test = JsonSerializer.Deserialize(File.ReadAllText(globalVars.cfgLoc)); } - catch { File.Delete(globalVars.cfgLoc); } - if (!File.Exists(globalVars.cfgLoc)) + try + { + _ = JsonSerializer.Deserialize(File.ReadAllText(GlobalVars.cfgLoc)); + } + catch { File.Delete(GlobalVars.cfgLoc); } + if (!File.Exists(GlobalVars.cfgLoc)) { Write("\nEnter your APIKey\n>"); - string apiKey = ReadLine(); - var tmp = new JsonHandling.config + string apiKey = ReadLine() ?? ""; + var tmp = new JsonHandling.Config { - apiKey = apiKey, - senderMail = "", - senderMailPassword = "", - hostDomain = "", - portNumber = "", - bcc = "" + ApiKey = apiKey, + SenderMail = "", + SenderMailPassword = "", + HostDomain = "", + PortNumber = "", + Bcc = "" }; - File.WriteAllText(globalVars.cfgLoc, JsonSerializer.Serialize(tmp)); + File.WriteAllText(GlobalVars.cfgLoc, JsonSerializer.Serialize(tmp)); } } - public static String langPreference() + public static string LangPreference() { - List availableLanguages = new(); - foreach (string l in globalVars.fullySupportedLanguages) - { - if (File.Exists($"{globalVars.tree}{l}Text.json")) - { - availableLanguages.Add($"{char.ToUpper(l[0]) + l.Substring(1)}"); - } - } + List availableLanguages = [.. GlobalVars.appLanguages]; - Menu languageMenu = new Menu("Please select your desired language or \"new\" to implement a new language", availableLanguages.ToArray()); + Menu languageMenu = new(Properties.Resources.SelectPreferredLanguage, [.. availableLanguages]); string spacer = "-------------------------"; - string selectedLanguage = languageMenu.SRExcecute(); + string selectedLanguage = languageMenu.SRExecute(); WriteLine($"\n{spacer}\n"); WriteLine($"using {selectedLanguage}"); WriteLine($"\n{spacer}"); diff --git a/AltReaper/IO/LanguageLoader.cs b/AltReaper/IO/LanguageLoader.cs new file mode 100644 index 0000000..81cacb9 --- /dev/null +++ b/AltReaper/IO/LanguageLoader.cs @@ -0,0 +1,31 @@ +using System.Globalization; + +namespace Reaper.IO +{ + internal static class LanguageLoader + { + // Load language values from RESX resources for a given selected language display name + public static (string apiCode, CultureInfo culture) Load(string selectedLanguageDisplay) + { + // Normalize selected display name + string selectedDisplay = string.IsNullOrEmpty(selectedLanguageDisplay) ? "English" : selectedLanguageDisplay; + + // Determine culture name and API code using app-level mappings + if (!Reaper.GlobalVars.appToCulture.TryGetValue(selectedDisplay, out string? cultureName)) + { + cultureName = "en"; + } + + if (!Reaper.GlobalVars.appToApiCode.TryGetValue(selectedDisplay, out string? apiCode)) + { + apiCode = "en"; + } + + CultureInfo culture = CultureInfo.InvariantCulture; + try { if (!string.IsNullOrEmpty(cultureName)) culture = new CultureInfo(cultureName); } + catch { culture = CultureInfo.InvariantCulture; } + + return (apiCode, culture); + } + } +} diff --git a/AltReaper/IO/Outputs.cs b/AltReaper/IO/Outputs.cs index ca5c191..6623fdc 100644 --- a/AltReaper/IO/Outputs.cs +++ b/AltReaper/IO/Outputs.cs @@ -1,83 +1,81 @@ -using System.Globalization; -using System.Net; +using System.Net; using System.Net.Mail; using static System.Console; -namespace Reaper +namespace Reaper.IO { internal class Outputs { - public static String[] WeatherOutput(WeatherResponse.root weatherData, String unitPreference, JsonHandling.langVal langValue) + public static string[] WeatherOutput(WeatherResponse.Root weatherData, string unitPreference) { - Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE"); - Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE"); //time & timezones, units char unitSymbol; DateTime localSystemTime = DateTime.Now; - int timeZoneShiftFromUTC = weatherData.timezone / 3600; + int timeZoneShiftFromUTC = weatherData.Timezone / 3600; string timezoneUTC; DateTime locTime = DateTime.UtcNow.AddHours(timeZoneShiftFromUTC); timezoneUTC = timeZoneShiftFromUTC >= 0 ? $"UTC+{timeZoneShiftFromUTC}" : $"UTC{timeZoneShiftFromUTC}" ; unitSymbol = unitPreference == "metric" ? 'c' : 'f'; //main output - List content = new(); + List content = []; string spacer = "\n-------------------------------------\n"; content.Add(spacer); - content.Add($"{langValue.theWeatherIn}: {weatherData.name}, {weatherData.sys.country}"); - content.Add($"{langValue.localSystemTime}: {localSystemTime}"); - content.Add($"{langValue.timeAtDestination}: : {locTime} {timezoneUTC} "); - content.Add($"{langValue.temp}: {weatherData.main.temp:0.#}°{unitSymbol}"); - content.Add($"{langValue.lowestTemp}: {weatherData.main.temp_min:0.#}°{unitSymbol}"); - content.Add($"{langValue.highestTemp}: {weatherData.main.temp_max:0.#}°{unitSymbol}"); - content.Add($"{langValue.description}: {weatherData.weather[0].description}"); + content.Add($"{Properties.Resources.theWeatherIn}: {weatherData.Name}, {weatherData.Sys.Country}"); + content.Add($"{Properties.Resources.localSystemTime}: {localSystemTime}"); + content.Add($"{Properties.Resources.timeAtDestination}: : {locTime} {timezoneUTC} "); + content.Add($"{Properties.Resources.temp}: {weatherData.Main.Temp:0.#}°{unitSymbol}"); + content.Add($"{Properties.Resources.lowestTemp}: {weatherData.Main.TempMin:0.#}°{unitSymbol}"); + content.Add($"{Properties.Resources.highestTemp}: {weatherData.Main.TempMax:0.#}°{unitSymbol}"); + content.Add($"{Properties.Resources.description}: {weatherData.Weather[0].Description}"); content.Add(spacer); - string[] cArray = content.ToArray(); - WriteLine(String.Join("\r\n", cArray)); - WriteLine(langValue.pressEnterContinue); + string[] cArray = [.. content]; + WriteLine(string.Join("\r\n", cArray)); + WriteLine(Properties.Resources.pressEnterContinue); while (ReadKey(true).Key != ConsoleKey.Enter) { continue; } return cArray; } - public static bool MailOutput(String recipient, String subjectLine, String[] content, JsonHandling.langVal langValue, JsonHandling.config config) + public static bool MailOutput(string recipient, string subjectLine, string[] content, JsonHandling.Config config) { //Set salutation - Write($"\n{langValue.nameOr}\n>"); + Write($"\n{Properties.Resources.nameOr}\n>"); CursorVisible = true; ForegroundColor = ConsoleColor.White; - string name = ReadLine(); - if (name == langValue.no) { name = ""; } + string? name = ReadLine(); + if (name == Properties.Resources.NoOption || string.IsNullOrEmpty(name) || string.IsNullOrWhiteSpace(name)) { name = ""; } ForegroundColor = ConsoleColor.Green; CursorVisible = false; //Set smtp config - var smtpClient = new SmtpClient(config.hostDomain, int.Parse(config.portNumber)) + var smtpClient = new SmtpClient(config.HostDomain, int.Parse(config.PortNumber)) { - Credentials = new NetworkCredential(config.senderMail, config.senderMailPassword), + Credentials = new NetworkCredential(config.SenderMail, config.SenderMailPassword), EnableSsl = true, }; //Set smtp content - string easterEgg = "https://bit.ly/3Gpgiyh"; var mailMessage = new MailMessage() { - From = new MailAddress(config.senderMail), + From = new MailAddress(config.SenderMail), Priority = MailPriority.Low, Subject = subjectLine, IsBodyHtml = true, - Body = HtmlBody.getBody(content,easterEgg,name,config) + Body = HtmlBody.GetBody(content, GlobalVars.easterEgg, name, config) }; //Set recipient mailMessage.To.Add(recipient); //Set bcc for analysation/archivating usage - if (config.bcc == langValue.no) { } - else { mailMessage.Bcc.Add(config.bcc); } + //empty bcc means no BCC mail. Older configs stored the localized "no" instead, so accept that of every app language + bool noBcc = string.IsNullOrWhiteSpace(config.Bcc) || GlobalVars.appToCulture.Values.Any(c => + config.Bcc == Properties.Resources.ResourceManager.GetString(nameof(Properties.Resources.NoOption), new System.Globalization.CultureInfo(c))); + if (noBcc) { } + else { mailMessage.Bcc.Add(config.Bcc); } //sending try { smtpClient.Send(mailMessage); } - catch + catch (Exception mail) { - Exception mail = new Exception(); WriteLine(mail.Message); return false; } diff --git a/AltReaper/IO/TranslationMaker.cs b/AltReaper/IO/TranslationMaker.cs deleted file mode 100644 index 76a0d66..0000000 --- a/AltReaper/IO/TranslationMaker.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System.Text.Json; -using static System.Console; - -namespace Reaper -{ - internal class TranslationMaker - { - public static bool newFileMaker(string langName) - { - string currentUserDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\Desktop\\Reaper\\langFiles\\"; - string futureFilePath = currentUserDesktopPath + langName.ToLower() + "Text.json"; - - bool langCreated = false; - if (langName.ToLower() == "default" | String.IsNullOrEmpty(langName) | langName.ToLower() == "english") { return false; } //ensures only files with names that arent defaultText or Text are created - //Creates file if not existant or user confirms that they want to - if (File.Exists(futureFilePath)) - { - Write("\nThere is already a File for the language you selected. If you want to overwrite it, type \"I know what I am doing!\" (without quotes)\n>"); - if (ReadLine() == "I know what I am doing!") { } else { return false; } - } - - //checks if language is fully supported - string shortLanguage = null; - if (globalVars.fullySupportedLanguages.Contains(langName, StringComparer.OrdinalIgnoreCase)) - { - int index = Array.FindIndex(globalVars.fullySupportedLanguages, x => x.ToLower() == langName.ToLower()); - shortLanguage = globalVars.supportedShortCodes[index]; - } - else { WriteLine("Language not fully supported. Some output may be in English"); shortLanguage = "en"; } - - //Instructions & translation items - WriteLine("Follow the instructions! \nOnly translate what is inside quotes! \nDo not put your translation in quotes unless told! \nPress Enter after translation to proceed"); - Write("\nTranslate \"Enter the name of the unit system you want to use\"\n>"); - string unitQuery = ReadLine(); - Write("\nTranslate the word \"metric\" (the measurement/unit system)\n>"); - string metric = ReadLine().ToLower(); - Write("\nTranslate the word \"imperial\" (the mesarement/unit system)\n>"); - string imperial = ReadLine().ToLower(); - Write("\nTranslate \"Enter the name of the city which you want weather data of.\"\n>"); - string nameOfCity = ReadLine(); - Write("\nTranslate \"Invalid input.\"\n>"); - string invalidInput = ReadLine(); - Write("\nTranslate \"\"Press Enter to continue.\n>"); - string pressEnterContinue = ReadLine(); - Write("\nTranslate \"Error found.\"\n>"); - string errorMessage = ReadLine(); - Write("\nTranslate \"The weather in\" (like in )\n>"); - string theWeatherIn = ReadLine(); - Write("\nTranslate the word \"temperature\"\n>"); - string temp = ReadLine(); - Write("\nTranslate \"lowest Temperature\"\n>"); - string lowestTemp = ReadLine(); - Write("\nTranslate \"highest temperature\"\n>"); - string highestTemp = ReadLine(); - Write("\nTranslate the word \"description\"\n>"); - string description = ReadLine(); - Write("\nTranslate \"local system time\"\n>"); - string localSystemTime = ReadLine(); - Write("\nTranslate \"time at destination\"\n>"); - string timeAtDestination = ReadLine(); - Write("\nTranslate \"your weather info\"(formal your)\n>"); - string yourWeatherInfo = ReadLine(); - Write("\nTranslate the word \"yes\"\n>"); - string yes = ReadLine().ToLower(); - Write("\nTranslate the word \"no\"\n>"); - string no = ReadLine().ToLower(); - Write("\nDo you want this as a mail?\n>"); - string mailWanted = ReadLine(); - Write("\nEnter your mail address\n>"); - string mailAddressQuery = ReadLine(); - string nameOr = ""; - while ((nameOr.Contains('"') && nameOr.Contains('(') && nameOr.Contains(')')) == false) - { - WriteLine("Translate everything inside the next message, including \" \\ and messages inside brackets"); - Write("\nEnter your name or type \"no\" to not be addressed (without quotes)\n>"); - nameOr = ReadLine(); - } - Write("\nMail sent successfully\n>"); - string mailSuccessMessage = ReadLine(); - - var langVal = new JsonHandling.langVal - { - shortLanguage = shortLanguage, - unitQuery = unitQuery, - metric = metric, - imperial = imperial, - nameOfCity = nameOfCity, - invalidInput = invalidInput, - pressEnterContinue = pressEnterContinue, - errorMessage = errorMessage, - theWeatherIn = theWeatherIn, - temp = temp, - lowestTemp = lowestTemp, - highestTemp = highestTemp, - description = description, - localSystemTime = localSystemTime, - timeAtDestination = timeAtDestination, - yourWeatherInfo = yourWeatherInfo, - yes = yes, - no = no, - mailWanted = mailWanted, - mailAddressQuery = mailAddressQuery, - nameOr = nameOr, - mailSuccessMessage = mailSuccessMessage, - }; - - WriteLine("Writing to file"); - File.WriteAllText(futureFilePath, JsonSerializer.Serialize(langVal)); - Clear(); - - if (File.Exists(futureFilePath)) - { - langCreated = true; - WriteLine($"{char.ToUpper(langName[0]) + langName.Substring(1)} language file successfully created."); - } - return langCreated; - } - - public static bool defaultFileMaker() - { - string langName = "english"; - bool langCreated = false; - - string currentUserDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\Desktop\\Reaper\\langFiles\\"; - string futureFilePath = currentUserDesktopPath + langName.ToLower() + "Text.json"; - - var langVal = new JsonHandling.langVal - { - shortLanguage = "en", - unitQuery = "Enter the name of the unit system you want to use", - metric = "metric", - imperial = "imperial", - errorMessage = "Error found.", - no = "no", - nameOfCity = "Enter the name of the city which you want weather data of.", - invalidInput = "Invalid input.", - pressEnterContinue = "Press Enter to continue.", - theWeatherIn = "The weather in", - temp = "temperature", - lowestTemp = "lowest temperature", - highestTemp = "highest temperature", - description = "description", - yes = "yes", - timeAtDestination = "time at destination", - yourWeatherInfo = "your weather info", - mailWanted = "Do you want this as a mail?", - mailAddressQuery = "Enter your mail address", - nameOr = "Enter your name or type \"no\" to not be addressed (without quotes)", - mailSuccessMessage = "Mail sent successfully", - localSystemTime = "local system time" - }; - File.WriteAllText(futureFilePath, JsonSerializer.Serialize(langVal)); - - if (File.Exists(futureFilePath)) - { - langCreated = true; - WriteLine($"{char.ToUpper(langName[0]) + langName.Substring(1)} language file successfully created."); - Clear(); - } - return langCreated; - } - } -} \ No newline at end of file diff --git a/AltReaper/JsonHandling.cs b/AltReaper/JsonHandling.cs index a4ab92b..8a1ca56 100644 --- a/AltReaper/JsonHandling.cs +++ b/AltReaper/JsonHandling.cs @@ -1,83 +1,85 @@ - +using System.Text.Json.Serialization; + namespace Reaper { internal static class JsonHandling { - public class config + public class Config { - public string apiKey { get; set; } - public string senderMail { get; set; } + [JsonPropertyName("apiKey")] + public string ApiKey { get; set; } = string.Empty; + [JsonPropertyName("senderMail")] + public string SenderMail { get; set; } = string.Empty; - public string senderMailPassword { get; set; } - public string hostDomain { get; set; } - public string portNumber { get; set; } - public string bcc { get; set; } - } - public class langVal - { - public string shortLanguage { get; set; } - public string unitQuery { get; set; } - public string metric { get; set; } - public string imperial { get; set; } - public string nameOfCity { get; set; } - public string invalidInput { get; set; } - public string pressEnterContinue { get; set; } - public string errorMessage { get; set; } - public string theWeatherIn { get; set; } - public string temp { get; set; } - public string lowestTemp { get; set; } - public string highestTemp { get; set; } - public string description { get; set; } - public string localSystemTime { get; set; } - public string timeAtDestination { get; set; } - public string yourWeatherInfo { get; set; } - public string yes { get; set; } - public string no { get; set; } - public string mailWanted { get; set; } - public string mailAddressQuery { get; set; } - public string nameOr { get; set; } - public string mailSuccessMessage { get; set; } + [JsonPropertyName("senderMailPassword")] + public string SenderMailPassword { get; set; } = string.Empty; + [JsonPropertyName("hostDomain")] + public string HostDomain { get; set; } = string.Empty; + [JsonPropertyName("portNumber")] + public string PortNumber { get; set; } = string.Empty; + [JsonPropertyName("bcc")] + public string Bcc { get; set; } = string.Empty; } - } public static class WeatherResponse { - public class weather + public class Weather { - public string description { get; set; } - public string main { get; set; } - public string icon { get; set; } + [JsonPropertyName("description")] + public string Description { get; set; } = string.Empty; + [JsonPropertyName("main")] + public string Main { get; set; } = string.Empty; + [JsonPropertyName("icon")] + public string Icon { get; set; } = string.Empty; } - public class main + public class Main { - public double temp { get; set; } - public double temp_min { get; set; } - public double temp_max { get; set; } - public double feels_like { get; set; } - public int pressure { get; set; } - public int humidity { get; set; } + [JsonPropertyName("temp")] + public double Temp { get; set; } + [JsonPropertyName("temp_min")] + public double TempMin { get; set; } + [JsonPropertyName("temp_max")] + public double TempMax { get; set; } + [JsonPropertyName("feels_like")] + public double FeelsLike { get; set; } + [JsonPropertyName("pressure")] + public int Pressure { get; set; } + [JsonPropertyName("humidity")] + public int Humidity { get; set; } } - public class sys + public class Sys { - public long sunrise { get; set; } - public long sunset { get; set; } - public string country { get; set; } + [JsonPropertyName("sunrise")] + public long Sunrise { get; set; } + [JsonPropertyName("sunset")] + public long Sunset { get; set; } + [JsonPropertyName("country")] + public string Country { get; set; } = string.Empty; } - public class wind + public class Wind { - public double speed { get; set; } - public int deg { get; set; } + [JsonPropertyName("speed")] + public double Speed { get; set; } + [JsonPropertyName("deg")] + public int Deg { get; set; } } - public class root + public class Root { - public List weather { get; set; } - public main main { get; set; } - public sys sys { get; set; } - public wind wind { get; set; } - public long dt { get; set; } - public int timezone { get; set; } - public string name { get; set; } + [JsonPropertyName("weather")] + public List Weather { get; set; } = []; + [JsonPropertyName("main")] + public Main Main { get; set; } = new(); + [JsonPropertyName("sys")] + public Sys Sys { get; set; } = new(); + [JsonPropertyName("wind")] + public Wind Wind { get; set; } = new(); + [JsonPropertyName("dt")] + public long Dt { get; set; } + [JsonPropertyName("timezone")] + public int Timezone { get; set; } + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; } } } \ No newline at end of file diff --git a/AltReaper/Properties/Resources.Designer.cs b/AltReaper/Properties/Resources.Designer.cs new file mode 100644 index 0000000..47d394d --- /dev/null +++ b/AltReaper/Properties/Resources.Designer.cs @@ -0,0 +1,480 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace Reaper.Properties { + using System; + + + /// + /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// + // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// + [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("Reaper.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die API is not online. Please try again later. ähnelt. + /// + public static string ApiOffline { + get { + return ResourceManager.GetString("ApiOffline", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die API is online ähnelt. + /// + public static string ApiOnline { + get { + return ResourceManager.GetString("ApiOnline", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Reaper ähnelt. + /// + public static string AppName { + get { + return ResourceManager.GetString("AppName", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die {0} v{1} ähnelt. + /// + public static string AppTitleFormat { + get { + return ResourceManager.GetString("AppTitleFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die {0} by {1} ähnelt. + /// + public static string BylineFormat { + get { + return ResourceManager.GetString("BylineFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Close {0} with error: {1} ähnelt. + /// + public static string CloseAppErrorFormat { + get { + return ResourceManager.GetString("CloseAppErrorFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Closed {0}. ähnelt. + /// + public static string CloseAppFormat { + get { + return ResourceManager.GetString("CloseAppFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Continuing in standard mode ähnelt. + /// + public static string ContinuingStandardMode { + get { + return ResourceManager.GetString("ContinuingStandardMode", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die description ähnelt. + /// + public static string description { + get { + return ResourceManager.GetString("description", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die + ///Your device is not connected to the internet. + ///This application needs internet access. + ///Please connect your device to the internet to use this application. ähnelt. + /// + public static string DeviceOfflineDetails { + get { + return ResourceManager.GetString("DeviceOfflineDetails", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Device is online ähnelt. + /// + public static string DeviceOnline { + get { + return ResourceManager.GetString("DeviceOnline", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die WetterSenseDev ähnelt. + /// + public static string DevName { + get { + return ResourceManager.GetString("DevName", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Error found. ähnelt. + /// + public static string errorMessage { + get { + return ResourceManager.GetString("errorMessage", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Error. Retype password ähnelt. + /// + public static string ErrorRetypePassword { + get { + return ResourceManager.GetString("ErrorRetypePassword", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die + ///The following Exception was raised : {0} ähnelt. + /// + public static string ExceptionRaisedFormat { + get { + return ResourceManager.GetString("ExceptionRaisedFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die highest temperature ähnelt. + /// + public static string highestTemp { + get { + return ResourceManager.GetString("highestTemp", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die imperial ähnelt. + /// + public static string imperial { + get { + return ResourceManager.GetString("imperial", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Invalid input. ähnelt. + /// + public static string invalidInput { + get { + return ResourceManager.GetString("invalidInput", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die local system time ähnelt. + /// + public static string localSystemTime { + get { + return ResourceManager.GetString("localSystemTime", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die lowest temperature ähnelt. + /// + public static string lowestTemp { + get { + return ResourceManager.GetString("lowestTemp", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Enter your mail address ähnelt. + /// + public static string mailAddressQuery { + get { + return ResourceManager.GetString("mailAddressQuery", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Mail powered by htmlemail.io & {0} ähnelt. + /// + public static string MailPoweredByFormat { + get { + return ResourceManager.GetString("MailPoweredByFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Mail sent successfully ähnelt. + /// + public static string mailSuccessMessage { + get { + return ResourceManager.GetString("mailSuccessMessage", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Do you want to send a BCC archive mail? ähnelt. + /// + public static string bccWanted { + get { + return ResourceManager.GetString("bccWanted", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Do you want this as a mail? ähnelt. + /// + public static string mailWanted { + get { + return ResourceManager.GetString("mailWanted", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die metric ähnelt. + /// + public static string metric { + get { + return ResourceManager.GetString("metric", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Enter the name of the city which you want weather data of. ähnelt. + /// + public static string nameOfCity { + get { + return ResourceManager.GetString("nameOfCity", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Enter your name or type "no" to not be addressed (without quotes) ähnelt. + /// + public static string nameOr { + get { + return ResourceManager.GetString("nameOr", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Network error contacting API: {0} ähnelt. + /// + public static string NetworkErrorFormat { + get { + return ResourceManager.GetString("NetworkErrorFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die no ähnelt. + /// + public static string NoOption { + get { + return ResourceManager.GetString("NoOption", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Press any key to exit. ähnelt. + /// + public static string PressAnyKeyExit { + get { + return ResourceManager.GetString("PressAnyKeyExit", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Press Enter to continue. ähnelt. + /// + public static string pressEnterContinue { + get { + return ResourceManager.GetString("pressEnterContinue", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Select your preferred language ähnelt. + /// + public static string SelectPreferredLanguage { + get { + return ResourceManager.GetString("SelectPreferredLanguage", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Enter the superuser password. Password won't be shown, type each char individually, backspace to correct, enter to continue ähnelt. + /// + public static string SuperUserPasswordPrompt { + get { + return ResourceManager.GetString("SuperUserPasswordPrompt", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Do you want to enter superuser mode? ähnelt. + /// + public static string SuperUserQuestion { + get { + return ResourceManager.GetString("SuperUserQuestion", resourceCulture); + } + } + + /// Sucht eine lokalisierte Zeichenfolge, die temperature ähnelt. + /// + public static string temp { + get { + return ResourceManager.GetString("temp", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Thank you for using {0}! ähnelt. + /// + public static string ThankYouFormat { + get { + return ResourceManager.GetString("ThankYouFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die The weather in ähnelt. + /// + public static string theWeatherIn { + get { + return ResourceManager.GetString("theWeatherIn", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die time at destination ähnelt. + /// + public static string timeAtDestination { + get { + return ResourceManager.GetString("timeAtDestination", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Uninstall of {0} failed with error: {1} ähnelt. + /// + public static string UninstallErrorFormat { + get { + return ResourceManager.GetString("UninstallErrorFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Do you want to unistall {0}? ähnelt. + /// + public static string UninstallPromptFormat { + get { + return ResourceManager.GetString("UninstallPromptFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Enter the name of the unit system you want to use ähnelt. + /// + public static string unitQuery { + get { + return ResourceManager.GetString("unitQuery", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die 0.9.1 ähnelt. + /// + public static string VersionNumber { + get { + return ResourceManager.GetString("VersionNumber", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Weather data powered by openweathermap.org ähnelt. + /// + public static string WeatherPoweredBy { + get { + return ResourceManager.GetString("WeatherPoweredBy", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die yes ähnelt. + /// + public static string YesOption { + get { + return ResourceManager.GetString("YesOption", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die your weather info ähnelt. + /// + public static string yourWeatherInfo { + get { + return ResourceManager.GetString("yourWeatherInfo", resourceCulture); + } + } + } +} diff --git a/AltReaper/Properties/Resources.de.resx b/AltReaper/Properties/Resources.de.resx new file mode 100644 index 0000000..d1ee718 --- /dev/null +++ b/AltReaper/Properties/Resources.de.resx @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Gerät ist online + + + +Ihr Gerät ist nicht mit dem Internet verbunden. +Diese Anwendung benötigt Internetzugang. +Bitte verbinden Sie Ihr Gerät mit dem Internet, um diese Anwendung zu benutzen. + + + API ist online + + + API ist nicht online. Bitte versuchen Sie es später erneut. + + + Netzwerkfehler beim Kontaktieren der API: {0} + + + +Die folgende Ausnahme wurde ausgelöst : {0} + + + {0} v{1} + + + Möchten Sie in den Superuser-Modus wechseln? + + + ja + + + nein + + + Geben Sie das Superuser-Passwort ein. Das Passwort wird nicht angezeigt, geben Sie jedes Zeichen einzeln ein, Rücktaste zum Korrigieren, Enter zum Fortfahren + + + Fehler. Passwort erneut eingeben + + + Wird im Standardmodus fortgesetzt + + + Reaper + + + WetterSenseDev + + + 0.9.1 + + + Danke für die Nutzung von {0}! + + + Wetterdaten von openweathermap.org + + + {0} von {1} + + + Beliebige Taste zum Verlassen drücken. + + + Mail von htmlemail.io & {0} + + + {0} deinstallieren? + + + Geschlossen: {0}. + + + Schließen von {0} mit Fehler: {1} + + + Deinstallation von {0} schlug fehl. Fehler: {1} + + + Geben Sie den Namen des Einheitensystems ein, das Sie verwenden möchten + + + metrisch + + + Imperial + + + Geben Sie den Namen der Stadt ein, für die Sie Wetterdaten wünschen. + + + Ungültige Eingabe. + + + Drücken Sie die Eingabetaste, um fortzufahren. + + + Fehler aufgetreten. + + + Das Wetter in + + + Temperatur + + + niedrigste Temperatur + + + höchste Temperatur + + + Beschreibung + + + lokale Systemzeit + + + Zeit am Zielort + + + Ihre Wetterinformationen + + + Möchten Sie eine BCC-Archiv-E-Mail senden? + + + Möchten Sie dies per E-Mail erhalten? + + + Geben Sie Ihre E-Mail-Adresse ein + + + Geben Sie Ihren Namen ein oder geben Sie "nein" ein, um nicht angesprochen zu werden (ohne Anführungszeichen) + + + E-Mail erfolgreich gesendet + + + Bevorzugte Sprache auswählen + + \ No newline at end of file diff --git a/AltReaper/Properties/Resources.resx b/AltReaper/Properties/Resources.resx new file mode 100644 index 0000000..1bc2cdc --- /dev/null +++ b/AltReaper/Properties/Resources.resx @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Device is online + + + +Your device is not connected to the internet. +This application needs internet access. +Please connect your device to the internet to use this application. + + + API is online + + + API is not online. Please try again later. + + + Network error contacting API: {0} + + + +The following Exception was raised : {0} + + + {0} v{1} + + + Do you want to enter superuser mode? + + + yes + + + no + + + Enter the superuser password. Password won't be shown, type each char individually, backspace to correct, enter to continue + + + Error. Retype password + + + Continuing in standard mode + + + Reaper + + + WetterSenseDev + + + 0.9.1 + + + Thank you for using {0}! + + + Weather data powered by openweathermap.org + + + {0} by {1} + + + Press any key to exit. + + + Mail powered by htmlemail.io & {0} + + + Do you want to unistall {0}? + + + Closed {0}. + + + Close {0} with error: {1} + + + Uninstall of {0} failed with error: {1} + + + Enter the name of the unit system you want to use + + + metric + + + imperial + + + Enter the name of the city which you want weather data of. + + + Invalid input. + + + Press Enter to continue. + + + Error found. + + + The weather in + + + temperature + + + lowest temperature + + + highest temperature + + + description + + + local system time + + + time at destination + + + your weather info + + + Do you want to send a BCC archive mail? + + + Do you want this as a mail? + + + Enter your mail address + + + Enter your name or type "no" to not be addressed (without quotes) + + + Mail sent successfully + + + Select your preferred language + + \ No newline at end of file diff --git a/AltReaper/Reaper.csproj b/AltReaper/Reaper.csproj index d1c785d..2a56ed6 100644 --- a/AltReaper/Reaper.csproj +++ b/AltReaper/Reaper.csproj @@ -2,13 +2,37 @@ Exe - net6.0 + net10.0 enable enable - + + + + True + True + Resources.resx + + + + + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + + + + Resources.resx + true + + + + + diff --git a/AltReaper/WetterApp.cs b/AltReaper/WetterApp.cs index 5dea5a8..9dc45f4 100644 --- a/AltReaper/WetterApp.cs +++ b/AltReaper/WetterApp.cs @@ -1,4 +1,6 @@ -using System.Text.Json; +using Reaper.IO; +using System.Globalization; +using System.Text.Json; using static Reaper.JsonHandling; using static Reaper.WeatherResponse; using static System.Console; @@ -7,10 +9,10 @@ namespace Reaper { public static class Program { - public static void Main(String[] args) + public static void Main() { - - Title = $"{globalVars.appName} v{globalVars.versionNumber}"; + + Title = string.Format(Properties.Resources.AppTitleFormat, Properties.Resources.AppName, Properties.Resources.VersionNumber); ForegroundColor = ConsoleColor.Green; OutputEncoding = System.Text.Encoding.UTF8; CursorVisible = false; @@ -19,51 +21,49 @@ public static void Main(String[] args) Checks.DeviceIsOnline(); Checks.APIisOnline(); - - if (!Directory.Exists(globalVars.tree)) { Directory.CreateDirectory(globalVars.tree); } + Directory.CreateDirectory(GlobalVars.baseLoc); - string[] superUserOptions = { "yes", "no" }; - Menu superUser = new("Do you want to enter superuser mode?", superUserOptions); + string[] superUserOptions = [Properties.Resources.YesOption, Properties.Resources.NoOption]; + Menu superUser = new(Properties.Resources.SuperUserQuestion, superUserOptions); - if (superUser.IRExcecute() == 0) + if (superUser.IRExecute() == 0) { - Write("\nEnter the superuser password. Password won't be shown, type each char individually, backspace to correct, enter to continue\n>"); + Write("\n" + Properties.Resources.SuperUserPasswordPrompt + "\n>"); while (true) { try { - Helper.SuperUserMode(Helper.PasswordMaker(), globalVars.appName, globalVars.baseLoc); + Helper.SuperUserMode(Helper.PasswordMaker(), Properties.Resources.AppName, GlobalVars.baseLoc); break; } - catch { Write("\nError. Retype password\n>"); continue; } + catch { Write("\n" + Properties.Resources.ErrorRetypePassword + "\n>"); continue; } } } - else { Write("Continuing in standard mode"); } - TranslationMaker.defaultFileMaker(); - + else { Write(Properties.Resources.ContinuingStandardMode); } - string chosenLanguage = Inputs.langPreference(); - langVal langValue = JsonSerializer.Deserialize(Inputs.langHandler(chosenLanguage)); + string chosenLanguage = Inputs.LangPreference(); + (string apiCode, CultureInfo culture) = LanguageLoader.Load(chosenLanguage); + Thread.CurrentThread.CurrentUICulture = culture; + Thread.CurrentThread.CurrentCulture = culture; Inputs.ConfigGetter(); - config config = JsonSerializer.Deserialize(File.ReadAllText(globalVars.cfgLoc)); - + Config config = JsonSerializer.Deserialize(File.ReadAllText(GlobalVars.cfgLoc))!; - string unitPreference = Inputs.UnitPreference(langValue); - string city = null; + string unitPreference = Inputs.UnitPreference(); int check = 0; CursorVisible = true; + string? city; while (true) { - Write($"\n{langValue.nameOfCity}\n>"); + Write($"\n{Properties.Resources.nameOfCity}\n>"); ForegroundColor = ConsoleColor.White; city = ReadLine(); - if (!String.IsNullOrEmpty(city)) { break; } + if (!string.IsNullOrEmpty(city)) { break; } if (check >= 1) { ForegroundColor = ConsoleColor.Green; - WriteLine(langValue.invalidInput); + WriteLine(Properties.Resources.invalidInput); continue; } check++; @@ -71,11 +71,11 @@ public static void Main(String[] args) ForegroundColor = ConsoleColor.Green; CursorVisible = false; - root weatherData = Inputs.APICall(city, langValue.shortLanguage, unitPreference, config.apiKey).Result; + Root weatherData = Inputs.APICall(city, apiCode, unitPreference, config.ApiKey).Result; - var content = Outputs.WeatherOutput(weatherData, unitPreference, langValue); + var content = Outputs.WeatherOutput(weatherData, unitPreference); - Helper.MailOption(langValue, config, content); + Helper.MailOption(config, content); } } } \ No newline at end of file