- correct subscription API calls
- move subscription rather than deleting and re-adding it - include authors
This commit is contained in:
parent
6f6e547a5b
commit
9d8d212f3c
|
@ -473,14 +473,23 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
|||
if from is Account {
|
||||
addWebFeed(for: account, with: feed, to: to, completion: completion)
|
||||
} else {
|
||||
deleteTagging(for: account, with: feed, from: from) { result in
|
||||
switch result {
|
||||
case .success:
|
||||
self.addWebFeed(for: account, with: feed, to: to, completion: completion)
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
guard let subscriptionId = feed.externalID, let fromTag = (from as? Folder)?.name, let toTag = (to as? Folder)?.name else {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
return
|
||||
}
|
||||
|
||||
refreshProgress.addToNumberOfTasksAndRemaining(1)
|
||||
caller.moveSubscription(subscriptionID: subscriptionId, fromTag: fromTag, toTag: toTag) { result in
|
||||
self.refreshProgress.completeTask()
|
||||
switch result {
|
||||
case .success:
|
||||
from.removeWebFeed(feed)
|
||||
to.addWebFeed(feed)
|
||||
completion(.success(()))
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1008,8 +1017,13 @@ private extension ReaderAPIAccountDelegate {
|
|||
guard let streamID = entry.origin.streamId else {
|
||||
return nil
|
||||
}
|
||||
// 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
|
||||
|
||||
var authors: Set<ParsedAuthor>? {
|
||||
guard let name = entry.author else {
|
||||
return nil
|
||||
}
|
||||
return Set([ParsedAuthor(name: name, url: nil, avatarURL: nil, emailAddress: nil)])
|
||||
}
|
||||
|
||||
return ParsedItem(syncServiceID: entry.uniqueID(variant: variant),
|
||||
uniqueID: entry.uniqueID(variant: variant),
|
||||
|
@ -1025,7 +1039,7 @@ private extension ReaderAPIAccountDelegate {
|
|||
bannerImageURL: nil,
|
||||
datePublished: entry.parseDatePublished(),
|
||||
dateModified: nil,
|
||||
authors: nil,
|
||||
authors: authors,
|
||||
tags: nil,
|
||||
attachments: nil)
|
||||
}
|
||||
|
@ -1132,32 +1146,4 @@ private extension ReaderAPIAccountDelegate {
|
|||
|
||||
}
|
||||
|
||||
func deleteTagging(for account: Account, with feed: WebFeed, from container: Container?, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
if let folder = container as? Folder, let feedName = feed.externalID {
|
||||
caller.deleteTagging(subscriptionID: feedName, tagName: folder.name ?? "") { result in
|
||||
switch result {
|
||||
case .success:
|
||||
DispatchQueue.main.async {
|
||||
self.clearFolderRelationship(for: feed, folderExternalID: folder.externalID)
|
||||
folder.removeWebFeed(feed)
|
||||
account.addFeedIfNotInAnyFolder(feed)
|
||||
completion(.success(()))
|
||||
}
|
||||
case .failure(let error):
|
||||
DispatchQueue.main.async {
|
||||
let wrappedError = AccountError.wrappedError(error: error, account: account)
|
||||
completion(.failure(wrappedError))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let account = container as? Account {
|
||||
account.removeWebFeed(feed)
|
||||
}
|
||||
completion(.success(()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -358,21 +358,19 @@ final class ReaderAPICaller: NSObject {
|
|||
self.requestAuthorizationToken(endpoint: baseURL) { (result) in
|
||||
switch result {
|
||||
case .success(let token):
|
||||
let url = baseURL
|
||||
let callURL = baseURL
|
||||
.appendingPathComponent(ReaderAPIEndpoints.subscriptionAdd.rawValue)
|
||||
.appendingQueryItem(URLQueryItem(name: "quickadd", value: url))
|
||||
|
||||
guard let callURL = url else {
|
||||
completion(.failure(TransportError.noURL))
|
||||
return
|
||||
}
|
||||
|
||||
var request = URLRequest(url: callURL, credentials: self.credentials)
|
||||
self.addVariantHeaders(&request)
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "POST"
|
||||
|
||||
let postData = "T=\(token)".data(using: String.Encoding.utf8)
|
||||
|
||||
guard let encodedFeedURL = self.encodeForURLPath(url) else {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
return
|
||||
}
|
||||
let postData = "T=\(token)&quickadd=\(encodedFeedURL)".data(using: String.Encoding.utf8)
|
||||
|
||||
self.transport.send(request: request, method: HTTPMethod.post, data: postData!, resultType: ReaderAPIQuickAddResult.self, completion: { (result) in
|
||||
switch result {
|
||||
|
@ -387,34 +385,7 @@ final class ReaderAPICaller: NSObject {
|
|||
return
|
||||
}
|
||||
|
||||
if name == nil && folder == nil {
|
||||
findSubscription(streamID: streamId, completion: completion)
|
||||
} else {
|
||||
let callURL = baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue)
|
||||
var request = URLRequest(url: callURL, credentials: self.credentials)
|
||||
self.addVariantHeaders(&request)
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "POST"
|
||||
|
||||
var postString = "T=\(token)&ac=subscribe&s=\(streamId)"
|
||||
if let folderName = self.encodeForURLPath(folder?.nameForDisplay) {
|
||||
postString += "&a=user/-/label/\(folderName)"
|
||||
}
|
||||
if let name = self.encodeForURLPath(name) {
|
||||
postString += "&t=\(name)"
|
||||
}
|
||||
|
||||
let postData = postString.data(using: String.Encoding.utf8)
|
||||
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||
switch result {
|
||||
case .success:
|
||||
findSubscription(streamID: streamId, completion: completion)
|
||||
case .failure:
|
||||
completion(.failure(AccountError.createErrorAlreadySubscribed))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
findSubscription(streamID: streamId, completion: completion)
|
||||
}
|
||||
|
||||
case .failure(let error):
|
||||
|
@ -432,42 +403,7 @@ final class ReaderAPICaller: NSObject {
|
|||
}
|
||||
|
||||
func renameSubscription(subscriptionID: String, newName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
|
||||
self.requestAuthorizationToken(endpoint: baseURL) { (result) in
|
||||
switch result {
|
||||
case .success(let token):
|
||||
var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials)
|
||||
self.addVariantHeaders(&request)
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "POST"
|
||||
|
||||
guard let encodedNewName = self.encodeForURLPath(newName) else {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
return
|
||||
}
|
||||
|
||||
let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&t=\(encodedNewName)".data(using: String.Encoding.utf8)
|
||||
|
||||
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||
switch result {
|
||||
case .success:
|
||||
completion(.success(()))
|
||||
break
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
changeSubscription(subscriptionID: subscriptionID, title: newName, completion: completion)
|
||||
}
|
||||
|
||||
func deleteSubscription(subscriptionID: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
@ -504,78 +440,64 @@ final class ReaderAPICaller: NSObject {
|
|||
}
|
||||
|
||||
func createTagging(subscriptionID: String, tagName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
|
||||
self.requestAuthorizationToken(endpoint: baseURL) { (result) in
|
||||
switch result {
|
||||
case .success(let token):
|
||||
var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials)
|
||||
self.addVariantHeaders(&request)
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "POST"
|
||||
|
||||
guard let tagName = self.encodeForURLPath(tagName) else {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
return
|
||||
}
|
||||
|
||||
let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&a=user/-/label/\(tagName)".data(using: String.Encoding.utf8)
|
||||
|
||||
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||
switch result {
|
||||
case .success:
|
||||
completion(.success(()))
|
||||
break
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
changeSubscription(subscriptionID: subscriptionID, addTagName: tagName, completion: completion)
|
||||
}
|
||||
|
||||
func deleteTagging(subscriptionID: String, tagName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
|
||||
self.requestAuthorizationToken(endpoint: baseURL) { (result) in
|
||||
switch result {
|
||||
case .success(let token):
|
||||
var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials)
|
||||
self.addVariantHeaders(&request)
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "POST"
|
||||
|
||||
let tagName = "user/-/label/\(tagName)"
|
||||
let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&r=\(tagName)".data(using: String.Encoding.utf8)
|
||||
|
||||
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||
switch result {
|
||||
case .success:
|
||||
completion(.success(()))
|
||||
break
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
changeSubscription(subscriptionID: subscriptionID, removeTagName: tagName, completion: completion)
|
||||
}
|
||||
|
||||
func moveSubscription(subscriptionID: String, fromTag: String, toTag: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
changeSubscription(subscriptionID: subscriptionID, removeTagName: fromTag, addTagName: toTag, completion: completion)
|
||||
}
|
||||
|
||||
private func changeSubscription(subscriptionID: String, removeTagName: String? = nil, addTagName: String? = nil, title: String? = nil, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
if removeTagName == nil && addTagName == nil && title == nil {
|
||||
completion(.failure(ReaderAPIAccountDelegateError.invalidParameter))
|
||||
return
|
||||
}
|
||||
|
||||
guard let baseURL = apiBaseURL else {
|
||||
completion(.failure(CredentialsError.incompleteCredentials))
|
||||
return
|
||||
}
|
||||
|
||||
self.requestAuthorizationToken(endpoint: baseURL) { (result) in
|
||||
switch result {
|
||||
case .success(let token):
|
||||
var request = URLRequest(url: baseURL.appendingPathComponent(ReaderAPIEndpoints.subscriptionEdit.rawValue), credentials: self.credentials)
|
||||
self.addVariantHeaders(&request)
|
||||
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
request.httpMethod = "POST"
|
||||
|
||||
var postString = "T=\(token)&s=\(subscriptionID)&ac=edit"
|
||||
if let fromLabel = self.encodeForURLPath(removeTagName) {
|
||||
postString += "&r=user/-/label/\(fromLabel)"
|
||||
}
|
||||
if let toLabel = self.encodeForURLPath(addTagName) {
|
||||
postString += "&a=user/-/label/\(toLabel)"
|
||||
}
|
||||
if let encodedTitle = self.encodeForURLPath(title) {
|
||||
postString += "&t=\(encodedTitle)"
|
||||
}
|
||||
let postData = postString.data(using: String.Encoding.utf8)
|
||||
|
||||
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||
switch result {
|
||||
case .success:
|
||||
completion(.success(()))
|
||||
break
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func retrieveEntries(articleIDs: [String], completion: @escaping (Result<([ReaderAPIEntry]?), Error>) -> Void) {
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ struct ReaderAPIEntry: Codable {
|
|||
|
||||
let articleID: String
|
||||
let title: String?
|
||||
let author: String?
|
||||
|
||||
let publishedTimestamp: Double?
|
||||
let crawledTimestamp: String?
|
||||
|
@ -64,6 +65,7 @@ struct ReaderAPIEntry: Codable {
|
|||
enum CodingKeys: String, CodingKey {
|
||||
case articleID = "id"
|
||||
case title = "title"
|
||||
case author = "author"
|
||||
case summary = "summary"
|
||||
case alternates = "alternate"
|
||||
case categories = "categories"
|
||||
|
|
Loading…
Reference in New Issue