diff options
author | Sacha Chua <sacha@sachachua.com> | 2022-11-23 13:14:04 -0500 |
---|---|---|
committer | Sacha Chua <sacha@sachachua.com> | 2022-11-23 13:14:04 -0500 |
commit | 7a6fd1aa2b9b56215c2e4884ed3f185fe8e9f44a (patch) | |
tree | 61f5ddfeaa4cc1b93514a18b135868d4095282d8 | |
parent | d59e5d4255f7d91f4ccba84d4200126c0c8d4d0a (diff) | |
download | emacsconf-el-7a6fd1aa2b9b56215c2e4884ed3f185fe8e9f44a.tar.xz emacsconf-el-7a6fd1aa2b9b56215c2e4884ed3f185fe8e9f44a.zip |
hyperlists
-rw-r--r-- | emacsconf-pad.el | 210 | ||||
-rw-r--r-- | emacsconf-publish.el | 51 | ||||
-rw-r--r-- | emacsconf-stream.el | 57 | ||||
-rw-r--r-- | emacsconf.el | 82 |
4 files changed, 229 insertions, 171 deletions
diff --git a/emacsconf-pad.el b/emacsconf-pad.el index ba216ce..afd734b 100644 --- a/emacsconf-pad.el +++ b/emacsconf-pad.el @@ -258,7 +258,7 @@ ${next-talk-list} (defun emacsconf-pad-prepopulate-all-talks (&optional info) (interactive) (mapc #'emacsconf-pad-prepopulate-talk-pad - (emacsconf-include-next-talks (or info (emacsconf-get-talk-info)) emacsconf-pad-number-of-next-talks))) + (emacsconf-include-next-talks (or info (emacsconf-get-talk-info)) emacsconf-pad-number-of-next-talks))) (defun emacsconf-pad-export-initial-content (o file) (interactive @@ -296,6 +296,8 @@ ${next-talk-list} (not (string= cached-last-modified (number-to-string .data.lastEdited)))))))) +;;; Hyperlists + (defun emacsconf-pad-export-initial-content-for-hyperlists (dir &optional info) (interactive (list (read-file-name "Output directory: " nil nil nil nil 'file-directory-p))) (setq info (emacsconf-prepare-for-display (emacsconf-get-talk-info))) @@ -328,12 +330,13 @@ ${next-talk-list} :track-id (plist-get (emacsconf-get-track (plist-get shift :track)) :id) :checkin (emacsconf-surround "CHECKIN-" (plist-get shift :checkin) "" "CHECKIN") :pad (emacsconf-surround "PAD-" (plist-get shift :pad) "" "PAD") - :coord (emacsconf-surround "COORD-" (plist-get shift :coord) "" "COORD"))) - (shift-talks - (mapcar (lambda (o) (append prefixed o)) - (seq-filter - (lambda (talk) (string= (plist-get talk :track) (plist-get shift :track))) - (emacsconf-filter-talks-by-time (plist-get shift :start) (plist-get shift :end) info))))) + :coord (emacsconf-surround "COORD-" (plist-get shift :coord) "" "COORD") + :checkin-pad (concat emacsconf-pad-base "checkin-" (downcase (format-time-string "%a" (date-to-time (plist-get shift :start))))))) + (shift-talks + (mapcar (lambda (o) (append prefixed o)) + (seq-filter + (lambda (talk) (string= (plist-get talk :track) (plist-get shift :track))) + (emacsconf-filter-talks-by-time (plist-get shift :start) (plist-get shift :end) info))))) (concat (emacsconf-replace-plist-in-string (append (list :index (concat emacsconf-pad-base @@ -351,7 +354,7 @@ ${next-talk-list} " <strong>Setup</strong> <ul> -<li>[ ] <em>${checkin}:</em> Open the index: https://media.emacsconf.org/${year}/backstage/index-${track-id}.html</li> +<li>[ ] <em>${checkin}:</em> Open ${checkin-pad}</li> <li>[ ] <em>${irc-volunteer}:</em> Watch the #emacsconf-${track-id} channel</li> <li>[ ] <em>${pad}:</em> Open the index: https://media.emacsconf.org/${year}/backstage/index-${track-id}.html</li> <li>[ ] <em>${stream}:</em> Start streaming with OBS @@ -367,6 +370,7 @@ ${next-talk-list} <li>[ ] Start recording (not streaming). (Alt-2, switch to workspace 2; Alt-Shift-2, move something to workspace 2).</li> <li>[ ] Watch the stream with MPV on your local system: mpv https://live0.emacsconf.org/emacsconf/$TRACK.webm &</li> <li>[ ] Check 480p: mpv https://live0.emacsconf.org/emacsconf/$TRACK-480p.webm &</li> +<li>[ ] Confirm that the streaming user has connected to Mumble, is in the ${channel} channel, and can hear what we say on Mumble.</li> <li>[ ] Test with a sample video or Q&A session: ssh emacsconf-$TRACK@res.emacsconf.org -p 46668 \"~/bin/track-mpv meetups &\"</li> </ul></li> <li>[ ] <em>${coord}:</em> ssh -t orga@live0.emacsconf.org 'screen -S restream-${track-id}-youtube /home/orga/restream-${track-id}-youtube.sh' and then confirm</li> @@ -376,31 +380,18 @@ ${next-talk-list} " "<strong>Talks</strong> <ul>" - (mapconcat #'cdr - (sort - (append - (delq nil - (mapcar (lambda (talk) - (when (plist-get talk :checkin-time) - (cons - (plist-get talk :checkin-time) - (emacsconf-pad-format-checkin-hyperlist talk)))) - shift-talks)) - (mapcar - ;; talks - (lambda (talk) - (cons (plist-get talk :start-time) - (emacsconf-pad-talk-hyperlist - (append prefixed talk)))) - shift-talks)) - (lambda (a b) (time-less-p (car a) (car b)))) - "\n") + (mapconcat + (lambda (talk) + (emacsconf-pad-talk-hyperlist + (append prefixed talk))) + (emacsconf-include-next-talks shift-talks 1) + "\n") "</ul>" "Teardown <ul> <li>[ ] <em>${stream}:</em> stop recording</li> -<li>[ ] <em>${coord}:</em> stop the restream-${track-id}-youtube screen on live0</li> -<li>[ ] <em>${coord}:</em> stop the restream-${track-id}-toobnix screen on live0</li> +<li>[ ] <em>${coord}:</em> stop the restream-${track-id}-youtube screen on live0: <strong>screen -S restream-${track-id}-youtube -X quit</strong></li> +<li>[ ] <em>${coord}:</em> stop the restream-${track-id}-toobnix screen on live0: <strong>screen -S restream-${track-id}-toobnix -X quit</strong></li> <li>[ ] <em>${coord}:</em> update the status page on live.emacsconf.org by changing emacsconf-tracks and calling emacsconf-stream-update-status-page</li> </ul>")) ))) @@ -408,42 +399,46 @@ ${next-talk-list} (defun emacsconf-pad-format-checkin-hyperlist (talk) (emacsconf-replace-plist-in-string (append (list :time - (format-time-string "%H:%M" (plist-get talk :checkin-time) emacsconf-timezone)) + (format-time-string "%H:%M" (plist-get talk :checkin-time) emacsconf-timezone) + :start + (format-time-string "%H:%M" (plist-get talk :start-time) emacsconf-timezone)) talk) (pcase (or (plist-get talk :q-and-a) "") ((rx "live") - "<li><strong>${time}</strong> <em>${checkin}:</em> By this time, ${speakers} should be checked into ${bbb-backstage} and set as moderator(s); let #emacsconf-org know if they're missing</li>") + "<li>[ ] <strong>${time}</strong> <em>${checkin}:</em> ${speakers} should be checked into ${bbb-backstage} and set as moderator(s) for talk time of ${start}</li>") ((rx "IRC") - "<li><strong>${time}</strong> <em>${checkin}:</em> Double-check ${speakers} in ${channel}; let #emacsconf-org know if not</li>") + "<li>[ ] <strong>${time}</strong> <em>${checkin}:</em> ${speakers} should be in #${channel} (${irc-nick}) for talk time of ${start}</li>") ((rx "Mumble") - "<li><strong>${time}</strong> <em>${checkin}:</em> Double-check ${speakers} on Mumble; let #emacsconf-org know if not</li>") + "<li>[ ] <strong>${time}</strong> <em>${checkin}:</em> ${speakers} should be Mumble for talk time of ${start}</li>") (_ "")))) (defun emacsconf-pad-prepopulate-checkins (&optional info) (interactive) - (setq info (or info (emacsconf-prepare-for-display info))) - (mapc (lambda (day) - (let ((pad-id (concat "checkin-" (downcase (format-time-string "%a" (plist-get (cadr day) :checkin-time)))))) - (emacsconf-create-pad) - (emasconf-set-pad) - (concat "<ul>" - (mapconcat - (lambda (talk) - (emacsconf-pad-format-checkin-hyperlist talk) - ) - (seq-sort - (lambda (a b) - (time-less-p (plist-get a :checkin-time) - (plist-get b :checkin-time))) - (seq-filter (lambda (talk) (plist-get talk :checkin-time)) info)) - "\n") - "</ul>")) - ) - (seq-group-by (lambda (talk) - (format-time-string "%A, %b %-e, %Y" (plist-get talk :checkin-time))) - info)))) - - ) + (setq info (or info (emacsconf-prepare-for-display (emacsconf-get-talk-info)))) + (mapc + (lambda (day) + (let ((pad-id (concat "checkin-" (downcase (format-time-string "%a" (plist-get (cadr day) :checkin-time)))))) + (emacsconf-pad-create-pad pad-id) + (emacsconf-pad-set-html + pad-id + (replace-regexp-in-string + "<em>${checkin}:</em> " "" + (concat + (car day) + "<ul>" + (mapconcat + (lambda (talk) + (emacsconf-pad-format-checkin-hyperlist talk)) + (seq-sort + (lambda (a b) + (time-less-p (plist-get a :checkin-time) + (plist-get b :checkin-time))) + (seq-filter (lambda (talk) (plist-get talk :checkin-time)) day)) + "\n") + "</ul>"))))) + (seq-group-by (lambda (talk) + (format-time-string "%A, %b %-e, %Y" (plist-get talk :checkin-time))) + info))) (defun emacsconf-pad-prepopulate-shift-hyperlist (shift &optional info) (interactive (list (completing-read "Shift: " @@ -464,81 +459,108 @@ ${next-talk-list} (interactive) (let ((info (emacsconf-prepare-for-display (emacsconf-get-talk-info)))) (mapc (lambda (shift) - (emacsconf-pad-prepopulate-shift-hyperlists info))) + (emacsconf-pad-prepopulate-shift-hyperlists info)) emacsconf-shifts))) ;; Related: emacsconf-talk-hyperlist (defun emacsconf-pad-talk-hyperlist (talk &optional do-insert) (interactive (list (emacsconf-complete-talk-info) t)) (let* ((track-id (plist-get (emacsconf-get-track talk) :id)) + (next-talk (car (plist-get talk :next-talks))) (modified-talk (apply #'append (list :year emacsconf-year :track-id track-id + :media-base emacsconf-media-base-url :mumble (concat emacsconf-id "-" track-id) + :next-talk-in-5 (if next-talk (format-time-string "%H:%M" (time-subtract (plist-get next-talk :start-time) (seconds-to-time 300)) emacsconf-timezone) "") + :next-talk-in-1 (if next-talk (format-time-string "%H:%M" (time-subtract (plist-get next-talk :start-time) (seconds-to-time 60)) emacsconf-timezone) "") :ssh "ssh orga@res.emacsconf.org -p 46668 " - :ssh-audio (format "ex: ssh emacsconf-%s@res.emacsconf.org -p 46668 \"%s-vol 85%%\" (or %s-louder, %s-quieter)" track-id track-id track-id track-id)) + :ssh-track (format "ssh %s-%s@res.emacsconf.org -p 46668 " emacsconf-id track-id) + :ssh-audio (format "ex: ssh emacsconf-%s@res.emacsconf.org -p 46668 \"qa-vol 85%%\" (or qa-louder, qa-quieter, mum-vol, mum-louder, mum-quieter)" track-id)) talk (mapcar (lambda (status) (list (intern (concat ":ssh-" (replace-regexp-in-string "_" "" (downcase status)))) - (format "ssh orga@res.emacsconf.org -p 46668 \"~/scripts/update-task-status.sh %s . %s\"" + (format "<strong>ssh orga@res.emacsconf.org -p 46668 \"~/scripts/update-task-status.sh %s . %s\"</strong>" (plist-get talk :slug) status))) '("PLAYING" "OPEN_Q" "CLOSED_Q")))) - (result + result) + (setq result (emacsconf-replace-plist-in-string modified-talk - (format "<li><strong>%s export SLUG=%s %s <a href=\"%s%s\">%s%s</a></strong>\n<ul>%s%s</ul></li>" + (format "<li><strong>%s %s (Talk: %s, Q&A: %s) %s <a href=\"%s\">%s</a></strong><ul>%s</ul>\n</li>" (format-time-string "%H:%M" (plist-get talk :start-time) emacsconf-timezone) (plist-get talk :slug) + (if (plist-get talk :video-file) "recorded" "live") + (or (plist-get talk :q-and-a) "none") (plist-get talk :title) - emacsconf-base-url - (plist-get talk :url) - emacsconf-base-url - (plist-get talk :url) - (emacsconf-surround - "<div><strong>" (plist-get talk :hyperlist-note) "</strong></div>" - "") - (pcase (or (plist-get talk :q-and-a) "") - ((rx "live") - "<li>[ ] ${stream}: Display the in-between slide <a href=\"https://media.emacsconf.org/${year}/in-between/${slug}.png\">https://media.emacsconf.org/${year}/in-between/${slug}.png</a></li> + (plist-get talk :absolute-url) + (plist-get talk :absolute-url) + + (concat + (emacsconf-surround "<li><strong>" (plist-get talk :hyperlist-note) "</strong></li>" "") + "<li>[ ] ${stream}: Display the in-between slide: ${ssh-track} and run <em>firefox ${in-between-url} &</em></li> <li>[ ] ${host}: Connect to the ${mumble} channel in Mumble and introduce the talk: <strong>${intro-note}</strong></li> -<li>[ ] ${stream}: Start playing the talk: ${ssh-playing}</li> -<li>[ ] ${host}: Join the Q&A room at <a href=\"${bbb-room}\">${bbb-room}</a> and open the pad at <a href=\"${pad-url}\">${pad-url}</a>; optionally open IRC for ${channel} (<a href=\"${webchat-url}\">${webchat-url}</a>)</li> +" + (if (plist-get talk :video-file) + "<li>[ ] ${stream}: Mark the talk as playing: ${ssh-playing} and confirm that it plays. If it doesn't play, go to the ~/stream directory and use track-mpv to play the video file.</li>" + "<li>[ ] ${stream}: <strong>LIVE talk:</strong> Mark the talk as playing: ${ssh-playing} and arrange windows (backup URL for BBB if it doesn't open: ${bbb-backstage}). Adjust audio as needed</li>") + (pcase (or (plist-get talk :q-and-a) "") + ((rx "live") + (concat + "<li>[ ] ${host}: Join the Q&A room at <a href=\"${bbb-backstage}\">${bbb-backstage}</a> and open the pad at <a href=\"${pad-url}\">${pad-url}</a>; optionally open IRC for ${channel} (<a href=\"${webchat-url}\">${webchat-url}</a>)</li> <li>[ ] [? speaker missing?] ${host}: Let #emacsconf-org know so that we can text or call the speaker</li> -<li>[ ] ${stream}: After the talk, open the Q&A window and the pad: ${ssh-closedq} </li> +<li>[ ] ${stream}: After the talk, open the Q&A window and the pad: ${ssh-closedq} +<ul> +<li>Backup URL for BBB: ${bbb-backstage}</li> +<li>Backup URL for pad: ${pad-url}</li> +</ul> +</li> <li>[ ] ${stream}: Give the host the go-ahead via Mumble or #emacsconf-org</li> <li>[ ] ${host}: Start recording and read questions</li> <li>[ ] ${stream}: Adjust the audio levels as needed: ${ssh-audio}</li> -<li>[ ] ${host}: Decide when to open the Q&A and let the streamer know</li> -<li>[ ] ${stream}: Mark the Q&A as open: ${ssh-openq}</li> -<li>[ ] ${host}: Announce that people can join using the URL on the talk page</li> -<li>[? Open Q&A is still going on and it's about five minutes before the next talk] +<li>[ ] ${host}: Decide when to open the Q&A and let ${coord} know privately</li> +<li>[ ] ${coord}: Mark the Q&A as open: ${ssh-openq} and double-check the redirect at ${bbb-redirect}. If the redirect doesn't work, ssh media \"cp ~/${year}/backstage/assets/redirects/open/bbb-${slug}.html ~/${year}/current/\" . Confirm the redirect and let ${host} know.</li> +<li>[ ] ${host}: Announce that people can join using the URL on the talk page or ask questions on the pad or IRC channel</li> +<li>${next-talk-in-5} [? Open Q&A is still going on and it's about five minutes before the next talk] <ul><li>[ ] ${host}: Let the speaker know about the time and that the Q&A can continue off-stream if people want to join</li></ul></li> -<li>[? Open Q&A is still going on and it's about two minutes before the next talk] +<li>${next-talk-in-1} [? Open Q&A is still going on and it's about a minute before the next talk] <ul><li>[ ] ${host}: Announce that the Q&A will continue if people want to join the BBB room from the talk page, and the stream will now move to the next talk</li></ul></li> <li>[? Q&A is done early] <ul> <li>[ ] ${stream}: Mark the talk as archived: ${ssh} \"~/current/scripts/update-task-status.sh ${slug} . TO_ARCHIVE\"</li> -</ul> -<li>[ ] ${stream}: Close the Q&A windows and move on to the next talk</li> +</ul></li> +")) + ((rx "irc") + " +<li>[ ] ${stream}: Update the task status: ${ssh-closedq} # this should open the pad and IRC; arrange the windows +<ul><li>Backup link to pad: ${pad-url}</li> +<li>Backup link to #${channel}: ${webchat-url}</li></ul></li> +<li>[ ] ${stream}: Update the task status: ${ssh-openq} # this should not make any visible changes, just update the task status</li> +<li>[ ] ${host}: Announce that people can ask questions in the ${channel} IRC channel.</li> ") - ((rx "irc") - "<li>[ ] ${stream}: Display the in-between slide <a href=\"https://media.emacsconf.org/${year}/in-between/${slug}.png\">https://media.emacsconf.org/${year}/in-between/${slug}.png</a></li> -<li>[ ] ${host}: Connect to the ${mumble} channel in Mumble and introduce the talk</li> -<li>[ ] ${stream}: ${ssh-playing}</li> -<li>[ ] ${stream}: Open the IRC channel (${channel}) and the pad, and arrange the windows: ${ssh-closedq}</li> -<li>[ ] ${stream}: When it's time for the next talk, close the Q&A windows and move on to the next talk</li> + ((rx "Mumble") + " +<li>[ ] ${stream}: Bring the speaker's Mumble login over to the ${channel} channel in Mumble. Confirm that Mumble is audible and adjust audio as needed: ssh emacsconf-${track-id}@res.emacsconf.org -p 46668 \"mum-vol 85%%\" (or mum-louder, mum-quieter)</li> +<li>[ ] ${stream}: Mark the Q&A as closed: ${ssh-closedq} . This should display the QA slide (backup: ${ssh-track} and run <em>firefox ${qa-slide-url} &</em>)</li> +<li>[ ] ${stream}: Update the task status: ${ssh-openq} # this should not make any visible changes, just update the task status</li> +<li>[ ] ${host}: Announce that people can ask questions in the pad or on the ${channel} IRC channel.</li> ") - (_ - "<li>[ ] ${stream}: Display the in-between slide <a href=\"https://media.emacsconf.org/${year}/in-between/${slug}.png\">https://media.emacsconf.org/${year}/in-between/${slug}.png</a></li> -<li>[ ] ${host}: Connect to the ${mumble} channel in Mumble and introduce the talk</li> -<li>[ ] ${stream}: Start the talk: ${ssh-playing}</li> -<li>[ ] ${stream}: Open the IRC channel (${channel}) and the pad, and arrange the windows: ${ssh-closedq}</li> -<li>[ ] ${stream}: When it's time for the next talk, close the Q&A windows and move on to the next talk</li> -")))))) + ((rx "after") + " +<li>[ ] ${stream}: Update the task status: ${ssh-closedq} # this should open the pad and IRC; arrange the windows +<ul><li>Backup link to pad: ${pad-url}</li> +<li>Backup link to #${channel}: ${webchat-url}</li></ul></li> +<li>[ ] ${host}: Announce that people can ask questions in the pad or on the ${channel} IRC channel, and that the speaker will follow up later.</li> +<li>[ ] ${stream}: Update the task status: ${ssh-openq} # this should not make any visible changes, just update the task status</li>" + ) + (_ + "<li>[ ] ${stream}: Open the IRC channel (${channel}) and the pad, and arrange the windows: ${ssh-closedq}</li> +")) + "<li>[ ] ${stream}: When it's time for the next talk, close the Q&A windows and move on to the next talk</li>")))) (if do-insert (insert result)) result)) diff --git a/emacsconf-publish.el b/emacsconf-publish.el index e6f55a9..585a688 100644 --- a/emacsconf-publish.el +++ b/emacsconf-publish.el @@ -95,6 +95,7 @@ (emacsconf-publish-info-pages) (emacsconf-generate-main-schedule) (emacsconf-ical-generate-all) + (emacsconf-publish-schedule-org-files) (emacsconf-publish-watch-pages) (when (functionp 'emacsconf-pentabarf-generate) (emacsconf-pentabarf-generate)))) @@ -151,6 +152,56 @@ talk "<div class=\"vid\">${video-html}<div>${extra}</div>${resources}${chapter-list}</div>")))) +;; (emacsconf-publish-format-track-as-org (car emacsconf-tracks) "US/Eastern") +;; (emacsconf-get-talk-info) +(defun emacsconf-publish-format-track-as-org (track tz &optional info) + (setq info (or info (emacsconf-prepare-for-display (emacsconf-get-talk-info)))) + (concat + "** " (plist-get track :name) " :" (plist-get track :id) ":\n:PROPERTIES:\n:CATEGORY: " (plist-get track :id) "\n:END:\n" + (mapconcat + (lambda (talk) + (concat + "*** " (plist-get talk :title) "\n" + "<" (format-time-string + (cdr org-time-stamp-formats) + (plist-get talk :start-time) + tz) + ">\n" + (emacsconf-surround "- " (plist-get talk :speakers-with-pronouns) "\n" "") + (emacsconf-surround "- " (plist-get talk :absolute-url) "\n" "") + (emacsconf-surround "- Etherpad: " (plist-get talk :pad-url) "\n" "") + (emacsconf-surround "- Q&A: " (plist-get talk :qa-info) "\n" "") + (emacsconf-surround "\n" (plist-get talk :intro-note) "\n" ""))) + (emacsconf-filter-talks-by-track track info) + "\n"))) + +(defun emacsconf-publish-schedule-org-for-timezone (timezone &optional info) + (interactive (list (completing-read "Timezone: " emacsconf-timezones))) + (let ((new-filename (expand-file-name + (concat "schedule-" + (replace-regexp-in-string + "[^a-z]+" "-" + (downcase timezone)) + ".org") + (expand-file-name "schedules" + emacsconf-public-media-directory)))) + (unless (file-directory-p (file-name-directory new-filename)) + (make-directory (file-name-directory new-filename))) + (with-temp-file new-filename + (insert + "* " emacsconf-name " " emacsconf-year "\n\nTimes are in " timezone " timezone. You can find this file and other calendars at " + emacsconf-media-base-url emacsconf-year "/schedules/ .\n\n" + (mapconcat (lambda (track) + (emacsconf-publish-format-track-as-org track timezone info)) + emacsconf-tracks + "\n"))))) + +(defun emacsconf-publish-schedule-org-files (&optional info) + (interactive) + (setq info (or info (emacsconf-prepare-for-display (emacsconf-get-talk-info)))) + (mapc (lambda (tz) (emacsconf-publish-schedule-org-for-timezone tz info)) + emacsconf-timezones)) + (defun emacsconf-publish-format-res-talks (info) (mapconcat (lambda (o) diff --git a/emacsconf-stream.el b/emacsconf-stream.el index 8fdfcbc..5d8078d 100644 --- a/emacsconf-stream.el +++ b/emacsconf-stream.el @@ -151,11 +151,23 @@ while OTHER-FILENAME will be displayed at other times." (plist-get talk :overlay-url) (plist-get talk :overlay-bottom))))) +(defun emacsconf-stream-open-in-between-slide (talk) + (interactive (list (emacsconf-complete-talk-info))) + (let ((default-directory (emacsconf-stream-track-login talk))) + (shell-command (concat "firefox " (plist-get talk :in-between-url) "&")))) + +(defun emacsconf-stream-open-qa-slide (talk) + (interactive (list (emacsconf-complete-talk-info))) + (let ((default-directory (emacsconf-stream-track-login talk))) + (shell-command (concat "firefox " (plist-get talk :qa-slide-url) "&")))) + (defun emacsconf-stream-open-qa-windows-on-change (talk) (interactive (list (emacsconf-complete-talk-info))) (when (or (not (boundp 'org-state)) (string= org-state "CLOSED_Q")) - (let ((default-directory (emacsconf-stream-track-login talk))) - (save-window-excursion + (save-window-excursion + (if (or (null (plist-get talk :q-and-a)) + (string-match "Mumble" (plist-get talk :q-and-a))) + (emacsconf-stream-open-in-between-slide talk) (emacsconf-stream-open-pad talk) (emacsconf-stream-join-qa talk) (shell-command "i3-msg 'layout splith'"))))) @@ -169,8 +181,17 @@ while OTHER-FILENAME will be displayed at other times." (defun emacsconf-stream-play-talk-on-change (talk) "Play the talk." (when (string= org-state "PLAYING") - (save-window-excursion - (emacsconf-stream-play-video talk)))) + (if (plist-get talk :video-file) + (save-window-excursion + (emacsconf-stream-play-video talk)) + (let ((default-directory (emacsconf-stream-track-login talk)) + (async-shell-command-buffer 'new-buffer)) + (save-window-excursion + (shell-command + (concat "nohup firefox -new-window " + (shell-quote-argument + (plist-get talk :bbb-room)) + " > /dev/null 2>&1 & "))))))) (defun emacsconf-stream-get-filename (talk) "Return the local filename for the video file for TALK. @@ -210,16 +231,24 @@ Final files should be stored in /data/emacsconf/stream/YEAR/video-slug--main.web "Join the Q&A for TALK. This uses the BBB room if available, or the IRC channel if not." (interactive (list (emacsconf-complete-talk-info))) - (let ((default-directory (emacsconf-stream-track-login talk)) - (async-shell-command-buffer 'new-buffer)) - (save-window-excursion - (shell-command - (concat "nohup firefox -new-window " - (shell-quote-argument - (if (string-match (plist-get talk :q-and-a) "IRC") - (plist-get talk :webchat-url) - (plist-get talk :bbb-room))) - " > /dev/null 2>&1 & "))))) + (if (and (null (plist-get talk :video-file)) + (string-match "live" (plist-get talk :q-and-a))) + ;; do nothing, streamer should already be in the room + (let ((default-directory (emacsconf-stream-track-login talk)) + (async-shell-command-buffer 'new-buffer)) + (save-window-excursion + (shell-command + (concat "nohup firefox -new-window " + (shell-quote-argument + (pcase (plist-get talk :q-and-a) + ((or nil "" (rx "Mumble")) + (plist-get talk :qa-slide-url)) + ((rx "live") + (plist-get talk :bbb-backstage)) + ((rx "IRC") + (plist-get talk :webchat-url)) + (_ (plist-get talk :qa-slide-url)))) + " > /dev/null 2>&1 & ")))))) (defun emacsconf-stream-join-chat (talk) "Join the IRC chat for TALK." diff --git a/emacsconf.el b/emacsconf.el index bf117af..a08aa3b 100644 --- a/emacsconf.el +++ b/emacsconf.el @@ -100,9 +100,8 @@ (defun emacsconf-backstage-dired () (interactive) (dired emacsconf-backstage-dir "-tl")) -(defun emacsconf-res-dired () - (interactive) - (dired emacsconf-res-dir "-tl")) +(defun emacsconf-res-dired () (interactive) (dired emacsconf-res-dir "-tl")) +(defun emacsconf-media-dired () (interactive) (dired emacsconf-public-media-directory "-tl")) (defun emacsconf-cache-dired () (interactive) (dired emacsconf-cache-dir "-tl")) @@ -574,6 +573,15 @@ o) (defun emacsconf-add-live-info (o) + (plist-put o :absolute-url (concat emacsconf-base-url (plist-get o :url))) + (plist-put o :in-between-url (format "%s%s/in-between/%s.png" + emacsconf-media-base-url + emacsconf-year + (plist-get o :slug))) + (plist-put o :qa-slide-url (format "%s%s/in-between/%s.png" + emacsconf-media-base-url + emacsconf-year + (plist-get o :slug))) (let ((track (emacsconf-get-track (plist-get o :track)))) (when track (plist-put o :watch-url (concat emacsconf-base-url emacsconf-year "/watch/" (plist-get track :id)))) @@ -581,14 +589,20 @@ (plist-put o :webchat-url (concat emacsconf-chat-base "?join=emacsconf," (plist-get track :channel))) (plist-put o :bbb-backstage (concat emacsconf-media-base-url emacsconf-year "/backstage/current/room/" (plist-get o :slug))) (cond - ((string-match "live" (or (plist-get o :q-and-a) "")) + ((string= (or (plist-get o :q-and-a) "") "") + (plist-put o :qa-info "none") + (plist-put o :qa-link "none")) + ((string-match "live" (plist-get o :q-and-a)) (plist-put o :bbb-redirect (format "https://emacsconf.org/current/%s/room/" (plist-get o :slug))) (plist-put o :qa-info (plist-get o :bbb-redirect)) (plist-put o :qa-link (format "<a href=\"%s\">live</a>" (plist-get o :bbb-redirect)))) - ((string-match "IRC" (or (plist-get o :q-and-a) "")) + ((string-match "IRC" (plist-get o :q-and-a)) (plist-put o :qa-info (concat (emacsconf-surround "nick: " (plist-get o :irc) ", " "") (plist-get o :channel))) (plist-put o :qa-link (format "<a href=\"%s\">%s</a>" (plist-get o :webchat-url) (plist-get o :qa-info)))) + ((string-match "Mumble" (plist-get o :q-and-a)) + (plist-put o :qa-info "Moderated via Mumble, ask questions via pad or IRC") + (plist-put o :qa-link (format "<a href=\"%s\">%s</a>" (plist-get o :webchat-url) (plist-get o :qa-info)))) (t (plist-put o :qa-info "none") (plist-put o :qa-link "none"))) (plist-put o :pad-url (format "https://pad.emacsconf.org/%s-%s" emacsconf-year (plist-get o :slug))) @@ -1246,64 +1260,6 @@ tracks with the ID in the cdr of that list." "Indent S by WIDTH spaces." (replace-regexp-in-string "\\(^\\)[ \t]*\\S-" (make-string width ?\s) s nil nil 1)) -(defun emacsconf-shift-hyperlist (params talks &optional do-insert) - "Use PARAMS to personalize the shift hyperlist." - (mapconcat (lambda (talk) - (emacsconf-talk-hyperlist (append (assoc-default (plist-get (emacsconf-get-track talk) :id) - params) - talk) - do-insert)) - talks)) - -(defun emacsconf-talk-hyperlist (talk &optional do-insert) - (interactive (list (emacsconf-complete-talk-info) t)) - (let ((result - (emacsconf-replace-plist-in-string - talk - (format "- %s %s %s %s\n%s" - (format-time-string "%H:%M" (plist-get talk :start-time) emacsconf-timezone) - (plist-get talk :track) - (plist-get talk :slug) - (plist-get talk :title) - (replace-regexp-in-string - "\\(^\\)[ \t]*\\S-" " " - (pcase (or (plist-get talk :q-and-a) "") - ((rx "live") - "- [ ] ${checkin}: Check ${speakers-with-pronouns} (${irc}) into BBB room sometime beforehand -- [ ] ${stream}: Display the in-between slide -- [ ] ${host}: Connect to the ${track} channel in Mumble and introduce the talk -- [ ] ${stream}: [[elisp:(emacsconf-update-talk-status \"${slug}\" \".\" \"PLAYING\")][Play the talk]] -- [ ] ${host}: Join the Q&A room and open the pad; optionally open IRC for ${channel} -- [ ] [? speaker missing?] ${host}: Let #emacsconf-org know so that we can text or call the speaker -- [ ] ${stream}: After the talk, [[elisp:(emacsconf-update-talk-status \"${slug}\" \".\" \"CLOSED_Q\")][open the Q&A window and the pad]], give the host the go-ahead via Mumble or #emacsconf-org -- [ ] ${host}: Start recording and read questions -- [ ] ${host}: [[elisp:(emacsconf-update-talk-status \"${slug}\" \".\" \"OPEN_Q\")][Decide when to open the Q&A]] and announce that people can join using the URL on the talk page -- [? Open Q&A is still going on and it's about five minutes before the next talk] - - [ ] ${host}: Let the speaker know about the time and that the Q&A can continue off-stream if people want to join -- [? Open Q&A is still going on and it's about two minutes before the next talk] - - [ ] ${host}: Announce that the Q&A will continue if people want to join the BBB room from the talk page, and the stream will now move to the next talk -- [? Q&A is done] - - [ ] ${host}: [[elisp:(emacsconf-update-talk-status \"${slug}\" \".\" \"TO_ARCHIVE\")][Mark talk as to archive]], close Q&A windows -- [ ] ${stream}: Close the Q&A windows and move on to the next talk -") - ((rx "irc") - "- [ ] ${stream}: Display the in-between slide -- [ ] ${host}: Connect to the ${track} channel in Mumble and introduce the talk -- [ ] ${stream}: [[elisp:(emacsconf-update-talk-status \"${slug}\" \".\" \"PLAYING\")][Start talk]] -- [ ] ${stream}: [[elisp:(emacsconf-update-talk-status \"${slug}\" \".\" \"OPEN_Q\")][Open the IRC channel (${channel}) and the pad]] -- [ ] ${stream}: When it's time for the next talk, close the Q&A windows and move on to the next talk -") - (_ - "- [ ] ${stream}: Display the in-between slide -- [ ] ${host}: Connect to the ${track} channel in Mumble and introduce the talk -- [ ] ${stream}: [[elisp:(emacsconf-update-talk-status \"${slug}\" \".\" \"PLAYING\")][Start talk]] -- [ ] ${stream}: [[elisp:(emacsconf-update-talk-status \"${slug}\" \".\" \"OPEN_Q\")][Open the IRC channel (${channel}) and the pad]] -- [ ] ${stream}: When it's time for the next talk, close the Q&A windows and move on to the next talk -")) - nil nil 1))))) - (if do-insert (insert result)) - result)) - (defun emacsconf-add-to-logbook (note) "Add NOTE as a logbook entry for the current subtree." (move-marker org-log-note-return-to (point)) |