From dc60ebf1f82e5ec56bb8bcd8cfa84a54aed63031 Mon Sep 17 00:00:00 2001 From: Jeremy Beker Date: Tue, 11 Jun 2019 15:37:21 -0400 Subject: [PATCH] Unread status is properly set when articles are downloaded from backend --- .../GoogleReaderCompatibleAPICaller.swift | 45 +++++++++++++------ ...oogleReaderCompatibleAccountDelegate.swift | 31 ++++++------- .../GoogleReaderCompatibleEntry.swift | 16 +++++++ 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAPICaller.swift b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAPICaller.swift index d1bc13c56..e3eb36e98 100644 --- a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAPICaller.swift +++ b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAPICaller.swift @@ -579,7 +579,6 @@ final class GoogleReaderCompatibleAPICaller: NSObject { }).joined(separator:"&") let postData = "T=\(token)&output=json&\(idsToFetch)".data(using: String.Encoding.utf8) - //let postData = "T=\(token)&output=json&i=1349530380539369".data(using: String.Encoding.utf8) self.transport.send(request: request, method: HTTPMethod.post, data: postData!, resultType: GoogleReaderCompatibleEntryWrapper.self, completion: { (result) in switch result { @@ -613,14 +612,6 @@ final class GoogleReaderCompatibleAPICaller: NSObject { } } - - - - - - - - } func retrieveEntries(page: String, completion: @escaping (Result<([GoogleReaderCompatibleEntry]?, String?), Error>) -> Void) { @@ -715,17 +706,45 @@ final class GoogleReaderCompatibleAPICaller: NSObject { } func retrieveStarredEntries(completion: @escaping (Result<[Int]?, Error>) -> Void) { + guard let baseURL = APIBaseURL else { + completion(.failure(CredentialsError.incompleteCredentials)) + return + } + + // Add query string for getting JSON (probably should break this out as I will be doing it a lot) + guard var components = URLComponents(url: baseURL.appendingPathComponent("/reader/api/0/stream/items/ids"), resolvingAgainstBaseURL: false) else { + completion(.failure(TransportError.noURL)) + return + } + + components.queryItems = [ + URLQueryItem(name: "s", value: "user/-/state/com.google/starred"), + URLQueryItem(name: "n", value: "10000"), + URLQueryItem(name: "output", value: "json") + ] + + guard let callURL = components.url else { + completion(.failure(TransportError.noURL)) + return + } - let callURL = GoogleReaderCompatibleBaseURL.appendingPathComponent("starred_entries.json") let conditionalGet = accountMetadata?.conditionalGetInfo[ConditionalGetKeys.starredEntries] let request = URLRequest(url: callURL, credentials: credentials, conditionalGet: conditionalGet) - transport.send(request: request, resultType: [Int].self) { result in + transport.send(request: request, resultType: GoogleReaderCompatibleReferenceWrapper.self) { result in switch result { - case .success(let (response, starredEntries)): + case .success(let (response, unreadEntries)): + + guard let itemRefs = unreadEntries?.itemRefs else { + completion(.success([])) + return + } + + let itemIds = itemRefs.map{ Int($0.itemId)! } + self.storeConditionalGet(key: ConditionalGetKeys.starredEntries, headers: response.allHeaderFields) - completion(.success(starredEntries)) + completion(.success(itemIds)) case .failure(let error): completion(.failure(error)) } diff --git a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAccountDelegate.swift b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAccountDelegate.swift index 8f192cd17..d9dcf46b3 100644 --- a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAccountDelegate.swift +++ b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleAccountDelegate.swift @@ -93,11 +93,6 @@ final class GoogleReaderCompatibleAccountDelegate: AccountDelegate { refreshAccount(account) { result in switch result { case .success(): - DispatchQueue.main.async { - completion(.success(())) - } - - self.refreshArticles(account) { self.refreshArticleStatus(for: account) { self.refreshMissingArticles(account) { @@ -179,18 +174,18 @@ final class GoogleReaderCompatibleAccountDelegate: AccountDelegate { } -// group.enter() -// caller.retrieveStarredEntries() { result in -// switch result { -// case .success(let articleIDs): -// self.syncArticleStarredState(account: account, articleIDs: articleIDs) -// group.leave() -// case .failure(let error): -// os_log(.info, log: self.log, "Retrieving starred entries failed: %@.", error.localizedDescription) -// group.leave() -// } -// -// } + group.enter() + caller.retrieveStarredEntries() { result in + switch result { + case .success(let articleIDs): + self.syncArticleStarredState(account: account, articleIDs: articleIDs) + group.leave() + case .failure(let error): + os_log(.info, log: self.log, "Retrieving starred entries failed: %@.", error.localizedDescription) + group.leave() + } + + } group.notify(queue: DispatchQueue.main) { os_log(.debug, log: self.log, "Done refreshing article statuses.") @@ -1008,7 +1003,7 @@ private extension GoogleReaderCompatibleAccountDelegate { // let authors = Set([ParsedAuthor(name: entry.authorName, url: entry.jsonFeed?.jsonFeedAuthor?.url, avatarURL: entry.jsonFeed?.jsonFeedAuthor?.avatarURL, emailAddress: nil)]) // let feed = account.idToFeedDictionary[entry.origin.streamId!]! // TODO clean this up - return ParsedItem(syncServiceID: String(entry.articleID), uniqueID: String(entry.articleID), feedURL: entry.origin.streamId!, url: nil, externalURL: entry.alternates.first?.url, title: entry.title, contentHTML: entry.summary.content, contentText: nil, summary: entry.summary.content, imageURL: nil, bannerImageURL: nil, datePublished: entry.parseDatePublished(), dateModified: nil, authors: nil, tags: nil, attachments: nil) + return ParsedItem(syncServiceID: entry.uniqueID(), uniqueID: entry.uniqueID(), feedURL: entry.origin.streamId!, url: nil, externalURL: entry.alternates.first?.url, title: entry.title, contentHTML: entry.summary.content, contentText: nil, summary: entry.summary.content, imageURL: nil, bannerImageURL: nil, datePublished: entry.parseDatePublished(), dateModified: nil, authors: nil, tags: nil, attachments: nil) } return Set(parsedItems) diff --git a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleEntry.swift b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleEntry.swift index c98212774..8757262ee 100644 --- a/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleEntry.swift +++ b/Frameworks/Account/GoogleReaderCompatible/GoogleReaderCompatibleEntry.swift @@ -81,6 +81,22 @@ struct GoogleReaderCompatibleEntry: Codable { return Date(timeIntervalSince1970: unixTime) } + + func uniqueID() -> String { + // Should look something like "tag:google.com,2005:reader/item/00058b10ce338909" + // REGEX feels heavy, I should be able to just split on / and take the last element + + guard let idPart = articleID.components(separatedBy: "/").last else { + return articleID + } + + // Convert hex representation back to integer and then a string representation + guard let idNumber = Int(idPart, radix: 16) else { + return articleID + } + + return String(idNumber, radix: 10, uppercase: false) + } } struct GoogleReaderCompatibleArticleSummary: Codable {