diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..393d187
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,13 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "csharpier": {
+ "version": "0.30.6",
+ "commands": [
+ "dotnet-csharpier"
+ ],
+ "rollForward": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index cbc3037..d830f82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -546,4 +546,4 @@ FodyWeavers.xsd
.idea/**
*.txt
*.toml
-*.json
\ No newline at end of file
+example.json
\ No newline at end of file
diff --git a/Config.cs b/Config.cs
index 9641754..bff3157 100644
--- a/Config.cs
+++ b/Config.cs
@@ -7,19 +7,18 @@ namespace StaggerPost;
///
public class Config
{
- ///
- /// Gets or sets the name of the schedule file.
- ///
- public string? File { get; set; }
+ ///
+ /// Gets or sets the name of the schedule file.
+ ///
+ public string? File { get; set; }
- ///
- /// Gets or sets the directory path where the schedule file is stored.
- ///
- public string? Path { get; set; }
-
- ///
- /// Gets or sets the list of available topics from the configuration file.
- ///
- public List Topics { get; set; } = new List();
+ ///
+ /// Gets or sets the directory path where the schedule file is stored.
+ ///
+ public string? Path { get; set; }
+ ///
+ /// Gets or sets the list of available topics from the configuration file.
+ ///
+ public List Communities { get; set; } = new List();
}
diff --git a/Export.cs b/Export.cs
new file mode 100644
index 0000000..7d4e895
--- /dev/null
+++ b/Export.cs
@@ -0,0 +1,128 @@
+// I hereby waive this project under the public domain - see UNLICENSE for details.
+namespace StaggerPost;
+
+internal static class Export
+{
+ ///
+ /// Retrieves configuration settings from a TOML file if it exists; otherwise, returns a default configuration.
+ ///
+ /// The name of the configuration file (defaults to "config.toml").
+ /// A Config object populated with values from the file, or a default Config instance if the file is not found.
+ static Config GetConfig(string file)
+ {
+ var cfgPath = Path.Combine(Tracer.AppDirectory, file);
+
+ if (!File.Exists(cfgPath))
+ {
+ Tracer.LogLine("Config file not found. Switching to defaults.");
+ var defaultList = new[]
+ {
+ "games@lemmy.world",
+ "politics@lemmy.world",
+ "science@lemmy.world",
+ "technology@lemmy.world",
+ };
+
+ var config = new Config()
+ {
+ File = "schedule.json",
+ Path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+ Communities = defaultList.ToList(),
+ };
+
+ return config;
+ }
+
+ Tracer.LogLine($"Discovered config file: {cfgPath}");
+ var toml = File.ReadAllText(cfgPath);
+ var model = Toml.ToModel(toml);
+
+ return model;
+ }
+
+ ///
+ /// Exports the scheduled articles to a file, allowing the user to modify
+ /// the directory, filename, and list of topics based on
+ /// a configuration file if available.
+ ///
+ public static void ToJSON(List storeTimes, string cfgPath)
+ {
+ // File directory is used for file location set in config
+ var topics = new List();
+ var config = GetConfig(cfgPath);
+ var outputDir = Tracer.OutputDirectory(config.Path!);
+ var outputFile = config.File;
+ var filePath = Path.Combine(outputDir, outputFile!);
+ var chosenTopic = "";
+ var times = new List();
+
+ // If the config file exists, read from that but don't assume anything is filled
+ if (File.Exists(cfgPath))
+ {
+ var toml = File.ReadAllText(cfgPath);
+ var usrDir = config.Path;
+ var usrFileName = config.File;
+ // Convert list into array
+ var list = config.Communities;
+ var tomlList = string.Join(", ", list);
+ var usrTopics = tomlList.Split(',');
+
+ if (string.IsNullOrEmpty(usrDir))
+ return;
+
+ outputDir = usrDir;
+
+ if (string.IsNullOrEmpty(usrFileName))
+ return;
+
+ outputFile = usrFileName;
+
+ // If array is empty, return; otherwise, apply config
+ if (usrTopics.Length < 0)
+ return;
+
+ foreach (var usrTopic in usrTopics)
+ topics.Add(usrTopic);
+
+ // Set new file Path
+ filePath = Path.Combine(outputDir, outputFile!);
+ }
+
+ if (!File.Exists(filePath))
+ File.WriteAllText(filePath, "[]");
+
+ foreach (var time in storeTimes)
+ times.Add(time.Trim());
+
+ // Set new topic
+ topics = config.Communities.ToList();
+ Console.Clear();
+ chosenTopic = Interactive.SelectTopics(topics);
+
+ var date = Interactive.SelectDate();
+
+ // Write to file.
+ var jsonFile = File.ReadAllText(filePath);
+ var jsonList = string.IsNullOrWhiteSpace(jsonFile)
+ ? new List()
+ : JsonSerializer.Deserialize>(jsonFile) ?? new List();
+
+ jsonList.Add(
+ new Schedule()
+ {
+ Community = chosenTopic.Trim(),
+ Date = date.Trim(),
+ Times = times,
+ }
+ );
+
+ var jsonOptions = new JsonSerializerOptions() { WriteIndented = true };
+
+ var json = JsonSerializer.Serialize(jsonList, jsonOptions);
+ File.WriteAllText(filePath, json);
+ Tracer.LogLine($"{json}{Environment.NewLine}Written to: {filePath}");
+
+ // Clear list from memory
+ storeTimes.Clear();
+ }
+}
diff --git a/Generator.cs b/Generator.cs
new file mode 100644
index 0000000..d0cd437
--- /dev/null
+++ b/Generator.cs
@@ -0,0 +1,60 @@
+// I hereby waive this project under the public domain - see UNLICENSE for details.
+namespace StaggerPost;
+
+internal static class Generator
+{
+ ///
+ /// Generates a schedule of article publishing times, ensuring a randomized
+ /// delay between each while avoiding time conflicts within a 30-minute window.
+ ///
+ /// A list of TimeSpan objects representing scheduled article times.
+ public static List GenerateTimes()
+ {
+ var numberOfArticles = 5; // Define how many articles to schedule
+ var startTime = new TimeSpan(9, 0, 0); // Starting time at 9:00 AM
+ var rng = new Random();
+ var scheduledTimes = new List();
+
+ for (int i = 0; i < numberOfArticles; i++)
+ {
+ var baseDelayHours = rng.Next(2, 4); // Randomly choose between 2-3 hours delay
+ var minutesToAdd = rng.Next(0, 60); // Randomly choose minutes (0-59)
+
+ // Calculate new time by adding base delay and random minutes
+ var nextTime = startTime.Add(new TimeSpan(baseDelayHours, minutesToAdd, 0));
+
+ // Check if the new time is within 30 minutes of any existing time
+ while (
+ scheduledTimes.Exists(previousTime =>
+ Math.Abs((nextTime - previousTime).TotalMinutes) < 30
+ )
+ )
+ {
+ // If the new time is within 30 minutes of an existing time, adjust it
+ nextTime = nextTime.Add(new TimeSpan(0, 30, 0));
+ }
+
+ scheduledTimes.Add(nextTime);
+ startTime = nextTime; // Update start time for the next article
+ }
+
+ return scheduledTimes;
+ }
+
+ ///
+ /// Converts a TimeSpan into a 12-hour AM/PM formatted time string.
+ ///
+ /// The TimeSpan representing the time of day.
+ /// A formatted string representing the time in AM/PM format.
+ public static string ConvertTo12Hour(TimeSpan time)
+ {
+ var minutes = time.TotalMinutes;
+ var hours12 = time.Hours % 12;
+
+ if (hours12 == 0)
+ hours12 = 1;
+
+ var period = time.Hours >= 12 ? "PM" : "AM";
+ return $"{hours12}:{time.Minutes:D2} {period}";
+ }
+}
diff --git a/GlobalUsings.cs b/GlobalUsings.cs
index 6a39b5d..40e65af 100644
--- a/GlobalUsings.cs
+++ b/GlobalUsings.cs
@@ -1,6 +1,7 @@
global using System.Diagnostics;
+global using System.Text;
+global using System.Text.Json;
+global using System.Text.Json.Serialization;
+global using StaggerPost;
global using Tomlyn;
global using Tomlyn.Model;
-global using StaggerPost;
-global using System.Text.Json;
-global using System.Text.Json.Serialization;
\ No newline at end of file
diff --git a/Interactive.cs b/Interactive.cs
new file mode 100644
index 0000000..5978eba
--- /dev/null
+++ b/Interactive.cs
@@ -0,0 +1,93 @@
+// I hereby waive this project under the public domain - see UNLICENSE for details.
+namespace StaggerPost;
+
+internal static class Interactive
+{
+ ///
+ /// Prompts the user with a yes/no question and returns their choice as a boolean value.
+ ///
+ /// The message to display to the user.
+ /// True if the user selects 'Y' or presses Enter, otherwise false.
+ public static bool UserChoice(string choice)
+ {
+ Console.WriteLine($"{Environment.NewLine}{choice} Y/N");
+ var input = Console.ReadKey().Key;
+ if (input == ConsoleKey.Y || input == ConsoleKey.Enter)
+ return true;
+
+ return false;
+ }
+
+ ///
+ /// Prompts the user to select a topic from a given list
+ /// and returns the chosen topic.
+ ///
+ /// An array of available topics.
+ /// The selected topic as a string.
+ public static string SelectTopics(List communities)
+ {
+ var topicChoice = "";
+ var topicNum = 0;
+ var userChoices = new List();
+ var numOfTopics = 0;
+ var topicDict = new Dictionary();
+
+ foreach (var community in communities)
+ {
+ numOfTopics++;
+ var title = community.Trim();
+ topicDict.Add(numOfTopics, title);
+ userChoices.Add($"{Environment.NewLine}{numOfTopics} {title}");
+ }
+
+ var topicSelect = string.Join(", ", userChoices.ToArray());
+ Console.WriteLine($"Choose a Topic{Environment.NewLine}{topicSelect}");
+ var input = Console.ReadLine();
+
+ // Attempt to parse a number.
+ if (int.TryParse(input, out topicNum) == true)
+ topicChoice = topicDict[topicNum];
+ else
+ SelectTopics(communities);
+
+ return topicChoice;
+ }
+
+ ///
+ /// Prompts the user to select a date (either today or tomorrow) and returns the selected date as a formatted string.
+ ///
+ /// A string representing the selected date in a short date format.
+ public static string SelectDate()
+ {
+ var dtChoices = new[] { "Today", "Tomorrow" };
+ var dtDict = new Dictionary();
+ var dtSelection = new List();
+ var dtChoice = 0;
+ var dtNum = 0;
+
+ foreach (var days in dtChoices)
+ {
+ dtNum++;
+ var day = days.Trim();
+ dtDict.Add(dtNum, day);
+ dtSelection.Add($"{dtNum} {day}");
+ }
+
+ var topicSelect = string.Join(", ", dtSelection.ToArray());
+ Console.WriteLine($"{Environment.NewLine}Choose a Date{Environment.NewLine}{topicSelect}");
+ var input = Console.ReadLine();
+
+ // Attempt to parse a number.
+ if (int.TryParse(input, out dtNum) == true)
+ dtChoice = dtNum;
+
+ // Any choice above 2 tomorrow
+ if (dtChoice >= 2)
+ {
+ var dt = DateTime.Now.AddDays(1);
+ return dt.ToString("d");
+ }
+
+ return DateTime.Today.ToString("d");
+ }
+}
diff --git a/Program.cs b/Program.cs
index 2b8e318..754ae66 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,322 +1,41 @@
// I hereby waive this project under the public domain - see UNLICENSE for details.
-///
-/// Retrieves configuration settings from a TOML file if it exists; otherwise, returns a default configuration.
-///
-/// The name of the configuration file (defaults to "config.toml").
-/// A Config object populated with values from the file, or a default Config instance if the file is not found.
-Config GetConfig(string file = "config.toml")
-{
- // App directory is used for config file
- var appDir = AppDomain.CurrentDomain.BaseDirectory;
- var cfgPath = Path.Combine(appDir, file);
-
- if (File.Exists(cfgPath))
- {
- var toml = File.ReadAllText(cfgPath);
- var model = Toml.ToModel(toml);
-
- return model;
- }
- var defaultList = new[] { "Games", "Politics", "Research", "Technology" };
- return new Config()
- {
- File = "schedule.json",
- Path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
- Topics = defaultList.ToList()
- };
-}
-
-///
-/// Prompts the user with a yes/no question and returns their choice as a boolean value.
-///
-/// The message to display to the user.
-/// True if the user selects 'Y' or presses Enter, otherwise false.
-bool UserChoice(string choice)
-{
- Console.WriteLine($"{Environment.NewLine}{choice} Y/N");
- var input = Console.ReadKey().Key;
- if (input == ConsoleKey.Y || input == ConsoleKey.Enter)
- return true;
-
- return false;
-}
-
-///
-/// Generates a schedule of article publishing times, ensuring a randomized
-/// delay between each while avoiding time conflicts within a 30-minute window.
-///
-/// A list of TimeSpan objects representing scheduled article times.
-List GenerateTimes()
-{
- var numberOfArticles = 5; // Define how many articles to schedule
- var startTime = new TimeSpan(9, 0, 0); // Starting time at 9:00 AM
- var rng = new Random();
- var scheduledTimes = new List();
-
- for (int i = 0; i < numberOfArticles; i++)
- {
- var baseDelayHours = rng.Next(2, 4); // Randomly choose between 2-3 hours delay
- var minutesToAdd = rng.Next(0, 60); // Randomly choose minutes (0-59)
-
- // Calculate new time by adding base delay and random minutes
- var nextTime = startTime.Add(new TimeSpan(baseDelayHours, minutesToAdd, 0));
-
- // Check if the new time is within 30 minutes of any existing time
- while (scheduledTimes.Exists(previousTime => Math.Abs((nextTime - previousTime).TotalMinutes) < 30))
- {
- // If the new time is within 30 minutes of an existing time, adjust it
- nextTime = nextTime.Add(new TimeSpan(0, 30, 0));
- }
-
- scheduledTimes.Add(nextTime);
- startTime = nextTime; // Update start time for the next article
- }
-
- return scheduledTimes;
-}
-
-///
-/// Converts a TimeSpan into a 12-hour AM/PM formatted time string.
-///
-/// The TimeSpan representing the time of day.
-/// A formatted string representing the time in AM/PM format.
-string ConvertTo12Hour(TimeSpan time)
-{
- var minutes = time.TotalMinutes;
- var hours12 = time.Hours % 12;
-
- if (hours12 == 0)
- hours12 = 1;
-
- var period = time.Hours >= 12 ? "PM" : "AM";
- return $"{hours12}:{time.Minutes:D2} {period}";
-}
-
-///
-/// Prompts the user to select a topic from a given list
-/// and returns the chosen topic.
-///
-/// An array of available topics.
-/// The selected topic as a string.
-string SelectTopics(List topics)
-{
- var topicChoice = "";
- var topicNum = 0;
- var userChoices = new List();
- var numOfTopics = 0;
- var topicDict = new Dictionary();
-
- foreach (var topic in topics)
- {
- numOfTopics++;
- var title = topic.Trim();
- topicDict.Add(numOfTopics, title);
- userChoices.Add($"{numOfTopics} {title}");
- }
-
- var topicSelect = string.Join(", ", userChoices.ToArray());
- Console.WriteLine($"{Environment.NewLine}Choose a Topic{Environment.NewLine}{topicSelect}");
- var input = Console.ReadLine();
-
- // Attempt to parse a number.
- if (int.TryParse(input, out topicNum) == true)
- topicChoice = topicDict[topicNum];
- else
- NewTopic(topics);
-
- return topicChoice;
-}
-
-///
-/// Prompts the user to select a date (either today or tomorrow) and returns the selected date as a formatted string.
-///
-/// A string representing the selected date in a short date format.
-string SelectDate()
-{
- var dtChoices = new[] { "Today", "Tomorrow" };
- var dtDict = new Dictionary();
- var dtSelection = new List();
- var dtChoice = 0;
- var dtNum = 0;
-
- foreach (var days in dtChoices)
- {
- dtNum++;
- var day = days.Trim();
- dtDict.Add(dtNum, day);
- dtSelection.Add($"{dtNum} {day}");
- }
-
- var topicSelect = string.Join(", ", dtSelection.ToArray());
- Console.WriteLine($"{Environment.NewLine}Choose a Date{Environment.NewLine}{topicSelect}");
- var input = Console.ReadLine();
-
- // Attempt to parse a number.
- if (int.TryParse(input, out dtNum) == true)
- dtChoice = dtNum;
-
- // Any choice above 2 tomorrow
- if (dtChoice >= 2)
- {
- var dt = DateTime.Now.AddDays(1);
- return dt.ToString("d");
- }
-
- return DateTime.Today.ToString("d");
-}
-
-///
-/// Allows the user to choose a new topic from a given list or default to placeholder if no selection is made.
-///
-/// A list of available topics.
-/// The selected topic or a default placeholder if none is chosen.
-string NewTopic(List topics)
-{
- var newTopic = "";
-
- if (UserChoice("Choose a Topic?"))
- newTopic = SelectTopics(topics);
- else
- newTopic = "Any";
-
- return newTopic;
-}
-
-///
-/// Exports the scheduled articles to a file, allowing the user to modify
-/// the directory, filename, and list of topics based on
-/// a configuration file if available.
-///
-void ExportSchedule(List storeTimes)
-{
- // App directory is used for config file
- var appDir = Tracer.AppDirectory;
- // File directory is used for file location set in config
- var outputDir = Directory.GetCurrentDirectory();
- var cfgFile = "config.toml";
-
- var topics = new List();
- var cfgPath = Path.Combine(appDir, cfgFile);
- var config = GetConfig(cfgPath);
- var outputFile = config.File;
- var filePath = Path.Combine(outputDir, outputFile!);
- var chosenTopic = "";
- var times = new List();
-
-
- // If the config file exists, read from that but don't assume anything is filled
- if (File.Exists(cfgPath))
- {
- Tracer.WriteLine(cfgPath);
- var toml = File.ReadAllText(cfgPath);
- var usrDir = config.Path;
- var usrFileName = config.File;
- // Convert list into array
- var list = config.Topics;
- var tomlList = string.Join(", ", list);
- var usrTopics = tomlList.Split(',');
-
- if (string.IsNullOrEmpty(usrDir))
- return;
-
- outputDir = usrDir;
-
- if (string.IsNullOrEmpty(usrFileName))
- return;
-
- outputFile = usrFileName;
-
- // If array is empty, return; otherwise, apply config
- if (usrTopics.Length < 0)
- return;
-
- foreach (var usrTopic in usrTopics)
- topics.Add(usrTopic);
-
-
- // Set new file Path
- filePath = Path.Combine(outputDir, outputFile!);
- }
-
- if (!File.Exists(filePath))
- File.WriteAllText(filePath, "[]");
-
- foreach (var time in storeTimes)
- times.Add(time.Trim());
-
- // Set new topic
- topics = config.Topics.ToList();
- chosenTopic = NewTopic(topics);
-
- var date = SelectDate();
-
- // Write to file.
- var jsonContent = File.ReadAllText(filePath);
- var jsonList = string.IsNullOrWhiteSpace(jsonContent) ? new List()
- : JsonSerializer.Deserialize>(jsonContent) ?? new List();
-
-
- jsonList.Add(new Schedule()
- {
- Topic = chosenTopic.Trim(),
- Date = date.Trim(),
- Times = times,
- });
-
- var jsonOptions = new JsonSerializerOptions()
- {
- WriteIndented = true,
- };
-
- var jsonString = JsonSerializer.Serialize(jsonList, jsonOptions);
- File.WriteAllText(filePath, jsonString);
- Tracer.WriteLine($"{jsonString}{Environment.NewLine}Written to: {filePath}");
-
- // Clear list from memory
- storeTimes.Clear();
-}
-
///
/// Displays the scheduled article times in a formatted manner and provides
/// options to export the schedule or restart the scheduling process.
///
-void PrintTimes(bool isRestart = false)
+void PrintTimes()
{
- var storeSchedule = new List();
- var scheduledTimes = GenerateTimes();
+ var storeSchedule = new List();
+ var scheduledTimes = Generator.GenerateTimes();
- // Clear the screen on restart
- if (isRestart)
- Console.Clear();
+ // Clear the screen on restart
+ Console.Clear();
- Console.WriteLine("=== Publish Times ===");
- foreach (var time in scheduledTimes)
- {
- var articleTime = $"{ConvertTo12Hour(time)}";
- // Correct format string to display time in 12-hour format with AM/PM
- Console.WriteLine(articleTime);
- // Store the schedule to memory for option export
- storeSchedule.Add(articleTime);
- }
+ Console.WriteLine("=== Publish Times ===");
+ foreach (var time in scheduledTimes)
+ {
+ var articleTime = $"{Generator.ConvertTo12Hour(time)}";
+ // Correct format string to display time in 12-hour format with AM/PM
+ Console.WriteLine(articleTime);
+ // Store the schedule to memory for option export
+ storeSchedule.Add(articleTime);
+ }
- // Give the user an option to export the schedule
- if (UserChoice("Retry?"))
- PrintTimes(true);
+ // Give the user an option to export the schedule
+ if (Interactive.UserChoice("Retry?"))
+ PrintTimes();
- // Give the user an option to export the schedule
- if (UserChoice("Export?"))
- ExportSchedule(storeSchedule);
+ // Give the user an option to export the schedule
+ Export.ToJSON(storeSchedule, "config.toml");
- if (UserChoice("Generate A New Batch?"))
- PrintTimes(true);
- else
- {
- Console.Clear();
- Environment.Exit(Environment.ExitCode);
- }
+ if (Interactive.UserChoice("Generate A New Batch?"))
+ PrintTimes();
+ else
+ {
+ Console.Clear();
+ Environment.Exit(Environment.ExitCode);
+ }
}
// Start the loop
diff --git a/README.md b/README.md
index 6d51334..0c30b34 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-# StaggerPost
+# Stagger Post
-This is a very simple console application that generates a list of times to publish news articles within a randomized 2-3 hour delay within a 30-minute window to avoid conflicts. This keeps thing flowing at an organic and slow pace.
+This is a very simple console application that suggests a list of times to post news articles within a randomized 2-3 hour and 30-minute delay to avoid conflicts. This keeps thing flowing at an organic and slow pace.
-It is not recommended for use with hot topics. Instead, you should focus on overlooked foreign affairs, local news or op-eds. Of course, this is just covering general news.
+It is not recommended for use with breaking news, of course. Instead, you should focus on overlooked local news or op-eds. Of course, this is just covering general news. It is really good niche communities.
## Exporting
@@ -17,14 +17,14 @@ An optional ``config.toml`` file allows for further customization of file name,
```json
[
{
- "topic": "Games",
- "date": "3/16/2025",
+ "community": "games@lemmy.world",
+ "date": "3/22/2025",
"times": [
- "11:41 AM",
- "2:05 PM",
- "5:05 PM",
- "8:18 PM",
- "11:02 PM"
+ "1:34 PM",
+ "3:03 PM",
+ "5:27 PM",
+ "9:13 PM",
+ "11:37 PM"
]
}
]
diff --git a/Schedule.cs b/Schedule.cs
index c430bc9..0591288 100644
--- a/Schedule.cs
+++ b/Schedule.cs
@@ -1,12 +1,11 @@
-
public class Schedule
{
- [JsonPropertyName("topic")]
- public string Topic { get; set; } = "";
+ [JsonPropertyName("community")]
+ public string Community { get; set; } = "";
- [JsonPropertyName("date")]
- public string Date { get; set; } = "";
+ [JsonPropertyName("date")]
+ public string Date { get; set; } = "";
- [JsonPropertyName("times")]
- public IList Times { get; set; } = new List();
+ [JsonPropertyName("times")]
+ public IList Times { get; set; } = new List();
}
diff --git a/Tracer.cs b/Tracer.cs
index ca6190e..8ab4550 100644
--- a/Tracer.cs
+++ b/Tracer.cs
@@ -7,60 +7,81 @@ namespace StaggerPost;
///
internal static class Tracer
{
- ///
- /// Writes a line of text to the console, but only when in DEBUG mode.
- ///
- /// The text to write to the console.
- [Conditional("DEBUG")]
- internal static void WriteLine(string content) =>
- Console.WriteLine(content);
+ const string LOG = "[LOG]:";
- ///
- /// Writes text to the console without a newline, but only when in DEBUG mode.
- ///
- /// The text to write to the console.
- [Conditional("DEBUG")]
- internal static void Write(string content) =>
- Console.Write(content);
+ ///
+ /// Writes a line of text to the console, but only when in DEBUG mode.
+ ///
+ /// The text to write to the console.
+ [Conditional("DEBUG")]
+ internal static void LogLine(string content) => Console.WriteLine($"{LOG} {content}");
- ///
- /// Writes multiple lines of text to the console, but only when in DEBUG mode.
- ///
- /// A collection of text lines to write to the console.
- [Conditional("DEBUG")]
- internal static void WriteLine(IEnumerable contents)
- {
- foreach (var content in contents)
- {
- Console.WriteLine(content);
- }
- }
+ ///
+ /// Writes text to the console without a newline, but only when in DEBUG mode.
+ ///
+ /// The text to write to the console.
+ [Conditional("DEBUG")]
+ internal static void Log(string content) => Console.Write($"{LOG} {content}");
- ///
- /// Writes multiple text entries to the console without newlines, but only when in DEBUG mode.
- ///
- /// A collection of text entries to write to the console.
- [Conditional("DEBUG")]
- internal static void Write(IEnumerable contents)
- {
- foreach (var content in contents)
- {
- Console.Write(content);
- }
- }
+ ///
+ /// Writes multiple lines of text to the console, but only when in DEBUG mode.
+ ///
+ /// A collection of text lines to write to the console.
+ [Conditional("DEBUG")]
+ internal static void LogLine(IEnumerable contents)
+ {
+ foreach (var content in contents)
+ {
+ Console.WriteLine($"{LOG} {content}");
+ }
+ }
- ///
- /// Gets the current working directory in DEBUG mode or the application's base directory in release mode.
- ///
- internal static string AppDirectory
- {
- get
- {
+ ///
+ /// Writes multiple text entries to the console without newlines, but only when in DEBUG mode.
+ ///
+ /// A collection of text entries to write to the console.
+ [Conditional("DEBUG")]
+ internal static void Log(IEnumerable contents)
+ {
+ foreach (var content in contents)
+ {
+ Console.Write($"{LOG} {content}");
+ }
+ }
+
+ ///
+ /// Gets the current working directory in DEBUG mode or the application's base directory in release mode.
+ ///
+ internal static string AppDirectory
+ {
+ get
+ {
#if DEBUG
- return Directory.GetCurrentDirectory();
+ return Directory.GetCurrentDirectory();
#else
- return AppDomain.CurrentDomain.BaseDirectory;
+ return AppDomain.CurrentDomain.BaseDirectory;
#endif
- }
- }
+ }
+ }
+
+ ///
+ /// Determines the appropriate output directory based on the given directory path.
+ /// In DEBUG mode, it always returns the current working directory.
+ /// In release mode, it returns the provided directory unless it contains a '/', in which case it defaults to the current directory.
+ ///
+ /// The directory path to evaluate.
+ /// The resolved output directory as a string.
+ internal static string OutputDirectory(string dir)
+ {
+ var curDir = Directory.GetCurrentDirectory();
+
+#if DEBUG
+ return curDir;
+#else
+ if (dir.Contains("/"))
+ return curDir;
+
+ return dir;
+#endif
+ }
}
diff --git a/config.toml.sample b/config.toml.sample
index c17da12..2fe4c1e 100644
--- a/config.toml.sample
+++ b/config.toml.sample
@@ -1,6 +1,6 @@
-path = "/home/tonytins/Documents/"
-file = "newscycle.json"
-topics = [
+path = "/"
+file = "example.json"
+communities = [
"Games",
"News",
"Science",