From c30daa382f31edd7d2f86fcdc8ede51110b530a7 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sun, 25 Oct 2020 17:15:24 -0500 Subject: [PATCH] Make remove folder code actually delete a server tag. --- .../ReaderAPI/ReaderAPIAccountDelegate.swift | 44 ++++++++----------- .../Account/ReaderAPI/ReaderAPICaller.swift | 12 ++--- .../Account/ReaderAPI/ReaderAPITag.swift | 7 +++ 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index eb7f6196c..79a6fdba2 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -241,13 +241,6 @@ final class ReaderAPIAccountDelegate: AccountDelegate { func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result) -> Void) { - // Feedbin uses tags and if at least one feed isn't tagged, then the folder doesn't exist on their system - guard folder.hasAtLeastOneWebFeed() else { - account.removeFolder(folder) - completion(.success(())) - return - } - let group = DispatchGroup() for feed in folder.topLevelWebFeeds { @@ -296,8 +289,15 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } group.notify(queue: DispatchQueue.main) { - account.removeFolder(folder) - completion(.success(())) + self.caller.deleteTag(folder: folder) { result in + switch result { + case .success: + account.removeFolder(folder) + completion(.success(())) + case .failure(let error): + completion(.failure(error)) + } + } } } @@ -581,12 +581,12 @@ private extension ReaderAPIAccountDelegate { } }() - let tagNames = deriveTagNames(tags) - + let readerFolderNames = tags.compactMap { $0.folderName } + // The sync service has a tag that we don't have a folder for. We might not get a new // taggings response for it if it is a folder rename. Force expire the subscription // so that we will for sure get the new tagging information by pulling all subscriptions. - tagNames.forEach { tagName in + readerFolderNames.forEach { tagName in if !folderNames.contains(tagName) { accountMetadata?.conditionalGetInfo[ReaderAPICaller.ConditionalGetKeys.subscriptions] = nil } @@ -600,12 +600,12 @@ private extension ReaderAPIAccountDelegate { os_log(.debug, log: log, "Syncing folders with %ld tags.", tags.count) - let tagNames = deriveTagNames(tags) + let readerFolderNames = tags.compactMap { $0.folderName } // Delete any folders not at Reader if let folders = account.folders { folders.forEach { folder in - if !tagNames.contains(folder.name ?? "") { + if !readerFolderNames.contains(folder.name ?? "") { for feed in folder.topLevelWebFeeds { account.addWebFeed(feed) clearFolderRelationship(for: feed, withFolderName: folder.name ?? "") @@ -624,23 +624,15 @@ private extension ReaderAPIAccountDelegate { }() // Make any folders Reader has, but we don't - tagNames.forEach { tagName in - if !folderNames.contains(tagName) { - _ = account.ensureFolder(with: tagName) + tags.forEach { tag in + if let tagFolderName = tag.folderName, !folderNames.contains(tagFolderName) { + let folder = account.ensureFolder(with: tagFolderName) + folder?.externalID = tag.tagID } } } - func deriveTagNames(_ tags: [ReaderAPITag]) -> [String] { - return tags.filter { $0.tagID.contains("/label/") }.compactMap { - guard let range = $0.tagID.range(of: "/label/") else { - return nil - } - return String($0.tagID.suffix(from: range.upperBound)) - } - } - func refreshFeeds(_ account: Account, completion: @escaping (Result) -> Void) { caller.retrieveSubscriptions { result in switch result { diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift index 8571bc509..af2cb8bc1 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift @@ -238,13 +238,17 @@ final class ReaderAPICaller: NSObject { } } - func deleteTag(name: String, completion: @escaping (Result) -> Void) { - + func deleteTag(folder: Folder, completion: @escaping (Result) -> Void) { guard let baseURL = APIBaseURL else { completion(.failure(CredentialsError.incompleteCredentials)) return } + guard let folderExternalID = folder.externalID else { + completion(.failure(ReaderAPIAccountDelegateError.invalidParameter)) + return + } + self.requestAuthorizationToken(endpoint: baseURL) { (result) in switch result { case .success(let token): @@ -253,8 +257,7 @@ final class ReaderAPICaller: NSObject { request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" - let tagName = "user/-/label/\(name)" - let postData = "T=\(token)&s=\(tagName)".data(using: String.Encoding.utf8) + let postData = "T=\(token)&s=\(folderExternalID)".data(using: String.Encoding.utf8) self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in switch result { @@ -272,7 +275,6 @@ final class ReaderAPICaller: NSObject { completion(.failure(error)) } } - } func retrieveSubscriptions(completion: @escaping (Result<[ReaderAPISubscription]?, Error>) -> Void) { diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPITag.swift b/Account/Sources/Account/ReaderAPI/ReaderAPITag.swift index 7f827e1a6..d64462701 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPITag.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPITag.swift @@ -26,4 +26,11 @@ struct ReaderAPITag: Codable { case type = "type" } + var folderName: String? { + guard let range = tagID.range(of: "/label/") else { + return nil + } + return String(tagID.suffix(from: range.upperBound)) + } + }