Jump to content
ginjaninja

Script: Remove Guest star from episode if already present on Series

Recommended Posts

ginjaninja
Posted (edited)

Background

I find it less than ideal when looking at a person's biography, to see them appear as guests stars on episodes as well as at the episode's series level

 

Goal

Remove duplicate guest stars and actors from episodes, whilst protecting legitimate duplication for non acting roles e.g Director.

Remove spurious noise from person's bio page. Easier to see where an actor has directed their main series or indeed other episodes in other series.

 

Design

Remove any guest stars on episodes which are actors on the series.

testmode (default on) to log proposed removals rather than make changes.

 

Installation

create an apikey and set your emby url and apikey in config.

Note - testmode = $false/$true in Config

may require latest powershell and relaxed powershell execution policy.

Backup your database prior to use

Use with extreme caution on live databases, best tried on a test database first

Would not use on a database with manually curated metadata [person especially] (without alot of testing)

 

Notes

tested on Windows Powershell but should be agnostic

Does not lock metadata so future library refreshes may revert changes, script could be scheduled for regular cleaning.

Does not actively respect metadata locking, may ignore, have not tested as i don't use.

I have run it on my live database but results have not undergone any long term testing.

For me, 10000 episodes with duplicates cleaned out of 40000 episodes, took about 30 minutes to run. reduced database by 50MB down to 440MB

 

Caveats

On very fast systems Powershell may open more sessions with the api than the OS network stack will support - havent found a solution to this but i was fine on my library since i rewrote script to reduce api calls. In any case the script can just be rerun and it will continue from where it finds the next duplicate.

 

issues / suggestions welcome.

 

PersonCleaner v0.0.0.1.zip

 

 

5ecd4b755eafa_Capture.jpg

Edited by ginjaninja
  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites
Oxide

Thx @ginjaninja been looking for something like this for a while 😁

I am getting this error when running the script, was hoping you could help out 😏

