Skip to content

Commit

Permalink
Fix #48: Rely on tab name thanks totabRenderer/title instead of a p…
Browse files Browse the repository at this point in the history
…ath existence

This commit is necessary and not just to make the code cleaner, as http://localhost/YouTube-operational-API/channels?part=channels&id=UCNEKMkg_DG8eAyR1BNWsSvw used to have a fatal error for instance due to the absence of `🔍` tab.

Verified exhaustiveness thanks to:

```sh
grep -rw 'tabs'
```

Verified endpoints with:

- http://localhost/YouTube-operational-API/channels?part=shorts&handle=@LeFatShow
- http://localhost/YouTube-operational-API/channels?part=community&handle=@LeFatShow
- http://localhost/YouTube-operational-API/channels?part=channels&handle=@LeFatShow
- http://localhost/YouTube-operational-API/channels?part=about&handle=@LeFatShow
- http://localhost/YouTube-operational-API/channels?part=playlists&handle=@LeFatShow

Maybe this commit will make some channels not having some tabs to not return emptyness correctly.

Also verified exhaustively the absence of `'n'` in JSON paths with `n` < 10.
  • Loading branch information
Benjamin-Loison committed Feb 21, 2023
1 parent 6cd2c46 commit 6287865
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 36 deletions.
57 changes: 22 additions & 35 deletions channels.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,8 @@ function getItem($id, $continuationToken)
}
$shorts = [];
if (!$continuationTokenProvided) {
$tabs = $result['contents']['twoColumnBrowseResultsRenderer']['tabs'];
$path = 'tabRenderer/content/richGridRenderer/contents';
foreach (array_slice($tabs, 1, 2) as $tab) {
if (doesPathExist($tab, $path)) {
$reelShelfRendererItems = getValue($tab, $path);
}
}
$tab = getTabByName($result, 'Shorts');
$reelShelfRendererItems = $tab['tabRenderer']['content']['richGridRenderer']['contents'];
}
else {
$reelShelfRendererItems = $result['onResponseReceivedActions'][0]['appendContinuationItemsAction']['continuationItems'];
Expand Down Expand Up @@ -211,13 +206,8 @@ function getItem($id, $continuationToken)
$community = [];
$contents = null;
if (!$continuationTokenProvided) {
$tabs = $result['contents']['twoColumnBrowseResultsRenderer']['tabs'];
$path = 'tabRenderer/content/sectionListRenderer/contents/0/itemSectionRenderer/contents';
foreach (array_slice($tabs, 2, 4) as $tab) {
if (doesPathExist($tab, $path)) {
$contents = getValue($tab, $path);
}
}
$tab = getTabByName($result, 'Community');
$contents = $tab['tabRenderer']['content']['sectionListRenderer']['contents'][0]['itemSectionRenderer']['contents'];
} else {
$contents = $result['onResponseReceivedEndpoints'][0]['appendContinuationItemsAction']['continuationItems'];
}
Expand Down Expand Up @@ -246,7 +236,8 @@ function getItem($id, $continuationToken)

$result = getJSONFromHTML("https://www.youtube.com/channel/$id/channels", $httpOptions);

$sectionListRenderer = array_slice($result['contents']['twoColumnBrowseResultsRenderer']['tabs'], -3)[0]['tabRenderer']['content']['sectionListRenderer'];
$tab = getTabByName($result, 'Channels');
$sectionListRenderer = $tab['tabRenderer']['content']['sectionListRenderer'];
$contents = array_map(fn($content) => $content['itemSectionRenderer']['contents'][0], $sectionListRenderer['contents']);
$itemsArray = [];
foreach($contents as $content)
Expand Down Expand Up @@ -331,7 +322,8 @@ function getItem($id, $continuationToken)

$result = getJSONFromHTML("https://www.youtube.com/channel/$id/about", $httpOptions);

$resultCommon = array_slice($result['contents']['twoColumnBrowseResultsRenderer']['tabs'], -2)[0]['tabRenderer']['content']['sectionListRenderer']['contents'][0]['itemSectionRenderer']['contents'][0]['channelAboutFullMetadataRenderer'];
$tab = getTabByName($result, 'About');
$resultCommon = $tab['tabRenderer']['content']['sectionListRenderer']['contents'][0]['itemSectionRenderer']['contents'][0]['channelAboutFullMetadataRenderer'];

$stats = [];

Expand Down Expand Up @@ -396,26 +388,21 @@ function getItem($id, $continuationToken)
];
$result = getJSONFromHTML("https://www.youtube.com/channel/$id/playlists", $httpOptions);

