Last active
April 10, 2024 15:11
-
-
Save 0187773933/5deeb471152e738112a907c308e42782 to your computer and use it in GitHub Desktop.
Exports Hulu TV Series IDs to yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( async ()=> { | |
function sleep( ms ) { return new Promise( resolve => setTimeout( resolve , ms ) ); } | |
function wait_on_element( query_selector ) { | |
return new Promise( function( resolve , reject ) { | |
try { | |
let READY_CHECK_INTERVAL = setInterval( function() { | |
let item = document.querySelectorAll( query_selector ); | |
if ( item ) { | |
if ( item[ 0 ] ) { | |
clearInterval( READY_CHECK_INTERVAL ); | |
resolve( item[0] ); | |
return; | |
} | |
} | |
} , 500 ); | |
setTimeout( function() { | |
clearInterval( READY_CHECK_INTERVAL ); | |
resolve(); | |
return; | |
} , 10000 ); | |
} | |
catch( error ) { console.log( error ); reject( error ); return; } | |
}); | |
} | |
function random_int( min , max ) { | |
min = Math.ceil( min ); | |
max = Math.floor( max ); | |
return Math.floor( Math.random() * ( max - min + 1 ) ) + min; | |
} | |
function click( element ) { | |
[ "mouseenter" , "mouseover" , "mousemove" ].forEach( event_type => { | |
const m_event = new MouseEvent( event_type , { | |
view: window , | |
bubbles: true , | |
cancelable: false , | |
clientX: element.getBoundingClientRect().left , | |
clientY: element.getBoundingClientRect().top | |
}); | |
element.dispatchEvent( m_event ); | |
}); | |
const mouse_click = new MouseEvent( "click" , { | |
view: window , | |
bubbles: true , | |
cancelable: false | |
}); | |
element.dispatchEvent( mouse_click ); | |
} | |
function get_episodes() { | |
let images = document.querySelectorAll( 'img[class^="StandardEmphasisHorizontalTileThumbnail"]' ); | |
let _ys = ""; | |
for ( let i = 0; i < images.length; ++i ) { | |
if ( images[ i ].src === "" ) { continue; } | |
let parts = images[ i ].src.split( "artwork/" ); | |
if ( parts.length < 2 ) { continue; } | |
let uuid = parts[ 1 ].split( "?" )[ 0 ]; | |
let alt = images[ i ].alt.split( "Cover art for " )[ 1 ]; | |
if ( alt === undefined ) { continue; } | |
_ys += ` - id: ${uuid}\n`; | |
_ys += ` name: "${alt}"\n`; | |
} | |
return _ys; | |
} | |
function get_seasons() { | |
let seasons_dropdown = document.querySelectorAll( 'div[data-testid="details-dropdown-container"]' ); | |
if ( seasons_dropdown.length < 1 ) { return false; } | |
seasons_dropdown = seasons_dropdown[ 0 ]; | |
let seasons_dropdown_arrow = seasons_dropdown.querySelectorAll( 'div[class*="dropdown-indicator"]' ); | |
if ( seasons_dropdown_arrow.length < 1 ) { return false; } | |
seasons_dropdown_arrow = seasons_dropdown_arrow[ 0 ]; | |
seasons_dropdown_arrow.click(); | |
let seasons = seasons_dropdown.querySelectorAll( "ul" ); | |
if ( seasons.length < 1 ) { return false; } | |
seasons = seasons[ 0 ]; | |
seasons = seasons.querySelectorAll( "li" ); | |
let first_season_number = parseInt( seasons[ 0 ].id.split( "::" )[ 1 ] ); | |
let last_season = parseInt( seasons[ seasons.length - 1 ].id.split( "::" )[ 1 ] ); | |
if ( first_season_number > last_season ) { | |
seasons = [...seasons].reverse(); | |
} | |
seasons_dropdown_arrow.click(); | |
return seasons_dropdown_arrow , seasons; | |
} | |
async function select_season( season_index ) { | |
let seasons_dropdown = document.querySelectorAll( 'div[data-testid="details-dropdown-container"]' ); | |
if ( seasons_dropdown.length < 1 ) { return false; } | |
seasons_dropdown = seasons_dropdown[ 0 ]; | |
let seasons_dropdown_arrow = seasons_dropdown.querySelectorAll( 'div[class*="dropdown-indicator"]' ); | |
if ( seasons_dropdown_arrow.length < 1 ) { return false; } | |
seasons_dropdown_arrow = seasons_dropdown_arrow[ 0 ]; | |
seasons_dropdown_arrow.click(); | |
let seasons = seasons_dropdown.querySelectorAll( "ul" ); | |
if ( seasons.length < 1 ) { return false; } | |
seasons = seasons[ 0 ]; | |
seasons = seasons.querySelectorAll( "li" ); | |
let first_season_number = parseInt( seasons[ 0 ].id.split( "::" )[ 1 ] ); | |
let last_season = parseInt( seasons[ seasons.length - 1 ].id.split( "::" )[ 1 ] ); | |
if ( first_season_number > last_season ) { | |
seasons = [...seasons].reverse(); | |
} | |
await sleep( random_int( 1000 , 1600 ) ); | |
console.log( "trying to select :" , seasons[ season_index ].innerText ); | |
console.log( seasons[ season_index ] ); | |
click( seasons[ season_index ] ); | |
} | |
function get_id() { | |
const url = window.location.href; | |
const parts = url.split( "/" ); | |
const uuid = parts[ parts.length - 1 ]; | |
return uuid | |
} | |
let id = get_id(); | |
let show_name = document.getElementById( "dialog-title" ).innerText; | |
let seasons = get_seasons(); | |
let yaml_string = ""; | |
yaml_string += ` ${id}:\n`; | |
yaml_string += ` name: "${show_name}"\n`; | |
yaml_string += ` seasons:\n`; | |
let total_seasons = seasons.length; | |
console.log( `total seasons === ${total_seasons}` ); | |
console.log( seasons ); | |
if ( total_seasons === undefined || total_seasons === 0 ) { | |
console.log( "probably only 1 season in show" ); | |
let episodes = get_episodes(); | |
if ( episodes === "" ) { console.log( yaml_string ); return } | |
yaml_string += ` - number: "one"\n`; | |
yaml_string += ` episodes:\n`; | |
yaml_string += episodes; | |
console.log( yaml_string ); | |
return; | |
} | |
for ( let i = 0; i < seasons.length; ++i ) { | |
console.log( `getting season [${(i+1)}] of ${total_seasons}` ); | |
let season = seasons[ i ]; | |
console.log( "selecting from dropdown" ); | |
select_season( i ); | |
await sleep( random_int( 2000 , 2600 ) ); | |
await wait_on_element( 'img[class^="StandardEmphasisHorizontalTileThumbnail"]' ); | |
let episodes = get_episodes(); | |
if ( episodes === "" ) { continue; } | |
yaml_string += ` - number: "${i+1}"\n`; | |
yaml_string += ` episodes:\n`; | |
yaml_string += episodes; | |
await sleep( random_int( 1200 , 1600 ) ); | |
} | |
console.log( yaml_string ); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment