From c928266f2a4d90c1cdb0a93d6040ab7216d0f9ea Mon Sep 17 00:00:00 2001 From: Tassilo Karge Date: Sun, 18 Aug 2024 17:40:25 +0200 Subject: [PATCH] Use earliest date available for publication date Only when there is a provided publication date on creation, use that one without questioning it Fix publication date not being transmitted by RefreshManager.m Most dates interpretations/manipulations are now in Database.m During fetching from feeds, we just retrieve the infos and store them in relevant Article fields. This makes the logic more apprehensible and easier to maintain. Solves issue #1749 Co-authored-by: Barijaona Ramaholimihaso --- Vienna/Sources/Database/Database.m | 49 ++++++++++++++++-------- Vienna/Sources/Fetching/OpenReader.m | 18 +++------ Vienna/Sources/Fetching/RefreshManager.m | 2 + Vienna/Sources/Parsing/AtomFeed.m | 10 ++++- 4 files changed, 50 insertions(+), 29 deletions(-) diff --git a/Vienna/Sources/Database/Database.m b/Vienna/Sources/Database/Database.m index a15dcfcd2e..717f3937e6 100644 --- a/Vienna/Sources/Database/Database.m +++ b/Vienna/Sources/Database/Database.m @@ -1521,11 +1521,25 @@ -(BOOL)addArticle:(Article *)article toFolder:(NSInteger)folderID NSDate *currentDate = [NSDate date]; - // We set the publication date ourselves if it is not contained in the feed, and only once when the article is created - NSDate *publicationDate = article.publicationDate ? article.publicationDate : currentDate; - article.publicationDate = publicationDate; + // use the given publication date if it is contained in the feed, or the earliest date available + NSDate * publicationDate = article.publicationDate; + if (!publicationDate) { + publicationDate = article.lastUpdate && [article.lastUpdate isLessThan:currentDate] + ? article.lastUpdate + : currentDate; + article.publicationDate = publicationDate; + } + + // if a last update date is not provided, use our publication date + NSDate * lastUpdate = article.lastUpdate; + if (!lastUpdate) { + lastUpdate = publicationDate; + article.lastUpdate = lastUpdate; + } - NSDate * lastUpdate = article.lastUpdate ? article.lastUpdate : currentDate; + // Dates are stored as time intervals + NSTimeInterval lastUpdateIntervalSince1970 = lastUpdate.timeIntervalSince1970; + NSTimeInterval publicationIntervalSince1970 = publicationDate.timeIntervalSince1970; // Set some defaults if (userName == nil) { @@ -1537,10 +1551,6 @@ -(BOOL)addArticle:(Article *)article toFolder:(NSInteger)folderID articleTitle = [NSString vna_stringByRemovingHTML:articleBody].vna_firstNonBlankLine; } - // Dates are stored as time intervals - NSTimeInterval lastUpdateIntervalSince1970 = lastUpdate.timeIntervalSince1970; - NSTimeInterval publicationIntervalSince1970 = publicationDate.timeIntervalSince1970; - __block BOOL success; [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { success = [db executeUpdate:@"INSERT INTO messages (message_id, parent_id, folder_id, sender, link, date, createddate, read_flag, marked_flag, deleted_flag, title, text, revised_flag, enclosure, hasenclosure_flag) " @@ -1600,9 +1610,20 @@ -(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID wit NSInteger parentId = article.parentId; BOOL revised_flag = article.revised; - //keep last update date the same if not set in the current version of the article - NSDate * lastUpdate = article.lastUpdate ? article.lastUpdate : existingArticle.lastUpdate; - //we do not update the publication date ever after inserting the article into the DB + // keep last update date the same if not set in the current version of the article + NSDate * lastUpdate = article.lastUpdate && [article.lastUpdate isGreaterThan:existingArticle.lastUpdate] + ? article.lastUpdate + : existingArticle.lastUpdate; + + // we never change the publication date, unless the date provided in the feed is prior to it and makes sense + NSDate * publicationDate = existingArticle.publicationDate; + if (article.publicationDate && [article.publicationDate isLessThan:existingArticle.publicationDate]) { + publicationDate = article.publicationDate; + } + + // Dates are stored as time intervals + NSTimeInterval lastUpdateIntervalSince1970 = lastUpdate.timeIntervalSince1970; + NSTimeInterval publicationIntervalSince1970 = publicationDate.timeIntervalSince1970; // Set some defaults if (userName == nil) { @@ -1614,9 +1635,6 @@ -(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID wit articleTitle = [NSString vna_stringByRemovingHTML:articleBody].vna_firstNonBlankLine; } - // Dates are stored as time intervals - NSTimeInterval lastUpdateIntervalSince1970 = lastUpdate.timeIntervalSince1970; - // The article is revised if either the title or the body has changed. NSString * existingTitle = existingArticle.title; @@ -1649,12 +1667,13 @@ -(BOOL)updateArticle:(Article *)existingArticle ofFolder:(NSInteger)folderID wit __block BOOL success; [queue inDatabase:^(FMDatabase *db) { - success = [db executeUpdate:@"UPDATE messages SET parent_id=?, sender=?, link=?, date=?, " + success = [db executeUpdate:@"UPDATE messages SET parent_id=?, sender=?, link=?, date=?, createddate=?, " @"read_flag=0, title=?, text=?, revised_flag=? WHERE folder_id=? AND message_id=?", @(parentId), userName, articleLink, @(lastUpdateIntervalSince1970), + @(publicationIntervalSince1970), articleTitle, articleBody, @(revised_flag), diff --git a/Vienna/Sources/Fetching/OpenReader.m b/Vienna/Sources/Fetching/OpenReader.m index 210f16a002..aa5e085667 100644 --- a/Vienna/Sources/Fetching/OpenReader.m +++ b/Vienna/Sources/Fetching/OpenReader.m @@ -611,21 +611,15 @@ -(void)feedRequestDone:(NSMutableURLRequest *)request response:(NSURLResponse *) article.link = refreshedFolder.feedURL; } - NSDate *currentDate = [NSDate date]; - NSString *publishedField = newsItem[@"published"]; - double publishedDate = [publishedField doubleValue]; - NSDate *publicationDate = [NSDate dateWithTimeIntervalSince1970:publishedDate]; + if (publishedField) { + article.publicationDate = [NSDate dateWithTimeIntervalSince1970:[publishedField doubleValue]]; + } NSString * updatedField = newsItem[@"updated"]; - //if we get no update date, use the publication date, if that does not exist either, use the current date. - NSDate *lastUpdate = updatedField - ? [NSDate dateWithTimeIntervalSince1970:[updatedField doubleValue]] - : (publicationDate ? publicationDate : [NSDate date]); - - //fallback to currentDate for publicationDate; this will not be stored in the db in case of an update - article.publicationDate = publicationDate ? publicationDate : currentDate; - article.lastUpdate = lastUpdate; + if (updatedField) { + article.lastUpdate = [NSDate dateWithTimeIntervalSince1970:[updatedField doubleValue]]; + } if ([newsItem[@"enclosure"] count] != 0) { article.enclosure = newsItem[@"enclosure"][0][@"href"]; diff --git a/Vienna/Sources/Fetching/RefreshManager.m b/Vienna/Sources/Fetching/RefreshManager.m index e749ec9d98..b2e7006695 100644 --- a/Vienna/Sources/Fetching/RefreshManager.m +++ b/Vienna/Sources/Fetching/RefreshManager.m @@ -764,6 +764,7 @@ -(void)finalizeFolderRefresh:(NSDictionary *)parameters for (id newsItem in newFeed.items) { NSDate * articleDate = newsItem.modificationDate; + NSDate * publicationDate = newsItem.publicationDate; NSString * articleGuid = newsItem.guid; @@ -838,6 +839,7 @@ -(void)finalizeFolderRefresh:(NSDictionary *)parameters } article.link = articleLink; article.lastUpdate = articleDate; + article.publicationDate = publicationDate; NSString * enclosureLink = newsItem.enclosure; if ([enclosureLink isNotEqualTo:@""] && ![enclosureLink hasPrefix:@"http:"] && ![enclosureLink hasPrefix:@"https:"]) { enclosureLink = [NSURL URLWithString:enclosureLink relativeToURL:url].absoluteString; diff --git a/Vienna/Sources/Parsing/AtomFeed.m b/Vienna/Sources/Parsing/AtomFeed.m index 0a66ff44e7..c350bdcb29 100644 --- a/Vienna/Sources/Parsing/AtomFeed.m +++ b/Vienna/Sources/Parsing/AtomFeed.m @@ -253,14 +253,20 @@ - (BOOL)initAtomFeed:(NSXMLElement *)atomElement } // Parse item date - if (isArticleElementAtomType && ([articleItemTag isEqualToString:@"modified"] || [articleItemTag isEqualToString:@"created"] || [articleItemTag isEqualToString:@"updated"])) { + if (isArticleElementAtomType && ([articleItemTag isEqualToString:@"modified"] || [articleItemTag isEqualToString:@"updated"])) { NSString *dateString = itemChildElement.stringValue; NSDate *newDate = [self dateWithXMLString:dateString]; if (newFeedItem.modificationDate == nil || [newDate isGreaterThan:newFeedItem.modificationDate]) { newFeedItem.modificationDate = newDate; } + continue; + } + + // Parse item date + if (isArticleElementAtomType && ([articleItemTag isEqualToString:@"created"] || [articleItemTag isEqualToString:@"published"])) { + NSString *dateString = itemChildElement.stringValue; + NSDate *newDate = [self dateWithXMLString:dateString]; if (newFeedItem.publicationDate == nil || [newDate isLessThan:newFeedItem.publicationDate]) { - //publication date will only be registered once for each article, so later updates donĀ“t matter newFeedItem.publicationDate = newDate; } continue;