// ==UserScript== // @name Horriblesubs Release Time Until // @namespace horriblesubs_release_time_until // @description Change times on horriblesubs to "until/ago", highlight shows you're watching, and highlights newly added shows, and adds links to various anime databases // @homepageURL https://github.com/namiman/horriblesubs_release_time_until // @author namiman // @version 1.2.1 // @date 2016-01-13 // @include /^https?:\/\/horriblesubs\.info\/.*/ // @grant none // @downloadURL none // ==/UserScript== console.log( "Horriblesubs Release Time Until userscript loaded" ); var user_shows_key = 'hrtu_user_shows'; var all_shows_key = 'hrtu_all_shows'; var version_key = 'hrtu_last_version'; var is_new_install = false; var current_version = '1.2.1'; var user_shows = JSON.parse( localStorage.getItem( user_shows_key ) ); if ( ! user_shows ) user_shows = {}; var all_shows = JSON.parse( localStorage.getItem( all_shows_key ) ); if ( ! all_shows ) { all_shows = {}; is_new_install = true; } var script_version = localStorage.getItem( version_key ); if ( ! script_version ) { if ( is_new_install ) script_version = current_version; else script_version = '0'; } function updateVersion() { if ( is_new_install ) { console.log( "HRTU version: "+ current_version ); } // else if ( script_version == '0' ) { // } localStorage.setItem( version_key, current_version ); } var weekdays = [ "YABOI", // horriblesubs starts the week on monday, not sunday "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ]; function parseTime( str ) { var match = str.match( /(\d+):(\d+)/ ); return { hours: match[1], minutes: match[2] }; } function timeAgo( hours, minutes, day ) { var now = new Date(); var dst_start = new Date( now.getFullYear(), 3, 8 ); var dst_end = new Date( now.getFullYear(), 11, 1 ); var offset = ( now > dst_start && now < dst_end ) ? -7 : -8 ; var pacific_time = new Date( now.getTime() + offset * 3600 * 1000 ); var time_show = new Date( pacific_time.getFullYear(), pacific_time.getMonth(), pacific_time.getDate(), 0, 0, 0 ); var day_diff = ( pacific_time.getDay() === 0 ) ? 0 : ( day - pacific_time.getDay() ); time_show.setDate( pacific_time.getDate() + day_diff ); time_show.setHours( parseInt( hours ) + parseInt( offset ) ); time_show.setMinutes( minutes ); var time_units; var time_until = Math.round( ( time_show - pacific_time ) / 1000 / 60 ); var time_direction = (time_until > 0) ? 1 : (time_until === 0) ? 0 : -1; time_until = Math.abs( time_until ); if ( time_until === 0 ) time_units = ''; else if ( time_until > 60 ) { time_until = ( time_until / 60 ).toFixed( 1 ); time_units = ( time_until > 1 ) ? 'hours' : 'hour'; } else time_units = ( time_until > 1 ) ? 'minutes' : 'minute'; var ending_phrase = (time_direction > 0) ? 'until' : (time_direction === 0) ? 'now' : 'ago'; return { 'text': ( time_direction === 0 ) ? ending_phrase : time_until + ' ' + time_units + ' ' + ending_phrase, 'time': time_until, 'direction': time_direction }; } function linkIdentifier( link ) { return link.substr( link.lastIndexOf( '/' ) + 1 ); } function sideBar() { if ( ! jQuery( ".schedule-today:not( .hrtu_sidebar )" ).length ) { console.warn( "Horriblesubs Release Time Until sideBar(): Unable to find '.schedule-today'" ); return false; } jQuery( ".schedule-today:not( .hrtu_sidebar ) .schedule-table tr" ).each(function(){ var row = jQuery(this); var title_el = row.find( ".schedule-widget-show" ); var no_link = false; if ( ! title_el.length ) { title_el = row.find( ".schedule-show" ); no_link = true; } if ( ! title_el.hasClass( "hrtu_sidebar_show_name" ) ) { title_el.addClass( "hrtu_sidebar_show_name" ); if ( no_link ) { var title = fixTitle( title_el.text() ); var link = false; title_el.text( title ); } else { var title = fixTitle( title_el.find( "a" ).text() ); var link = linkIdentifier( title_el.find( "a" ).attr( "href" ) ); title_el.find( "a" ).text( title ); } } if ( isUserShow( title, link ) ) row.addClass( "hrtu_sidebar_highlight" ); else row.removeClass( "hrtu_sidebar_highlight" ); if ( ! isAllShow( title, link ) ) row.addClass( "hrtu_sidebar_highlight_new" ); else row.removeClass( "hrtu_sidebar_highlight_new" ); var time_el = row.find( '.schedule-time' ); if ( time_el[0].hasAttribute( 'data-hrtu-time' ) ) var time_text = time_el.attr( 'title' ); else var time_text = time_el.text(); var match = parseTime( time_text ); var today = new Date(); var show = timeAgo( match.hours, match.minutes, today.getDay() ); time_el .attr( 'title', time_text ) .attr( 'data-hrtu-time', show.time ) .text( show.text ); if ( show.direction < 0 ) time_el.addClass( 'hrtu_release_page_time_passed' ); }); } function fixTitle( str ) { return str.replace( /\u2013|\u002D/g, "-" ); } function addShow( title, link ) { console.log( "addShow( "+ title +", "+ link +" )" ) if ( typeof all_shows[ title ] !== "undefined" ) { if ( link ) { all_shows[ link ] = 1; delete all_shows[ title ]; } else { all_shows[ title ] = 1; } } else { if ( link ) all_shows[ link ] = 1; else all_shows[ title ] = 1; } localStorage.setItem( all_shows_key, JSON.stringify( all_shows ) ); } function isAllShow( title, link ) { console.log( "isAllShow( "+ title +", "+ link +" )" ); if ( ( typeof all_shows[ title ] !== "undefined" ) ) { if ( link ) { all_shows[ link ] = JSON.parse( JSON.stringify( all_shows[ title ] ) ); delete all_shows[ title ]; } else { all_shows[ title ] = 1; } localStorage.setItem( all_shows_key, JSON.stringify( all_shows ) ); return true } else { return ( typeof all_shows[ link ] !== "undefined" ); } } function addUserShow( title, link ) { console.log( "addUserShow( "+ title +", "+ link +" )" ) if ( typeof user_shows[ title ] !== "undefined" ) { if ( link ) { user_shows[ link ] = 1; delete user_shows[ title ]; } else { user_shows[ title ] = 1; } } else { if ( link ) user_shows[ link ] = 1; else user_shows[ title ] = 1; } localStorage.setItem( user_shows_key, JSON.stringify( user_shows ) ); } function removeUserShow( title, link ) { console.log( "removeUserShow( "+ title +", "+ link +" )" ) delete user_shows[ title ]; delete user_shows[ link ]; localStorage.setItem( user_shows_key, JSON.stringify( user_shows ) ); } /* function isUserShow( title, link ) { console.log( "isUserShow( "+ title +", "+ link +" )" ) return ( typeof user_shows[ title ] !== "undefined" ) || ( typeof user_shows[ link ] !== "undefined" ); } */ function isUserShow( title, link ) { console.log( "isUserShow( "+ title +", "+ link +" )" ); if ( ( typeof user_shows[ title ] !== "undefined" ) ) { if ( link ) { user_shows[ link ] = JSON.parse( JSON.stringify( user_shows[ title ] ) ); delete user_shows[ title ]; } else { user_shows[ title ] = 1; } localStorage.setItem( user_shows_key, JSON.stringify( user_shows ) ); return true } else { return ( typeof user_shows[ link ] !== "undefined" ); } } function releasePage() { if ( ! jQuery( '.entry-content' ).length || ! jQuery( '.entry-content' ).children().length ) { console.warn( "Horriblesubs Release Time Until releasePage(): Unable to find release entries" ); return false; } if ( ! jQuery( '.hrtu_instructions' ).length ) jQuery( jQuery( ".entry-content ul" ).get(0) ).append( '