Skip to content

Commit

Permalink
Made videosAndTime in HistoryResponse iterable
Browse files Browse the repository at this point in the history
  • Loading branch information
Mcrich23 authored and b5i committed Feb 15, 2024
1 parent d907049 commit 80e40ed
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ public struct HistoryResponse: AuthenticatedResponse {
///
/// Example:
/// ```swift
/// var videosAndTime = [("Today", [A few videos]), ("Yesterday", [A few videos too])]
/// var videosAndTime = [HistoryBlock(groupTitle: "Today", videosArray: [A few videos]), (groupTitle: "Yesterday", videosArray: [A few videos too])]
/// ```
public var videosAndTime: [(groupTitle: String, videosArray: [(YTVideo, suppressToken: String?)])] = []
public var videosAndTime: [HistoryBlock] = []

/// Title of the playlist.
public var title: String?
Expand All @@ -46,10 +46,10 @@ public struct HistoryResponse: AuthenticatedResponse {

for videoGroup in tabJSON["content"]["sectionListRenderer"]["contents"].arrayValue.map({$0["itemSectionRenderer"]}) {
let title = videoGroup["header"]["itemSectionHeaderRenderer"]["title"]["runs"].array?.map({$0["text"].stringValue}).joined() ?? videoGroup["header"]["itemSectionHeaderRenderer"]["title"]["simpleText"].stringValue
var toAppend: (String , [(YTVideo, String?)]) = (title, [])
var toAppend: HistoryBlock = .init(groupTitle: title, videosArray: [])
for videoJSON in videoGroup["contents"].arrayValue {
if let video = YTVideo.decodeJSON(json: videoJSON["videoRenderer"]) {
toAppend.1.append((video, videoJSON["videoRenderer"]["menu"]["menuRenderer"]["topLevelButtons"].array?.first?["buttonRenderer"]["serviceEndpoint"]["feedbackEndpoint"]["feedbackToken"].string))
toAppend.videosArray.append(.init(video: video, suppressToken: videoJSON["videoRenderer"]["menu"]["menuRenderer"]["topLevelButtons"].array?.first?["buttonRenderer"]["serviceEndpoint"]["feedbackEndpoint"]["feedbackToken"].string))
}
}
toReturn.videosAndTime.append(toAppend)
Expand All @@ -73,7 +73,7 @@ public struct HistoryResponse: AuthenticatedResponse {
public var continuationToken: String?

/// Array of videos.
public var videosAndTime: [(String, [(YTVideo, suppressToken: String?)])] = []
public var videosAndTime: [HistoryBlock] = []

public static func decodeData(data: Data) -> HistoryResponse.Continuation {
let json = JSON(data)
Expand All @@ -84,10 +84,10 @@ public struct HistoryResponse: AuthenticatedResponse {
guard let continuationItemsArray = continationAction["appendContinuationItemsAction"]["continuationItems"].array else { continue }
for videoGroup in continuationItemsArray {
let title = videoGroup["header"]["itemSectionHeaderRenderer"]["title"]["runs"].array?.map({$0["text"].stringValue}).joined() ?? videoGroup["header"]["itemSectionHeaderRenderer"]["title"]["simpleText"].stringValue
var toAppend: (String , [(YTVideo, String?)]) = (title, [])
var toAppend: HistoryBlock = .init(groupTitle: title, videosArray: [])
for videoJSON in videoGroup["contents"].arrayValue {
if let video = YTVideo.decodeJSON(json: videoJSON["videoRenderer"]) {
toAppend.1.append((video, videoJSON["videoRenderer"]["menu"]["menuRenderer"]["topLevelButtons"].array?.first?["buttonRenderer"]["serviceEndpoint"]["feedbackEndpoint"]["feedbackToken"].string))
toAppend.videosArray.append(.init(video: video, suppressToken: videoJSON["videoRenderer"]["menu"]["menuRenderer"]["topLevelButtons"].array?.first?["buttonRenderer"]["serviceEndpoint"]["feedbackEndpoint"]["feedbackToken"].string))
}
}
toReturn.videosAndTime.append(toAppend)
Expand All @@ -96,4 +96,24 @@ public struct HistoryResponse: AuthenticatedResponse {
return toReturn
}
}
/// Struct representing a block of history, containing a title and an array of YTVideos.
public struct HistoryBlock: Hashable, Identifiable {
public var id: Int { return groupTitle.hashValue }

/// Ttitle of the group, usually represent a part of the time in the history like "Today", "Yesterday" or "February 15".
public let groupTitle: String

/// An array of the videos that have been watched in the part of time indicated by the HistoryResponse/HistoryBlock/groupTitle.
public var videosArray: [VideoWithToken]
}

/// Struct representing a video and the token that should be used to suppress it from the history.
public struct VideoWithToken: Hashable, Identifiable {
public var id: Int { return video.hashValue + (suppressToken?.hashValue ?? 0) }

public let video: YTVideo

/// Token that can be used to remove the video from the history, using for example HistoryResponse/removeVideo(withSuppressToken:youtubeModel:).
public let suppressToken: String?
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public struct ChannelInfosResponse: YouTubeResponse {

toReturn.name = channelInfos["title"].string
if let handle = channelInfos["channelHandleText"]["runs"].array?.first?["text"].string, !handle.isEmpty {
toReturn.handle = channelInfos["channelHandleText"]["runs"].array?.first?["text"].string
toReturn.handle = handle
} else {
toReturn.handle = channelInfos["navigationEndpoint"]["browseEndpoint"]["canonicalBaseUrl"].string?.replacingOccurrences(of: "/", with: "") // Need to remove the first slash because the string is like "/@ChannelHandle"
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/YouTubeKitTests/YouTubeKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ final class YouTubeKitTests: XCTestCase {
XCTAssertNotNil(historyResponse.title, TEST_NAME + "Checking if historyResponse.title has been extracted.")
XCTAssertNotEqual(historyResponse.videosAndTime.count, 0, TEST_NAME + "Checking if historyResponse.videosAndTime is not empty.")

guard let firstVideoToken = historyResponse.videosAndTime.first?.1.first?.suppressToken else { XCTFail(TEST_NAME + "Could not find a video with a suppressToken in the history"); return }
guard let firstVideoToken = historyResponse.videosAndTime.first?.videosArray.first?.suppressToken else { XCTFail(TEST_NAME + "Could not find a video with a suppressToken in the history"); return }

let deleteFromHistoryError = await historyResponse.removeVideo(withSuppressToken: firstVideoToken, youtubeModel: YTM)

Expand Down

0 comments on commit 80e40ed

Please sign in to comment.