Use NewsBlur terminologies in models (Feed, Story)

This commit is contained in:
Anh Do 2020-03-13 18:30:36 -04:00
parent 175cd0e798
commit f4a0c56a54
No known key found for this signature in database
GPG Key ID: 451E3092F917B62D
7 changed files with 123 additions and 123 deletions

View File

@ -7,12 +7,12 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
179DB02FFBC17AC9798F0EBC /* NewsBlurArticle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB7399814F6FB3247825C /* NewsBlurArticle.swift */; }; 179DB02FFBC17AC9798F0EBC /* NewsBlurStory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB7399814F6FB3247825C /* NewsBlurStory.swift */; };
179DB28CF49F73A945EBF5DB /* NewsBlurLoginResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB088236E3236010462E8 /* NewsBlurLoginResponse.swift */; }; 179DB28CF49F73A945EBF5DB /* NewsBlurLoginResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB088236E3236010462E8 /* NewsBlurLoginResponse.swift */; };
179DB49A960F8B78C4924458 /* NewsBlurGenericCodingKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB66D933E976C29159DEE /* NewsBlurGenericCodingKeys.swift */; }; 179DB49A960F8B78C4924458 /* NewsBlurGenericCodingKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB66D933E976C29159DEE /* NewsBlurGenericCodingKeys.swift */; };
179DB61D33CD8DC94C90F7ED /* NewsBlurDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DBB17C42E6E434EDC29FA /* NewsBlurDate.swift */; }; 179DB61D33CD8DC94C90F7ED /* NewsBlurDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DBB17C42E6E434EDC29FA /* NewsBlurDate.swift */; };
179DBED55C9B4D6A413486C1 /* NewsBlurUnreadArticle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB818180A51098A9816B2 /* NewsBlurUnreadArticle.swift */; }; 179DBED55C9B4D6A413486C1 /* NewsBlurUnreadStory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB818180A51098A9816B2 /* NewsBlurUnreadStory.swift */; };
179DBF4DE2562D4C532F6008 /* NewsBlurSubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB1B909672E0E807B5E8C /* NewsBlurSubscription.swift */; }; 179DBF4DE2562D4C532F6008 /* NewsBlurFeed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DB1B909672E0E807B5E8C /* NewsBlurFeed.swift */; };
3B3A33E7238D3D6800314204 /* Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3A33E6238D3D6800314204 /* Secrets.swift */; }; 3B3A33E7238D3D6800314204 /* Secrets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B3A33E6238D3D6800314204 /* Secrets.swift */; };
3B826DA72385C81C00FC1ADB /* FeedWranglerAuthorizationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826D9E2385C81C00FC1ADB /* FeedWranglerAuthorizationResult.swift */; }; 3B826DA72385C81C00FC1ADB /* FeedWranglerAuthorizationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826D9E2385C81C00FC1ADB /* FeedWranglerAuthorizationResult.swift */; };
3B826DA82385C81C00FC1ADB /* FeedWranglerFeedItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826D9F2385C81C00FC1ADB /* FeedWranglerFeedItem.swift */; }; 3B826DA82385C81C00FC1ADB /* FeedWranglerFeedItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B826D9F2385C81C00FC1ADB /* FeedWranglerFeedItem.swift */; };
@ -229,10 +229,10 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
179DB088236E3236010462E8 /* NewsBlurLoginResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurLoginResponse.swift; sourceTree = "<group>"; }; 179DB088236E3236010462E8 /* NewsBlurLoginResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurLoginResponse.swift; sourceTree = "<group>"; };
179DB1B909672E0E807B5E8C /* NewsBlurSubscription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurSubscription.swift; sourceTree = "<group>"; }; 179DB1B909672E0E807B5E8C /* NewsBlurFeed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurFeed.swift; sourceTree = "<group>"; };
179DB66D933E976C29159DEE /* NewsBlurGenericCodingKeys.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurGenericCodingKeys.swift; sourceTree = "<group>"; }; 179DB66D933E976C29159DEE /* NewsBlurGenericCodingKeys.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurGenericCodingKeys.swift; sourceTree = "<group>"; };
179DB7399814F6FB3247825C /* NewsBlurArticle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurArticle.swift; sourceTree = "<group>"; }; 179DB7399814F6FB3247825C /* NewsBlurStory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurStory.swift; sourceTree = "<group>"; };
179DB818180A51098A9816B2 /* NewsBlurUnreadArticle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurUnreadArticle.swift; sourceTree = "<group>"; }; 179DB818180A51098A9816B2 /* NewsBlurUnreadStory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurUnreadStory.swift; sourceTree = "<group>"; };
179DBB17C42E6E434EDC29FA /* NewsBlurDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurDate.swift; sourceTree = "<group>"; }; 179DBB17C42E6E434EDC29FA /* NewsBlurDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewsBlurDate.swift; sourceTree = "<group>"; };
3B3A33E6238D3D6800314204 /* Secrets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Secrets.swift; path = ../../Shared/Secrets.swift; sourceTree = "<group>"; }; 3B3A33E6238D3D6800314204 /* Secrets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Secrets.swift; path = ../../Shared/Secrets.swift; sourceTree = "<group>"; };
3B826D9E2385C81C00FC1ADB /* FeedWranglerAuthorizationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerAuthorizationResult.swift; sourceTree = "<group>"; }; 3B826D9E2385C81C00FC1ADB /* FeedWranglerAuthorizationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedWranglerAuthorizationResult.swift; sourceTree = "<group>"; };
@ -455,10 +455,10 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
179DB088236E3236010462E8 /* NewsBlurLoginResponse.swift */, 179DB088236E3236010462E8 /* NewsBlurLoginResponse.swift */,
179DB1B909672E0E807B5E8C /* NewsBlurSubscription.swift */, 179DB1B909672E0E807B5E8C /* NewsBlurFeed.swift */,
179DB7399814F6FB3247825C /* NewsBlurArticle.swift */, 179DB7399814F6FB3247825C /* NewsBlurStory.swift */,
179DB66D933E976C29159DEE /* NewsBlurGenericCodingKeys.swift */, 179DB66D933E976C29159DEE /* NewsBlurGenericCodingKeys.swift */,
179DB818180A51098A9816B2 /* NewsBlurUnreadArticle.swift */, 179DB818180A51098A9816B2 /* NewsBlurUnreadStory.swift */,
179DBB17C42E6E434EDC29FA /* NewsBlurDate.swift */, 179DBB17C42E6E434EDC29FA /* NewsBlurDate.swift */,
); );
path = Models; path = Models;
@ -1150,10 +1150,10 @@
769F295938E5A30D03DFF88F /* NewsBlurAccountDelegate.swift in Sources */, 769F295938E5A30D03DFF88F /* NewsBlurAccountDelegate.swift in Sources */,
769F2BA02EF5F329CDE45F5A /* NewsBlurAPICaller.swift in Sources */, 769F2BA02EF5F329CDE45F5A /* NewsBlurAPICaller.swift in Sources */,
179DB28CF49F73A945EBF5DB /* NewsBlurLoginResponse.swift in Sources */, 179DB28CF49F73A945EBF5DB /* NewsBlurLoginResponse.swift in Sources */,
179DBF4DE2562D4C532F6008 /* NewsBlurSubscription.swift in Sources */, 179DBF4DE2562D4C532F6008 /* NewsBlurFeed.swift in Sources */,
179DB02FFBC17AC9798F0EBC /* NewsBlurArticle.swift in Sources */, 179DB02FFBC17AC9798F0EBC /* NewsBlurStory.swift in Sources */,
179DB49A960F8B78C4924458 /* NewsBlurGenericCodingKeys.swift in Sources */, 179DB49A960F8B78C4924458 /* NewsBlurGenericCodingKeys.swift in Sources */,
179DBED55C9B4D6A413486C1 /* NewsBlurUnreadArticle.swift in Sources */, 179DBED55C9B4D6A413486C1 /* NewsBlurUnreadStory.swift in Sources */,
179DB61D33CD8DC94C90F7ED /* NewsBlurDate.swift in Sources */, 179DB61D33CD8DC94C90F7ED /* NewsBlurDate.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View File

@ -1,5 +1,5 @@
// //
// NewsBlurSubscription.swift // NewsBlurFeed.swift
// Account // Account
// //
// Created by Anh Quang Do on 2020-03-09. // Created by Anh Quang Do on 2020-03-09.
@ -10,13 +10,13 @@ import Foundation
import RSCore import RSCore
import RSParser import RSParser
typealias NewsBlurSubscription = NewsBlurFeedsResponse.Subscription typealias NewsBlurFeed = NewsBlurFeedsResponse.Feed
struct NewsBlurFeedsResponse: Decodable { struct NewsBlurFeedsResponse: Decodable {
let subscriptions: [Subscription] let feeds: [Feed]
let folders: [Folder] let folders: [Folder]
struct Subscription: Hashable, Codable { struct Feed: Hashable, Codable {
let title: String let title: String
let feedId: Int let feedId: Int
let feedURL: String let feedURL: String
@ -26,7 +26,7 @@ struct NewsBlurFeedsResponse: Decodable {
struct Folder: Hashable, Codable { struct Folder: Hashable, Codable {
let name: String let name: String
let subscriptionIds: [Int] let feedIds: [Int]
} }
} }
@ -40,12 +40,12 @@ extension NewsBlurFeedsResponse {
init(from decoder: Decoder) throws { init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self) let container = try decoder.container(keyedBy: CodingKeys.self)
// Parse subscriptions // Parse feeds
var subscriptions: [Subscription] = [] var feeds: [Feed] = []
let subscriptionContainer = try container.nestedContainer(keyedBy: NewsBlurGenericCodingKeys.self, forKey: .feeds) let feedContainer = try container.nestedContainer(keyedBy: NewsBlurGenericCodingKeys.self, forKey: .feeds)
try subscriptionContainer.allKeys.forEach { key in try feedContainer.allKeys.forEach { key in
let subscription = try subscriptionContainer.decode(Subscription.self, forKey: key) let subscription = try feedContainer.decode(Feed.self, forKey: key)
subscriptions.append(subscription) feeds.append(subscription)
} }
// Parse folders // Parse folders
@ -53,17 +53,17 @@ extension NewsBlurFeedsResponse {
let folderContainer = try container.nestedContainer(keyedBy: NewsBlurGenericCodingKeys.self, forKey: .folders) let folderContainer = try container.nestedContainer(keyedBy: NewsBlurGenericCodingKeys.self, forKey: .folders)
try folderContainer.allKeys.forEach { key in try folderContainer.allKeys.forEach { key in
let subscriptionIds = try folderContainer.decode([Int].self, forKey: key) let subscriptionIds = try folderContainer.decode([Int].self, forKey: key)
let folder = Folder(name: key.stringValue, subscriptionIds: subscriptionIds) let folder = Folder(name: key.stringValue, feedIds: subscriptionIds)
folders.append(folder) folders.append(folder)
} }
self.subscriptions = subscriptions self.feeds = feeds
self.folders = folders self.folders = folders
} }
} }
extension NewsBlurFeedsResponse.Subscription { extension NewsBlurFeedsResponse.Feed {
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case title = "feed_title" case title = "feed_title"
case feedId = "id" case feedId = "id"

View File

@ -1,5 +1,5 @@
// //
// NewsBlurArticle.swift // NewsBlurStory.swift
// Account // Account
// //
// Created by Anh Quang Do on 2020-03-10. // Created by Anh Quang Do on 2020-03-10.
@ -10,13 +10,13 @@ import Foundation
import RSCore import RSCore
import RSParser import RSParser
typealias NewsBlurArticle = NewsBlurArticlesResponse.Article typealias NewsBlurStory = NewsBlurStoriesResponse.Story
struct NewsBlurArticlesResponse: Decodable { struct NewsBlurStoriesResponse: Decodable {
let articles: [Article] let stories: [Story]
struct Article: Decodable { struct Story: Decodable {
let articleId: String let storyId: String
let feedId: Int let feedId: Int
let title: String? let title: String?
let url: String? let url: String?
@ -26,15 +26,15 @@ struct NewsBlurArticlesResponse: Decodable {
} }
} }
extension NewsBlurArticlesResponse { extension NewsBlurStoriesResponse {
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case articles = "stories" case stories = "stories"
} }
} }
extension NewsBlurArticlesResponse.Article { extension NewsBlurStoriesResponse.Story {
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case articleId = "story_hash" case storyId = "story_hash"
case feedId = "story_feed_id" case feedId = "story_feed_id"
case title = "story_title" case title = "story_title"
case url = "story_permalink" case url = "story_permalink"

View File

@ -1,50 +0,0 @@
//
// NewsBlurUnreadArticle.swift
// Account
//
// Created by Anh Quang Do on 2020-03-13.
// Copyright (c) 2020 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import RSCore
import RSParser
typealias NewsBlurArticleHash = NewsBlurUnreadArticleHashesResponse.ArticleHash
struct NewsBlurUnreadArticleHashesResponse: Decodable {
let subscriptions: [String: [ArticleHash]]
struct ArticleHash: Hashable, Codable {
var hash: String
var timestamp: Date
}
}
extension NewsBlurUnreadArticleHashesResponse {
private enum CodingKeys: String, CodingKey {
case feeds = "unread_feed_story_hashes"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Parse subscriptions
var subscriptions: [String: [ArticleHash]] = [:]
let subscriptionContainer = try container.nestedContainer(keyedBy: NewsBlurGenericCodingKeys.self, forKey: .feeds)
try subscriptionContainer.allKeys.forEach { key in
subscriptions[key.stringValue] = []
var hashArrayContainer = try subscriptionContainer.nestedUnkeyedContainer(forKey: key)
while !hashArrayContainer.isAtEnd {
var hashContainer = try hashArrayContainer.nestedUnkeyedContainer()
let hash = try hashContainer.decode(String.self)
let timestamp = try hashContainer.decode(Date.self)
let articleHash = ArticleHash(hash: hash, timestamp: timestamp)
subscriptions[key.stringValue]?.append(articleHash)
}
}
self.subscriptions = subscriptions
}
}

View File

@ -0,0 +1,50 @@
//
// NewsBlurUnreadStory.swift
// Account
//
// Created by Anh Quang Do on 2020-03-13.
// Copyright (c) 2020 Ranchero Software, LLC. All rights reserved.
//
import Foundation
import RSCore
import RSParser
typealias NewsBlurStoryHash = NewsBlurUnreadStoryHashesResponse.StoryHash
struct NewsBlurUnreadStoryHashesResponse: Decodable {
let feeds: [String: [StoryHash]]
struct StoryHash: Hashable, Codable {
var hash: String
var timestamp: Date
}
}
extension NewsBlurUnreadStoryHashesResponse {
private enum CodingKeys: String, CodingKey {
case feeds = "unread_feed_story_hashes"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// Parse feeds
var feeds: [String: [StoryHash]] = [:]
let feedContainer = try container.nestedContainer(keyedBy: NewsBlurGenericCodingKeys.self, forKey: .feeds)
try feedContainer.allKeys.forEach { key in
feeds[key.stringValue] = []
var hashArrayContainer = try feedContainer.nestedUnkeyedContainer(forKey: key)
while !hashArrayContainer.isAtEnd {
var hashContainer = try hashArrayContainer.nestedUnkeyedContainer()
let hash = try hashContainer.decode(String.self)
let timestamp = try hashContainer.decode(Date.self)
let storyHash = StoryHash(hash: hash, timestamp: timestamp)
feeds[key.stringValue]?.append(storyHash)
}
}
self.feeds = feeds
}
}

View File

@ -84,7 +84,7 @@ final class NewsBlurAPICaller: NSObject {
} }
} }
func retrieveSubscriptions(completion: @escaping (Result<[NewsBlurSubscription]?, Error>) -> Void) { func retrieveFeeds(completion: @escaping (Result<[NewsBlurFeed]?, Error>) -> Void) {
let url = baseURL let url = baseURL
.appendingPathComponent("reader/feeds") .appendingPathComponent("reader/feeds")
.appendingQueryItems([ .appendingQueryItems([
@ -101,14 +101,14 @@ final class NewsBlurAPICaller: NSObject {
transport.send(request: request, resultType: NewsBlurFeedsResponse.self) { result in transport.send(request: request, resultType: NewsBlurFeedsResponse.self) { result in
switch result { switch result {
case .success((_, let payload)): case .success((_, let payload)):
completion(.success(payload?.subscriptions)) completion(.success(payload?.feeds))
case .failure(let error): case .failure(let error):
completion(.failure(error)) completion(.failure(error))
} }
} }
} }
func retrieveUnreadArticleHashes(completion: @escaping (Result<[NewsBlurArticleHash]?, Error>) -> Void) { func retrieveUnreadStoryHashes(completion: @escaping (Result<[NewsBlurStoryHash]?, Error>) -> Void) {
let url = baseURL let url = baseURL
.appendingPathComponent("reader/unread_story_hashes") .appendingPathComponent("reader/unread_story_hashes")
.appendingQueryItems([ .appendingQueryItems([
@ -121,17 +121,17 @@ final class NewsBlurAPICaller: NSObject {
} }
let request = URLRequest(url: callURL, credentials: credentials) let request = URLRequest(url: callURL, credentials: credentials)
transport.send(request: request, resultType: NewsBlurUnreadArticleHashesResponse.self, dateDecoding: .secondsSince1970) { result in transport.send(request: request, resultType: NewsBlurUnreadStoryHashesResponse.self, dateDecoding: .secondsSince1970) { result in
switch result { switch result {
case .success((_, let payload)): case .success((_, let payload)):
completion(.success(payload?.subscriptions.values.flatMap { $0 })) completion(.success(payload?.feeds.values.flatMap { $0 }))
case .failure(let error): case .failure(let error):
completion(.failure(error)) completion(.failure(error))
} }
} }
} }
func retrieveArticles(hashes: [NewsBlurArticleHash], completion: @escaping (Result<[NewsBlurArticle]?, Error>) -> Void) { func retrieveStories(hashes: [NewsBlurStoryHash], completion: @escaping (Result<[NewsBlurStory]?, Error>) -> Void) {
let url = baseURL let url = baseURL
.appendingPathComponent("reader/river_stories") .appendingPathComponent("reader/river_stories")
.appendingQueryItem(.init(name: "include_hidden", value: "true"))? .appendingQueryItem(.init(name: "include_hidden", value: "true"))?
@ -143,10 +143,10 @@ final class NewsBlurAPICaller: NSObject {
} }
let request = URLRequest(url: callURL, credentials: credentials) let request = URLRequest(url: callURL, credentials: credentials)
transport.send(request: request, resultType: NewsBlurArticlesResponse.self, dateDecoding: .formatted(NewsBlurDate.yyyyMMddHHmmss)) { result in transport.send(request: request, resultType: NewsBlurStoriesResponse.self, dateDecoding: .formatted(NewsBlurDate.yyyyMMddHHmmss)) { result in
switch result { switch result {
case .success((_, let payload)): case .success((_, let payload)):
completion(.success(payload?.articles)) completion(.success(payload?.stories))
case .failure(let error): case .failure(let error):
completion(.failure(error)) completion(.failure(error))
} }

View File

@ -60,7 +60,7 @@ final class NewsBlurAccountDelegate: AccountDelegate {
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> ()) { func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> ()) {
self.refreshProgress.addToNumberOfTasksAndRemaining(5) self.refreshProgress.addToNumberOfTasksAndRemaining(5)
refreshSubscriptions(for: account) { result in refreshFeeds(for: account) { result in
self.refreshProgress.completeTask() self.refreshProgress.completeTask()
switch result { switch result {
@ -75,12 +75,12 @@ final class NewsBlurAccountDelegate: AccountDelegate {
switch result { switch result {
case .success: case .success:
self.refreshArticles(for: account) { result in self.refreshStories(for: account) { result in
self.refreshProgress.completeTask() self.refreshProgress.completeTask()
switch result { switch result {
case .success: case .success:
self.refreshMissingArticles(for: account) { result in self.refreshMissingStories(for: account) { result in
self.refreshProgress.completeTask() self.refreshProgress.completeTask()
switch result { switch result {
@ -123,23 +123,23 @@ final class NewsBlurAccountDelegate: AccountDelegate {
completion(.success(())) completion(.success(()))
} }
func refreshArticles(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) { func refreshStories(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
os_log(.debug, log: log, "Refreshing articles...") os_log(.debug, log: log, "Refreshing stories...")
os_log(.debug, log: log, "Refreshing unread articles...") os_log(.debug, log: log, "Refreshing unread stories...")
caller.retrieveUnreadArticleHashes { result in caller.retrieveUnreadStoryHashes { result in
switch result { switch result {
case .success(let articleHashes): case .success(let storyHashes):
self.refreshProgress.completeTask() self.refreshProgress.completeTask()
self.refreshUnreadArticles(for: account, hashes: articleHashes, updateFetchDate: nil, completion: completion) self.refreshUnreadStories(for: account, hashes: storyHashes, updateFetchDate: nil, completion: completion)
case .failure(let error): case .failure(let error):
completion(.failure(error)) completion(.failure(error))
} }
} }
} }
func refreshUnreadArticles(for account: Account, hashes: [NewsBlurArticleHash]?, updateFetchDate: Date?, completion: @escaping (Result<Void, Error>) -> Void) { func refreshUnreadStories(for account: Account, hashes: [NewsBlurStoryHash]?, updateFetchDate: Date?, completion: @escaping (Result<Void, Error>) -> Void) {
guard let hashes = hashes, !hashes.isEmpty else { guard let hashes = hashes, !hashes.isEmpty else {
if let lastArticleFetch = updateFetchDate { if let lastArticleFetch = updateFetchDate {
self.accountMetadata?.lastArticleFetchStartTime = lastArticleFetch self.accountMetadata?.lastArticleFetchStartTime = lastArticleFetch
@ -149,13 +149,13 @@ final class NewsBlurAccountDelegate: AccountDelegate {
return return
} }
let numberOfArticles = min(hashes.count, 100) // api limit let numberOfStories = min(hashes.count, 100) // api limit
let hashesToFetch = Array(hashes[..<numberOfArticles]) let hashesToFetch = Array(hashes[..<numberOfStories])
caller.retrieveArticles(hashes: hashesToFetch) { result in caller.retrieveStories(hashes: hashesToFetch) { result in
switch result { switch result {
case .success(let articles): case .success(let stories):
self.processArticles(account: account, articles: articles) { error in self.processStories(account: account, stories: stories) { error in
self.refreshProgress.completeTask() self.refreshProgress.completeTask()
if let error = error { if let error = error {
@ -163,7 +163,7 @@ final class NewsBlurAccountDelegate: AccountDelegate {
return return
} }
self.refreshUnreadArticles(for: account, hashes: Array(hashes[numberOfArticles...]), updateFetchDate: updateFetchDate, completion: completion) self.refreshUnreadStories(for: account, hashes: Array(hashes[numberOfStories...]), updateFetchDate: updateFetchDate, completion: completion)
} }
case .failure(let error): case .failure(let error):
completion(.failure(error)) completion(.failure(error))
@ -171,24 +171,24 @@ final class NewsBlurAccountDelegate: AccountDelegate {
} }
} }
func refreshMissingArticles(for account: Account, completion: @escaping (Result<Void, Error>)-> Void) { func refreshMissingStories(for account: Account, completion: @escaping (Result<Void, Error>)-> Void) {
completion(.success(())) completion(.success(()))
} }
func processArticles(account: Account, articles: [NewsBlurArticle]?, completion: @escaping DatabaseCompletionBlock) { func processStories(account: Account, stories: [NewsBlurStory]?, completion: @escaping DatabaseCompletionBlock) {
let parsedItems = mapArticlesToParsedItems(articles: articles) let parsedItems = mapStoriesToParsedItems(stories: stories)
let webFeedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) } let webFeedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) }
account.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: true, completion: completion) account.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: true, completion: completion)
} }
func mapArticlesToParsedItems(articles: [NewsBlurArticle]?) -> Set<ParsedItem> { func mapStoriesToParsedItems(stories: [NewsBlurStory]?) -> Set<ParsedItem> {
guard let articles = articles else { guard let stories = stories else {
return Set<ParsedItem>() return Set<ParsedItem>()
} }
let parsedItems: [ParsedItem] = articles.map { article in let parsedItems: [ParsedItem] = stories.map { story in
let author = Set([ParsedAuthor(name: article.authorName, url: nil, avatarURL: nil, emailAddress: nil)]) let author = Set([ParsedAuthor(name: story.authorName, url: nil, avatarURL: nil, emailAddress: nil)])
return ParsedItem(syncServiceID: article.articleId, uniqueID: String(article.articleId), feedURL: String(article.feedId), url: article.url, externalURL: nil, title: article.title, contentHTML: article.contentHTML, contentText: nil, summary: nil, imageURL: nil, bannerImageURL: nil, datePublished: article.datePublished, dateModified: nil, authors: author, tags: nil, attachments: nil) return ParsedItem(syncServiceID: story.storyId, uniqueID: String(story.storyId), feedURL: String(story.feedId), url: story.url, externalURL: nil, title: story.title, contentHTML: story.contentHTML, contentText: nil, summary: nil, imageURL: nil, bannerImageURL: nil, datePublished: story.datePublished, dateModified: nil, authors: author, tags: nil, attachments: nil)
} }
return Set(parsedItems) return Set(parsedItems)
@ -271,13 +271,13 @@ final class NewsBlurAccountDelegate: AccountDelegate {
} }
extension NewsBlurAccountDelegate { extension NewsBlurAccountDelegate {
private func refreshSubscriptions(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) { private func refreshFeeds(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
os_log(.debug, log: log, "Refreshing subscriptions...") os_log(.debug, log: log, "Refreshing feeds...")
caller.retrieveSubscriptions { result in caller.retrieveFeeds { result in
switch result { switch result {
case .success(let subscriptions): case .success(let feeds):
print(subscriptions) print(feeds)
completion(.success(())) completion(.success(()))
case .failure(let error): case .failure(let error):
completion(.failure(error)) completion(.failure(error))