DEV Community

david duymelinck
david duymelinck

Posted on

Powershell fun: checking Netflix genre codes

I know not all genre codes are available in every country, so I wanted to make a tool that checks the url, https://www.netflix.com/browse/genre/XXXX, by title.

The first tool that came to mind was powershell. I haven't done much scripting with that shell so I thought it would be fun to learn the possibilities of the shell.

How to open a tab and read the title

I'm using Firefox so I asked an AI to open Firefox and return the title.
After a bit of finetuning I got to this code.

$uri = "https://www.netflix.com/browse/genre/2"
Start-Process "firefox.exe" -ArgumentList $uri

Start-Sleep -Seconds 5

$browser = Get-Process -Name firefox | Where-Object { $_.MainWindowTitle -ne "" } | Select-Object -First 1

if ($browser) {
    Write-Output "$browser.MainWindowTitle"
}
Enter fullscreen mode Exit fullscreen mode

The process written out in steps is;

  • Set the url.
  • Start the browser with the url.
  • Wait five seconds to load the tab.
  • Get the browser the browser process.
  • Check if the process title is not empty.
  • Return the first process to the $browser variable.
  • Check the $browser variable.
  • Write the title in the shell.

There are already a lot of things that can be made dynamic, so it is a good first step.

Close the tab

When I tested the code above I found out you need to be logged in and the profile needs to be active.

The idea is not to test a single url but multiple. And I didn't want to have a browser window with x amount of open Netflix tabs after the script ran.

Again I asked an AI to show example code, and following is what I ended up with.

Add-Type -AssemblyName System.Windows.Forms
$signature = @"
        [DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
"@
try {
    Add-Type -MemberDefinition $signature -Name "User32" -Namespace "Win32"
} catch {
    # It's already defined — do nothing
}

# unchanged code

if($browser) {
   # unchanged code
   [void][Win32.User32]::SetForegroundWindow($browser.MainWindowHandle)

   # Send Ctrl+W to close the current tab
   [System.Windows.Forms.SendKeys]::SendWait("^w")
}
Enter fullscreen mode Exit fullscreen mode

The Add-Type commands extend the Powershell functionality.
The first one the script to use the namespace.
And the second one allows the script to use a method from the user32.dll

I added a try catch statement because I got an error the namespace already existed. But after some web searching I found out that it could be caused by the Powershell session. And indeed after closing the window and opening a new one the error was gone. I left the statement just to remind me an error can occur.

When I call the SetForegroundWindow method you see [void]. People who are familiar with type conversion in other languages already have a clue.
But Powershell goes a little bit further and allows you to ignore output from an imported method. The method writes the boolean value to the output without the conversion.

Ctrl+W is the shortcut for Firefox and Chrome browsers. Sometimes browser vendors can make developers lives easy.

Adding the Netflix genre ids

At the moment you need to add the url to the code, and because there are so many and there is no logic in the ids, I searched for the most complete list I could find.

I found The latest codes in an article. And the full table can be found in the HTML. So I did copy-paste the table in a file. Found an online html table to csv converter, and I ended up with a list where the first column contained the title and the second contained the id.

I'm used to array slice methods, which made me look in that direction to run over the full list of ids or pick out a slice to run.

Because of readability I'm not going to show the whole list here, just enough the explain the code.

$genreIds = @(
    @{  "category" = "Scary Cult Movies from the 1980s" ; "id" = 2}
    @{  "category" = "Tearjerkers from the 1970s" ; "id" = 4}
    @{  "category" = "Gay & Lesbian Psychological Movies" ; "id" = 5}
    @{  "category" = "Showbiz Movies based on real life" ; "id" = 7}
    @{  "category" = "Exciting Film Noir" ; "id" = 8}
)

$defaultStartValue = "0"
$startInput = Read-Host "Enter start value for the genre list (or press Enter for default [$defaultStartValue])"
$startValue = if ([string]::IsNullOrEmpty($startInput)) { [int]$defaultStartValue } else { [int]$startInput }

$defaultEndValue = "4103"
$endInput = Read-Host "Enter end value for the genre list (or press Enter for default [$defaultEndValue])"
$endValue = if ([string]::IsNullOrEmpty($endInput)) { [int]$defaultEndValue } else { [int]$endInput }

$urls = $genreIds[$startValue..$endValue]
$urlPrefix = "https://www.netflix.com/browse/genre/"

# Add-Type code here

foreach($url in $urls) {
    $uri = "$urlPrefix" + $url["id"]
    Start-Process "firefox.exe" -ArgumentList $uri
    # rest of the code here
}
Enter fullscreen mode Exit fullscreen mode

With @() you can create an array, and with @{} you can create a hashtable (associate array/tuple).

Because I want to make the input as easy as possible for the user I set a default value for the begin and end numbers of the slice.

There are multiple languages that use the [start..end] syntax to get a slice, so I think most people will recognize that syntax.

And then it is just a question of looping the slice items and creating the url to add to the Start_Process command.

The output

With the current code the title is returned, but if the genre is not available in you country the title looks like "Netflix - Mozilla Firefox".

The main thing to identify the genre is by the id, so that should be in the output no matter what.

I also discovered some of the genre titles are translated. This is the reason I kept the titles in the code. It allows to output both the hardcoded titles and the browser titles.

Having the suffix "Netflix - Mozilla Firefox" next to the title or as title is just visual noise, I need to remove that form the output for a better user experience.

# command setup variables
$defaultBrowserSuffixValue = ""
$browserInput = Read-Host "Enter browser suffix when added to the window (or press Enter for default [$defaultBrowserSuffixValue])"
$browserSuffixValue = if ([string]::IsNullOrEmpty($browserInput)) { $defaultBrowserSuffixValue } else { $browserInput }
# genre ids code

foreach($url in $urls) {
  # unchanged code
  if($browser){
    $pattern = " ?-? ?Netflix$browserSuffixValue"
    $tabTitle = $browser.MainWindowTitle -replace $pattern, ""
    $genreId = $url["id"]
    Write-Output "$genreId, $tabTitle"
  }
}
Enter fullscreen mode Exit fullscreen mode

" - Netflix" is always added to the title, but the browser suffix changes when using another browser. So that is the only part that is relevant for the user to add to the command.

Powershell has a regex syntax that is a bit unfamiliar in programming languages, but it a common syntax to add optional argument to a script.

Conclusion

The full script adds the possibility to choose another browser, and I made Chrome the default browser.

The most notable code in the full script for me is
$browser = Get-Process -Name ([System.IO.Path]::GetFileNameWithoutExtension($browserValue)).

That is a great function to have when dealing with applications.

I liked the Powershell scripting. I probably need to change many things to be taken serious as a Powershell scripter. But for now I'm happy with the result.

It took me longer to convert the genre ids HTML table to hashtables, than writing the code. I really need to learn to dump a csv in a sqlite database instead of toying around with multiline cursors and replace all commands.

Top comments (0)