From 23ea156cc0e9401536ba5222362c0ebb5e9fb90b Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Mon, 19 Oct 2020 16:20:55 -0500 Subject: [PATCH] Fix the ReaderAPI so that it updates name and folder when creating a subscription --- .../ReaderAPI/ReaderAPIAccountDelegate.swift | 7 +- .../Account/ReaderAPI/ReaderAPICaller.swift | 93 +++++++------------ .../ReaderAPI/ReaderAPISubscription.swift | 14 +-- 3 files changed, 41 insertions(+), 73 deletions(-) diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 117cc3daa..d4d0271bb 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -267,8 +267,12 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } func createWebFeed(for account: Account, url: String, name: String?, container: Container, completion: @escaping (Result) -> Void) { + guard let folder = container as? Folder else { + completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) + return + } - caller.createSubscription(url: url) { result in + caller.createSubscription(url: url, name: name, folder: folder) { result in switch result { case .success(let subResult): switch subResult { @@ -291,7 +295,6 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } } - } func renameWebFeed(for account: Account, with feed: WebFeed, to name: String, completion: @escaping (Result) -> Void) { diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift index a7622db14..0bb91ef46 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift @@ -44,7 +44,6 @@ final class ReaderAPICaller: NSObject { case tagList = "/reader/api/0/tag/list" case subscriptionList = "/reader/api/0/subscription/list" case subscriptionEdit = "/reader/api/0/subscription/edit" - case subscriptionAdd = "/reader/api/0/subscription/quickadd" case contents = "/reader/api/0/stream/items/contents" case itemIds = "/reader/api/0/stream/items/ids" case editTag = "/reader/api/0/edit-tag" @@ -303,7 +302,7 @@ final class ReaderAPICaller: NSObject { } - func createSubscription(url: String, completion: @escaping (Result) -> Void) { + func createSubscription(url: String, name: String?, folder: Folder, completion: @escaping (Result) -> Void) { guard let baseURL = APIBaseURL else { completion(.failure(CredentialsError.incompleteCredentials)) return @@ -318,69 +317,52 @@ final class ReaderAPICaller: NSObject { switch result { case .success(let feedSpecifiers): - guard let bestFeedSpecifier = FeedSpecifier.bestFeed(in: feedSpecifiers), - let url = URL(string: bestFeedSpecifier.urlString) else { - completion(.failure(AccountError.createErrorNotFound)) - return + + let feedSpecifiers = feedSpecifiers.filter { !$0.urlString.hasSuffix(".json") } + guard let bestFeedSpecifier = FeedSpecifier.bestFeed(in: feedSpecifiers), let feedURL = URL(string: bestFeedSpecifier.urlString) else { + completion(.failure(AccountError.createErrorNotFound)) + return } + self.requestAuthorizationToken(endpoint: baseURL) { (result) in switch result { case .success(let token): - let url = baseURL - .appendingPathComponent(ReaderAPIEndpoints.subscriptionAdd.rawValue) - .appendingQueryItem(URLQueryItem(name: "quickadd", value: url.absoluteString)) - - guard let callURL = url else { - completion(.failure(TransportError.noURL)) - return - } - + let callURL = baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue) + var request = URLRequest(url: callURL, credentials: self.credentials) request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" - let postData = "T=\(token)".data(using: String.Encoding.utf8) + let postData = "T=\(token)&ac=subscribe&s=feed/\(feedURL.absoluteString)&a=user/-/label/\(folder.nameForDisplay)&t=\(name ?? "")".data(using: String.Encoding.utf8) - self.transport.send(request: request, method: HTTPMethod.post, data: postData!, resultType: ReaderAPIQuickAddResult.self, completion: { (result) in + self.self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in switch result { - case .success(let (_, subResult)): + case .success: - switch subResult?.numResults { - case 0: - completion(.success(.alreadySubscribed)) - default: - // We have a feed ID but need to get feed information - guard let streamId = subResult?.streamId else { - completion(.failure(AccountError.createErrorNotFound)) - return - } - - // There is no call to get a single subscription entry, so we get them all, - // look up the one we just subscribed to and return that - self.retrieveSubscriptions(completion: { (result) in - switch result { - case .success(let subscriptions): - guard let subscriptions = subscriptions else { - completion(.failure(AccountError.createErrorNotFound)) - return - } - - let newStreamId = "feed/\(streamId)" - - guard let subscription = subscriptions.first(where: { (sub) -> Bool in - sub.feedID == newStreamId - }) else { - completion(.failure(AccountError.createErrorNotFound)) - return - } - - completion(.success(.created(subscription))) - - case .failure(let error): - completion(.failure(error)) + // There is no call to get a single subscription entry, so we get them all, + // look up the one we just subscribed to and return that + self.retrieveSubscriptions(completion: { (result) in + switch result { + case .success(let subscriptions): + guard let subscriptions = subscriptions else { + completion(.failure(AccountError.createErrorNotFound)) + return } - }) + + guard let subscription = subscriptions.first(where: { (sub) -> Bool in + sub.url == feedURL.absoluteString + }) else { + completion(.failure(AccountError.createErrorNotFound)) + return + } + + completion(.success(.created(subscription))) + + case .failure: + completion(.failure(AccountError.createErrorAlreadySubscribed)) } + }) + case .failure(let error): completion(.failure(error)) } @@ -392,14 +374,12 @@ final class ReaderAPICaller: NSObject { } } - - case .failure: completion(.failure(AccountError.createErrorNotFound)) } } -// + } func renameSubscription(subscriptionID: String, newName: String, completion: @escaping (Result) -> Void) { @@ -447,8 +427,6 @@ final class ReaderAPICaller: NSObject { switch result { case .success(let token): var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials) - - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" @@ -465,7 +443,6 @@ final class ReaderAPICaller: NSObject { } }) - case .failure(let error): completion(.failure(error)) } diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPISubscription.swift b/Account/Sources/Account/ReaderAPI/ReaderAPISubscription.swift index 3072656ec..8ac63a9e9 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPISubscription.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPISubscription.swift @@ -1,5 +1,5 @@ // -// ReaderAPIFeed.swift +// ReaderAPISubscription.swift // Account // // Created by Jeremy Beker on 5/28/19. @@ -19,18 +19,6 @@ import RSParser */ -struct ReaderAPIQuickAddResult: Codable { - let numResults: Int - let error: String? - let streamId: String? - - enum CodingKeys: String, CodingKey { - case numResults = "numResults" - case error = "error" - case streamId = "streamId" - } -} - struct ReaderAPISubscriptionContainer: Codable { let subscriptions: [ReaderAPISubscription]