From 561e9a657ca24810d0591a70522f40e1e01af132 Mon Sep 17 00:00:00 2001 From: usu-access <54073918+usu-access@users.noreply.github.com> Date: Fri, 3 Dec 2021 14:48:39 -0700 Subject: [PATCH 1/3] Adding info about 500 video limit per channel Adding information about the issue and workaround from https://github.com/terrill/YTCA/issues/4 --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7045457..90ceee0 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,10 @@ As of January 2020, quota costs associated with running this application are: * 3 units for each channel ID lookup from a user name A typical daily quota is 10,000 units per day for free (higher quotas can be requested for a fee). -With 10,000 units, you could run this application to collect data from 25 channels and 1,500 total videos within those channels. +With 10,000 units, you could run this application to collect data from 25 channels and 1,500 total videos within those channels. + +### Quotas for Large Channels +YouTube limits the number of videos you can query for a specific channelID to a maximum of 500 videos (see [channelID Search Parameter Documentation][]). You can get around this limitation in YTCA by setting the "Published after" and "Published before" parameters to dates that include 500 videos or less. [YouTube Data API Reference]: https://developers.google.com/youtube/v3/docs/ @@ -170,3 +173,4 @@ With 10,000 units, you could run this application to collect data from 25 channe [W3Schools URL Encoding Reference]: https://www.w3schools.com/tags/ref_urlencode.asp [channels.ini]: channels.ini [ytca.php]: ytca.php +[channelID Search Parameter Documentation]: https://developers.google.com/youtube/v3/docs/search/list#channelId From 6296936f5efc0d122d9418008f36920e172788b1 Mon Sep 17 00:00:00 2001 From: usu-access <54073918+usu-access@users.noreply.github.com> Date: Mon, 9 Jan 2023 11:15:35 -0700 Subject: [PATCH 2/3] Update ytca.php Updated code so that the query only searches for the dates within the specific dates instead of filtering the all queries after the query is made resulting in fewer queries and better accuracy for channels with over 500 videos. --- ytca.php | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ytca.php b/ytca.php index e079e20..86e7c93 100644 --- a/ytca.php +++ b/ytca.php @@ -1360,6 +1360,19 @@ function buildYouTubeQuery($which, $id=NULL, $userName=NULL, $apiKey, $sortBy=NU $request = 'https://www.googleapis.com/youtube/v3/search?'; $request .= 'key='.$apiKey; $request .= '&channelId='.$id; + // check if date-start is set + if (isset($_GET['date-start'])) { + if (isValid('date',$_GET['date-start'])) { + $request .= '&publishedAfter='.formatDateForYoutube($_GET['date-start']); + } + } + + // check if date-start is set + if (isset($_GET['date-end'])) { + if (isValid('date',$_GET['date-end'])) { + $request .= '&publishedBefore='.formatDateForYoutube($_GET['date-end']); + } + } $request .= '&part=id,snippet'; if ($sortBy) { $request .= '&order='.$sortBy; @@ -1553,7 +1566,7 @@ function applyFilter($videos,$filter) { $v = $videos; } if ($filter['dateStart'] || $filter['dateEnd']) { - $v = filterByDate($v,$filter); + // $v = filterByDate($v,$filter); } return $v; } @@ -1876,4 +1889,9 @@ function getLastKey($channels) { return $key; } -?> \ No newline at end of file +function formatDateForYoutube($date) { + // YYY-MM-DD -> YYYY-MM-DDT00:00:00Z + + return trim($date)."T00:00:00Z"; + +?> From d034d6f9627c9e0092c9eeeb16a923bae81cfda8 Mon Sep 17 00:00:00 2001 From: usu-access <54073918+usu-access@users.noreply.github.com> Date: Mon, 9 Jan 2023 11:37:00 -0700 Subject: [PATCH 3/3] Update ytca.php When we upgraded a server running this code to PHP 8 we were experiencing errors that were fixed by replacing sizeof with count. --- ytca.php | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/ytca.php b/ytca.php index 86e7c93..d130788 100644 --- a/ytca.php +++ b/ytca.php @@ -189,7 +189,7 @@ if (is_array($channels)) { - $numChannels = sizeof($channels); + $numChannels = count($channels); if ($numChannels > 0) { @@ -278,7 +278,7 @@ $channelCost += $channelQueryArray['cost']; $channelRequests++; // create an array of metadata for this channel (if any exists) - $numKeys = sizeof($channels[$k]); + $numKeys = count($channels[$k]); if ($numKeys > 2) { // there is supplemental meta data in the array $keys = array_keys($channels[$k]); @@ -327,7 +327,7 @@ } // $numVideos is the *actual* number of videos returned // Note that it includes 2 additional keys ('requests' and 'costs') that must be removed from the total - $numVideos = sizeof($videos) - 2; + $numVideos = count($videos) - 2; // add values to channel totals if ($settings['debug'] > 0) { $channelData['all']['approxCount'] = $approxNumVideos; @@ -507,7 +507,7 @@ function showSummaryTableTop($settings,$numChannels,$firstChannelName,$channelMe } if ($channelMeta) { $metaKeys = array_keys($channelMeta[0]); // get keys from first channel in array - $numMeta = sizeof($metaKeys); + $numMeta = count($metaKeys); // there is supplemental meta data // display a column header for each metaData key $i = 0; @@ -541,7 +541,7 @@ function showSummaryTableTop($settings,$numChannels,$firstChannelName,$channelMe $highTrafficHeaders[] = '% Captioned High Traffic'; $highTrafficHeaders[] = '# '.ucfirst($settings['timeUnit']).' High Traffic'; $highTrafficHeaders[] = '# '.ucfirst($settings['timeUnit']).' Captioned High Traffic'; - $numHighTrafficHeaders = sizeof($highTrafficHeaders); + $numHighTrafficHeaders = count($highTrafficHeaders); $i=0; while ($i < $numHighTrafficHeaders) { echo ''.$highTrafficHeaders[$i]; @@ -605,7 +605,7 @@ function showSummaryTableRow($settings,$rowNum,$numChannels,$channel=NULL,$nextC // $rowNum is either an integer, or 'totals' // $channel, $metaData, and $channelData are all arrays - $numMeta = sizeof($metaData); + $numMeta = count($metaData); // calculate percentages and averages $pctCaptioned = round($channelData['cc']['count']/$channelData['all']['count'] * 100,1); @@ -657,10 +657,10 @@ function showSummaryTableRow($settings,$rowNum,$numChannels,$channel=NULL,$nextC $classes[] = 'meta_'.$value; } } - if (is_array($classes) && sizeof($classes) > 0) { + if (is_array($classes) && count($classes) > 0) { echo ' class="'; $i=0; - while ($i < sizeof($classes)) { + while ($i < count($classes)) { if ($i > 0) { echo ' '; } @@ -870,7 +870,7 @@ function showSummaryTableBottom($output,$footnotes=NULL) { echo "\n"; if ($footnotes) { - $numFootnotes = sizeof($footnotes); + $numFootnotes = count($footnotes); if ($numFootnotes > 0) { $i = 1; while ($i <= $numFootnotes) { @@ -912,9 +912,9 @@ function showDetails($settings,$rowNum,$numChannels,$channel,$channelMeta,$chann // $channelMeta is an array of metadata fields and their values for this channel // $channelData is an array of statistical summary data for this channel // $videos is an array of *filtered* videos (if filters are used, this is a subset of $channel['videos']) - - $numMeta = sizeof($channelMeta); - + if (is_countable($channelMeta)){ + $numMeta = count($channelMeta); + } // calculate percentages $pctCaptioned = round($channelData['cc']['count']/$channelData['all']['count'] * 100,1); @@ -951,7 +951,7 @@ function showDetails($settings,$rowNum,$numChannels,$channel,$channelMeta,$chann if ($filter) { // if videos are filtered, show count for both filtered and unfiltered echo '
  • Number of videos (unfiltered): '; - echo ''.number_format(sizeof($channel['videos'])-2).'
  • '."\n"; + echo ''.number_format(count($channel['videos'])-2).''."\n"; // and filtered echo '
  • Number of videos (filtered): '; @@ -1305,9 +1305,9 @@ function getChannelMeta($channels) { // first, retrieve all metadata keys $i=0; - while ($i < sizeof($channels)) { + while ($i < count($channels)) { $keys = array_keys($channels[$i]); - $numKeys = sizeof($keys); + $numKeys = count($keys); if ($numKeys > 2) { // this channel has meta keys $j=0; @@ -1326,10 +1326,12 @@ function getChannelMeta($channels) { } // second, if metadata keys were found, // build an array of each channel's data for each key - $numMeta = sizeof($metaKeys); + if (is_countable($metaKeys)){ + $numMeta = count($metaKeys); + } if ($numMeta > 0) { $i=0; - while ($i < sizeof($channels)) { + while ($i < count($channels)) { $j=0; while ($j < $numMeta) { $key = $metaKeys[$j]; @@ -1524,7 +1526,7 @@ function applyFilter($videos,$filter) { // $filter is an array with 'type' and 'value' // All filters are based on views // First, must sort $videos array by views DESC - $numVideos = sizeof($videos); + $numVideos = count($videos); if ($filter['type'] == 'views') { // include only videos with X views @@ -1573,7 +1575,7 @@ function applyFilter($videos,$filter) { function filterBydate($videos,$filter) { - $numVideos = sizeof($videos); + $numVideos = count($videos); if ($numVideos > 0) { $i = 0; while ($i <= $numVideos) { @@ -1893,5 +1895,5 @@ function formatDateForYoutube($date) { // YYY-MM-DD -> YYYY-MM-DDT00:00:00Z return trim($date)."T00:00:00Z"; - +} ?>