From e459fe92b0d81c8212be291bfde1cb3bf603b7b4 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Mon, 20 Apr 2020 12:05:57 -0500 Subject: [PATCH] Add TwitterMedia type to delete media URL's shown in tweets. --- .../Account/Account.xcodeproj/project.pbxproj | 12 ++- .../Twitter/TwitterEntities.swift | 7 +- .../Twitter/TwitterExtendedEntities.swift | 2 +- .../Twitter/TwitterExtendedMedia.swift | 100 ++++++++++++++++++ .../Twitter/TwitterFeedProvider.swift | 8 +- .../FeedProvider/Twitter/TwitterMedia.swift | 84 +-------------- 6 files changed, 122 insertions(+), 91 deletions(-) create mode 100644 Frameworks/Account/FeedProvider/Twitter/TwitterExtendedMedia.swift diff --git a/Frameworks/Account/Account.xcodeproj/project.pbxproj b/Frameworks/Account/Account.xcodeproj/project.pbxproj index 3659abf65..5f2eaa40e 100644 --- a/Frameworks/Account/Account.xcodeproj/project.pbxproj +++ b/Frameworks/Account/Account.xcodeproj/project.pbxproj @@ -33,6 +33,7 @@ 5107A09D227DE77700C7C3C5 /* TestTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5107A09C227DE77700C7C3C5 /* TestTransport.swift */; }; 510BD111232C3801002692E4 /* AccountMetadataFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510BD110232C3801002692E4 /* AccountMetadataFile.swift */; }; 510BD113232C3E9D002692E4 /* WebFeedMetadataFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510BD112232C3E9D002692E4 /* WebFeedMetadataFile.swift */; }; + 510E3317244E0CED00E7A6AF /* TwitterMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510E3316244E0CED00E7A6AF /* TwitterMedia.swift */; }; 511B9804237CD4270028BCAA /* FeedIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 511B9803237CD4270028BCAA /* FeedIdentifier.swift */; }; 512DD4CB2431000600C17B1F /* CKRecord+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 512DD4CA2431000600C17B1F /* CKRecord+Extensions.swift */; }; 512DD4CD2431098700C17B1F /* CloudKitAccountZoneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 512DD4CC2431098700C17B1F /* CloudKitAccountZoneDelegate.swift */; }; @@ -68,7 +69,7 @@ 51B3630B244B634A000DEF2A /* TwitterMention.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B3630A244B634A000DEF2A /* TwitterMention.swift */; }; 51B3630D244B6428000DEF2A /* TwitterSymbol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B3630C244B6428000DEF2A /* TwitterSymbol.swift */; }; 51B3630F244B6CB9000DEF2A /* TwitterExtendedEntities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B3630E244B6CB9000DEF2A /* TwitterExtendedEntities.swift */; }; - 51B36311244B6CFB000DEF2A /* TwitterMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B36310244B6CFA000DEF2A /* TwitterMedia.swift */; }; + 51B36311244B6CFB000DEF2A /* TwitterExtendedMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B36310244B6CFA000DEF2A /* TwitterExtendedMedia.swift */; }; 51B36313244B8B5E000DEF2A /* TwitterVideo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B36312244B8B5E000DEF2A /* TwitterVideo.swift */; }; 51B36315244BCCA4000DEF2A /* TwitterSearchResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B36314244BCCA4000DEF2A /* TwitterSearchResult.swift */; }; 51BB7B84233531BC008E8144 /* AccountBehaviors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BB7B83233531BC008E8144 /* AccountBehaviors.swift */; }; @@ -280,6 +281,7 @@ 5107A09C227DE77700C7C3C5 /* TestTransport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestTransport.swift; sourceTree = ""; }; 510BD110232C3801002692E4 /* AccountMetadataFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountMetadataFile.swift; sourceTree = ""; }; 510BD112232C3E9D002692E4 /* WebFeedMetadataFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebFeedMetadataFile.swift; sourceTree = ""; }; + 510E3316244E0CED00E7A6AF /* TwitterMedia.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterMedia.swift; sourceTree = ""; }; 511076A3243BD33100D97C8C /* .framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = .framework; sourceTree = BUILT_PRODUCTS_DIR; }; 511076F4243BD96D00D97C8C /* FeedProvider.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = FeedProvider.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 511B9803237CD4270028BCAA /* FeedIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedIdentifier.swift; sourceTree = ""; }; @@ -318,7 +320,7 @@ 51B3630A244B634A000DEF2A /* TwitterMention.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterMention.swift; sourceTree = ""; }; 51B3630C244B6428000DEF2A /* TwitterSymbol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterSymbol.swift; sourceTree = ""; }; 51B3630E244B6CB9000DEF2A /* TwitterExtendedEntities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterExtendedEntities.swift; sourceTree = ""; }; - 51B36310244B6CFA000DEF2A /* TwitterMedia.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterMedia.swift; sourceTree = ""; }; + 51B36310244B6CFA000DEF2A /* TwitterExtendedMedia.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterExtendedMedia.swift; sourceTree = ""; }; 51B36312244B8B5E000DEF2A /* TwitterVideo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterVideo.swift; sourceTree = ""; }; 51B36314244BCCA4000DEF2A /* TwitterSearchResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwitterSearchResult.swift; sourceTree = ""; }; 51BB7B83233531BC008E8144 /* AccountBehaviors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountBehaviors.swift; sourceTree = ""; }; @@ -588,7 +590,7 @@ 51B3630E244B6CB9000DEF2A /* TwitterExtendedEntities.swift */, 5132AAC32448BAD90077840A /* TwitterFeedProvider.swift */, 51B36306244B6234000DEF2A /* TwitterHashtag.swift */, - 51B36310244B6CFA000DEF2A /* TwitterMedia.swift */, + 51B36310244B6CFA000DEF2A /* TwitterExtendedMedia.swift */, 51B3630A244B634A000DEF2A /* TwitterMention.swift */, 51B36314244BCCA4000DEF2A /* TwitterSearchResult.swift */, 5132DE822449306F00806ADE /* TwitterStatus.swift */, @@ -596,6 +598,7 @@ 51B36308244B62A5000DEF2A /* TwitterURL.swift */, 5132DE802449159100806ADE /* TwitterUser.swift */, 51B36312244B8B5E000DEF2A /* TwitterVideo.swift */, + 510E3316244E0CED00E7A6AF /* TwitterMedia.swift */, ); path = Twitter; sourceTree = ""; @@ -1256,6 +1259,7 @@ 84F1F06E2243524700DA0616 /* AccountMetadata.swift in Sources */, 9EF1B10723590D61000A486A /* FeedlyGetStreamIdsOperation.swift in Sources */, 84245C851FDDD8CB0074AFBB /* FeedbinSubscription.swift in Sources */, + 510E3317244E0CED00E7A6AF /* TwitterMedia.swift in Sources */, 9EF2602C23C91FFE006D160C /* FeedlyGetUpdatedArticleIdsOperation.swift in Sources */, 3B826DAA2385C81C00FC1ADB /* FeedWranglerSubscription.swift in Sources */, 5132DE812449159100806ADE /* TwitterUser.swift in Sources */, @@ -1264,7 +1268,7 @@ 51B3630D244B6428000DEF2A /* TwitterSymbol.swift in Sources */, 769F2BA02EF5F329CDE45F5A /* NewsBlurAPICaller.swift in Sources */, 51C034DF242D65D20014DC71 /* CloudKitZoneResult.swift in Sources */, - 51B36311244B6CFB000DEF2A /* TwitterMedia.swift in Sources */, + 51B36311244B6CFB000DEF2A /* TwitterExtendedMedia.swift in Sources */, 179DB28CF49F73A945EBF5DB /* NewsBlurLoginResponse.swift in Sources */, 179DBF4DE2562D4C532F6008 /* NewsBlurFeed.swift in Sources */, 179DB02FFBC17AC9798F0EBC /* NewsBlurStory.swift in Sources */, diff --git a/Frameworks/Account/FeedProvider/Twitter/TwitterEntities.swift b/Frameworks/Account/FeedProvider/Twitter/TwitterEntities.swift index 92d53e020..15d4c39ee 100644 --- a/Frameworks/Account/FeedProvider/Twitter/TwitterEntities.swift +++ b/Frameworks/Account/FeedProvider/Twitter/TwitterEntities.swift @@ -37,12 +37,14 @@ struct TwitterEntities: Codable { let urls: [TwitterURL]? let userMentions: [TwitterMention]? let symbols: [TwitterSymbol]? - + let media: [TwitterMedia]? + enum CodingKeys: String, CodingKey { case hashtags = "hashtags" case urls = "urls" case userMentions = "user_mentions" case symbols = "symbols" + case media = "media" } func combineAndSort() -> [TwitterEntity] { @@ -59,6 +61,9 @@ struct TwitterEntities: Codable { if let symbols = symbols { entities.append(contentsOf: symbols) } + if let media = media { + entities.append(contentsOf: media) + } return entities.sorted(by: { $0.startIndex < $1.startIndex }) } diff --git a/Frameworks/Account/FeedProvider/Twitter/TwitterExtendedEntities.swift b/Frameworks/Account/FeedProvider/Twitter/TwitterExtendedEntities.swift index 1dedd3052..e449e66ca 100644 --- a/Frameworks/Account/FeedProvider/Twitter/TwitterExtendedEntities.swift +++ b/Frameworks/Account/FeedProvider/Twitter/TwitterExtendedEntities.swift @@ -10,7 +10,7 @@ import Foundation struct TwitterExtendedEntities: Codable { - let medias: [TwitterMedia]? + let medias: [TwitterExtendedMedia]? enum CodingKeys: String, CodingKey { case medias = "media" diff --git a/Frameworks/Account/FeedProvider/Twitter/TwitterExtendedMedia.swift b/Frameworks/Account/FeedProvider/Twitter/TwitterExtendedMedia.swift new file mode 100644 index 000000000..442f4043c --- /dev/null +++ b/Frameworks/Account/FeedProvider/Twitter/TwitterExtendedMedia.swift @@ -0,0 +1,100 @@ +// +// TwitterExtendedMedia.swift +// Account +// +// Created by Maurice Parker on 4/18/20. +// Copyright © 2020 Ranchero Software, LLC. All rights reserved. +// + +import Foundation + +struct TwitterExtendedMedia: Codable { + + let idStr: String? + let indices: [Int]? + let mediaURL: String? + let httpsMediaURL: String? + let url: String? + let displayURL: String? + let type: String? + let video: TwitterVideo? + + enum CodingKeys: String, CodingKey { + case idStr = "idStr" + case indices = "indices" + case mediaURL = "media_url" + case httpsMediaURL = "media_url_https" + case url = "url" + case displayURL = "display_url" + case type = "type" + case video = "video_info" + } + + func renderAsHTML() -> String { + var html = String() + + switch type { + case "photo": + if let url = url { + html += "" + html += renderPhotoAsHTML() + html += "" + } else { + html += renderPhotoAsHTML() + } + case "video", "animated_gif": + html += renderVideoAsHTML() + default: + break + } + + return html + } + +} + +private extension TwitterExtendedMedia { + + func renderPhotoAsHTML() -> String { + if let httpsMediaURL = httpsMediaURL { + return "
" + } + if let mediaURL = mediaURL { + return "
" + } + return "" + } + + func renderVideoAsHTML() -> String { + guard let bestVariantURL = findBestVariant()?.url else { return "" } + + var html = "" + return html + } + + func findBestVariant() -> TwitterVideo.Variant? { + var best: TwitterVideo.Variant? = nil + if let variants = video?.variants { + for variant in variants { + if let currentBest = best { + if variant.bitrate ?? 0 > currentBest.bitrate ?? 0 { + best = variant + } + } else { + best = variant + } + } + } + return best + } + +// +} diff --git a/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift b/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift index 10892371f..4bcfac8fe 100644 --- a/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift +++ b/Frameworks/Account/FeedProvider/Twitter/TwitterFeedProvider.swift @@ -254,10 +254,10 @@ private extension TwitterFeedProvider { dateFormatter.dateFormat = Self.dateFormat decoder.dateDecodingStrategy = .formatted(dateFormatter) - let jsonString = String(data: response.data, encoding: .utf8) - let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("twitter.json") - print("******** writing to: \(url.path)") - try? jsonString?.write(toFile: url.path, atomically: true, encoding: .utf8) +// let jsonString = String(data: response.data, encoding: .utf8) +// let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("twitter.json") +// print("******** writing to: \(url.path)") +// try? jsonString?.write(toFile: url.path, atomically: true, encoding: .utf8) do { let tweets: [TwitterStatus] diff --git a/Frameworks/Account/FeedProvider/Twitter/TwitterMedia.swift b/Frameworks/Account/FeedProvider/Twitter/TwitterMedia.swift index 2b825a069..57f279a19 100644 --- a/Frameworks/Account/FeedProvider/Twitter/TwitterMedia.swift +++ b/Frameworks/Account/FeedProvider/Twitter/TwitterMedia.swift @@ -2,99 +2,21 @@ // TwitterMedia.swift // Account // -// Created by Maurice Parker on 4/18/20. +// Created by Maurice Parker on 4/20/20. // Copyright © 2020 Ranchero Software, LLC. All rights reserved. // import Foundation -struct TwitterMedia: Codable { +struct TwitterMedia: Codable, TwitterEntity { - let idStr: String? let indices: [Int]? - let mediaURL: String? - let httpsMediaURL: String? - let url: String? - let displayURL: String? - let type: String? - let video: TwitterVideo? enum CodingKeys: String, CodingKey { - case idStr = "idStr" case indices = "indices" - case mediaURL = "media_url" - case httpsMediaURL = "media_url_https" - case url = "url" - case displayURL = "display_url" - case type = "type" - case video = "video_info" } func renderAsHTML() -> String { - var html = String() - - switch type { - case "photo": - if let url = url { - html += "" - html += renderPhotoAsHTML() - html += "" - } else { - html += renderPhotoAsHTML() - } - case "video", "animated_gif": - html += renderVideoAsHTML() - default: - break - } - - return html + return String() } - -} - -private extension TwitterMedia { - - func renderPhotoAsHTML() -> String { - if let httpsMediaURL = httpsMediaURL { - return "
" - } - if let mediaURL = mediaURL { - return "
" - } - return "" - } - - func renderVideoAsHTML() -> String { - guard let bestVariantURL = findBestVariant()?.url else { return "" } - - var html = "" - return html - } - - func findBestVariant() -> TwitterVideo.Variant? { - var best: TwitterVideo.Variant? = nil - if let variants = video?.variants { - for variant in variants { - if let currentBest = best { - if variant.bitrate ?? 0 > currentBest.bitrate ?? 0 { - best = variant - } - } else { - best = variant - } - } - } - return best - } - -// }