$tabs = $result['contents']['twoColumnBrowseResultsRenderer']['tabs'];
$path = 'tabRenderer/content/sectionListRenderer';
foreach (array_slice($tabs, 1, 4) as $tab) {
if (doesPathExist($tab, $path)) {
$sectionListRenderer = getValue($tab, $path);
$contents = array_map(fn($content) => $content['itemSectionRenderer']['contents'][0], $sectionListRenderer['contents']);
$itemsArray = [];
foreach($contents as $content)
{
if (array_key_exists('shelfRenderer', $content)) {
$sectionTitle = $content['shelfRenderer']['title']['runs'][0]['text'];
$content = $content['shelfRenderer']['content'];
$content = array_key_exists('horizontalListRenderer', $content) ? $content['horizontalListRenderer'] : $content['expandedShelfContentsRenderer'];
} else {
$sectionTitle = $sectionListRenderer['subMenu']['channelSubMenuRenderer']['contentTypeSubMenuItems'][0]['title'];
$content = $content['gridRenderer'];
}
array_push($itemsArray, [$sectionTitle, $content['items']]);
}
$tab = getTabByName($result, 'Playlists');
$sectionListRenderer = $tab['tabRenderer']['content']['sectionListRenderer'];
$contents = array_map(fn($content) => $content['itemSectionRenderer']['contents'][0], $sectionListRenderer['contents']);
$itemsArray = [];
foreach($contents as $content)
{
if (array_key_exists('shelfRenderer', $content)) {
$sectionTitle = $content['shelfRenderer']['title']['runs'][0]['text'];
$content = $content['shelfRenderer']['content'];
$content = array_key_exists('horizontalListRenderer', $content) ? $content['horizontalListRenderer'] : $content['expandedShelfContentsRenderer'];
} else {
$sectionTitle = $sectionListRenderer['subMenu']['channelSubMenuRenderer']['contentTypeSubMenuItems'][0]['title'];
$content = $content['gridRenderer'];
}
array_push($itemsArray, [$sectionTitle, $content['items']]);
}
} else {
$rawData = '{"context":{"client":{"clientName":"WEB","clientVersion":"' . MUSIC_VERSION . '"}},"continuation":"' . $continuationToken . '"}';
Expand Down
4 changes: 4 additions & 0 deletions common.php
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,8 @@ function getIntFromDuration($timeStr)
return ($isNegative ? -1 : 1) * $timeInt;
}

function getTabByName($result, $tabName) {
return array_values(array_filter($result['contents']['twoColumnBrowseResultsRenderer']['tabs'], fn($tab) => $tab['tabRenderer']['title'] === $tabName))[0];
}

?>
2 changes: 1 addition & 1 deletion search.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ function getAPI($id, $order, $continuationToken)
$items = $continuationTokenProvided ? $json['onResponseReceivedActions'][0]['appendContinuationItemsAction']['continuationItems'] : $json['contents']['twoColumnBrowseResultsRenderer']['tabs'][0]['tabRenderer']['content']['richGridRenderer']['contents'];
} elseif (isset($_GET['eventType'])) {
$json = getJSONFromHTML("https://www.youtube.com/channel/{$_GET['channelId']}/videos?view=2&live_view=502");
$items = $json['contents']['twoColumnBrowseResultsRenderer']['tabs']['1']['tabRenderer']['content']['sectionListRenderer']['contents']['0']['itemSectionRenderer']['contents']['0']['gridRenderer']['items'];
$items = $json['contents']['twoColumnBrowseResultsRenderer']['tabs'][1]['tabRenderer']['content']['sectionListRenderer']['contents'][0]['itemSectionRenderer']['contents'][0]['gridRenderer']['items'];
} elseif (isset($_GET['q'])) {
$typeBase64 = $order === 'relevance' ? '' : 'EgIQAQ==';
$rawData = '{"context":{"client":{"clientName":"WEB","clientVersion":"' . MUSIC_VERSION . '"}}' . ($continuationTokenProvided ? ',"continuation":"' . $continuationToken . '"' : ',"query":"' . str_replace('"', '\"', $_GET['q']) . '"' . ($typeBase64 !== '' ? ',"params":"' . $typeBase64 . '"' : '')) . '}';
Expand Down

1 comment on commit 6287865

@Benjamin-Loison
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.