Method invocation failed because [Selected.System.Management.Automation.PSCustomObject] does not contain a method
named 'foreach'.
At D:\PersonCleaner v0.0.0.1\PersonCleaner.ps1:70 char:13
+             $removed.foreach{
+             ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (foreach:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

 

 

 

Share this post


Link to post
Share on other sites
ginjaninja
Posted (edited)

i think this points to not having the latest powershell installed

https://github.com/PowerShell/PowerShell/releases

(go to assets section)

are you on Windows?

edit

and you need to launch with latest version of powershell..on windows this may mean launching pwsh.exe first  and calling fron there (as opposed to double clickkng) or perhaps associating .ps1 with pwsh.exe

edit

https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows?view=powershell-7

suggests you should get a new open with pwsh when right clicking.

 

 

 

 

Edited by ginjaninja
  • Thanks 2

Share this post


Link to post
Share on other sites
Oxide

Thanks @ginjaninja installing v7.0.2 and opening with pwsh.exe did the trick 😁

Share this post


Link to post
Share on other sites
ginjaninja
Thanks @ginjaninja installing v7.0.2 and opening with pwsh.exe did the trick [emoji16]
interested to know how you find it. for me i schedule the script nightly to keep everything clean. not earth shattering but a meaningful improvement when browsing biographies.

there is a feature request for the server to include this functionality if youre interested.
https://emby.media/community/index.php?/topic/83577-server-prevent-people-assigned-to-series-being-assigned-to-episode/&tab=comments#comment-855622

Sent from my SM-G955F using Tapatalk

  • Like 1

Share this post


Link to post
Share on other sites
gillmacca01

This is something I desperately need, currently doing it manually, and with my collection will take months.

Do you know if this can be installed on a QNAP, or does it have to run on windows

Share this post


Link to post
Share on other sites
ginjaninja

alas i dont know.

https://www.adilhindistan.com/2011/06/running-powershell-from-nas-without.html

suggests powershell CAN work on qnap

There isnt much help on the internet for powershell on QNAP so its perhaps not going to be straight forward. You could always like the feature request linked in post above and hope it gets enough upvotes to come to dev teams attention to add in as standard, it is a worthwhile improvement imo.

if you can  get powershell 7 working on qnap there  is a good chance you will get the script to work (it just needs powershell 7 + http access to api). I believe QNAP is linux based and there is a linux release.

https://www.qnapclub.eu/en/qpkg/1011#

seems to suggest that someone has packaged powershell 7.03 for QNAP but i cant vouch for it.

if you do give it a go, i would be interested to hear if you can get powershell working on qnap.

 

Share this post


Link to post
Share on other sites
gillmacca01

This works great.

I have a request:

Would it be possible to create a script, that does the same, but for 'Parental Rating', 'Genres' and 'Studios'?

Edited by gillmacca01

Share this post


Link to post
Share on other sites
ginjaninja
On 10/10/2020 at 22:05, gillmacca01 said:

This works great.

I have a request:

Would it be possible to create a script, that does the same, but for 'Parental Rating', 'Genres' and 'Studios'?

glad to hear it works on qnap.

i wont get time to develop for genres and studios in near future. Are you tempted to give it a go yourself? happy to offer advice.

this is not tested , but gives an idea on how the code could be tweaked, the apis calls need to retrieve the genredata, but the required logic is going to be very similar just working on the genredata. From what i can tell the api used fields=genres to return genres, and the resultant datastructure has genres under .genreitems.

i wouldnt run on a live system without some testing but its not going to be too far off from complete. just need a windows pc and visual studio code to give it a go.

although the case for removing genres on episodes when present on series is not entirely clear to me.

 

<#
v0.0.0.1

Removes Genres from Episodes if they are present on series object

#>

$Config = (Import-PowerShellDataFile -Path "$PSScriptRoot\Config.psd1")
$EmbyURL = $Config.Emby.URL
$EmbyApiKey = $Config.Emby.ApiKey

#Wipe the Duplciate logging file
if (Test-Path $PSScriptRoot\$($Config.Files.Duplicates)) {
    Clear-Content $PSScriptRoot\$($Config.Files.Duplicates)
}

#Retrieve all series from all librarys
$ApiURL = $EmbyURL + "/emby/Users/$EmbyApiKey/Items?Fields=Genres&IncludeItemTypes=Series&Recursive=true&SortBy=Name&api_key=$EmbyApiKey"
$serieslist = Invoke-WebRequest -Uri $ApiUrl -Method get -ContentType "application/json" -SessionVariable 'Session'
$serieslist = $serieslist.content | ConvertFrom-Json


$serieslist.items.foreach{
    Write-Host "Series "$_.name
    #Read-Host "pause for each series in loop"
    $series = $_.Name
    $seriesgenres = $_.genreitems


    #Get Episodes for Series
    $ApiURL = $EmbyURL + "/emby/Items?Recursive=true&Fields=Genres&ParentId=$($_.id)&IncludeItemTypes=Episode&api_key=$EmbyApiKey"
    $episodes = Invoke-WebRequest -Uri $ApiUrl -Method get -ContentType "application/json" -WebSession $Session
    $episodes = $episodes.content | ConvertFrom-Json



    #Loop through the episodes for the series
    $episodes.items.foreach{
        
        #$episode = $_
        $precount = $_.genreitems.count
        $pre = $_.genreitems


        $_.genreitems = $_.genreitems.where{
            $_.id -notin $seriesgenres.id
        }

    
        $postcount = $_.genreitems.count
        $post = $_.genreitems

        $Removed = $pre.where{ $_.name -notin $post.name }
        $removed = $removed | Select-Object -Property Name, Id

        $pre = $_.genreitems.name -join ","
        $post = $_.genreitems.Name -join ","
        $seriesg = $seriesgenres.name -join ","
    
        #If duplicates are found
        if ($precount -ne $postcount) {
        
            Write-Host "Duplicate Found" $Series $($_.id) $($_.Name) $($_.ParentIndexNumber) $($_.IndexNumber) $precount $postcount
            #Add-Content $PSScriptRoot\$($Config.Files.Duplicates) "`n$Series Season $($_.ParentIndexNumber) Episode $($_.IndexNumber)`nSeriesPeople $seriesp `nEpisodeAsis $pre`nEpisodeTobe $post"
            Add-Content $PSScriptRoot\$($Config.Files.Duplicates) "$Series Season $($_.ParentIndexNumber) Episode $($_.IndexNumber)"
            Add-Content $PSScriptRoot\$($Config.Files.Duplicates) "SeriesGenre $seriesg"
            $removed.foreach{
                Add-Content $PSScriptRoot\$($Config.Files.Duplicates) "Remove $($_.name) $($_.id)"

            }

            #if testmode is false removed duplicates
            if (!$Config.Testmode) {
                Write-Host "Cleaning " $Series Season $($_.ParentIndexNumber) Episode $($_.IndexNumber)
                $ApiURL = $EmbyURL + "/emby/Users/$EmbyApiKey/Items/$($_.id)?api_key=$EmbyApiKey"
                $fullmetadata = Invoke-WebRequest -Uri $ApiUrl -Method get -ContentType "application/json" -WebSession $Session
                $fullmetadata = $fullmetadata.Content | ConvertFrom-Json
                $fullmetadata.genreitems = $_.genreitems
                    
                $body = $fullmetadata | ConvertTo-Json

                $ApiURL = $EmbyURL + "/emby/Items/$($_.id)?api_key=$EmbyApiKey"
                $response = Invoke-WebRequest -Uri $ApiUrl -Method Post -Body $Body -ContentType "application/json" -WebSession $Session

            }
                
        }
  
    }




}

 

 

 

 

 

 

 

 

 

 

Share this post


Link to post
Share on other sites
gillmacca01

I'll take a look when I get the chance. Thanks.

The reason for removing them from episode level is, for example, I select the genre tab, and then action, it shows the series, plus every episode in that series that has that genre 

Share this post


Link to post
Share on other sites
gillmacca01

Works perfectly.

Looking at the script, it shouldn't be that hard to change it for studios/parental rating.

 

Many thanks. You have saved me weeks and maybe months of work

Share this post


Link to post
Share on other sites

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...