diff --git a/URLNotesGrabberCORE/DataAccess.cs b/URLNotesGrabberCORE/DataAccess.cs index 01759a8..61b6032 100644 --- a/URLNotesGrabberCORE/DataAccess.cs +++ b/URLNotesGrabberCORE/DataAccess.cs @@ -767,7 +767,7 @@ namespace URLNotesGrabberCORE if (!string.IsNullOrEmpty(specificBlog)) sql = "SELECT BlogName, COALESCE(LikesPulled, 0), COALESCE(LikesCursor, 0) FROM Blogs WHERE BlogName = @blog"; else - sql = "SELECT BlogName, COALESCE(LikesPulled, 0), COALESCE(LikesCursor, 0) FROM Blogs WHERE COALESCE(LikesPulled, 0) = 0"; + sql = "SELECT B.BlogName, COALESCE(LikesPulled, 0), COALESCE(LikesCursor, 0) FROM Blogs B INNER JOIN Notes N ON N.NoteBlogName = B.BlogName WHERE B.LikesPulled = 0 AND N.TimeStamp >= 1535778000 AND N.rootBlogName = B.BlogName AND EXISTS (SELECT 1 FROM Posts P WHERE P.BlogName = B.BlogName) GROUP BY B.BlogName ORDER BY MIN(N.Timestamp);"; using (SQLiteCommand command = new SQLiteCommand(sql, connection)) { @@ -1280,6 +1280,7 @@ namespace URLNotesGrabberCORE { public static string Blog { get; set; } = string.Empty; private static IConfiguration Configuration { get; set; } = null!; + private static string ApiConfigSection { get; set; } = "TumblrApi"; static APIAccess() { @@ -1288,17 +1289,37 @@ namespace URLNotesGrabberCORE .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); - if (Configuration["TumblrApi:ConsumerKey"] == null) - throw new InvalidOperationException("TumblrApi configuration is missing in appsettings.json"); + ValidateApiSection(ApiConfigSection); } - private static string ConsumerKey => Configuration["TumblrApi:ConsumerKey"] ?? + public static void SetApiConfigSection(string sectionName) + { + if (string.IsNullOrWhiteSpace(sectionName)) + sectionName = "TumblrApi"; + + ValidateApiSection(sectionName); + ApiConfigSection = sectionName; + Console.WriteLine($"Using API settings section: {ApiConfigSection}"); + } + + private static void ValidateApiSection(string sectionName) + { + if (Configuration[$"{sectionName}:ConsumerKey"] == null || + Configuration[$"{sectionName}:ConsumerSecret"] == null || + Configuration[$"{sectionName}:OAuthToken"] == null || + Configuration[$"{sectionName}:OAuthTokenSecret"] == null) + { + throw new InvalidOperationException($"{sectionName} configuration is missing required keys in appsettings.json"); + } + } + + private static string ConsumerKey => Configuration[$"{ApiConfigSection}:ConsumerKey"] ?? throw new InvalidOperationException("ConsumerKey is not configured"); - private static string ConsumerSecret => Configuration["TumblrApi:ConsumerSecret"] ?? + private static string ConsumerSecret => Configuration[$"{ApiConfigSection}:ConsumerSecret"] ?? throw new InvalidOperationException("ConsumerSecret is not configured"); - private static string OAuthToken => Configuration["TumblrApi:OAuthToken"] ?? + private static string OAuthToken => Configuration[$"{ApiConfigSection}:OAuthToken"] ?? throw new InvalidOperationException("OAuthToken is not configured"); - private static string OAuthTokenSecret => Configuration["TumblrApi:OAuthTokenSecret"] ?? + private static string OAuthTokenSecret => Configuration[$"{ApiConfigSection}:OAuthTokenSecret"] ?? throw new InvalidOperationException("OAuthTokenSecret is not configured"); private static int GetRetryDelaySecondsFromHeaders(IEnumerable? headers) diff --git a/URLNotesGrabberCORE/Program.cs b/URLNotesGrabberCORE/Program.cs index 07f14f9..bbfa6c3 100644 --- a/URLNotesGrabberCORE/Program.cs +++ b/URLNotesGrabberCORE/Program.cs @@ -21,6 +21,45 @@ namespace URLNotesGrabberCORE .Build(); var settings = config.GetSection("appSettings"); + string apiSectionName = "TumblrApi"; + List filteredArgs = new List(); + for (int i = 0; i < args.Length; i++) + { + if (string.Equals(args[i], "-api3", StringComparison.OrdinalIgnoreCase) || + string.Equals(args[i], "--api3", StringComparison.OrdinalIgnoreCase)) + { + apiSectionName = "TumblrApi3"; + continue; + } + + if (string.Equals(args[i], "-api4", StringComparison.OrdinalIgnoreCase) || + string.Equals(args[i], "--api4", StringComparison.OrdinalIgnoreCase)) + { + apiSectionName = "TumblrApi4"; + continue; + } + + if (string.Equals(args[i], "-api", StringComparison.OrdinalIgnoreCase) || + string.Equals(args[i], "--api", StringComparison.OrdinalIgnoreCase)) + { + if (i + 1 < args.Length && !string.IsNullOrWhiteSpace(args[i + 1])) + { + apiSectionName = args[i + 1].Trim(); + i++; + } + else + { + Console.WriteLine("--Missing API section after -api/--api. Using default TumblrApi.--"); + } + continue; + } + + filteredArgs.Add(args[i]); + } + + args = filteredArgs.ToArray(); + APIAccess.SetApiConfigSection(apiSectionName); + // Setup Dual Logging string logPath = "console_output.log"; if (File.Exists(logPath)) @@ -77,6 +116,12 @@ namespace URLNotesGrabberCORE Console.WriteLine("-likes\t Fetch likes for all blogs needing it (LikesPulled=0), or a specific blog via param"); + Console.WriteLine("-api3\t Use TumblrApi3 settings from appsettings.json"); + + Console.WriteLine("-api4\t Use TumblrApi4 settings from appsettings.json"); + + Console.WriteLine("-api [section]\t Use a specific API settings section from appsettings.json (e.g. TumblrApi3)"); + break; case "-parse": diff --git a/URLNotesGrabberCORE/appsettings.json b/URLNotesGrabberCORE/appsettings.json index 69ff7c5..69358fd 100644 --- a/URLNotesGrabberCORE/appsettings.json +++ b/URLNotesGrabberCORE/appsettings.json @@ -15,5 +15,17 @@ "ConsumerSecret": "sA8BwNVTVKqBRRJmHbAD6NuyKPJ3bb9cei2bYhMgqT8cLX8tSG", "OAuthToken": "HPJI6IijHoKN6WzBumG7KjS7g01iCu07jQsulpueKbWN1ZJ35J", "OAuthTokenSecret": "ajkN0Z1kKrsJaIXZEDI8zLsjRSQxFkfgO1i5k78FuQYCQjSY7w" + }, + "TumblrApi3": { + "ConsumerKey": "Jmoh13AS9hKBYsf939uENQsiWUuZJLFT3do4YK9P0bpspVuxkH", + "ConsumerSecret": "8LcHjuqpOS9gZZPaML1joT330w5NqyGdreSqSBazdAWCADzcms", + "OAuthToken": "Gm2esFTeb5LKsb4A2YJGrF2Udycfc0AF8afof2qNGyzNSq1qWM", + "OAuthTokenSecret": "Kfokor80s5fVue91OmNHidCdILZ9AnHtRplrct2P6Q75jgNTLa" + }, + "TumblrApi4": { + "ConsumerKey": "gOuydIEENkRmEvvuf57R69yPRb39FC0Egb9p6ntxWuCuFzlsV3", + "ConsumerSecret": "0my913slXAHgra4mEEYV98stJ3wXGjPTWJeviiZXwJ2AqzYtIF ", + "OAuthToken": "JHk08YufSrsetTR1Ekuh10cPOzC6rjqU5WwVu3uV4vvLzp0w8w", + "OAuthTokenSecret": "1oryr4WMBxuDrt4vL4sJQs5qNagkH3KxwIf61M8SfvklTrhHSb" } } \ No newline at end of file