diff --git a/Config.cs b/Config.cs
index b5c236f..14a4dc2 100644
--- a/Config.cs
+++ b/Config.cs
@@ -10,15 +10,16 @@ public class Config
///
/// Gets or sets the name of the schedule file.
///
- public string File { get; set; } = "schedule.json";
+ public string? File { get; set; }
///
/// Gets or sets the directory path where the schedule file is stored.
///
- public string Path { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+ public string? Path { get; set; }
///
/// Gets or sets the list of available topics from the configuration file.
///
- public IList Topics { get; set; } = new[] { "Games", "Politics", "Research", "Technology" };
+ public List Topics { get; set; } = new List();
+
}
diff --git a/GlobalUsings.cs b/GlobalUsings.cs
index 6e12d2f..5e35567 100644
--- a/GlobalUsings.cs
+++ b/GlobalUsings.cs
@@ -1,3 +1,4 @@
+global using System.Diagnostics;
global using Tomlyn;
global using Tomlyn.Model;
global using PublishTimes;
diff --git a/Program.cs b/Program.cs
index 631fc3d..c5dd133 100644
--- a/Program.cs
+++ b/Program.cs
@@ -18,8 +18,13 @@ Config GetConfig(string file = "config.toml")
return model;
}
-
- return new Config();
+ var defaultList = new[] { "Games", "Politics", "Research", "Technology" };
+ return new Config()
+ {
+ File = "schedule.json",
+ Path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+ Topics = defaultList.ToList()
+ };
}
///
@@ -42,7 +47,7 @@ bool UserChoice(string choice)
/// delay between each while avoiding time conflicts within a 30-minute window.
///
/// A list of TimeSpan objects representing scheduled article times.
-List GenerateSchedule()
+List GenerateTimes()
{
var numberOfArticles = 5; // Define how many articles to schedule
var startTime = new TimeSpan(9, 0, 0); // Starting time at 9:00 AM
@@ -149,7 +154,7 @@ string NewTopic(List topics)
void ExportSchedule(List storeTimes)
{
// App directory is used for config file
- var appDir = AppDomain.CurrentDomain.BaseDirectory;
+ var appDir = Tracer.AppDirectory;
// File directory is used for file location set in config
var outputDir = Directory.GetCurrentDirectory();
var cfgFile = "config.toml";
@@ -166,24 +171,32 @@ void ExportSchedule(List storeTimes)
// 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 usrTopics = config.Topics;
+ var list = config.Topics;
+ var tomlList = string.Join(", ", list);
+ var usrTopics = tomlList.Split(',');
- if (!string.IsNullOrEmpty(usrDir))
- outputDir = usrDir;
+ if (string.IsNullOrEmpty(usrDir))
+ return;
- if (!string.IsNullOrEmpty(usrFileName))
- outputFile = usrFileName;
+ 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);
- // If array is populated, apply config
- if (!usrTopics.Any())
- {
- foreach (var usrTopic in usrTopics)
- topics.Add(usrTopic);
- }
// Set new file Path
filePath = Path.Combine(outputDir, outputFile!);
@@ -211,10 +224,14 @@ void ExportSchedule(List storeTimes)
Times = times,
});
- var jsonString = JsonSerializer.Serialize(jsonList);
- Console.WriteLine(jsonList);
+ var jsonOptions = new JsonSerializerOptions()
+ {
+ WriteIndented = true,
+ };
+
+ var jsonString = JsonSerializer.Serialize(jsonList, jsonOptions);
File.WriteAllText(filePath, jsonString);
- Console.WriteLine($"{Environment.NewLine}Written to: {filePath}");
+ Tracer.WriteLine($"{jsonString}{Environment.NewLine}Written to: {filePath}");
// Clear list from memory
storeTimes.Clear();
@@ -224,10 +241,10 @@ void ExportSchedule(List storeTimes)
/// Displays the scheduled article times in a formatted manner and provides
/// options to export the schedule or restart the scheduling process.
///
-void PrintSchedule(bool isRestart = false)
+void PrintTimes(bool isRestart = false)
{
var storeSchedule = new List();
- var scheduledTimes = GenerateSchedule();
+ var scheduledTimes = GenerateTimes();
// Clear the screen on restart
if (isRestart)
@@ -245,14 +262,14 @@ void PrintSchedule(bool isRestart = false)
// Give the user an option to export the schedule
if (UserChoice("Retry?"))
- PrintSchedule(true);
+ PrintTimes(true);
// Give the user an option to export the schedule
if (UserChoice("Export?"))
ExportSchedule(storeSchedule);
if (UserChoice("Generate A New Batch?"))
- PrintSchedule(true);
+ PrintTimes(true);
else
{
Console.Clear();
@@ -261,4 +278,4 @@ void PrintSchedule(bool isRestart = false)
}
// Start the loop
-PrintSchedule();
+PrintTimes();
diff --git a/PublishTimes.csproj b/PublishTimes.csproj
index 109581c..ef9295c 100644
--- a/PublishTimes.csproj
+++ b/PublishTimes.csproj
@@ -4,6 +4,7 @@
Exe
net9.0
enable
+ 0.2.101
enable
diff --git a/README.md b/README.md
index 5322e33..191612d 100644
--- a/README.md
+++ b/README.md
@@ -6,12 +6,29 @@ It is not recommended for use with hot topics. Instead, you should focus on over
## Exporting
-Once it generates a list of times, you can retry or export the times. If you export, you're requested to select from a number of topics or default to none if no selection is made. Upon export, you can start over or exit.
+Once it generates a list of times, you can retry or export it as a JSON format. If you export, you're requested to select from a number of topics or default to none if no selection is made. Upon export, you can start over or exit.
Choice selection is based on the Y/N keys. ``Enter`` works the same as ``Y`` while pressing any other key is the equivalent of ``N``. You can make mistakes, but it expects failure.
An optional ``config.toml`` file allows for further customization of file name, directory, and topics.
+### Example
+
+```json
+[
+ {
+ "topic": "Games",
+ "times": [
+ "11:41 AM",
+ "2:05 PM",
+ "5:05 PM",
+ "8:18 PM",
+ "11:02 PM"
+ ]
+ }
+]
+```
+
## Background
A while back, I [found a tool](https://schedule.lemmings.world) to schedule articles on Lemmy. I've been posting within a few hours apart at random minutes and I wanted to something decide that for me. I had AI write the base algorithm, everything else is my own touches.
diff --git a/Tracer.cs b/Tracer.cs
new file mode 100644
index 0000000..c9dc29c
--- /dev/null
+++ b/Tracer.cs
@@ -0,0 +1,66 @@
+// I hereby waive this project under the public domain - see UNLICENSE for details.
+namespace PublishTimes;
+
+///
+/// Provides debug-only console output methods.
+/// These methods are only executed when the application is compiled in DEBUG mode.
+///
+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);
+
+ ///
+ /// 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 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 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);
+ }
+ }
+
+ ///
+ /// 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();
+#else
+ return AppDomain.CurrentDomain.BaseDirectory;
+#endif
+ }
+ }
+}