From 64a914c14de894b632579b88d82f73f49b29dfd2 Mon Sep 17 00:00:00 2001 From: jim Date: Thu, 7 May 2026 14:10:37 -0500 Subject: [PATCH] fix: tolerate ~5s timestamp drift in UpdateNoteReplyText The API returns reply timestamps that are ~1s ahead of what -collect originally stored, so an exact TimeStamp match in the UPDATE was hitting zero rows for every note - the API call worked, the reply text came back, but nothing landed in the DB. Match within +-5s instead. Also return rowsAffected from UpdateNoteReplyText and report it separately from notes-seen in the summary so misses are visible. --- URLNotesGrabberCORE/DataAccess.cs | 11 +++++++---- URLNotesGrabberCORE/Program.cs | 9 +++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/URLNotesGrabberCORE/DataAccess.cs b/URLNotesGrabberCORE/DataAccess.cs index 7f3f76b..43398d4 100644 --- a/URLNotesGrabberCORE/DataAccess.cs +++ b/URLNotesGrabberCORE/DataAccess.cs @@ -1467,17 +1467,19 @@ namespace URLNotesGrabberCORE return APICount; } - public static void UpdateNoteReplyText(string rootBlogName, long postID, string noteBlogName, long timestamp, string replyText, string? DBPath = null) + public static int UpdateNoteReplyText(string rootBlogName, long postID, string noteBlogName, long timestamp, string replyText, string? DBPath = null) { DBPath ??= GetDefaultDbPath(); SQLiteConnection connection = new SQLiteConnection("Data Source=" + DBPath); + int rowsAffected = 0; try { connection.Open(); //string sql = "UPDATE Notes SET replyText = @replyText WHERE rootBlogName = @rootBlogName AND PostID = @PostID AND noteBlogName = @noteBlogName AND TimeStamp = @TimeStamp AND Type = 'reply'"; - string sql = "UPDATE Notes SET replyText = @replyText, DateModified = @dateModified WHERE PostID = @PostID AND noteBlogName = @noteBlogName AND TimeStamp = @TimeStamp AND Type = 'reply' AND IFNULL(replyText, '.') <> @replyText"; + // Tolerance window on TimeStamp absorbs the ~1s drift between what -collect stored and what mode=conversation returns now. + string sql = "UPDATE Notes SET replyText = @replyText, DateModified = @dateModified WHERE PostID = @PostID AND noteBlogName = @noteBlogName AND ABS(TimeStamp - @TimeStamp) <= 5 AND Type = 'reply' AND IFNULL(replyText, '.') <> @replyText"; using (SQLiteCommand command = new SQLiteCommand(sql, connection)) { command.Parameters.AddWithValue("@replyText", replyText ?? "."); @@ -1486,8 +1488,8 @@ namespace URLNotesGrabberCORE command.Parameters.AddWithValue("@PostID", postID); command.Parameters.AddWithValue("@noteBlogName", noteBlogName); command.Parameters.AddWithValue("@TimeStamp", timestamp); - int rowsAffected = command.ExecuteNonQuery(); - + rowsAffected = command.ExecuteNonQuery(); + if (rowsAffected == 0) { Console.WriteLine($"[UpdateNoteReplyText] INFO: No rows updated for {rootBlogName}/{postID} from {noteBlogName} at {UnixTimeStampToDateTime(timestamp)} (row not found or value unchanged)"); @@ -1510,6 +1512,7 @@ namespace URLNotesGrabberCORE { connection.Close(); } + return rowsAffected; } public static void UpdateAllNoteReplyTextForPost(string rootBlogName, long postID, string replyText, string? DBPath = null) diff --git a/URLNotesGrabberCORE/Program.cs b/URLNotesGrabberCORE/Program.cs index 612ac9d..cc170be 100644 --- a/URLNotesGrabberCORE/Program.cs +++ b/URLNotesGrabberCORE/Program.cs @@ -455,6 +455,7 @@ namespace URLNotesGrabberCORE Console.WriteLine($"[Reply Text] Fetching reply text for {blogName}/{postID}"); int replyCount = 0; + int rowsUpdated = 0; int emptyReplyCount = 0; long pageTimestamp = 0; int page = 0; @@ -500,7 +501,7 @@ namespace URLNotesGrabberCORE { if (!string.IsNullOrEmpty(note.reply_text)) { - DataAccess.UpdateNoteReplyText(blogName, postID, note.blog_name, note.timestamp, note.reply_text); + rowsUpdated += DataAccess.UpdateNoteReplyText(blogName, postID, note.blog_name, note.timestamp, note.reply_text); replyCount++; string displayText = note.reply_text.Length > 100 @@ -513,14 +514,14 @@ namespace URLNotesGrabberCORE } else { - DataAccess.UpdateNoteReplyText(blogName, postID, note.blog_name, note.timestamp, "?"); + rowsUpdated += DataAccess.UpdateNoteReplyText(blogName, postID, note.blog_name, note.timestamp, "?"); emptyReplyCount++; Console.WriteLine($"[Reply Text] Reply from {note.blog_name} returned with empty reply_text - marked '?'"); } } else if (note.type == "reblog" && !string.IsNullOrEmpty(note.reply_text)) { - DataAccess.UpdateNoteReplyText(blogName, postID, note.blog_name, note.timestamp, note.reply_text); + rowsUpdated += DataAccess.UpdateNoteReplyText(blogName, postID, note.blog_name, note.timestamp, note.reply_text); replyCount++; string displayText = note.reply_text.Length > 100 @@ -540,7 +541,7 @@ namespace URLNotesGrabberCORE pageTimestamp = lastNoteTimestamp; } - Console.WriteLine($"[Reply Text] Done {blogName}/{postID}: updated={replyCount}, empty='?'={emptyReplyCount}, pages={page}"); + Console.WriteLine($"[Reply Text] Done {blogName}/{postID}: notes={replyCount}, rowsUpdated={rowsUpdated}, empty='?'={emptyReplyCount}, pages={page}"); } catch (Exception ex) {