Add subreddit name lookup and fix rate limit when one isn't returned

This commit is contained in:
Maurice Parker 2020-05-07 15:39:02 -05:00
parent 4aa0033270
commit ea5c06f3a7
2 changed files with 36 additions and 14 deletions

View File

@ -91,17 +91,7 @@ public final class RedditFeedProvider: FeedProvider {
return return
} }
let splitPath = urlComponents.path.split(separator: "/") subreddit(urlComponents) { result in
guard splitPath.count > 1 else {
completion(.failure(RedditFeedProviderError.unknown))
return
}
let secondElement = String(splitPath[1])
let api = "/r/\(secondElement)/about.json"
fetch(api: api, parameters: [:], resultType: RedditSubreddit.self) { result in
switch result { switch result {
case .success(let subreddit): case .success(let subreddit):
if let iconURL = subreddit.data?.iconURL, !iconURL.isEmpty { if let iconURL = subreddit.data?.iconURL, !iconURL.isEmpty {
@ -134,7 +124,19 @@ public final class RedditFeedProvider: FeedProvider {
let name = "\(splitPath[0])/\(splitPath[1])" let name = "\(splitPath[0])/\(splitPath[1])"
let homePageURL = "https://www.reddit.com/\(name)" let homePageURL = "https://www.reddit.com/\(name)"
completion(.success(FeedProviderFeedMetaData(name: name, homePageURL: homePageURL))) subreddit(urlComponents) { result in
switch result {
case .success(let subreddit):
if let displayName = subreddit.data?.displayName {
completion(.success(FeedProviderFeedMetaData(name: displayName, homePageURL: homePageURL)))
} else {
completion(.failure(RedditFeedProviderError.unknown))
}
case .failure(let error):
completion(.failure(error))
}
}
} }
public func refresh(_ webFeed: WebFeed, completion: @escaping (Result<Set<ParsedItem>, Error>) -> Void) { public func refresh(_ webFeed: WebFeed, completion: @escaping (Result<Set<ParsedItem>, Error>) -> Void) {
@ -221,6 +223,19 @@ extension RedditFeedProvider: OAuth2SwiftProvider {
private extension RedditFeedProvider { private extension RedditFeedProvider {
func subreddit(_ urlComponents: URLComponents, completion: @escaping (Result<RedditSubreddit, Error>) -> Void) {
let splitPath = urlComponents.path.split(separator: "/")
guard splitPath.count > 1 else {
completion(.failure(RedditFeedProviderError.unknown))
return
}
let secondElement = String(splitPath[1])
let api = "/r/\(secondElement)/about.json"
fetch(api: api, parameters: [:], resultType: RedditSubreddit.self, completion: completion)
}
func fetch<R: Decodable>(api: String, parameters: [String: Any] = [:], resultType: R.Type, completion: @escaping (Result<R, Error>) -> Void) { func fetch<R: Decodable>(api: String, parameters: [String: Any] = [:], resultType: R.Type, completion: @escaping (Result<R, Error>) -> Void) {
guard let client = client else { guard let client = client else {
completion(.failure(RedditFeedProviderError.unknown)) completion(.failure(RedditFeedProviderError.unknown))
@ -247,10 +262,15 @@ private extension RedditFeedProvider {
// try? jsonString?.write(toFile: url.path, atomically: true, encoding: .utf8) // try? jsonString?.write(toFile: url.path, atomically: true, encoding: .utf8)
if let remaining = response.response.value(forHTTPHeaderField: "X-Ratelimit-Remaining") { if let remaining = response.response.value(forHTTPHeaderField: "X-Ratelimit-Remaining") {
self.rateLimitRemaining = Int(remaining) ?? 0 self.rateLimitRemaining = Int(remaining)
} else {
self.rateLimitRemaining = nil
} }
if let reset = response.response.value(forHTTPHeaderField: "X-Ratelimit-Reset") { if let reset = response.response.value(forHTTPHeaderField: "X-Ratelimit-Reset") {
self.rateLimitReset = Date(timeIntervalSinceNow: Double(reset) ?? 0) self.rateLimitReset = Date(timeIntervalSinceNow: Double(reset) ?? 0)
} else {
self.rateLimitReset = nil
} }
DispatchQueue.global(qos: .background).async { DispatchQueue.global(qos: .background).async {

View File

@ -22,10 +22,12 @@ struct RedditSubreddit: Codable {
struct RedditSubredditData: Codable { struct RedditSubredditData: Codable {
let displayName: String?
let iconImg: String? let iconImg: String?
let communityIcon: String? let communityIcon: String?
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case displayName = "display_name_prefixed"
case iconImg = "icon_img" case iconImg = "icon_img"
case communityIcon = "community_icon" case communityIcon = "community_icon"
} }