plex-api icon indicating copy to clipboard operation
plex-api copied to clipboard

Cannot seem to access seasons in TV shows

Open delovelady opened this issue 1 year ago • 1 comments

I have the following simple code:

    $librarySections = $client->getLibrarySections();
    foreach ($librarySections['Directory'] as $directoryNumber => $directoryAttributes) {
        if ($directoryAttributes['type'] == 'show') {
            $key = $directoryAttributes['key'] ;
            $collection = $client->getLibrarySectionContents($key, true) ;
            foreach ($collection as $TVShow) {
                $title = $TVShow->title ;
                $children = $TVShow->getChildren() ;
                printf("%2d %s\n", $title, count($children)) ;
                $unusedVar = true ;
            }
        }
    }

This dies with error "Error: Call to undefined method jc21\TV\Show::getChildren()"

I also tried to access $TVShow->seasons and $TVShow->Seasons and so on... to no avail.

Ultimately, I want to list the number of seasons for each show and the number of episodes for each season. But it seems that seasons are not accessible through the show???

delovelady avatar Oct 07 '24 00:10 delovelady

#!/usr/bin/env php
<?php


//######################################################################################
// https://github.com/jc21/plex-api/blob/master/docs/Documentation.md
//######################################################################################


require_once('lovefunctions.php') ;
//require_once('jc21/plex-api/src/jc21/PlexApi.php') ;
require_once('vendor/autoload.php') ; // Found in /www/cgi-bin/GoogleRelated/

$ini = $lov->parseIniFile('plexFavorite.ini') ;

define('FAVORITES_TITLE', $ini['Favorites title']) ;
define('GENERAL_TITLE', $ini['General title']) ;
define('PLEX_DATABASE_SERVER', $ini['Database server']) ;
define('PLEX_HOST', $ini['Plex host']) ;
define('KNOWN_MOVIE_EXTENSIONS', implode('|', $ini['Known movie extensions'])) ;

$lov->setLogName(LoveFunctions::MONTHLY_LOG_WITH_HEADER) ;
use jc21\PlexApi ;
use jc21\Util\Filter ;

$debug = (array_key_exists('Debug', $ini) ? $ini['Debug'] : faLSE) ;
$errors = false ;

$pdo = $lov->pdoConnect(PLEX_DATABASE_SERVER) ;
$getCredsStmt = $lov->pdoPrepare($pdo, <<<EOS
            SELECT cred.*
            FROM   plexCredentials cred
            WHERE  cred.hostname = :hostname
               AND effective <= CURRENT_TIMESTAMP
            ORDER BY effective DESC
            LIMIT 1
            EOS
                    ) ;
$sqlVars = [ 'hostname' => PLEX_HOST ] ;
$getCredsStmt->execute( $sqlVars ) ;
$nbrRows = $getCredsStmt->rowCount() ;
if ($nbrRows == 0) {
    printf("Could not obtain PLEX credentials from database.\nSQL: %s", $lov->mergeSqlAndAssociativeData($getCredsStmt, $sqlVars)) ;
    exit(1) ;
} elseif ($nbrRows > 1) {
    printf("%d rows returned requesting PLEX credentials from database.\nSQL: %s", $nbrRows, $lov->mergeSqlAndAssociativeData($getCredsStmt, $sqlVars)) ;
    exit(1) ;
}

$creds = $getCredsStmt->fetch(PDO::FETCH_ASSOC) ;
$client = new PlexApi($creds['hostname']);
$client->setAuth($creds['userId'], $creds['password'] ) ;
if (isset($creds['token']))
    $client->setToken($creds['token']) ;
for ($i=1; $i<9; $i++) { // Try up to 9 times because there are times that $client->getLibrarySections() has failed
    $librarySections = $client->getLibrarySections();
    if (is_array($librarySections) && is_array($librarySections['Directory']) && count($librarySections['Directory'])>0) {
        break ;
    }
    if ( ! ($token = $client->getToken()))
        printf("Login was not successful.\n") ;
    elseif ($debug)
        printf("No library sections found. (%d)\n", $i) ;
}
if ( ! ($token = $client->getToken())) {
    printf("%s\n", "Unable to log in. ($client->getToken failed.)") ;
    die() ;
} elseif ($token != $creds['token']) {
    // code to insert new plexCredentials row omitted here
}
if ( (! $librarySections) || count($librarySections['Directory']) < 1) {
    printf("No library sections found.\n") ;
    exit(1) ;
}

