fix: mark replies '?' after pagination yields no reply notes

Previously, the '?' marker only fired when page 1 returned empty notes.
Posts whose page 1 contained only likes/reblogs and whose page 2 came
back empty were never marked, so GetRepliesWithFilledText kept reselecting
them every iteration. Now mark after the pagination loop whenever
rowsUpdated==0 and at least one page returned 200 OK.

UpdateAllNoteReplyTextForPost now returns int so the caller can fold
the count into emptyReplyCount/rowsUpdated for accurate Done logging.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
jim
2026-05-07 15:01:04 -05:00
co-authored by Claude Opus 4.7
parent f2539dc9d0
commit 081528a81a
2 changed files with 21 additions and 12 deletions
+4 -1
View File
@@ -1515,7 +1515,7 @@ namespace URLNotesGrabberCORE
return rowsAffected; return rowsAffected;
} }
public static void UpdateAllNoteReplyTextForPost(string rootBlogName, long postID, string replyText, string? DBPath = null) public static int UpdateAllNoteReplyTextForPost(string rootBlogName, long postID, string replyText, string? DBPath = null)
{ {
DBPath ??= GetDefaultDbPath(); DBPath ??= GetDefaultDbPath();
SQLiteConnection connection = new SQLiteConnection("Data Source=" + DBPath); SQLiteConnection connection = new SQLiteConnection("Data Source=" + DBPath);
@@ -1543,6 +1543,8 @@ namespace URLNotesGrabberCORE
{ {
Console.WriteLine($"[UpdateAllNoteReplyTextForPost] Successfully updated {rowsAffected} row(s) for {rootBlogName}/{postID} with '{replyText}'"); Console.WriteLine($"[UpdateAllNoteReplyTextForPost] Successfully updated {rowsAffected} row(s) for {rootBlogName}/{postID} with '{replyText}'");
} }
return rowsAffected;
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -1550,6 +1552,7 @@ namespace URLNotesGrabberCORE
// Breakpoint here // Breakpoint here
Console.WriteLine($"[UpdateAllNoteReplyTextForPost] Error updating reply text: {ex.Message}"); Console.WriteLine($"[UpdateAllNoteReplyTextForPost] Error updating reply text: {ex.Message}");
Console.WriteLine($"[UpdateAllNoteReplyTextForPost] StackTrace: {ex.StackTrace}"); Console.WriteLine($"[UpdateAllNoteReplyTextForPost] StackTrace: {ex.StackTrace}");
return 0;
} }
finally finally
{ {
+16 -10
View File
@@ -459,6 +459,7 @@ namespace URLNotesGrabberCORE
int emptyReplyCount = 0; int emptyReplyCount = 0;
long pageTimestamp = 0; long pageTimestamp = 0;
int page = 0; int page = 0;
bool sawHealthyResponse = false;
while (page < MaxPages) while (page < MaxPages)
{ {
@@ -478,6 +479,9 @@ namespace URLNotesGrabberCORE
if (postsResponse?.meta?.status != 429) if (postsResponse?.meta?.status != 429)
ApiKeyPool.MarkAvailable(key); ApiKeyPool.MarkAvailable(key);
if (postsResponse?.meta?.status == 200)
sawHealthyResponse = true;
if (postsResponse?.response == null || postsResponse.response.notes == null || postsResponse.response.notes.Count == 0) if (postsResponse?.response == null || postsResponse.response.notes == null || postsResponse.response.notes.Count == 0)
{ {
var prevColor = Console.ForegroundColor; var prevColor = Console.ForegroundColor;
@@ -488,16 +492,6 @@ namespace URLNotesGrabberCORE
var raw = postsResponse?.rawJson ?? string.Empty; var raw = postsResponse?.rawJson ?? string.Empty;
if (raw.Length > 500) raw = raw.Substring(0, 500) + "...[truncated]"; if (raw.Length > 500) raw = raw.Substring(0, 500) + "...[truncated]";
Console.WriteLine($"[Reply Text] raw: {raw}"); Console.WriteLine($"[Reply Text] raw: {raw}");
// First-page 200 OK with empty notes = post has no conversational notes per Tumblr.
// Mark all the post's replies '?' so the work queue stops handing this post back.
if (page == 1 && postsResponse?.meta?.status == 200)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"[Reply Text] Marking all replies for {blogName}/{postID} '?' (200 OK with no conversational notes)");
Console.ForegroundColor = prevColor;
DataAccess.UpdateAllNoteReplyTextForPost(blogName, postID, "?");
}
break; break;
} }
@@ -551,6 +545,18 @@ namespace URLNotesGrabberCORE
pageTimestamp = lastNoteTimestamp; pageTimestamp = lastNoteTimestamp;
} }
// If pagination finished without updating any reply rows but the API responded healthily
// at least once, mark the post's outstanding '.' replies '?' so the work queue releases it.
if (rowsUpdated == 0 && sawHealthyResponse)
{
var prevColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"[Reply Text] Marking outstanding replies for {blogName}/{postID} '?' (healthy 200 OK, no matching reply notes after {page} page(s))");
Console.ForegroundColor = prevColor;
rowsUpdated = DataAccess.UpdateAllNoteReplyTextForPost(blogName, postID, "?");
emptyReplyCount += rowsUpdated;
}
Console.WriteLine($"[Reply Text] Done {blogName}/{postID}: notes={replyCount}, rowsUpdated={rowsUpdated}, empty='?'={emptyReplyCount}, pages={page}"); Console.WriteLine($"[Reply Text] Done {blogName}/{postID}: notes={replyCount}, rowsUpdated={rowsUpdated}, empty='?'={emptyReplyCount}, pages={page}");
} }
catch (Exception ex) catch (Exception ex)