Add support for Reddit feed icons
This commit is contained in:
parent
78cefecaad
commit
143c102454
|
@ -47,6 +47,7 @@
|
|||
5133BB47245FD8140001E3D0 /* RedditLinkListing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5133BB46245FD8140001E3D0 /* RedditLinkListing.swift */; };
|
||||
5133BB49246078910001E3D0 /* RedditLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5133BB48246078910001E3D0 /* RedditLink.swift */; };
|
||||
5133BB4B2460BDF30001E3D0 /* RedditSubreddit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5133BB4A2460BDF30001E3D0 /* RedditSubreddit.swift */; };
|
||||
5133BB4D2460CA0B0001E3D0 /* RedditMe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5133BB4C2460CA0B0001E3D0 /* RedditMe.swift */; };
|
||||
5139A6382459822D004D960C /* CloudKitArticleStatusUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5139A6372459822D004D960C /* CloudKitArticleStatusUpdate.swift */; };
|
||||
5144EA49227B497600D19003 /* FeedbinAPICaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA48227B497600D19003 /* FeedbinAPICaller.swift */; };
|
||||
5144EA4E227B829A00D19003 /* FeedbinAccountDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5144EA4D227B829A00D19003 /* FeedbinAccountDelegate.swift */; };
|
||||
|
@ -65,7 +66,6 @@
|
|||
516896352448EBEA00185AC5 /* FeedProviderManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516896342448EBEA00185AC5 /* FeedProviderManager.swift */; };
|
||||
5170743C232AEDB500A461A3 /* OPMLFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5170743B232AEDB500A461A3 /* OPMLFile.swift */; };
|
||||
5193CD54245E3F7A0092735E /* RedditFeedProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5193CD53245E3F7A0092735E /* RedditFeedProvider.swift */; };
|
||||
5193CD81245F295E0092735E /* RedditUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5193CD80245F295E0092735E /* RedditUser.swift */; };
|
||||
519E84A62433D49000D238B0 /* OPMLNormalizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E84A52433D49000D238B0 /* OPMLNormalizer.swift */; };
|
||||
519E84A82434C5EF00D238B0 /* CloudKitArticlesZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E84A72434C5EF00D238B0 /* CloudKitArticlesZone.swift */; };
|
||||
519E84AC2435019100D238B0 /* CloudKitArticlesZoneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519E84AB2435019100D238B0 /* CloudKitArticlesZoneDelegate.swift */; };
|
||||
|
@ -306,6 +306,7 @@
|
|||
5133BB46245FD8140001E3D0 /* RedditLinkListing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedditLinkListing.swift; sourceTree = "<group>"; };
|
||||
5133BB48246078910001E3D0 /* RedditLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedditLink.swift; sourceTree = "<group>"; };
|
||||
5133BB4A2460BDF30001E3D0 /* RedditSubreddit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedditSubreddit.swift; sourceTree = "<group>"; };
|
||||
5133BB4C2460CA0B0001E3D0 /* RedditMe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedditMe.swift; sourceTree = "<group>"; };
|
||||
5139A6372459822D004D960C /* CloudKitArticleStatusUpdate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudKitArticleStatusUpdate.swift; sourceTree = "<group>"; };
|
||||
5144EA48227B497600D19003 /* FeedbinAPICaller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinAPICaller.swift; sourceTree = "<group>"; };
|
||||
5144EA4D227B829A00D19003 /* FeedbinAccountDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedbinAccountDelegate.swift; sourceTree = "<group>"; };
|
||||
|
@ -324,7 +325,6 @@
|
|||
516896342448EBEA00185AC5 /* FeedProviderManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedProviderManager.swift; sourceTree = "<group>"; };
|
||||
5170743B232AEDB500A461A3 /* OPMLFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OPMLFile.swift; sourceTree = "<group>"; };
|
||||
5193CD53245E3F7A0092735E /* RedditFeedProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedditFeedProvider.swift; sourceTree = "<group>"; };
|
||||
5193CD80245F295E0092735E /* RedditUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedditUser.swift; sourceTree = "<group>"; };
|
||||
519E84A52433D49000D238B0 /* OPMLNormalizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OPMLNormalizer.swift; sourceTree = "<group>"; };
|
||||
519E84A72434C5EF00D238B0 /* CloudKitArticlesZone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudKitArticlesZone.swift; sourceTree = "<group>"; };
|
||||
519E84AB2435019100D238B0 /* CloudKitArticlesZoneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CloudKitArticlesZoneDelegate.swift; sourceTree = "<group>"; };
|
||||
|
@ -642,7 +642,7 @@
|
|||
5133BB48246078910001E3D0 /* RedditLink.swift */,
|
||||
5133BB46245FD8140001E3D0 /* RedditLinkListing.swift */,
|
||||
5133BB4A2460BDF30001E3D0 /* RedditSubreddit.swift */,
|
||||
5193CD80245F295E0092735E /* RedditUser.swift */,
|
||||
5133BB4C2460CA0B0001E3D0 /* RedditMe.swift */,
|
||||
);
|
||||
path = Reddit;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1185,6 +1185,7 @@
|
|||
9ECC9A85234DC16E009B5144 /* FeedlyAccountDelegateError.swift in Sources */,
|
||||
9EA3133B231E368100268BA0 /* FeedlyAccountDelegate.swift in Sources */,
|
||||
51E5959B228C781500FCC42B /* FeedbinStarredEntry.swift in Sources */,
|
||||
5133BB4D2460CA0B0001E3D0 /* RedditMe.swift in Sources */,
|
||||
846E77451F6EF9B900A165E2 /* Container.swift in Sources */,
|
||||
9EA643D3239305680018A28C /* FeedlySearchOperation.swift in Sources */,
|
||||
5150FFFE243823B800C1A442 /* CloudKitError.swift in Sources */,
|
||||
|
@ -1229,7 +1230,6 @@
|
|||
9E1D15512334282100F4944C /* FeedlyMirrorCollectionsAsFoldersOperation.swift in Sources */,
|
||||
9E1773D7234575AB0056A5A8 /* FeedlyTag.swift in Sources */,
|
||||
3B826DAB2385C81C00FC1ADB /* FeedWranglerConfig.swift in Sources */,
|
||||
5193CD81245F295E0092735E /* RedditUser.swift in Sources */,
|
||||
515E4EB62324FF8C0057B0E7 /* URLRequest+RSWeb.swift in Sources */,
|
||||
51B36315244BCCA4000DEF2A /* TwitterSearchResult.swift in Sources */,
|
||||
9EB1D576238E6A3900A753D7 /* FeedlyAddNewFeedOperation.swift in Sources */,
|
||||
|
|
|
@ -80,8 +80,25 @@ public final class RedditFeedProvider: FeedProvider {
|
|||
}
|
||||
|
||||
public func iconURL(_ urlComponents: URLComponents, completion: @escaping (Result<String, Error>) -> Void) {
|
||||
// TODO: call https://www.reddit.com/user/<USERNAME>/about.json to get the key "icon_img"
|
||||
completion(.failure(RedditFeedProviderError.unknown))
|
||||
guard urlComponents.path.hasPrefix("/r/"), let secondElement = extractSecondElement(path: urlComponents.path) else {
|
||||
completion(.failure(RedditFeedProviderError.unknown))
|
||||
return
|
||||
}
|
||||
|
||||
let api = "/r/\(secondElement)/about.json"
|
||||
|
||||
fetch(api: api, parameters: [:], resultType: RedditSubreddit.self) { result in
|
||||
switch result {
|
||||
case .success(let subreddit):
|
||||
if let iconURL = subreddit.data?.iconURL, !iconURL.isEmpty {
|
||||
completion(.success(iconURL))
|
||||
} else {
|
||||
completion(.failure(RedditFeedProviderError.unknown))
|
||||
}
|
||||
case .failure(let error):
|
||||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func assignName(_ urlComponents: URLComponents, completion: @escaping (Result<String, Error>) -> Void) {
|
||||
|
@ -106,7 +123,9 @@ public final class RedditFeedProvider: FeedProvider {
|
|||
completion(.failure(TwitterFeedProviderError.unknown))
|
||||
return
|
||||
}
|
||||
|
||||
let api = "\(urlComponents.path).json"
|
||||
|
||||
fetch(api: api, parameters: [:], resultType: RedditLinkListing.self) { result in
|
||||
switch result {
|
||||
case .success(let linkListing):
|
||||
|
@ -116,7 +135,6 @@ public final class RedditFeedProvider: FeedProvider {
|
|||
completion(.failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static func create(tokenSuccess: OAuthSwift.TokenSuccess, completion: @escaping (Result<RedditFeedProvider, Error>) -> Void) {
|
||||
|
@ -124,7 +142,7 @@ public final class RedditFeedProvider: FeedProvider {
|
|||
let oauthRefreshToken = tokenSuccess.credential.oauthRefreshToken
|
||||
let redditFeedProvider = RedditFeedProvider(oauthToken: oauthToken, oauthRefreshToken: oauthRefreshToken)
|
||||
|
||||
redditFeedProvider.fetch(api: "/api/v1/me", resultType: RedditUser.self) { result in
|
||||
redditFeedProvider.fetch(api: "/api/v1/me", resultType: RedditMe.self) { result in
|
||||
switch result {
|
||||
case .success(let user):
|
||||
guard let username = user.name else {
|
||||
|
@ -146,7 +164,6 @@ public final class RedditFeedProvider: FeedProvider {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: OAuth1SwiftProvider
|
||||
|
@ -264,7 +281,7 @@ private extension RedditFeedProvider {
|
|||
var urlComponents = URLComponents(string: "https://www.reddit.com")
|
||||
urlComponents?.path = "/u/\(username)"
|
||||
let userURL = urlComponents?.url?.absoluteString
|
||||
return Set([ParsedAuthor(name: "u/\(username)", url: userURL, avatarURL: userURL, emailAddress: nil)])
|
||||
return Set([ParsedAuthor(name: "u/\(username)", url: userURL, avatarURL: nil, emailAddress: nil)])
|
||||
}
|
||||
|
||||
func handleFailure(error: OAuthSwiftError, completion: @escaping (Error?) -> Void) {
|
||||
|
@ -299,10 +316,22 @@ private extension RedditFeedProvider {
|
|||
}
|
||||
}
|
||||
|
||||
func extractSecondElement(path: String) -> String? {
|
||||
let scanner = Scanner(string: path)
|
||||
if let _ = scanner.scanString("/"),
|
||||
let _ = scanner.scanUpToString("/"),
|
||||
let _ = scanner.scanString("/"),
|
||||
let secondElement = scanner.scanUpToString("/") {
|
||||
return secondElement
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
static func storeCredentials(username: String, oauthToken: String, oauthRefreshToken: String) throws {
|
||||
let tokenCredentials = Credentials(type: .oauthAccessToken, username: username, secret: oauthToken)
|
||||
try CredentialsManager.storeCredentials(tokenCredentials, server: Self.server)
|
||||
let tokenSecretCredentials = Credentials(type: .oauthRefreshToken, username: username, secret: oauthRefreshToken)
|
||||
try CredentialsManager.storeCredentials(tokenSecretCredentials, server: Self.server)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
//
|
||||
// RedditUser.swift
|
||||
// RedditMe.swift
|
||||
// Account
|
||||
//
|
||||
// Created by Maurice Parker on 5/3/20.
|
||||
// Created by Maurice Parker on 5/4/20.
|
||||
// Copyright © 2020 Ranchero Software, LLC. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct RedditUser: Codable {
|
||||
struct RedditMe: Codable {
|
||||
|
||||
let name: String?
|
||||
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case name = "name"
|
||||
}
|
|
@ -10,10 +10,32 @@ import Foundation
|
|||
|
||||
struct RedditSubreddit: Codable {
|
||||
|
||||
let kind: String?
|
||||
let data: RedditSubredditData?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case kind = "kind"
|
||||
case data = "data"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct RedditSubredditData: Codable {
|
||||
|
||||
let iconImg: String?
|
||||
let communityIcon: String?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case iconImg = "iconImg"
|
||||
case iconImg = "icon_img"
|
||||
case communityIcon = "community_icon"
|
||||
}
|
||||
|
||||
var iconURL: String? {
|
||||
if let communityIcon = communityIcon, !communityIcon.isEmpty {
|
||||
return communityIcon
|
||||
} else {
|
||||
return iconImg
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue