// ==UserScript==
// @name drnu
// @namespace marlar
// @description Dette script gør det muligt at optage programmer fra DR TV og Bonanza så de kan ses offline
// @version 2.0
// @include http://www.dr.dk/TV/se/*
// @include http://www.dr.dk/tv/se/*
// @include http://www.dr.dk/bonanza/*/serie/*
// @include http://www.dr.dk/bonanza/serie/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);
if(document.location.href.match(/http:\/\/drnu\.tumblr\.com/)) {
alert("Du skal ikke klikke på linket. Træk det op på bogmærkelinjen i din browser.");
exit;
}
if(document.location.href.match(/www.dr.dk\/tv\/?$/i)) {
alert("Vælg en udsendelse og klik derefter igen på bogmærket");
exit;
}
if(document.location.href.match(/www.dr.dk\/bonanza\/.*kategori\//i)) {
alert("Vælg først en underkategori");
exit;
}
var showType = document.location.href.match(/www.dr.dk\/(tv\/se|bonanza)/i);
if(!showType) {
if(confirm("Scriptet virker kun på DR TV eller Bonanza.\nØnsker du at gå dertil?\n\nNB: du skal klikke på bogmærket igen når du kommer derhen :-)")) {
document.location="http://www.dr.dk/tv";
}
exit;
}
showType = showType[1];
$("body").prepend($("<style>\
.bodymargin {margin-left:237px !important}\
.showcb { vertical-align: text-bottom; visibility: hidden}\
#showList p { font-size:13px; margin-left:10px; padding:5px 10px; text-indent:-18px; color: white}\
#showList select { width: 96px; margin-bottom:5px; }\
#showList a { color:yellow }\
#makelist a, #showList .bigbutton a { font-size: 13px; color:lightblue; font-weight: bold; cursor: pointer; display: block; width:192px; padding:5px; border: 1px solid}\
#makelist, #showList .bigbutton, #showWait { margin: 10px 0; font-size: 13px; }\
#makelist { margin-top: 27px }\
#showoptions, .bigbutton, #showWait { display: none }\
#showWait { color: yellow }\
#showintro { padding: 2px }\
#resultlist { position: fixed; margin: 10%; z-index:99999 }\
#resultlist textarea { border:6px solid silver; padding-top:20px; white-space: nowrap; overflow: auto; width: 100%; height: 100%}\
#showclose { right: 0; position:absolute; z-index: 100000; cursor: pointer; margin: -4px 4px 0 0; font-weight:bold; font-size:13px; color:lightblue !important}\
#resultlist a { right: 0; position:absolute; z-index: 100000; cursor: pointer; margin: 6px 7px 0 0; font-weight:bold; font-size:13px; color:red}\
#autoscan { margin: 5px 0 10px 0}\
.bold { font-weight: bold }\
.justifywidth { width: 112px; float:left}\
</style>"));
$("<img id='dllogo' title='Klik for at åbne programscanneren' src='http://i42.tinypic.com/2iqgymr.png' style='display:none;top:0;position:fixed;left:0;z-index:99999;margin:4px;cursor:pointer'>").prependTo("body").click(function(){
$("body").toggleClass("bodymargin");
$("#showList").show();
$("#dllogo").hide();
});
var showdata = new Array();
$("body").addClass("bodymargin");
$progDiv = $("<div id='showList'><a id='showclose' title='Luk'>[X]</a>\
<div id='makelist' title='Scan programmer som kan optages'><a>Start programscanning</a></div>\
<div class='bold autoscan' title='Scan automatisk når du skifter program\nBemærk: kan gøre programskift trægt!'><input type='checkbox' id='autoscan'> Scan automatisk</div>\
<div id='showoptions'>\
<div title='Vælg hvilken kvalitet du foretrækker.'><div class='justifywidth'>Kvalitet </div><select id='showQual'><option value='0'>Bedst</option><option value='1'>God</option><option value='2'>Mindre god</option><option value='3'>Dårligst</option></select></div>\
<div title='Vælg det maksimale antal programmer som skal scannes for hver serie. Jo større tal, jo langsommere kan browseren føles.'><div class='justifywidth'>Max programmer </div><select id='maxprogs'><option selected>5</option><option>10</option><option>15</option><option>alle</option></select></div>\
<div id='runbg' title='Kør optagkommandoerne i baggrunden (optag flere på en gang).'><br><input type='checkbox' id='bgmode'> Kør i baggrunden</div>\
<div title='Quiet mode - vis ikke output undervejs'><input type='checkbox' id='quietmode'> Skjul output fra kommandoen</div>\
</div>\
<div class='bigbutton' id='browserdownload' title='Download film direkte i browseren'><a>Hent via browser</a></div>\
<div class='bigbutton' id='makecmdline' title='Generér kommandolinjer til at copy-paste ind i terminalen'><a>Generér kommandolinje</a></div>\
<div class='bigbutton' id='showlinks' title='Vis downloadlinks'><a>Vis links</a></div>\
<h2 id='showWait'>Henter<br>programoversigt...</h2>\
<div id='showintro'>Dette script genererer kommandolinjer til at optage udsendelser fra DR TV med programmet \
<b>wget</b> som er standard i Linux, men fås også <a href='http://gnuwin32.sourceforge.net/packages/wget.htm'>til Windows</a>, eller direkte fra browseren. Sidstnævnte er det letteste, men wget giver flere muligheder.<br><br>\
1) Klik på linket herover for at scanne programmer der kan optages.<br><br>2) Når oversigten er dannet, kan du vælge den kvalitet som ønskes optages. Hvis en ønsket kvalitet ikke er til rådighed, vælges automatisk en anden.<br><br>\
Du kan også vælge om output fra optageprogrammet skal undertrykkes (quiet) og om der skal optages i baggrunden (dvs. flere udsendelser på en gang).<br><br>\
3) Vælg tilsidst de programmer der skal optages og tryk på 'Generér kommandolinje' eller 'Hent via browser'<br><br>\
4) Klik dig evt. frem til andre programmer på DR NU og klik på 'Scan igen'<br><br>\
<b>5) Respektér DRs ophavsret: Materialet må ikke gengives uden tilladelse jævnfør lov om ophavsret.</b></div>\
</div>")
.prependTo("body")
.css({
padding: "5px 0 0 5px",
border: "4px solid lightblue",
position: "fixed",
top:0, left:0,
zIndex:10000,
backgroundColor:"#666666",
fontSize: "13px",
color:"white",
width:"225px",
height:"100%",
overflow:"auto"
});
$("#showclose").click(function(){
$("body").toggleClass("bodymargin");
$("#showList").hide();
$("#dllogo").show();
})
if(document.cookie.match(/autoscan=1/)) {
$("#autoscan").attr("checked","checked");
scanprogs();
}
$("#autoscan").click(function(){
var cookieval=0;
var cookiename = this.id;
if($(this).is(":checked")) {
cookieval=1;
scanprogs();
}
var date = new Date();
date.setDate(date.getDate() + 365)
document.cookie = cookiename + "=" + cookieval + "; expires=" + date + "; path=/"
})
if(navigator.appVersion.indexOf("Win")!=-1) $("#runbg").hide();
$("<div id='resultlist' style='display:none'><a onclick='document.getElementById(\"resultlist\").style.display=\"none\"'>[X]</a><textarea wrap='off'></textarea></div>").prependTo("body");
$("#resultlist").keyup(function(e) {
if (e.keyCode == 27) { $(this).hide() } // esc
});
function getDRNUShows() {
$.ajaxSetup( { "async": false } );
$("#showList p").remove();
if(showType.toLowerCase() == "bonanza") {
getBonanza();
}
else {
getByProgramCard();
getBySeriesUrl();
}
if( $("#showList p").length==1 ) $("#showList p input:checkbox").attr("checked","1");
$.ajaxSetup( { "async": true } );
var ea = 0; $("#maxprogs").parent().click(function(){ ea++; if(ea % 5 == 0) $(".showcb").prop("checked",1); })
}
function getBonanza() {
var maxprogs = $("#maxprogs").val();
if(maxprogs=="alle") maxprogs=999;
$(".listItem[onclick]").slice(0, maxprogs).each(function() {
var onclick = $(this).attr("onclick").match(/{.*}/);
if (onclick) {
var json = $.parseJSON(onclick[0]);
var showDate = json.FirstPublished.split("T")[0];
var html = "<p id='prog" + json.AssetId + "'><input class='showcb' type='checkbox'> <b>" + json.Title + " (" + showDate + ")</b><br>" + json.Description + "</p>";
$progDiv.append(html);
var medialinks = new Array();
var qual = 0;
for (var i = 0; i < json.Files.length; i++) {
var f = json.Files[i];
if (f.Type.match(/Video|Audio/)) {
var l = f.Location.match(/.*(bonanza.*)/)
if (l) {
switch (f.Type) {
case "VideoHigh": qual = 3; break;
case "VideoMid": qual = 2; break;
case "VideoLow": qual = 1; break;
case "Audio": qual = 0; break;
}
if(f.Location.match(/mp3$/i))
medialinks.push(qual + "::" + l[0]);
else
medialinks.push(qual + "::" + "http://vodfiles.dr.dk/" + l[1]);
}
}
}
medialinks.sort(function(a,b){
return b.split(/::/)[0]-a.split(/::/)[0];
});
showdata["prog"+json.AssetId] = [medialinks, json.Title + "-" + showDate];
}
})
}
function getByProgramCard() {
var resourceUrl = $("script:contains('videoData')").text().match('resource: "(http://www.dr.dk/mu/programcard/expanded/[^"]*)"')[1];
$.getJSON(resourceUrl, function(data) {
var showId = "";
//var showDate = data.publish.split("T")[0];
var showDate = data.Data[0].PrimaryAssetStartPublish.split("T")[0];
var html = "<p id='prog" + showId + "'><input class='showcb' type='checkbox'> <b>" + data.Data[0].Title + " (" + showDate + ")</b><br>" + data.Data[0].Description + "</p>";
$progDiv.append(html);
var medialinks = new Array();
var asset="";
for(var a in data.Data[0].Assets) {
asset=data.Data[0].Assets[a]
if(asset.Kind=="VideoResource") {
break;
}
}
if(!asset) return;
$.each(asset.Links, function(resource, link) {
bitrate = link.Bitrate;
medialinks.push(bitrate + "::" + link.Uri);
return true;
});
medialinks.sort(function(a,b){
return b.split(/::/)[0]-a.split(/::/)[0];
});
showdata["prog"+showId]= [medialinks, data.Data[0].Title + "-" + showDate];
});
}
function getBySeriesUrl() {
var serie = document.location.href.match(/http:\/\/www.dr.dk\/TV\/se\/([^\/]+)(\/([^\/]+))?\/?(#!.+)?$/i);
if(!serie) return;
var serieUrl = "http://www.dr.dk/nu/api/programseries/" + serie[1] + "/videos";
var maxprogs = $("#maxprogs").val();
if(maxprogs=="alle") maxprogs=999;
$.getJSON(serieUrl, function(data) {
var moreProgs = "<p style='font-weight:bold;color:#ADD8E6'>Flere programmer i serien</p>";
if(data.length) $.each(data, function(showId, show) {
// Method 1
if(showId < maxprogs) {
$.getJSON(show.videoResourceUrl, function(resData) {
var html = moreProgs + "<p id='prog" + showId + "'><input class='showcb' type='checkbox'> <b>" + show.title + " (" + show.formattedBroadcastTime + ")</b><br>" + show.description + "</p>";
moreProgs = "";
$progDiv.append(html);
var medialinks = new Array();
$.each(resData.links, function(resource, link) {
bitrate = link.bitrateKbps;
medialinks.push(bitrate + "::" + link.uri);
return true;
});
medialinks.sort(function(a,b){
return b.split(/::/)[0]-a.split(/::/)[0];
});
showdata["prog"+showId]= [medialinks, show.title + "-" + show.formattedBroadcastTime];
});
}
})
});
}
$('#makelist').click(function(){
scanprogs();
});
$('#makecmdline, #browserdownload, #showlinks').click(function(){
if($("#showList input.showcb:checked").length==0) {
alert("Du skal vælge et eller flere programmer på listen");
return;
}
fixFlash();
var buttonId = this.id;
var width = $("body").width()-$("#showList").width();
var height = $(window).height()*0.7;
var bgmode = $("#bgmode").is(":checked") ? "b" : "";
var quietmode = $("#quietmode").is(":checked") ? "q" : "";
var dash = bgmode+quietmode!="" ? " -" : "";
var cmdline = "";
$("#showList input.showcb:checked").parent().each(function(){
var show = showdata[this.id][0];
var qual = document.getElementById("showQual").selectedIndex;
if(qual>show.length-1) qual = show.length-1;
var rtmpUrl = show[qual].split(/::/)[1];
var mp4Url = "";
if(rtmpUrl.match(/bonanza/i))
mp4Url = rtmpUrl;
else
mp4Url = rtmpUrl.replace(/(rtmp|rtsp|http).*[:\/]CMS\//, "http://vodfiles.dr.dk/CMS/").match(/.*?mp4/)[0];
var match = mp4Url.match(/([^\/\?]*\.(mp4|flv|mp3))/);
var filnavn = match[1];
var filename = showdata[this.id][1].replace(/[-, :\?\/"']+/g,"-").replace(/\./g,"").replace(/-*_/,"_") + "." + match[2];
filename = filename.replace("--","-");
switch(buttonId) {
case "showlinks":
cmdline = cmdline + filename.replace(/\.(flv|mp4)/,"") + "\n" + mp4Url + "\n\n";
break;
case "makecmdline":
cmdline = cmdline + "wget" + dash + bgmode + quietmode + " -O '" + filename + "' '" + mp4Url + "'\n";
break;
case "browserdownload":
if(confirm("Titel: " + showdata[this.id][1] + "\nFilnavn: " + filnavn + "\n\nNår vinduet eller fanebladet med filmen vises, skal du trykke Ctrl-S for at gemme eller bruge menuen Filer > Gem. Derefter kan du lukke vinduet/fanebladet. Hvis du har sat kryds ved flere film, skal du bare vælge de pågældende vinduer/faneblade og trykke Ctrl-S.\n\nTip: Det kan være en god idé at omdøbe filen når du gemmer da navnet ofte er intetsigende."))
window.open(mp4Url);
break;
}
});
if(buttonId=="makecmdline" || buttonId=="showlinks") {
$("#resultlist").width(width).height(height).show();
$("#resultlist textarea").val(cmdline).focus(function(){this.select()}).focus();
}
});
function scanprogs() {
if(showType.toLowerCase() == "bonanza") $("#maxprogs").val("alle");
$("#showWait").show();
$("#resultlist,#showoptions,#makecmdline,#showlinks,#browserdownload,#makelist,#showintro,.autoscan").hide();
$("#makelist a").text("Scan igen");
$(".showcb").css("visibility","hidden");
getDRNUShows();
$("#showWait").hide();
$("#showoptions,#makecmdline,#showlinks,#browserdownload,#makelist,.autoscan").show();
$(".showcb").css("visibility","visible");
}
var last_path = document.location.pathname;
var timeout_id;
start();
function start() {
clearTimeout( timeout_id );
var path = document.location.pathname;
if ( path !== last_path ) {
if($("#showList").is(":visible") && $("#autoscan").is(":checked")) scanprogs();
last_path = path;
}
timeout_id = setTimeout( start, 1000 );
};
function fixFlash() {
$('object').each(function(){
if($(this).find('param[name=wmode]').attr('value') != 'transparent') {
$(this).prepend('<param name="wmode" value="transparent" />');
$(this).parent().html($(this).parent().html());
}
});
}