From 8fcb36f42440939835fd18809edd449f1191d42e Mon Sep 17 00:00:00 2001 From: Sacha Chua Date: Sun, 7 Dec 2025 12:49:25 -0500 Subject: updates --- emacsconf-hyperlist.el | 4 +-- emacsconf-pad.el | 70 ++++++++++++++++++------------------- emacsconf-publish.el | 93 ++++++++++++++++++++++++++++++++------------------ emacsconf.el | 28 ++++++--------- 4 files changed, 105 insertions(+), 90 deletions(-) diff --git a/emacsconf-hyperlist.el b/emacsconf-hyperlist.el index df1ed02..bbc3f41 100644 --- a/emacsconf-hyperlist.el +++ b/emacsconf-hyperlist.el @@ -138,7 +138,7 @@ (defun emacsconf-hyperlist-day-events (day &optional track info) (let* ((talks - (emacsconf-prepare-for-display + (emacsconf-publish-prepare-for-display (emacsconf-filter-talks-by-time (concat day "T00:00:00" emacsconf-timezone-offset) (concat day "T23:59:59" emacsconf-timezone-offset) @@ -163,7 +163,7 @@ (time-less-p (car a) (car b)))))) (defun emacsconf-hyperlist-format-streamer-day (day &optional track info) - (setq info (emacsconf-prepare-for-display + (setq info (emacsconf-publish-prepare-for-display (if info (mapcar #'emacsconf-resolve-talk info) (emacsconf-get-talk-info)))) (when track (setq info (emacsconf-filter-talks-by-track track info))) diff --git a/emacsconf-pad.el b/emacsconf-pad.el index 3078167..fe52fd1 100644 --- a/emacsconf-pad.el +++ b/emacsconf-pad.el @@ -369,7 +369,7 @@ ${next-talk-list} (replace-regexp-in-string "https://studio\\.youtube\\.com/video/\\([^/]+\\)/livestreaming" "https://youtube.com/live/\\1" (assoc-default "YouTube URL" shift-rtmp 'string=)) - :checkin-pad (concat emacsconf-pad-base "private-" emacsconf-private-pad-prefix "-checkin-" (downcase (format-time-string "%a" (date-to-time (plist-get shift :start))))))) + :checkin-pad (concat emacsconf-pad-base "private-" emacsconf-private-pad-prefix "-" emacsconf-year "-checkin-" (downcase (format-time-string "%a" (date-to-time (plist-get shift :start))))))) (shift-talks (mapcar (lambda (o) (append prefixed o)) (seq-filter @@ -489,7 +489,7 @@ ${next-talk-list} (plist-get talk :timezone) "%-l:%M %p")) "
  • OK to do other things until going live at ${live}
  • People will add questions to the pad or IRC channel; host can read them to you, or you can read them
  • @@ -528,7 +528,8 @@ ${bbb-checklist}") (emacsconf-publish-prepare-for-display (emacsconf-get-talk-info))))) (mapc (lambda (day) - (let ((pad-id (concat "private-" emacsconf-private-pad-prefix "-checkin-" (downcase (format-time-string "%a" (plist-get (cadr day) :checkin-time)))))) + (let ((base-pad (concat "private-" emacsconf-private-pad-prefix "-" emacsconf-year)) + (pad-id (concat "private-" emacsconf-private-pad-prefix "-" emacsconf-year "-checkin-" (downcase (format-time-string "%a" (plist-get (cadr day) :checkin-time)))))) (emacsconf-pad-create-pad pad-id) (emacsconf-pad-set-html pad-id @@ -536,17 +537,20 @@ ${bbb-checklist}") "${checkin}: " "" (concat (car day) + "\n" + emacsconf-pad-base base-pad "\n" "

    If anyone's still missing by the specified time, please let us know in #emacsconf-org so we can call them.

    " ""))))) (seq-group-by (lambda (talk) (format-time-string "%A, %b %-e, %Y" (plist-get talk :checkin-time))) @@ -691,6 +695,7 @@ ${bbb-checklist}") (format-time-string "%-l:%M %p" (plist-get talk :start-time) emacsconf-timezone)) (plist-get talk :hyperlist-note) "" "") :next-talk-in-5 (if next-talk (format-time-string "%-l:%M %p" (time-subtract (plist-get next-talk :start-time) (seconds-to-time 300)) emacsconf-timezone) "") + :next-talk-in-2 (if next-talk (format-time-string "%-l:%M %p" (time-subtract (plist-get next-talk :start-time) (seconds-to-time 120)) emacsconf-timezone) "") :next-talk-in-1 (if next-talk (format-time-string "%-l:%M %p" (time-subtract (plist-get next-talk :start-time) (seconds-to-time 60)) emacsconf-timezone) "")) talk) (concat @@ -698,7 +703,7 @@ ${bbb-checklist}") (if (emacsconf-talk-recorded-p talk) "
  • Backup: ${start-hhmm} ${slug}: it should play a prerecorded intro and talk, but if it doesn't, join ${mumble} in Mumble and introduce talk: ${expanded-intro} (pronunciation: ${pronunciation}); then play ${slug}
  • " ;; live talk, join BBB - "
  • ${start-hhmm} ${slug} live talk: it should play a prerecorded intro, but if it doesn't, join ${bbb-backstage} (mod code ${bbb-mod-code} ) and introduce talk, then turn it over to speaker for live talk: ${expanded-intro} (pronunciation: ${pronunciation})
  • ") + "
  • ${start-hhmm} ${slug} live talk: it should play a prerecorded intro, but if it doesn't, use mod code ${bbb-mod-code} to join ${bbb-backstage} and introduce talk, then turn it over to speaker for live talk: ${expanded-intro} (pronunciation: ${pronunciation})
  • ") ;; Q&A (if (and (not (emacsconf-talk-recorded-p talk)) (not (string= (or (plist-get talk :qa-type) "none") "none"))) @@ -716,7 +721,7 @@ ${bbb-checklist}") "
  • [ ] ${qa-hhmm} ${slug} Q&A mumble: Join ${mumble} in Mumble. Bring the speaker into the right channel if needed. Invite people to put their questions in the Etherpad and read questions and answers from there. ${pad-url} Paste questions into Mumble chat or read them out loud.
  • ") ((rx "live") (concat - "
  • [ ] ${qa-hhmm} ${slug} Q&A live (on stream until ${end-of-qa}): Join ${bbb-backstage} (mod code ${bbb-mod-code} ). START RECORDING. Invite people to put their questions in the Etherpad, and read questions from there. ${pad-url}
  • + "
  • [ ] ${qa-hhmm} ${slug} Q&A live (on stream until ${end-of-qa}): Use mod code ${bbb-mod-code} to join ${bbb-backstage} . START RECORDING. Invite people to put their questions in the Etherpad, and read questions from there. ${pad-url}
  • ${open-qa} " (if next-talk @@ -743,7 +748,8 @@ ${bbb-checklist}") (interactive) (emacsconf-pad-prepopulate-shift-hyperlists) (emacsconf-pad-prepopulate-checkins) - (emacsconf-pad-prepopulate-host-hyperlists)) + (emacsconf-pad-prepopulate-host-hyperlists) + (emacsconf-pad-prepopulate-index)) (defun emacsconf-pad-expand-intro (talk) "Make an intro for TALK." @@ -839,18 +845,18 @@ ${bbb-checklist}") (emacsconf-surround "
  • " (plist-get talk :hyperlist-note) "
  • " "") "
  • Recorded intro: ${media-base}${year}/backstage/${file-prefix}--intro.webm" (if (emacsconf-talk-recorded-p talk) - "
  • [ ] [? stream didn't auto-play] ${stream}: handle-session ${slug}; if that doesn't work, play ${slug}; if that still doesn't work, track-mpv ~/current/cache/${conf-id}-${year}-${slug}*--intro.webm and track-mpv ~/current/cache/${conf-id}-${year}-${slug}*--main.webm
  • " + "
  • [? stream didn't auto-play] ${stream}: handle-session ${slug}
  • " (concat "
  • Live talk:
  • ")) + "
  • [? stream didn't auto-join] ${stream}: mod code ${bbb-mod-code} ${bbb-backstage}
  • " + "
  • [ ] ${host}: mod code ${bbb-mod-code} , join ${bbb-backstage} and turn over to speaker.
  • ")) (pcase (or (plist-get talk :qa-type) "") ((rx "live") (concat "
  • Live Q&A start ${qa-start}, on stream until ${qa-end}
  • ")) ((rx "irc") " -
  • [ ] ${stream}: Update the task status, which should open the pad and IRC; arrange windows: ${ssh-closedq} -
  • -
  • [ ] ${stream}: Update the task status (no visible changes): ${ssh-openq}
  • -
  • [ ] ${host}: Announce that people can ask questions in the ${channel} IRC channel.
  • +
  • Backup link to pad: ${pad-url}
  • +
  • Backup link to #${channel}: ${webchat-url}
  • ") ((rx "Mumble") "
  • [ ] ${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)
  • [ ] ${stream}: Mark the Q&A as closed: ${ssh-closedq} . This should display the QA slide (backup: ${ssh-track} and run firefox ${qa-slide-url} &)
  • -
  • [ ] ${stream}: Update the task status (no visible changes): ${ssh-openq}
  • -
  • [ ] ${host}: Announce that people can ask questions in the pad or on the ${channel} IRC channel.
  • ") ((rx "after") " -
  • [ ] ${stream}: Update the task status: ${ssh-closedq} # this should open the pad and IRC; arrange the windows
  • [ ] ${host}: Announce that people can ask questions in the pad or on the ${channel} IRC channel, and that the speaker will follow up later.
  • -
  • [ ] ${stream}: Update the task status: ${ssh-openq} # this should not make any visible changes, just update the task status
  • " +" ) ((rx "pad") - "
  • [ ] [? pad didn't auto-open] ${stream}: ${pad-url}
  • ") + "
  • [? pad didn't auto-open] ${stream}: ${pad-url}
  • ") (_ "
  • [ ] ${stream}: Open the IRC channel (${channel}) and the pad, and arrange the windows: ${ssh-closedq}
  • ")))))) diff --git a/emacsconf-publish.el b/emacsconf-publish.el index 479de96..96d9232 100644 --- a/emacsconf-publish.el +++ b/emacsconf-publish.el @@ -159,7 +159,17 @@ :audio-html (or (plist-get video :audio) "") :chapter-list (or (plist-get video :chapter-list) "") :resources (or (plist-get video :resources) "") - :extra (or (plist-get talk :extra) "") + :extra + (concat + (if (plist-get talk :backstage) + ;; include schedule + (concat + "Starts: " + (format-time-string "%-I:%M %#p" + (plist-get talk :start-time)) + " - Q&A: " (plist-get talk :q-and-a) "\n") + "") + (or (plist-get talk :extra) "")) :speaker-info (or (plist-get talk :speakers-with-pronouns) "")))) (emacsconf-replace-plist-in-string talk @@ -204,6 +214,7 @@ (plist-get track :watch) "web-based player") "\n" + "- You can also watch it in VLC by choosing menu - Media - Open Network Stream and putting in " (plist-get track :stream) "\n" (emacsconf-surround "- Q&A: " (if (plist-get talk :qa-url) (org-make-link-string @@ -470,6 +481,10 @@ (and (plist-get talk :backstage) (plist-get talk :bbb-backstage)) "\">Open backstage BigBlueButton" "") + (emacsconf-surround "
  • BBB mod code: " + (and (plist-get talk :backstage) + (plist-get talk :bbb-mod-code)) + "
  • " "") (emacsconf-surround "
  • Play recording from BigBlueButton
  • " "")) :files @@ -1889,25 +1904,31 @@ ${include} "")))) (defun emacsconf-publish-link-file-formats-as-list (talk) - (seq-map - (lambda (file) - (let ((cache-file (expand-file-name (file-name-nondirectory file) emacsconf-cache-dir))) - (format "Download %s%s%s" - (or (plist-get talk :base-url) "") - (file-name-nondirectory file) - (replace-regexp-in-string (concat "^" (regexp-quote (plist-get talk :file-prefix))) "" (file-name-nondirectory file)) - (if (and (file-exists-p cache-file) - (> (file-attribute-size (file-attributes cache-file)) 1000000)) - (format " (%sB)" (file-size-human-readable (file-attribute-size (file-attributes cache-file)))) - "") - (if (and (string-match "--\\(main\\|answers\\)\\.vtt" file) - (not (emacsconf-captions-edited-p (expand-file-name file emacsconf-cache-dir)))) - " (unedited)" - "")))) - (or (plist-get talk :files) - (if (plist-get talk :backstage) - (emacsconf-publish-talk-files talk) - (emacsconf-publish-filter-public-files talk))))) + (let ((public-files (emacsconf-publish-filter-public-files talk))) + (seq-map + (lambda (file) + (let ((cache-file (expand-file-name (file-name-nondirectory file) emacsconf-cache-dir))) + (format "Download %s%s%s%s" + (or (plist-get talk :base-url) "") + (file-name-nondirectory file) + (replace-regexp-in-string (concat "^" (regexp-quote (plist-get talk :file-prefix))) "" (file-name-nondirectory file)) + (if (and (file-exists-p cache-file) + (> (file-attribute-size (file-attributes cache-file)) 1000000)) + (format " (%sB)" (file-size-human-readable (file-attribute-size (file-attributes cache-file)))) + "") + (if (and (string-match "--\\(main\\|answers\\)\\.vtt" file) + (not (emacsconf-captions-edited-p (expand-file-name file emacsconf-cache-dir)))) + " (unedited)" + "") + (if (and (plist-get talk :backstage) + (not (member file public-files))) + " (backstage)" + "") + ))) + (or (plist-get talk :files) + (if (plist-get talk :backstage) + (emacsconf-publish-talk-files talk) + public-files))))) (defun emacsconf-publish-talks-json () "Return JSON format with a subset of talk information." @@ -2219,11 +2240,11 @@ This video is available under the terms of the Creative Commons Attribution-Shar (interactive (list (emacsconf-complete-talk-info (seq-remove (lambda (talk) - (or (not (emacsconf-talk-file talk "--main.webm")) + (or (not (plist-get talk :video-file)) (plist-get talk :youtube-url))) (emacsconf-get-talk-info))))) - (kill-new (emacsconf-talk-file talk "--main.webm")) - (y-or-n-p (format "Video: %s - create video and upload this filename. Done?" (emacsconf-talk-file talk "--main.webm"))) + (kill-new (plist-get talk :video-file)) + (y-or-n-p (format "Video: %s - create video and upload this filename. Done?" (plist-get talk :video-file))) (kill-new (emacsconf-publish-video-description talk t)) (y-or-n-p "Copied description. Paste into description, move first line to title, add to playlist. Done?") (when (emacsconf-talk-file talk "--main.vtt") @@ -2239,26 +2260,26 @@ This video is available under the terms of the Creative Commons Attribution-Shar (catch 'done (while t (let ((talk (seq-find (lambda (o) - (and (member (plist-get o :status) '("TO_STREAM" "TO_CHECK" "PLAYING")) + (and (member (plist-get o :status) '("TO_STREAM" "TO_CHECK" "PLAYING" "TO_ARCHIVE")) (not (plist-get o :youtube-url)) - (emacsconf-talk-file o "--main.webm"))) + (plist-get o :video-file))) (emacsconf-publish-prepare-for-display (emacsconf-get-talk-info))))) (unless talk (message "All done so far.") (throw 'done t)) - (emacsconf-youtube-step-through-publishing talk))))) + (emacsconf-publish-youtube-step-through-publishing-talk talk))))) (defun emacsconf-publish-toobnix-step-through-publishing-talk (talk) (interactive (list (emacsconf-complete-talk-info (seq-remove (lambda (talk) - (or (not (emacsconf-talk-file talk "--main.webm")) + (or (not (plist-get talk :video-file)) (plist-get talk :toobnix-url))) (emacsconf-get-talk-info))))) - (kill-new (emacsconf-talk-file talk "--main.webm")) + (kill-new (plist-get talk :video-file)) (y-or-n-p (format "Video: %s - create video and upload this filename. Done?" - (emacsconf-talk-file talk "--main.webm"))) + (plist-get talk :video-file))) (kill-new (emacsconf-publish-video-description talk t)) (y-or-n-p "Copied description. Paste into description, move first line to title, add to playlist. Done?") (when (emacsconf-talk-file talk "--main.vtt") @@ -2281,7 +2302,7 @@ This video is available under the terms of the Creative Commons Attribution-Shar (unless talk (message "All done so far.") (throw 'done t)) - (emacsconf-toobnix-step-through-publishing-talk talk))))) + (emacsconf-publish-toobnix-step-through-publishing-talk talk))))) ;; (emacsconf-publish-video-description (emacsconf-find-talk-info "async") t) @@ -2303,7 +2324,8 @@ This video is available under the terms of the Creative Commons Attribution-Shar (emacsconf-with-talk-heading talk (let* ((video-file-name (emacsconf-get-preferred-video (plist-get talk :file-prefix))) (video-file (and video-file-name (expand-file-name video-file-name emacsconf-cache-dir))) - (qa-file (emacsconf-talk-file talk "--answers.webm")) + (qa-file (or (emacsconf-talk-file talk "--answers.webm") + (emacsconf-get-preferred-video (concat (plist-get talk :file-prefix) "--answers")))) (intro-file (expand-file-name (concat (plist-get talk :slug) ".webm") (expand-file-name "intros" emacsconf-stream-asset-dir))) duration) @@ -2329,7 +2351,7 @@ This video is available under the terms of the Creative Commons Attribution-Shar (org-entry-delete (point) "VIDEO_DURATION") (org-entry-delete (point) "VIDEO_TIME") (org-entry-delete (point) "CAPTIONS_EDITED")) - (if qa-file + (if (and qa-file (file-exists-p qa-file)) (progn (org-entry-put (point) "QA_VIDEO_FILE" (file-name-nondirectory qa-file)) (org-entry-put (point) "QA_VIDEO_FILE_SIZE" (file-size-human-readable (file-attribute-size (file-attributes qa-file)))) @@ -2552,6 +2574,7 @@ For better performance, we recommend watching ${stre
  • mpv ${stream-hires}
  • vlc ${stream-hires}
  • ffplay ${stream-hires}
  • +
  • You can also watch it in VLC by choosing menu - Media - Open Network Stream and putting in " (plist-get track :stream) "
  • If you have limited bandwidth, you can watch the low-res stream
    ${480p}. @@ -2655,6 +2678,8 @@ vlc https://live0.emacsconf.org/gen.webm ffplay https://live0.emacsconf.org/gen.webm +

    You can also watch it in VLC by using menu - Media - Open Network Stream and putting in https://live0.emacsconf.org/gen.webm

    . +

    If you experience any disruptions, try reloading the page you're using to watch the video. If that still doesn't work, please check our status page at https://status.emacsconf.org for updates on the diff --git a/emacsconf.el b/emacsconf.el index 417f4ae..8f1da84 100644 --- a/emacsconf.el +++ b/emacsconf.el @@ -138,7 +138,7 @@ (defvar emacsconf-backstage-dir "/ssh:orga@media.emacsconf.org:/var/www/media.emacsconf.org/2022/backstage") (defvar emacsconf-upload-dir "/ssh:orga@media.emacsconf.org:/srv/upload") (defvar emacsconf-res-dir (format "/ssh:orga@res.emacsconf.org:/data/emacsconf/shared/%s" emacsconf-year)) -(defvar emacsconf-media-extensions '("webm" "mkv" "mp4" "webm" "mov" "avi" "mpv" "ts" "ogv" "wav" "ogg" "mp3" )) +(defvar emacsconf-media-extensions '("webm" "mkv" "mp4" "m4v" "mov" "avi" "mpv" "ts" "ogv" "wav" "ogg" "mp3" )) (defvar emacsconf-ftp-upload-dir "/ssh:orga@media.emacsconf.org:/srv/ftp/anon/upload-here") (defvar emacsconf-backstage-user "emacsconf") (defvar emacsconf-backstage-password nil "Password for backstage area.") @@ -1493,9 +1493,9 @@ If TIMEZONES is a string, split it by commas." :webchat-url "https://chat.emacsconf.org/?join=emacsconf,emacsconf-org,emacsconf-accessible,emacsconf-dev,emacsconf-gen" :stream ,(concat emacsconf-stream-base "gen.webm") :480p ,(concat emacsconf-stream-base "gen-480p.webm") - ;; :youtube-url "https://www.youtube.com/watch?v=UEJ88c7MJq0" - ;; :youtube-studio-url "https://studio.youtube.com/video/UEJ88c7MJq0/livestreaming" - ;; :toobnix-url "https://toobnix.org/w/7t9X8eXuSby8YpyEKTb4aj" + :youtube-url "https://www.youtube.com/live/FI3eGeGCyQM" + :youtube-studio-url "https://studio.youtube.com/video/FI3eGeGCyQM/livestreaming" + :toobnix-url "https://toobnix.org/w/oLwaPU7MgMFDAWPhaFdW1t" :start "09:00" :end "17:00" :uid 2002 :vnc-display ":5" @@ -1504,11 +1504,11 @@ If TIMEZONES is a string, split it by commas." :status "online") (:name "Development" :color "skyblue" :id "dev" :channel "emacsconf-dev" :watch ,(format "https://live.emacsconf.org/%s/watch/dev/" emacsconf-year) - :webchat-url "https://chat.emacsconf.org/?join=emacsconf,emacsconf-org,emacsconf-accessible,emacsconf-gen,emacsconf-dev" + :webchat-url "https://chat.emacsconf.org/?join=emacsconf,emacsconf-org,emacsconf-accessible,emacsconf-gen,emacsconf-de" :tramp "/ssh:emacsconf-dev@res.emacsconf.org#46668:" - ;; :toobnix-url "https://toobnix.org/w/w6K77y3bNMo8xsNuqQeCcD" - ;; :youtube-url "https://www.youtube.com/watch?v=PMaoF-xa1b4" - ;; :youtube-studio-url "https://studio.youtube.com/video/PMaoF-xa1b4/livestreaming" + :toobnix-url "https://toobnix.org/w/uXGmcRigZD82UWr5nehKeL" + :youtube-url "https://youtube.com/live/KCZthyBhHtg" + :youtube-studio-url "https://studio.youtube.com/video/KCZthyBhHtg/livestreaming" :stream ,(concat emacsconf-stream-base "dev.webm") :480p ,(concat emacsconf-stream-base "dev-480p.webm") :uid 2003 @@ -1773,16 +1773,8 @@ Room.all.each { |x| puts x.friendly_id + " " + x.name }; nil (defun emacsconf-volunteer-insert-email (&optional info) (interactive) - (insert (completing-read - (mapcar - (lambda (o) - (emacsconf-surround - (if (assoc-default "ITEM" o) - (concat (assoc-default "ITEM" o) " <") - "<") - (assoc-default "EMAIL" o) - ">" "")) - (or info (emacsconf-get-volunteer-info)))))) + (insert (assoc-default "EMAIL" (emacsconf-complete-volunteer info) #'string=))) + (defun emacsconf-complete-volunteer (&optional info) (setq info (or info (emacsconf-get-volunteer-info))) (let* ((choices -- cgit v1.2.3