From 60c61458364d4010c8ec7380989c95b34f79251f Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 01:26:25 -0700 Subject: [PATCH 01/20] nginx: Fix invalid config when no services deployed ie. for a thrimbletrimmer-only node. --- nginx/generate-config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx/generate-config b/nginx/generate-config index 17f846d..9726f78 100755 --- a/nginx/generate-config +++ b/nginx/generate-config @@ -9,7 +9,7 @@ generate_location() { } LOCATIONS=$( - echo "$SERVICES" | while read name port; do + [ -n "$SERVICES" ] && echo "$SERVICES" | while read name port; do # restreamer is the catch-all [ "$name" == "restreamer" ] && generate_location / "http://restreamer:$port" # thrimshim takes any calls to thrimshim/ From 15cf65c92636d78b1b98f895d6c61643cc704673 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 01:26:56 -0700 Subject: [PATCH 02/20] nginx: Nicer formatting for thrimbletrimmer part of config --- nginx/generate-config | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nginx/generate-config b/nginx/generate-config index 9726f78..f03f7e1 100755 --- a/nginx/generate-config +++ b/nginx/generate-config @@ -17,7 +17,9 @@ LOCATIONS=$( # all services have metrics under /metrics/SERVICE, except for thrimebletrimmer generate_location "/metrics/$name" "http://$name:$port/metrics" done - [ -n "$THRIMBLETRIMMER" ] && echo -e "\t\tlocation = / { return 301 /thrimbletrimmer/dashboard.html; }\n\t\tlocation /thrimbletrimmer { }" + [ -n "$THRIMBLETRIMMER" ] && + echo -e "\t\tlocation = / { return 301 /thrimbletrimmer/dashboard.html; }" && + echo -e "\t\tlocation /thrimbletrimmer { }" ) cat > /etc/nginx/nginx.conf < Date: Sat, 26 Oct 2019 04:06:32 -0700 Subject: [PATCH 03/20] thrimbletrimmer: Fix Streams and Hours links to not leave the current page The existing approach, at least in my browser (firefox), was causing the page to be replaced with "[window Object]". --- thrimbletrimmer/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/thrimbletrimmer/index.html b/thrimbletrimmer/index.html index 7d85657..865893e 100644 --- a/thrimbletrimmer/index.html +++ b/thrimbletrimmer/index.html @@ -57,8 +57,8 @@ - - + + From caa129e19292fde2398bde128c727f502a0bfc9f Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 04:09:45 -0700 Subject: [PATCH 04/20] thrimbletrimmer: allow holes should be off by default --- thrimbletrimmer/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thrimbletrimmer/index.html b/thrimbletrimmer/index.html index 865893e..caa8e59 100644 --- a/thrimbletrimmer/index.html +++ b/thrimbletrimmer/index.html @@ -60,7 +60,7 @@ - + From 91c67899eee657da18aaad909c2f47a8644226d9 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 04:11:33 -0700 Subject: [PATCH 05/20] thrimbletrimmer: Read title prefix from thrimshim and display it greyed out This gives a visual indicator showing the editor what prefix the title will have. It also allows us to set the correct max title length. --- thrimbletrimmer/index.html | 3 ++- thrimbletrimmer/scripts/IO.js | 3 +++ thrimbletrimmer/styles/style.css | 8 +++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/thrimbletrimmer/index.html b/thrimbletrimmer/index.html index caa8e59..f17b952 100644 --- a/thrimbletrimmer/index.html +++ b/thrimbletrimmer/index.html @@ -80,7 +80,8 @@
Title:
- + +
Description:
diff --git a/thrimbletrimmer/scripts/IO.js b/thrimbletrimmer/scripts/IO.js index 4c99422..c1a24a5 100644 --- a/thrimbletrimmer/scripts/IO.js +++ b/thrimbletrimmer/scripts/IO.js @@ -11,6 +11,9 @@ pageSetup = function() { } //data = testThrimShim; desertBusStart = new Date(data.bustime_start); + document.getElementById("VideoTitlePrefix").value = data.title_prefix; + document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length); + document.getElementById("hiddenSubmissionID").value = data.id; document.getElementById("StreamName").value = data.video_channel ? data.video_channel:document.getElementById("StreamName").value; document.getElementById("StreamStart").value = data.event_start; diff --git a/thrimbletrimmer/styles/style.css b/thrimbletrimmer/styles/style.css index 4641de0..08010b9 100644 --- a/thrimbletrimmer/styles/style.css +++ b/thrimbletrimmer/styles/style.css @@ -28,7 +28,13 @@ body.ultrawide .my-player-dimensions { width:100% !important; } #EditorDetailsPane { margin-top:100px; } -#VideoTitle, #VideoDescription { +#VideoTitle { + width:90% +} +#VideoTitlePrefix { + width:5%; +} +#VideoDescription { width:100%; } From b06721df07a128939a68428a11867b66dfcf97c9 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 04:14:23 -0700 Subject: [PATCH 06/20] thrimbletrimmer: Update bustime/UTC values when you switch so if you change one it changes the other. Also in general takes those conversions and makes them available as functions for re-use. --- thrimbletrimmer/index.html | 2 ++ thrimbletrimmer/scripts/IO.js | 48 ++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/thrimbletrimmer/index.html b/thrimbletrimmer/index.html index f17b952..54215f0 100644 --- a/thrimbletrimmer/index.html +++ b/thrimbletrimmer/index.html @@ -127,11 +127,13 @@ } function toggleTimeInput(toggleInput) { if(toggleInput == "UTC") { + setStreamRange(); document.getElementById("BusTimeStart").style.display = "none"; document.getElementById("BusTimeEnd").style.display = "none"; document.getElementById("StreamStart").style.display = ""; document.getElementById("StreamEnd").style.display = ""; } else { + setBustimeRange(); document.getElementById("StreamStart").style.display = "none"; document.getElementById("StreamEnd").style.display = "none"; document.getElementById("BusTimeStart").style.display = ""; diff --git a/thrimbletrimmer/scripts/IO.js b/thrimbletrimmer/scripts/IO.js index c1a24a5..67d61d9 100644 --- a/thrimbletrimmer/scripts/IO.js +++ b/thrimbletrimmer/scripts/IO.js @@ -9,19 +9,19 @@ pageSetup = function() { alert("No video available for stream."); return; } - //data = testThrimShim; desertBusStart = new Date(data.bustime_start); document.getElementById("VideoTitlePrefix").value = data.title_prefix; document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length); document.getElementById("hiddenSubmissionID").value = data.id; document.getElementById("StreamName").value = data.video_channel ? data.video_channel:document.getElementById("StreamName").value; + // set stream start/end, then copy to bustime inputs document.getElementById("StreamStart").value = data.event_start; - document.getElementById("BusTimeStart").value = (new Date(data.event_start+"Z") < desertBusStart ? "-":"") + videojs.formatTime(Math.abs((new Date(data.event_start+"Z") - desertBusStart)/1000), 600.01).padStart(7, "0:"); document.getElementById("StreamEnd").value = data.event_end; - document.getElementById("BusTimeEnd").value = (new Date(data.event_end+"Z") < desertBusStart ? "-":"") + videojs.formatTime(Math.abs((new Date(data.event_end+"Z") - desertBusStart)/1000), 600.01).padStart(7, "0:"); - document.getElementById("VideoTitle").value = data.video_title ? data.video_title:document.getElementById("VideoTitle").value; - document.getElementById("VideoDescription").value = data.video_description ? data.video_description:data.description; + setBustimeRange(); + // title and description both default to row description + document.getElementById("VideoTitle").value = data.video_title ? data.video_title : data.description; + document.getElementById("VideoDescription").value = data.video_description ? data.video_description : data.description; loadPlaylist(data.video_start, data.video_end); }); @@ -37,20 +37,38 @@ pageSetup = function() { } }; +timestampToBustime = function(ts) { + date = new Date(ts + "Z"); + return (date < desertBusStart ? "-":"") + videojs.formatTime(Math.abs((date - desertBusStart)/1000), 600.01).padStart(7, "0:"); +}; + +bustimeToTimestamp = function(bustime) { + direction = 1; + if(bustime.startsWith("-")) { + bustime = bustime.slice(1); + direction = -1; + } + parts = bustime.split(':') + bustime_ms = (parseInt(parts[0]) + parts[1]/60 + parts[2]/3600) * 1000 * 60 * 60; + return new Date(desertBusStart.getTime() + direction * bustime_ms).toISOString().substring(0, 19); +}; + +setBustimeRange = function() { + document.getElementById("BusTimeStart").value = timestampToBustime(document.getElementById("StreamStart").value); + document.getElementById("BusTimeEnd").value = timestampToBustime(document.getElementById("StreamEnd").value); +}; + +setStreamRange = function() { + document.getElementById("StreamStart").value = bustimeToTimestamp(document.getElementById("BusTimeStart").value); + document.getElementById("StreamEnd").value = bustimeToTimestamp(document.getElementById("BusTimeEnd").value); +} + loadPlaylist = function(startTrim, endTrim) { var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8"; + // If we're using bustime, update stream start/end from it first if(document.getElementById("BusTimeToggleBus").checked) { - var streamStart = desertBusStart; - var busTimeStart = document.getElementById("BusTimeStart").value; - var busTimeEnd = document.getElementById("BusTimeEnd").value; - - //Convert BusTime to milliseconds from start of stream - busTimeStart = (parseInt(busTimeStart.split(':')[0]) + busTimeStart.split(':')[1]/60) * 1000 * 60 * 60; - busTimeEnd = (parseInt(busTimeEnd.split(':')[0]) + busTimeEnd.split(':')[1]/60) * 1000 * 60 * 60; - - document.getElementById("StreamStart").value = new Date(streamStart.getTime() + busTimeStart).toISOString().substring(0,19); - document.getElementById("StreamEnd").value = new Date(streamStart.getTime() + busTimeEnd).toISOString().substring(0,19); + setStreamRange(); } var streamStart = document.getElementById("StreamStart").value ? "start="+document.getElementById("StreamStart").value:null; From cdd286c0eea54ef1176379f10baeece973fdb056 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 04:16:52 -0700 Subject: [PATCH 07/20] thrimbletrimmer: manual link and download buttons: cleanup, error handling, no-auth mode --- thrimbletrimmer/index.html | 2 +- thrimbletrimmer/scripts/IO.js | 68 +++++++++++++++++++++++++---------- 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/thrimbletrimmer/index.html b/thrimbletrimmer/index.html index 54215f0..eea7623 100644 --- a/thrimbletrimmer/index.html +++ b/thrimbletrimmer/index.html @@ -97,7 +97,7 @@ Ultrawide
- + diff --git a/thrimbletrimmer/scripts/IO.js b/thrimbletrimmer/scripts/IO.js index 6edccf8..c0241a6 100644 --- a/thrimbletrimmer/scripts/IO.js +++ b/thrimbletrimmer/scripts/IO.js @@ -23,6 +23,8 @@ pageSetup = function() { document.getElementById("VideoTitle").value = data.video_title ? data.video_title : data.description; document.getElementById("VideoDescription").value = data.video_description ? data.video_description : data.description; + setOptions('uploadLocation', data.upload_locations); + loadPlaylist(data.video_start, data.video_end); }); } @@ -63,6 +65,13 @@ setStreamRange = function() { document.getElementById("StreamEnd").value = bustimeToTimestamp(document.getElementById("BusTimeEnd").value); } +// For a given select input element id, add the given list of options, defaulting to the first one. +setOptions = function(element, options) { + options.forEach(function(option, index) { + document.getElementById(element).innerHTML += ''; + }); +} + loadPlaylist = function(startTrim, endTrim) { var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8"; @@ -85,9 +94,7 @@ loadPlaylist = function(startTrim, endTrim) { return; } var qualityLevels = data.sort().reverse(); - qualityLevels.forEach(function(level, index) { - document.getElementById('qualityLevel').innerHTML += ''; - }); + setOptions('qualityLevel', qualityLevels); }); }; diff --git a/thrimshim/thrimshim/main.py b/thrimshim/thrimshim/main.py index a96e26e..4e69860 100644 --- a/thrimshim/thrimshim/main.py +++ b/thrimshim/thrimshim/main.py @@ -147,6 +147,7 @@ def get_row(ident): response["title_prefix"] = app.title_header response["title_max_length"] = MAX_TITLE_LENGTH - len(app.title_header) response["bustime_start"] = app.bustime_start + response["upload_locations"] = app.upload_locations # remove any added headers or footers so round-tripping is a no-op if ( @@ -308,8 +309,9 @@ def reset_row(ident, editor=None): @argh.arg('--no-authentication', help='Do not authenticate') @argh.arg('--title-header', help='A header to prefix all titles with, seperated from the submitted title by " - "') @argh.arg('--description-footer', help='A footer to suffix all descriptions with, seperated from the submitted description by a blank line.') +@argh.arg('--upload-locations', help='A comma-seperated list of valid upload locations, to pass to thrimbletrimmer. The first is the default. Note this is NOT validated on write.') def main(connection_string, default_channel, bustime_start, host='0.0.0.0', port=8004, backdoor_port=0, - no_authentication=False, title_header=None, description_footer=None): + no_authentication=False, title_header=None, description_footer=None, upload_locations=''): """Thrimshim service.""" server = WSGIServer((host, port), cors(app)) @@ -318,6 +320,7 @@ def main(connection_string, default_channel, bustime_start, host='0.0.0.0', port app.bustime_start = bustime_start app.title_header = "" if title_header is None else "{} - ".format(title_header) app.description_footer = "" if description_footer is None else "\n\n{}".format(description_footer) + app.upload_locations = upload_locations.split(',') if upload_locations else [] stopping = gevent.event.Event() def stop(): From 7dea1f0cdb649f6c448e55393420e81208ca6c9f Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 06:21:24 -0700 Subject: [PATCH 13/20] thrimbletrimmer: Fix some typos in the new error handling --- thrimbletrimmer/scripts/IO.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/thrimbletrimmer/scripts/IO.js b/thrimbletrimmer/scripts/IO.js index c0241a6..fd0d8f0 100644 --- a/thrimbletrimmer/scripts/IO.js +++ b/thrimbletrimmer/scripts/IO.js @@ -137,7 +137,7 @@ thrimbletrimmerSubmit = function(state) { alert(error); document.getElementById('SubmitButton').disabled = false; } else { - setTimeout(() => window.location.href = '/thrimbletrimmer/dashboard.html'; }, 500); + setTimeout(() => { window.location.href = '/thrimbletrimmer/dashboard.html'; }, 500); } })); }; @@ -184,7 +184,7 @@ thrimbletrimmerManualLink = function() { document.getElementById("ManualButton").disabled = false; } else { alert("Manual link set to " + body.link); - setTimeout(() => window.location.href = '/thrimbletrimmer/dashboard.html'; }, 500); + setTimeout(() => { window.location.href = '/thrimbletrimmer/dashboard.html'; }, 500); } })); }; @@ -221,7 +221,7 @@ thrimbletrimmerResetLink = function() { document.getElementById("ResetButton").disabled = false; } else { alert("Row has been reset. Reloading..."); - setTimeout(() => window.location.reload(); }, 500); + setTimeout(() => { window.location.reload(); }, 500); } })); }; From 775799944a324fa3d7b6f84bf18ff5f7f8de6c50 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 06:21:58 -0700 Subject: [PATCH 14/20] thrimbletrimmer: Don't hide the video player on error It means you can't read the error, and it's more confusing. --- thrimbletrimmer/scripts/playerSetup.js | 1 - 1 file changed, 1 deletion(-) diff --git a/thrimbletrimmer/scripts/playerSetup.js b/thrimbletrimmer/scripts/playerSetup.js index 285d3bc..77f2c86 100644 --- a/thrimbletrimmer/scripts/playerSetup.js +++ b/thrimbletrimmer/scripts/playerSetup.js @@ -53,7 +53,6 @@ function setupPlayer(source, startTrim, endTrim) { this.on('error', function() { videojs.log("Could not load video stream"); alert("No video available for stream."); - document.getElementById("my-player").style.display = "none"; }) }); var hlsQS = player.hlsQualitySelector(); From 983e3a61c693ba0ee7a33f670b14a1e41213cc55 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 06:24:04 -0700 Subject: [PATCH 15/20] thrimbletrimmer: also pause on spacebar Most video players pause on space, so we make sure it works if they try --- thrimbletrimmer/scripts/keyboardShortcuts.js | 1 + 1 file changed, 1 insertion(+) diff --git a/thrimbletrimmer/scripts/keyboardShortcuts.js b/thrimbletrimmer/scripts/keyboardShortcuts.js index 78c9fd6..627df05 100644 --- a/thrimbletrimmer/scripts/keyboardShortcuts.js +++ b/thrimbletrimmer/scripts/keyboardShortcuts.js @@ -6,6 +6,7 @@ document.addEventListener('keypress', (event) => { player.currentTime(player.currentTime()-10); break; case "k": + case " ": // also pause on space player.paused() ? player.play():player.pause(); break; case "l": From 728ede61c0c859a3c4f7502019113bfb7955a319 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 06:50:49 -0700 Subject: [PATCH 16/20] thrimbletrimmer: Don't leave page after saving edits --- thrimbletrimmer/scripts/IO.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/thrimbletrimmer/scripts/IO.js b/thrimbletrimmer/scripts/IO.js index fd0d8f0..55b66f7 100644 --- a/thrimbletrimmer/scripts/IO.js +++ b/thrimbletrimmer/scripts/IO.js @@ -135,10 +135,12 @@ thrimbletrimmerSubmit = function(state) { error = response.statusText + ": " + text; console.log(error); alert(error); - document.getElementById('SubmitButton').disabled = false; - } else { + } else if (state == 'EDITED') { + // Only return to dashboard if submitted, not for save draft setTimeout(() => { window.location.href = '/thrimbletrimmer/dashboard.html'; }, 500); + return } + document.getElementById('SubmitButton').disabled = false; })); }; From 6cfad08a2612d220c3e6b4bad6b6ebefb5e9f4bd Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 06:51:04 -0700 Subject: [PATCH 17/20] thrimbletrimmer: Restore previously saved advanced options and show the advanced pane if any are non-default. --- thrimbletrimmer/scripts/IO.js | 36 ++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/thrimbletrimmer/scripts/IO.js b/thrimbletrimmer/scripts/IO.js index 55b66f7..2653551 100644 --- a/thrimbletrimmer/scripts/IO.js +++ b/thrimbletrimmer/scripts/IO.js @@ -13,8 +13,8 @@ pageSetup = function() { document.getElementById("VideoTitlePrefix").value = data.title_prefix; document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length); - document.getElementById("hiddenSubmissionID").value = data.id; document.getElementById("StreamName").value = data.video_channel ? data.video_channel:document.getElementById("StreamName").value; + document.getElementById("hiddenSubmissionID").value = data.id; // set stream start/end, then copy to bustime inputs document.getElementById("StreamStart").value = data.event_start; document.getElementById("StreamEnd").value = data.event_end; @@ -23,9 +23,19 @@ pageSetup = function() { document.getElementById("VideoTitle").value = data.video_title ? data.video_title : data.description; document.getElementById("VideoDescription").value = data.video_description ? data.video_description : data.description; - setOptions('uploadLocation', data.upload_locations); + // Restore advanced options. If any of these are non-default, automatically expand the advanced options pane. + setOptions('uploadLocation', data.upload_locations, data.upload_location); + document.getElementById("AllowHoles").checked = data.allow_holes; + document.getElementById("uploaderWhitelist").value = (!!data.uploader_whitelist) ? data.uploader_whitelist.join(",") : ""; + if ( + (data.upload_locations.length > 0 && data.upload_location != data.upload_locations[0]) + || data.allow_holes + || !!data.uploader_whitelist + ) { + document.getElementById('wubloaderAdvancedInputTable').style.display = "block"; + } - loadPlaylist(data.video_start, data.video_end); + loadPlaylist(data.video_start, data.video_end, data.video_quality); }); } else { @@ -65,14 +75,19 @@ setStreamRange = function() { document.getElementById("StreamEnd").value = bustimeToTimestamp(document.getElementById("BusTimeEnd").value); } -// For a given select input element id, add the given list of options, defaulting to the first one. -setOptions = function(element, options) { - options.forEach(function(option, index) { - document.getElementById(element).innerHTML += ''; +// For a given select input element id, add the given list of options. +// If selected is given, it should be the name of an option to select. +// Otherwise the first one is used. +setOptions = function(element, options, selected) { + if (!selected && options.length > 0) { + selected = options[0] + } + options.forEach(function(option) { + document.getElementById(element).innerHTML += ''; }); } -loadPlaylist = function(startTrim, endTrim) { +loadPlaylist = function(startTrim, endTrim, defaultQuality) { var playlist = "/playlist/" + document.getElementById("StreamName").value + ".m3u8"; // If we're using bustime, update stream start/end from it first @@ -94,7 +109,10 @@ loadPlaylist = function(startTrim, endTrim) { return; } var qualityLevels = data.sort().reverse(); - setOptions('qualityLevel', qualityLevels); + setOptions('qualityLevel', qualityLevels, defaultQuality); + if (!!defaultQuality && qualityLevels.length > 0 && defaultQuality != qualityLevels[0]) { + document.getElementById('wubloaderAdvancedInputTable').style.display = "block"; + } }); }; From d03120548b1e6c7eb0e1f1376301ebcbbf421a62 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 06:54:44 -0700 Subject: [PATCH 18/20] thrimbletrimmer: Always respect the channel given by thrimshim --- thrimbletrimmer/scripts/IO.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thrimbletrimmer/scripts/IO.js b/thrimbletrimmer/scripts/IO.js index 2653551..5d6d848 100644 --- a/thrimbletrimmer/scripts/IO.js +++ b/thrimbletrimmer/scripts/IO.js @@ -13,7 +13,7 @@ pageSetup = function() { document.getElementById("VideoTitlePrefix").value = data.title_prefix; document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length); - document.getElementById("StreamName").value = data.video_channel ? data.video_channel:document.getElementById("StreamName").value; + document.getElementById("StreamName").value = data.video_channel; document.getElementById("hiddenSubmissionID").value = data.id; // set stream start/end, then copy to bustime inputs document.getElementById("StreamStart").value = data.event_start; From f7f07a26880ed8a909f226a13535d267284b9b78 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 07:15:37 -0700 Subject: [PATCH 19/20] Add /defaults to thrimshim, use it to populate config stuff in thrimbletrimmer Thrimbletrimmer needs to know stuff like the bustime start time, default channel, even if it's not looking at a specific row. --- thrimbletrimmer/index.html | 4 ++-- thrimbletrimmer/scripts/IO.js | 15 ++++++++++++--- thrimshim/thrimshim/main.py | 13 +++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/thrimbletrimmer/index.html b/thrimbletrimmer/index.html index 33d1700..cd5a2d6 100644 --- a/thrimbletrimmer/index.html +++ b/thrimbletrimmer/index.html @@ -41,8 +41,8 @@ - - + + diff --git a/thrimbletrimmer/scripts/IO.js b/thrimbletrimmer/scripts/IO.js index 5d6d848..5b8a07a 100644 --- a/thrimbletrimmer/scripts/IO.js +++ b/thrimbletrimmer/scripts/IO.js @@ -41,9 +41,18 @@ pageSetup = function() { else { document.getElementById('SubmitButton').disabled = true; - var startOfHour = new Date(new Date().setMinutes(0,0,0)); - document.getElementById("StreamStart").value = new Date(startOfHour.getTime() - 1000*60*60).toISOString().substring(0,19); - document.getElementById("StreamEnd").value = startOfHour.toISOString().substring(0,19); + fetch("/thrimshim/defaults").then(data => data.json()).then(function (data) { + desertBusStart = new Date(data.bustime_start); + document.getElementById("VideoTitlePrefix").value = data.title_prefix; + document.getElementById("VideoTitle").setAttribute("maxlength", data.title_max_length); + document.getElementById("StreamName").value = data.video_channel; + setOptions('uploadLocation', data.upload_locations); + + // Default time range to the last 10min. This is useful for giffers, immediate replay, etc. + document.getElementById("StreamStart").value = new Date(new Date().getTime() - 1000*60*10).toISOString().substring(0,19); + document.getElementById("StreamEnd").value = new Date().toISOString().substring(0,19); + setBustimeRange(); + }); loadPlaylist(); } diff --git a/thrimshim/thrimshim/main.py b/thrimshim/thrimshim/main.py index 4e69860..cca218b 100644 --- a/thrimshim/thrimshim/main.py +++ b/thrimshim/thrimshim/main.py @@ -120,6 +120,19 @@ def get_all_rows(): return json.dumps(rows) +@app.route('/thrimshim/defaults') +@request_stats +def get_defaults(): + """Get default info needed by thrimbletrimmer when not loading a specific row.""" + return json.dumps({ + "video_channel": app.default_channel, + "bustime_start": app.bustime_start, + "title_prefix": app.title_header, + "title_max_length": MAX_TITLE_LENGTH - len(app.title_header), + "upload_locations": app.upload_locations, + }) + + @app.route('/thrimshim/', methods=['GET']) @request_stats def get_row(ident): From 934c640a04a0c638e5a72e7ffd6a2c1fad3389b7 Mon Sep 17 00:00:00 2001 From: Mike Lang Date: Sat, 26 Oct 2019 07:37:27 -0700 Subject: [PATCH 20/20] thrimbletrimmer: Display edit notes below the video In nice distracting pink so they're sure to see it. --- thrimbletrimmer/index.html | 6 +++++- thrimbletrimmer/scripts/IO.js | 6 ++++++ thrimbletrimmer/styles/style.css | 6 ++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/thrimbletrimmer/index.html b/thrimbletrimmer/index.html index cd5a2d6..eceb298 100644 --- a/thrimbletrimmer/index.html +++ b/thrimbletrimmer/index.html @@ -78,9 +78,13 @@
+
Title:
- +
diff --git a/thrimbletrimmer/scripts/IO.js b/thrimbletrimmer/scripts/IO.js index 5b8a07a..16225e9 100644 --- a/thrimbletrimmer/scripts/IO.js +++ b/thrimbletrimmer/scripts/IO.js @@ -23,6 +23,12 @@ pageSetup = function() { document.getElementById("VideoTitle").value = data.video_title ? data.video_title : data.description; document.getElementById("VideoDescription").value = data.video_description ? data.video_description : data.description; + // If any edit notes, show them + if (data.notes.length > 0) { + document.getElementById("EditNotes").value = data.notes; + document.getElementById("EditNotesPane").style.display = "block"; + } + // Restore advanced options. If any of these are non-default, automatically expand the advanced options pane. setOptions('uploadLocation', data.upload_locations, data.upload_location); document.getElementById("AllowHoles").checked = data.allow_holes; diff --git a/thrimbletrimmer/styles/style.css b/thrimbletrimmer/styles/style.css index 08010b9..d93a0ae 100644 --- a/thrimbletrimmer/styles/style.css +++ b/thrimbletrimmer/styles/style.css @@ -28,6 +28,12 @@ body.ultrawide .my-player-dimensions { width:100% !important; } #EditorDetailsPane { margin-top:100px; } +#EditNotes { + width: 100%; + background-color: pink; + color: black; + border: none; +} #VideoTitle { width:90% }