Jump to content

Using NextPVR to fill gaps in emby shows


sytone

Recommended Posts

sytone

I wanted to use NextPVR to record new shows and fill any missing episode in EMBY so I can access them anyware and use the metadata in emby and other functions rather than the native recording in npvr or kodi.

 

GIST: https://gist.github.com/sytone/637a14253dac119c41f7e2c1589dd614


<#
Set these values and uncomment. 
$embyServerUrl = "http://localhost:8096"
$embyUsername = "user"
$embyPassword = "password"
$npvrServerUrl = "http://localhost:8866"

#>

$embyClientName = "PowerShellScript"
$embyDeviceName = "PowerShellScriptEpisodeFiller"
$embyDeviceId = "1"
$embyApplicationVersion = "1.0.0";

Function Get-StringHash([String] $String,$HashName = "MD5") 
{ 
    $StringBuilder = New-Object System.Text.StringBuilder 
    [System.Security.Cryptography.HashAlgorithm]::Create($HashName).ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))|%{ 
        [Void]$StringBuilder.Append($_.ToString("x2")) 
    } 
    $StringBuilder.ToString() 
}

 
function Get-EmbyAccessToken {
    [CmdletBinding()]
    param ($Username, $Password)
    $authUrl = "{0}/Users/AuthenticateByName?format=json" -f $embyServerUrl
    $sha1Pass = Get-StringHash -String $password -HashName "SHA1"
    $md5Pass = Get-StringHash -String $password 
    $postParams = (@{Username="$username";password="$sha1Pass";passwordMd5="$md5Pass"} | ConvertTo-Json)
    $headers = @{"Authorization"="MediaBrowser Client=`"$embyClientName`", Device=`"$embyDeviceName`", DeviceId=`"$embyDeviceId`", Version=`"$embyApplicationVersion`""}

    Write-Verbose ("authUrl={0},Username={1},sha1Pass={2},md5Pass={3},params={4}" -f $authUrl, $Username,$sha1Pass,$md5Pass,$postParams)
    return (Invoke-WebRequest -Uri $authUrl -Method POST -Body $postParams -ContentType "application/json" -Headers $headers)
} 

function Get-EmbyEpisodesMissingItems {
    [CmdletBinding()]
    param ($AccessToken)

    $url = "{0}/Items?format=json&recursive=true&IncludeItemTypes=Episode&IsMissing=true" -f $embyServerUrl
    $embyHeaderWithAccessToken = @{"X-MediaBrowser-Token"=$user.AccessToken}


    Write-Verbose ("authUrl={0},Header={1}" -f $url, $embyHeaderWithAccessToken)
    return (Invoke-WebRequest -Uri $url -Method GET -ContentType "application/json" -Headers $embyHeaderWithAccessToken)

}



function Get-NpvrAccessSid {
    [CmdletBinding()]
    param ($Pin)
    $InstantiateUrl = "{0}/public/Util/NPVR/Client/Instantiate" -f $npvrServerUrl
    $InitializeUrl = "{0}/public/Util/NPVR/Client/Initialize" -f $npvrServerUrl
    $pinHash  = Get-StringHash $Pin
    $keys = Invoke-WebRequest -Uri $InstantiateUrl -Method Get
    $clientKeys = $keys.Content | ConvertFrom-Json
    $authString = ':'+ $pinHash + ':' + $clientKeys.clientKeys.salt
    $authHash = Get-StringHash $authString
    $sid = $clientKeys.clientKeys.sid
    
    $authUrl = "{0}/{1}?sid={2}" -f $InitializeUrl,$authHash,$sid
    $finalAuth = Invoke-WebRequest -Uri "$authUrl" -Method Get 
    return $sid
}

function Get-NpvrSearchResult {
    [CmdletBinding()]
    param ($Sid, $SearchTerm)
    $SearchUrl = "{0}/public/SearchService/Search" -f $npvrServerUrl
    $searchBody = @"
{
  "searchName": "$searchTerm",
  "autoShowSearch": true,
  "autoRecordSearch": false,
  "searchTitle": true,
  "searchSubTitle": true,
  "searchDescription": false,
  "matchTitle": false,
  "matchSubTitle": false,
  "matchDescription": false,
  "startTitle": false,
  "startSubTitle": false,
  "startDescription": false,
  "searchPhrase": "$searchTerm",
  "searchCaseSensitive": false,
}
"@
    $fullSearchUrl = ("{0}?sid={1}" -f $SearchUrl, $sid)
    $searchResults = Invoke-WebRequest -Uri $fullSearchUrl -Method Post -Body $searchBody -ContentType "application/json"
    return $searchResults
}

function Get-NpvrScheduleServiceDefaults {
    [CmdletBinding()]
    param ($Sid)
    $SearchUrl = "{0}/public/ScheduleService/Get/SchedSettingsObj" -f $npvrServerUrl

    $fullSearchUrl = ("{0}?sid={1}" -f $SearchUrl, $sid)
    $searchResults = Invoke-WebRequest -Uri $fullSearchUrl -Method Get -ContentType "application/json"
    return ($searchResults.Content | ConvertFrom-Json)
}

function Get-NpvrScheduleServiceRecord {
    [CmdletBinding()]
    param ($Sid, $ChannelOid, $EpgEventOid, $start, $end)
    $recordUrl = "{0}/public/ScheduleService/Record" -f $npvrServerUrl
    
    $defaultSchedule = Get-NpvrScheduleServiceDefaults -Sid $Sid
    
    $defaultSchedule.allChannels = $false
    $defaultSchedule.ChannelOID  = $ChannelOid
    $defaultSchedule.epgeventOID = $EpgEventOid
    $defaultSchedule.qualityDefault = $true
    $defaultSchedule.recordOnce = $true
    $defaultSchedule.startDate = $start
    $defaultSchedule.endDate = $end



    $fullRecordUrl = ("{0}?sid={1}" -f $recordUrl, $sid)
    $recordResults = Invoke-WebRequest -Uri $fullRecordUrl -Method POST -ContentType "application/json" -Body ($defaultSchedule | ConvertTo-Json)
    return ($recordResults.Content | ConvertFrom-Json)
}

function Get-NpvrManageServiceRecordingsSortFilterObj {
    [CmdletBinding()]
    param ($Sid)
    $SearchUrl = "{0}/public/ManageService/Get/RecordingsSortFilterObj" -f $npvrServerUrl

    $fullSearchUrl = ("{0}?sid={1}" -f $SearchUrl, $sid)
    $searchResults = Invoke-WebRequest -Uri $fullSearchUrl -Method Get -ContentType "application/json"
    return ($searchResults.Content | ConvertFrom-Json)
}

function Get-NpvrManageServiceRecordingsSummary {
    [CmdletBinding()]
    param ($Sid)
    $recordingsSummaryUrl = "{0}/public/ManageService/Get/SortedFilteredList" -f $npvrServerUrl
    
    $defaultSchedule = Get-NpvrManageServiceRecordingsSortFilterObj -Sid $Sid
    $defaultSchedule.Pending = $true
    $defaultSchedule.InProgress = $true
    

    $fullRecordingsSummaryUrl = ("{0}?sid={1}" -f $recordingsSummaryUrl, $sid)
    $recordResults = Invoke-WebRequest -Uri $fullRecordingsSummaryUrl -Method POST -ContentType "application/json" -Body ($defaultSchedule | ConvertTo-Json)
    return ($recordResults.Content | ConvertFrom-Json)
}

$accessSid = Get-NpvrAccessSid -Pin "0000"

#$schedule = Get-NpvrScheduleService -Sid $accessSid
#$schedule.Content | ConvertFrom-Json


$recordings = Get-NpvrManageServiceRecordingsSummary -Sid $accessSid
$scheduled = @()
foreach($rec in $recordings.ManageResults.EPGEvents.epgEventJSONObject.epgEvent) {
    $scheduled += "{0} - {1}" -f $rec.Title,$rec.Subtitle
}



$authResult = Get-EmbyAccessToken -Username $embyUsername -Password $embyPassword
$user = $authResult.Content | ConvertFrom-Json
$items = Get-EmbyEpisodesMissingItems -AccessToken $user.AccessToken -Verbose
$missingContent = $items.Content | ConvertFrom-Json
$missingContent.Items | % {

    $seriesName = $_.SeriesName
    $episodeName = $_.Name

    
    $searchResults = Get-NpvrSearchResult -Sid $accessSid -SearchTerm $seriesName
    $found = $searchResults.Content | ConvertFrom-Json 
    Write-Host ("Searching for: {0} - {1}" -f $seriesName,$episodeName)
    #$found.SearchResults.EPGEvents[0]
    $showsToRecord = $found.SearchResults.EPGEvents | ? {$_.epgEventJSONObject.epgEvent.Subtitle -eq $episodeName -and $_.epgEventJSONObject.epgEvent.StartTime -gt (Get-Date)}
    if($showsToRecord.Count -gt 0) {
        $showsToRecord[0] | % {
        
            $found = "{0}: {1} - {2}`n  {3} " -f $_.epgEventJSONObject.epgEvent.ChannelName,$_.epgEventJSONObject.epgEvent.Title,$_.epgEventJSONObject.epgEvent.Subtitle,$_.epgEventJSONObject.epgEvent.Desc
            Write-Host ("Missing {0} from {1}" -f $episodeName, $seriesName)
            Write-Host $found
            $scheduleMatch = "{0} - {1}" -f $_.epgEventJSONObject.epgEvent.Title,$_.epgEventJSONObject.epgEvent.Subtitle
            if($scheduled -contains $scheduleMatch) {
                Write-Host "Already Scheduled"
            } else {
                $record = Get-NpvrScheduleServiceRecord -Sid $accessSid -ChannelOid ($_.epgEventJSONObject.epgEvent.ChannelOid) -EpgEventOid ($_.epgEventJSONObject.epgEvent.OID) `
                    -start $_.epgEventJSONObject.epgEvent.StartTime -end $_.epgEventJSONObject.epgEvent.EndTime
            }
            
            
        }
    }
}









Link to comment
Share on other sites

  • 2 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...