Fix update for feeds where all articles have the same URL. Closes #3

This commit is contained in:
relikd
2019-03-15 00:09:00 +01:00
parent 3ace169549
commit cdc2d07456
3 changed files with 39 additions and 33 deletions

View File

@@ -6,16 +6,21 @@ and this project does NOT adhere to [Semantic Versioning](https://semver.org/spe
## [Unreleased] ## [Unreleased]
## [0.9.3] - 2019-03-14
### Added ### Added
- Changelog - Changelog
- UI: Show body tag in article tooltip if abstract tag is empty
### Fixed ### Fixed
- 'Update all feeds' will shows unread items count properly during update - 'Update all feeds' will shows unread items count properly during update
- Fixed update for feeds where all article URLs point to the same resource (issue: #3)
## [0.9.2] - 2019-03-07 ## [0.9.2] - 2019-03-07
### Added ### Added
- Limit number of articles that are displayed in feed menu - Limit number of articles that are displayed in feed menu (issue: #2)
### Fixed ### Fixed
- Cmd+Q in preferences will close the window instead of quitting the application - Cmd+Q in preferences will close the window instead of quitting the application
@@ -46,6 +51,7 @@ Initial release
[Unreleased]: https://github.com/relikd/baRSS/compare/v0.9.2...HEAD [Unreleased]: https://github.com/relikd/baRSS/compare/v0.9.2...HEAD
[0.9.3]: https://github.com/relikd/baRSS/compare/v0.9.2...v0.9.3
[0.9.2]: https://github.com/relikd/baRSS/compare/v0.9.1...v0.9.2 [0.9.2]: https://github.com/relikd/baRSS/compare/v0.9.1...v0.9.2
[0.9.1]: https://github.com/relikd/baRSS/compare/v0.9...v0.9.1 [0.9.1]: https://github.com/relikd/baRSS/compare/v0.9...v0.9.1
[0.9]: https://github.com/relikd/baRSS/compare/e1f36514a8aa2d5fb9a575b6eb19adc2ce4a04d9...v0.9 [0.9]: https://github.com/relikd/baRSS/compare/e1f36514a8aa2d5fb9a575b6eb19adc2ce4a04d9...v0.9

View File

@@ -92,9 +92,9 @@
self.group.name = obj.title; self.group.name = obj.title;
// Add and remove articles // Add and remove articles
NSMutableSet<NSString*> *urls = [[self.articles valueForKeyPath:@"link"] mutableCopy]; NSMutableSet<FeedArticle*> *oldSet = [self.articles mutableCopy];
NSInteger diff = [self addMissingArticles:obj updateLinks:urls]; // will remove links in 'urls' that should be kept NSInteger diff = [self addMissingArticles:obj withOldSet:oldSet]; // will remove items that should be kept
diff -= [self deleteArticlesWithLink:urls]; // remove old, outdated articles diff -= [self deleteArticlesWithOldSet:oldSet]; // remove old, outdated articles
// Get new total article count and post unread-count-change notification // Get new total article count and post unread-count-change notification
if (flag && diff != 0) { if (flag && diff != 0) {
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationTotalUnreadCountChanged object:@(diff)]; [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationTotalUnreadCountChanged object:@(diff)];
@@ -108,9 +108,10 @@
New articles should be in ascending order without any gaps in between. New articles should be in ascending order without any gaps in between.
If new article is disjunct from the article before, assume a deleted article re-appeared and mark it as read. If new article is disjunct from the article before, assume a deleted article re-appeared and mark it as read.
@param urls Input will be used to identify new articles. Output will contain URLs that aren't present in the feed anymore. @param oldSet Input will be used to identify new articles.
Output contains articles that aren't present in the feed anymore and should be deleted.
*/ */
- (NSInteger)addMissingArticles:(RSParsedFeed*)obj updateLinks:(NSMutableSet<NSString*>*)urls { - (NSInteger)addMissingArticles:(RSParsedFeed*)obj withOldSet:(NSMutableSet<FeedArticle*>*)oldSet {
NSInteger newOnes = 0; NSInteger newOnes = 0;
int32_t currentIndex = [[self.articles valueForKeyPath:@"@min.sortIndex"] intValue]; int32_t currentIndex = [[self.articles valueForKeyPath:@"@min.sortIndex"] intValue];
FeedArticle *lastInserted = nil; FeedArticle *lastInserted = nil;
@@ -118,10 +119,10 @@
for (RSParsedArticle *article in [obj.articles reverseObjectEnumerator]) { for (RSParsedArticle *article in [obj.articles reverseObjectEnumerator]) {
// reverse enumeration ensures correct article order // reverse enumeration ensures correct article order
if ([urls containsObject:article.link]) { FeedArticle *storedArticle = [self findArticle:article inSet:oldSet];
[urls removeObject:article.link]; if (storedArticle) {
FeedArticle *storedArticle = [self findArticleWithLink:article.link]; // TODO: use two synced arrays? [oldSet removeObject:storedArticle];
if (storedArticle && storedArticle.sortIndex != currentIndex) { if (storedArticle.sortIndex != currentIndex) {
storedArticle.sortIndex = currentIndex; storedArticle.sortIndex = currentIndex;
} }
hasGapBetweenNewArticles = YES; hasGapBetweenNewArticles = YES;
@@ -146,26 +147,19 @@
} }
/** /**
Delete all items where @c link matches one of the URLs in the @c NSSet. Delete all articles from core data, that are still in the oldSet.
*/ */
- (NSUInteger)deleteArticlesWithLink:(NSMutableSet<NSString*>*)urls { - (NSUInteger)deleteArticlesWithOldSet:(NSMutableSet<FeedArticle*>*)oldSet {
if (!urls || urls.count == 0) if (!oldSet || oldSet.count == 0)
return 0; return 0;
NSUInteger c = 0; NSUInteger c = 0;
for (FeedArticle *fa in self.articles) { for (FeedArticle *fa in oldSet) {
if ([urls containsObject:fa.link]) {
[urls removeObject:fa.link];
if (fa.unread) ++c; if (fa.unread) ++c;
// TODO: keep unread articles? // TODO: keep unread articles?
[self.managedObjectContext deleteObject:fa]; [self.managedObjectContext deleteObject:fa];
if (urls.count == 0)
break;
}
}
NSSet<FeedArticle*> *delArticles = [self.managedObjectContext deletedObjects];
if (delArticles.count > 0) {
[self removeArticles:delArticles];
} }
if (oldSet.count > 0)
[self removeArticles:oldSet];
return c; return c;
} }
@@ -183,12 +177,18 @@
} }
/** /**
Iterate over all Articles and return the one where @c .link matches. Or @c nil if no matching article found. Iterate over oldSet and return the one where @c link and @c guid matches. Or @c nil if no matching article found.
*/ */
- (FeedArticle*)findArticleWithLink:(NSString*)url { - (FeedArticle*)findArticle:(RSParsedArticle*)article inSet:(NSSet<FeedArticle*>*)oldSet {
for (FeedArticle *a in self.articles) { NSString *searchLink = article.link;
if ([a.link isEqualToString:url]) NSString *searchGuid = article.guid;
return a; BOOL linkIsNil = (searchLink == nil);
BOOL guidIsNil = (searchGuid == nil);
for (FeedArticle *old in oldSet) {
if ((linkIsNil && old.link == nil) || [old.link isEqualToString:searchLink]) {
if ((guidIsNil && old.guid == nil) || [old.guid isEqualToString:searchGuid])
return old;
}
} }
return nil; return nil;
} }

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.9.2</string> <string>0.9.3</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
<array> <array>
<dict> <dict>
@@ -32,7 +32,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1146</string> <string>1153</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string> <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSUIElement</key> <key>LSUIElement</key>