if ($debug) {
    printf("%d library sections found.\n", count($librarySections['Directory'])) ;
    $lov->dumpArray($librarySections, 'result', '', LoveFunctions::OUTPUT_TYPE_CONSOLE) ;
}

// Here, we'll get all the "sections" (which are the key# for each Library) from the system
$allShows = [] ;
$maxTitleWidth = 0 ;
$maxRunTime = 0 ;
foreach ($librarySections['Directory'] as $directoryNumber => $directoryAttributes) {
    if ($directoryAttributes['type'] == 'show') {
        $key = $directoryAttributes['key'] ;
        $collection = $client->getLibrarySectionContents($key, true) ;
        foreach ($collection as $TVShow) {
            $title = $TVShow->title ;
            $allShows[$title] = [  'title' => $title, 'seasonCount' => 0, 'episodeCount' => 0, 'runTime' => 0 ] ;
            if (strlen($title) > $maxTitleWidth)
                $maxTitleWidth = strlen($title) ;
            $showVars = get_class_vars(get_class($TVShow)) ;
            $showMethods = get_class_methods(get_class($TVShow)) ;
            $seasons = $TVShow->getSeasons() ;
            $episodeCount = 0 ;
            foreach ($seasons AS $season) {
                $allShows[$title]['seasonCount']++ ;
                $allShows[$title][$season->index] = [ 'title' => $season->title, 'episodeCount' => 0, 'runTime' => 0 ] ;
                $seasonVars = get_class_vars(get_class($TVShow)) ;
                $seasonMethods = get_class_methods(get_class($TVShow)) ;
                $episodes = $season->getChildren() ;
                $episodesVars = get_class_vars(get_class($episodes)) ;
                $episodesMethods = get_class_methods(get_class($episodes)) ;
                $episodeCount += $episodes->count() ;
                $episodeIter = $episodes->getIterator() ;
                foreach ($episodeIter as $episode) {
                    $episodeVars = get_class_vars(get_class($episode)) ;
                    $episodeMethods = get_class_methods(get_class($episode)) ;
                    $allShows[$title]['episodeCount']++ ;
                    $allShows[$title]['runTime'] += $episode->duration->minutes() ;
                    $allShows[$title][$season->index]['episodeCount']++ ;
                    $allShows[$title][$season->index]['runTime'] += $episode->duration->minutes() ;
                    $allShows[$title][$season->index]['episodes'][$episode->index] = ['title' => $episode->title, 'runTime' => $episode->duration->minutes() ] ;
                    // For example, $episode->media->path points to the video file
                    //              $episode->title is the episode title
                    $dummy = 0 ;
                } // Episodes
            } // Seasons
            if ($allShows[$title]['runTime'] > $maxRunTime)
                $maxRunTime = $allShows[$title]['runTime'] ;
        }
    }
}

$runTimeWidth = max(7, strlen(formatRunTime($maxRunTime))) ;
uksort($allShows, 'compareTitles') ;
printf("%-*s Seasons Episodes RunTime\n", $maxTitleWidth, "--Title--") ;    
foreach ($allShows as $show => $details) {
    printf("%-*s %7d %8d %*s\n", $maxTitleWidth, $details['title'], $details['seasonCount'], $details['episodeCount'], $runTimeWidth, formatRunTime($details['runTime'])) ;
}


function compareTitles(string $a, string $b) {
    if (preg_match('%^(a|an|the)\s+(.*)$%i', $a, $matches))
        $a = $matches[2] . ', ' . $matches[1] ;
    if (preg_match('%^(a|an|the)\s+(.*)$%i', $b, $matches))
        $b = $matches[2] . ', ' . $matches[1] ;
    return strcasecmp($a, $b) ;
}


function formatRunTime(float $runTimeMinutes) : string {
    if ($runTimeMinutes >= 60)
        return (intval($runTimeMinutes/60) . ':' . twoDigits($runTimeMinutes % 60)) ;
    else
        return ':' . twodigits($runTimeMinutes) ;
}


function twodigits(int $value) : string {
    return (($value < 10 ? '9' : '') . $value) ;
}

delovelady avatar Oct 08 '24 22:10 delovelady