Disbale and rename tags functional.
This commit is contained in:
parent
41af536212
commit
17439c8c5e
@ -15,7 +15,6 @@ import RSWeb
|
|||||||
|
|
||||||
enum CreateGoogleReaderSubscriptionResult {
|
enum CreateGoogleReaderSubscriptionResult {
|
||||||
case created(GoogleReaderCompatibleSubscription)
|
case created(GoogleReaderCompatibleSubscription)
|
||||||
//case multipleChoice([GoogleReaderCompatibleSubscriptionChoice])
|
|
||||||
case alreadySubscribed
|
case alreadySubscribed
|
||||||
case notFound
|
case notFound
|
||||||
}
|
}
|
||||||
@ -39,6 +38,8 @@ final class GoogleReaderCompatibleAPICaller: NSObject {
|
|||||||
enum GoogleReaderEndpoints: String {
|
enum GoogleReaderEndpoints: String {
|
||||||
case login = "/accounts/ClientLogin"
|
case login = "/accounts/ClientLogin"
|
||||||
case token = "/reader/api/0/token"
|
case token = "/reader/api/0/token"
|
||||||
|
case disableTag = "/reader/api/0/disable-tag"
|
||||||
|
case renameTag = "/reader/api/0/rename-tag"
|
||||||
case tagList = "/reader/api/0/tag/list"
|
case tagList = "/reader/api/0/tag/list"
|
||||||
case subscriptionList = "/reader/api/0/subscription/list"
|
case subscriptionList = "/reader/api/0/subscription/list"
|
||||||
case subscriptionEdit = "/reader/api/0/subscription/edit"
|
case subscriptionEdit = "/reader/api/0/subscription/edit"
|
||||||
@ -243,28 +244,76 @@ final class GoogleReaderCompatibleAPICaller: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func renameTag(oldName: String, newName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
func renameTag(oldName: String, newName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
// let callURL = GoogleReaderCompatibleBaseURL.appendingPathComponent("tags.json")
|
guard let baseURL = APIBaseURL else {
|
||||||
// let request = URLRequest(url: callURL, credentials: credentials)
|
completion(.failure(CredentialsError.incompleteCredentials))
|
||||||
// let payload = GoogleReaderCompatibleRenameTag(oldName: oldName, newName: newName)
|
return
|
||||||
// transport.send(request: request, method: HTTPMethod.post, payload: payload, completion: completion)
|
}
|
||||||
|
|
||||||
|
self.requestAuthorizationToken(endpoint: baseURL) { (result) in
|
||||||
|
switch result {
|
||||||
|
case .success(let token):
|
||||||
|
var request = URLRequest(url: baseURL.appendingPathComponent(GoogleReaderEndpoints.renameTag.rawValue), credentials: self.credentials)
|
||||||
|
|
||||||
|
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||||
|
request.httpMethod = "POST"
|
||||||
|
|
||||||
|
let oldTagName = "user/-/label/\(oldName)"
|
||||||
|
let newTagName = "user/-/label/\(newName)"
|
||||||
|
let postData = "T=\(token)&s=\(oldTagName)&dest=\(newTagName)".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 deleteTag(name: String, completion: @escaping (Result<[GoogleReaderCompatibleTagging]?, Error>) -> Void) {
|
func deleteTag(name: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
|
||||||
// let callURL = GoogleReaderCompatibleBaseURL.appendingPathComponent("tags.json")
|
guard let baseURL = APIBaseURL else {
|
||||||
// let request = URLRequest(url: callURL, credentials: credentials)
|
completion(.failure(CredentialsError.incompleteCredentials))
|
||||||
// let payload = GoogleReaderCompatibleDeleteTag(name: name)
|
return
|
||||||
//
|
}
|
||||||
// transport.send(request: request, method: HTTPMethod.delete, payload: payload, resultType: [GoogleReaderCompatibleTagging].self) { result in
|
|
||||||
//
|
self.requestAuthorizationToken(endpoint: baseURL) { (result) in
|
||||||
// switch result {
|
switch result {
|
||||||
// case .success(let (_, taggings)):
|
case .success(let token):
|
||||||
// completion(.success(taggings))
|
var request = URLRequest(url: baseURL.appendingPathComponent(GoogleReaderEndpoints.disableTag.rawValue), credentials: self.credentials)
|
||||||
// case .failure(let error):
|
|
||||||
// completion(.failure(error))
|
|
||||||
// }
|
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)
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,65 +506,78 @@ final class GoogleReaderCompatibleAPICaller: NSObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTagging(feedID: Int, name: String, completion: @escaping (Result<Int, Error>) -> Void) {
|
func createTagging(subscriptionID: String, tagName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
|
||||||
// let callURL = GoogleReaderCompatibleBaseURL.appendingPathComponent("taggings.json")
|
guard let baseURL = APIBaseURL else {
|
||||||
// var request = URLRequest(url: callURL, credentials: credentials)
|
completion(.failure(CredentialsError.incompleteCredentials))
|
||||||
// request.addValue("application/json; charset=utf-8", forHTTPHeaderField: HTTPRequestHeader.contentType)
|
return
|
||||||
//
|
}
|
||||||
// let payload: Data
|
|
||||||
// do {
|
self.requestAuthorizationToken(endpoint: baseURL) { (result) in
|
||||||
// payload = try JSONEncoder().encode(GoogleReaderCompatibleCreateTagging(feedID: feedID, name: name))
|
switch result {
|
||||||
// } catch {
|
case .success(let token):
|
||||||
// completion(.failure(error))
|
var request = URLRequest(url: baseURL.appendingPathComponent(GoogleReaderEndpoints.subscriptionEdit.rawValue), credentials: self.credentials)
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||||
// transport.send(request: request, method: HTTPMethod.post, payload:payload) { result in
|
request.httpMethod = "POST"
|
||||||
//
|
|
||||||
// switch result {
|
let tagName = "user/-/label/\(tagName)"
|
||||||
// case .success(let (response, _)):
|
let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&a=\(tagName)".data(using: String.Encoding.utf8)
|
||||||
// if let taggingLocation = response.valueForHTTPHeaderField(HTTPResponseHeader.location),
|
|
||||||
// let lowerBound = taggingLocation.range(of: "v2/taggings/")?.upperBound,
|
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||||
// let upperBound = taggingLocation.range(of: ".json")?.lowerBound,
|
switch result {
|
||||||
// let taggingID = Int(taggingLocation[lowerBound..<upperBound]) {
|
case .success:
|
||||||
// completion(.success(taggingID))
|
completion(.success(()))
|
||||||
// } else {
|
break
|
||||||
// completion(.failure(TransportError.noData))
|
case .failure(let error):
|
||||||
// }
|
completion(.failure(error))
|
||||||
// case .failure(let error):
|
break
|
||||||
// completion(.failure(error))
|
}
|
||||||
// }
|
})
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteTagging(taggingID: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
func deleteTagging(subscriptionID: String, tagName: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
// let callURL = GoogleReaderCompatibleBaseURL.appendingPathComponent("taggings/\(taggingID).json")
|
guard let baseURL = APIBaseURL else {
|
||||||
// var request = URLRequest(url: callURL, credentials: credentials)
|
completion(.failure(CredentialsError.incompleteCredentials))
|
||||||
// request.addValue("application/json; charset=utf-8", forHTTPHeaderField: HTTPRequestHeader.contentType)
|
return
|
||||||
// transport.send(request: request, method: HTTPMethod.delete, completion: completion)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func retrieveIcons(completion: @escaping (Result<[GoogleReaderCompatibleIcon]?, Error>) -> Void) {
|
self.requestAuthorizationToken(endpoint: baseURL) { (result) in
|
||||||
|
switch result {
|
||||||
|
case .success(let token):
|
||||||
|
var request = URLRequest(url: baseURL.appendingPathComponent(GoogleReaderEndpoints.subscriptionEdit.rawValue), credentials: self.credentials)
|
||||||
|
|
||||||
// let callURL = GoogleReaderCompatibleBaseURL.appendingPathComponent("icons.json")
|
|
||||||
// let conditionalGet = accountMetadata?.conditionalGetInfo[ConditionalGetKeys.icons]
|
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||||
// let request = URLRequest(url: callURL, credentials: credentials, conditionalGet: conditionalGet)
|
request.httpMethod = "POST"
|
||||||
//
|
|
||||||
// transport.send(request: request, resultType: [GoogleReaderCompatibleIcon].self) { result in
|
let tagName = "user/-/label/\(tagName)"
|
||||||
//
|
let postData = "T=\(token)&s=\(subscriptionID)&ac=edit&r=\(tagName)".data(using: String.Encoding.utf8)
|
||||||
// switch result {
|
|
||||||
// case .success(let (response, icons)):
|
self.transport.send(request: request, method: HTTPMethod.post, payload: postData!, completion: { (result) in
|
||||||
// self.storeConditionalGet(key: ConditionalGetKeys.icons, headers: response.allHeaderFields)
|
switch result {
|
||||||
// completion(.success(icons))
|
case .success:
|
||||||
// case .failure(let error):
|
completion(.success(()))
|
||||||
// completion(.failure(error))
|
break
|
||||||
// }
|
case .failure(let error):
|
||||||
//
|
completion(.failure(error))
|
||||||
// }
|
break
|
||||||
//
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func retrieveEntries(articleIDs: [String], completion: @escaping (Result<([GoogleReaderCompatibleEntry]?), Error>) -> Void) {
|
func retrieveEntries(articleIDs: [String], completion: @escaping (Result<([GoogleReaderCompatibleEntry]?), Error>) -> Void) {
|
||||||
@ -544,7 +606,6 @@ final class GoogleReaderCompatibleAPICaller: NSObject {
|
|||||||
}).joined(separator:"&")
|
}).joined(separator:"&")
|
||||||
|
|
||||||
let postData = "T=\(token)&output=json&\(idsToFetch)".data(using: String.Encoding.utf8)
|
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
|
self.transport.send(request: request, method: HTTPMethod.post, data: postData!, resultType: GoogleReaderCompatibleEntryWrapper.self, completion: { (result) in
|
||||||
switch result {
|
switch result {
|
||||||
|
@ -265,13 +265,6 @@ final class GoogleReaderCompatibleAccountDelegate: AccountDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
|
||||||
// Feedbin uses tags and if at least one feed isn't tagged, then the folder doesn't exist on their system
|
|
||||||
guard folder.hasAtLeastOneFeed() else {
|
|
||||||
account.removeFolder(folder)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let group = DispatchGroup()
|
let group = DispatchGroup()
|
||||||
|
|
||||||
for feed in folder.topLevelFeeds {
|
for feed in folder.topLevelFeeds {
|
||||||
@ -288,8 +281,17 @@ final class GoogleReaderCompatibleAccountDelegate: AccountDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group.notify(queue: DispatchQueue.main) {
|
group.notify(queue: DispatchQueue.main) {
|
||||||
account.removeFolder(folder)
|
self.caller.deleteTag(name: folder.name!) { (result) in
|
||||||
completion(.success(()))
|
switch result {
|
||||||
|
case .success:
|
||||||
|
account.removeFolder(folder)
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
os_log(.error, log: self.log, "Remove feed error: %@.", error.localizedDescription)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -373,12 +375,12 @@ final class GoogleReaderCompatibleAccountDelegate: AccountDelegate {
|
|||||||
|
|
||||||
func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
|
func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
|
||||||
if let folder = container as? Folder, let feedID = Int(feed.feedID) {
|
if let folder = container as? Folder, let feedName = feed.subscriptionID {
|
||||||
caller.createTagging(feedID: feedID, name: folder.name ?? "") { result in
|
caller.createTagging(subscriptionID: feedName, tagName: folder.name ?? "") { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let taggingID):
|
case .success:
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.saveFolderRelationship(for: feed, withFolderName: folder.name ?? "", id: String(taggingID))
|
self.saveFolderRelationship(for: feed, withFolderName: folder.name ?? "", id: feed.subscriptionID!)
|
||||||
account.removeFeed(feed)
|
account.removeFeed(feed)
|
||||||
folder.addFeed(feed)
|
folder.addFeed(feed)
|
||||||
completion(.success(()))
|
completion(.success(()))
|
||||||
@ -705,7 +707,8 @@ private extension GoogleReaderCompatibleAccountDelegate {
|
|||||||
for subscription in groupedTaggings {
|
for subscription in groupedTaggings {
|
||||||
let taggingFeedID = String(subscription.feedID)
|
let taggingFeedID = String(subscription.feedID)
|
||||||
if !folderFeedIds.contains(taggingFeedID) {
|
if !folderFeedIds.contains(taggingFeedID) {
|
||||||
guard let feed = account.idToFeedDictionary[taggingFeedID] else {
|
let idDictionary = account.idToFeedDictionary
|
||||||
|
guard let feed = idDictionary[taggingFeedID] else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
@ -1097,8 +1100,8 @@ private extension GoogleReaderCompatibleAccountDelegate {
|
|||||||
|
|
||||||
func deleteTagging(for account: Account, with feed: Feed, from container: Container?, completion: @escaping (Result<Void, Error>) -> Void) {
|
func deleteTagging(for account: Account, with feed: Feed, from container: Container?, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
|
||||||
if let folder = container as? Folder, let feedTaggingID = feed.folderRelationship?[folder.name ?? ""] {
|
if let folder = container as? Folder, let feedName = feed.subscriptionID {
|
||||||
caller.deleteTagging(taggingID: feedTaggingID) { result in
|
caller.deleteTagging(subscriptionID: feedName, tagName: folder.name ?? "") { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success:
|
case .success:
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user