From 07af483b3670878d42540d099d18764b5b6e4980 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Fri, 17 Apr 2020 15:31:13 -0500 Subject: [PATCH] Renamed Tweet to TwitterStatus since that matches the API better. --- .../Account/Account.xcodeproj/project.pbxproj | 8 +-- .../Account/FeedProvider/Twitter/Tweet.swift | 6 +- .../Twitter/TwitterFeedProvider.swift | 42 +++++--------- .../FeedProvider/Twitter/TwitterStatus.swift | 55 +++++++++++++++++++ .../FeedProvider/Twitter/TwitterUser.swift | 4 ++ 5 files changed, 80 insertions(+), 35 deletions(-) create mode 100644 Frameworks/Account/FeedProvider/Twitter/TwitterStatus.swift diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index 450707e1c..e956f2bba 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -39,7 +39,7 @@ 5132AAC42448BAD90077840A /* FeedProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5132AAC12448BAD90077840A /* FeedProvider.swift */; }; 5132AAC52448BAD90077840A /* TwitterFeedProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5132AAC32448BAD90077840A /* TwitterFeedProvider.swift */; }; 5132DE812449159100806ADE /* TwitterUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5132DE802449159100806ADE /* TwitterUser.swift */; }; - 5132DE832449306F00806ADE /* Tweet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5132DE822449306F00806ADE /* Tweet.swift */; }; + 5132DE832449306F00806ADE /* TwitterStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5132DE822449306F00806ADE /* TwitterStatus.swift */; }; 513323082281070D00C30F19 /* AccountFeedbinSyncTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513323072281070C00C30F19 /* AccountFeedbinSyncTest.swift */; }; 5133230A2281082F00C30F19 /* subscriptions_initial.json in Resources */ = {isa = PBXBuildFile; fileRef = 513323092281082F00C30F19 /* subscriptions_initial.json */; }; 5133230C2281088A00C30F19 /* subscriptions_add.json in Resources */ = {isa = PBXBuildFile; fileRef = 5133230B2281088A00C30F19 /* subscriptions_add.json */; }; @@ -279,7 +279,7 @@ 5132AAC12448BAD90077840A /* FeedProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedProvider.swift; sourceTree = ""; }; 5132AAC32448BAD90077840A /* TwitterFeedProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwitterFeedProvider.swift; sourceTree = ""; }; 5132DE802449159100806ADE /* TwitterUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterUser.swift; sourceTree = ""; }; - 5132DE822449306F00806ADE /* Tweet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tweet.swift; sourceTree = ""; }; + 5132DE822449306F00806ADE /* TwitterStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterStatus.swift; sourceTree = ""; }; 513323072281070C00C30F19 /* AccountFeedbinSyncTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountFeedbinSyncTest.swift; sourceTree = ""; }; 513323092281082F00C30F19 /* subscriptions_initial.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = subscriptions_initial.json; sourceTree = ""; }; 5133230B2281088A00C30F19 /* subscriptions_add.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = subscriptions_add.json; sourceTree = ""; }; @@ -568,7 +568,7 @@ children = ( 5132AAC32448BAD90077840A /* TwitterFeedProvider.swift */, 5132DE802449159100806ADE /* TwitterUser.swift */, - 5132DE822449306F00806ADE /* Tweet.swift */, + 5132DE822449306F00806ADE /* TwitterStatus.swift */, ); path = Twitter; sourceTree = ""; @@ -1130,7 +1130,7 @@ 552032FD229D5D5A009559E0 /* ReaderAPITagging.swift in Sources */, 9EAEC62A23331EE70085D7C9 /* FeedlyOrigin.swift in Sources */, 9E5EC15B23E01DEF00A4E503 /* FeedlyRTLTextSanitizer.swift in Sources */, - 5132DE832449306F00806ADE /* Tweet.swift in Sources */, + 5132DE832449306F00806ADE /* TwitterStatus.swift in Sources */, 511B9804237CD4270028BCAA /* FeedIdentifier.swift in Sources */, 84F73CF1202788D90000BCEF /* ArticleFetcher.swift in Sources */, 841974251F6DDCE4006346C4 /* AccountDelegate.swift in Sources */, diff --git a/Frameworks/Account/FeedProvider/Twitter/Tweet.swift b/Frameworks/Account/FeedProvider/Twitter/Tweet.swift index 3da8930c0..f71853a4c 100644 --- a/Frameworks/Account/FeedProvider/Twitter/Tweet.swift +++ b/Frameworks/Account/FeedProvider/Twitter/Tweet.swift @@ -8,7 +8,7 @@ import Foundation -final class Tweet: Codable { +final class TwitterStatus: Codable { let createdAt: Date? let idStr: String? @@ -17,7 +17,8 @@ final class Tweet: Codable { let user: TwitterUser let truncated: Bool let retweeted: Bool - let retweetedStatus: Tweet? + let retweetedStatus: TwitterStatus? + let quotedStatus: TwitterStatus? enum CodingKeys: String, CodingKey { case createdAt = "created_at" @@ -28,6 +29,7 @@ final class Tweet: Codable { case truncated = "truncated" case retweeted = "retweeted" case retweetedStatus = "retweeted_status" + case quotedStatus = "quoted_status" } } diff --git a/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift b/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift index d10852912..0d6c33bec 100644 --- a/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift +++ b/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift @@ -214,7 +214,7 @@ private extension TwitterFeedProvider { } } - func retrieveTweets(api: String, completion: @escaping (Result<[Tweet], Error>) -> Void) { + func retrieveTweets(api: String, completion: @escaping (Result<[TwitterStatus], Error>) -> Void) { let url = "\(Self.apiBase)\(api)" let parameters = ["tweet_mode": "extended"] @@ -232,7 +232,7 @@ private extension TwitterFeedProvider { try? jsonString?.write(toFile: url.path, atomically: true, encoding: .utf8) do { - let tweets = try decoder.decode([Tweet].self, from: response.data) + let tweets = try decoder.decode([TwitterStatus].self, from: response.data) completion(.success(tweets)) } catch { completion(.failure(error)) @@ -243,29 +243,27 @@ private extension TwitterFeedProvider { } } - func makeParsedItems(_ webFeedURL: String, _ tweets: [Tweet]) -> Set { + func makeParsedItems(_ webFeedURL: String, _ statuses: [TwitterStatus]) -> Set { var parsedItems = Set() - for tweet in tweets { - guard let idStr = tweet.idStr, let userScreenName = tweet.user.screenName else { continue } - - let userURL = makeUserURL(userScreenName) + for status in statuses { + guard let idStr = status.idStr, let statusURL = status.url else { continue } let parsedItem = ParsedItem(syncServiceID: idStr, uniqueID: idStr, feedURL: webFeedURL, - url: "\(userURL)/status/\(idStr)", + url: statusURL, externalURL: nil, title: nil, language: nil, - contentHTML: makeTweetHTML(tweet), - contentText: makeTweetText(tweet), + contentHTML: status.renderAsHTML(), + contentText: status.renderAsText(), summary: nil, imageURL: nil, bannerImageURL: nil, - datePublished: tweet.createdAt, + datePublished: status.createdAt, dateModified: nil, - authors: makeParsedAuthors(tweet.user), + authors: makeParsedAuthors(status.user), tags: nil, attachments: nil) parsedItems.insert(parsedItem) @@ -278,23 +276,9 @@ private extension TwitterFeedProvider { return "https://twitter.com/\(screenName)" } - func makeParsedAuthors(_ user: TwitterUser) -> Set { - return Set([ParsedAuthor(name: user.name, url: makeUserURL(user.screenName!), avatarURL: user.avatarURL, emailAddress: nil)]) - } - - func makeTweetText(_ tweet: Tweet) -> String? { - let tweetToUse = tweet.retweetedStatus != nil ? tweet.retweetedStatus! : tweet - if let text = tweetToUse.fullText, let displayRange = tweetToUse.displayTextRange, displayRange.count > 1, - let startIndex = text.index(text.startIndex, offsetBy: displayRange[0], limitedBy: text.endIndex), - let endIndex = text.index(text.startIndex, offsetBy: displayRange[1], limitedBy: text.endIndex) { - return String(text[startIndex.. String? { - return nil + func makeParsedAuthors(_ user: TwitterUser?) -> Set? { + guard let user = user else { return nil } + return Set([ParsedAuthor(name: user.name, url: user.url, avatarURL: user.avatarURL, emailAddress: nil)]) } } diff --git a/Frameworks/Account/FeedProvider/Twitter/TwitterStatus.swift b/Frameworks/Account/FeedProvider/Twitter/TwitterStatus.swift new file mode 100644 index 000000000..31d22f06d --- /dev/null +++ b/Frameworks/Account/FeedProvider/Twitter/TwitterStatus.swift @@ -0,0 +1,55 @@ +// +// TwitterStatus.swift +// Account +// +// Created by Maurice Parker on 4/16/20. +// Copyright © 2020 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +final class TwitterStatus: Codable { + + let createdAt: Date? + let idStr: String? + let fullText: String? + let displayTextRange: [Int]? + let user: TwitterUser? + let truncated: Bool? + let retweeted: Bool? + let retweetedStatus: TwitterStatus? + let quotedStatus: TwitterStatus? + + enum CodingKeys: String, CodingKey { + case createdAt = "created_at" + case idStr = "id_str" + case fullText = "full_text" + case displayTextRange = "display_text_range" + case user = "user" + case truncated = "truncated" + case retweeted = "retweeted" + case retweetedStatus = "retweeted_status" + case quotedStatus = "quoted_status" + } + + var url: String? { + guard let userURL = user?.url, let idStr = idStr else { return nil } + return "\(userURL)/status/\(idStr)" + } + + func renderAsText() -> String? { + let statusToRender = retweetedStatus != nil ? retweetedStatus! : self + if let text = statusToRender.fullText, let displayRange = statusToRender.displayTextRange, displayRange.count > 1, + let startIndex = text.index(text.startIndex, offsetBy: displayRange[0], limitedBy: text.endIndex), + let endIndex = text.index(text.startIndex, offsetBy: displayRange[1], limitedBy: text.endIndex) { + return String(text[startIndex.. String? { + return nil + } + +} diff --git a/Frameworks/Account/FeedProvider/Twitter/TwitterUser.swift b/Frameworks/Account/FeedProvider/Twitter/TwitterUser.swift index 5b2aa24c8..6d10fac7b 100644 --- a/Frameworks/Account/FeedProvider/Twitter/TwitterUser.swift +++ b/Frameworks/Account/FeedProvider/Twitter/TwitterUser.swift @@ -20,4 +20,8 @@ struct TwitterUser: Codable { case avatarURL = "profile_image_url_https" } + var url: String { + return "https://twitter.com/\(screenName ?? "")" + } + }