summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSacha Chua <sacha@sachachua.com>2023-11-19 16:09:12 -0500
committerSacha Chua <sacha@sachachua.com>2023-11-19 16:09:12 -0500
commit250f05ad5dddf75a670b6583bf2c377869f912ba (patch)
treefe936cbfe3fa0247e5588196ddaf45e489f60756
parentba6b92500dae792e34dd163514d7c2b631c659d1 (diff)
downloademacsconf-el-250f05ad5dddf75a670b6583bf2c377869f912ba.tar.xz
emacsconf-el-250f05ad5dddf75a670b6583bf2c377869f912ba.zip
backstage tweaks
-rw-r--r--emacsconf-publish.el245
1 files changed, 125 insertions, 120 deletions
diff --git a/emacsconf-publish.el b/emacsconf-publish.el
index 95cfecc..f0388d8 100644
--- a/emacsconf-publish.el
+++ b/emacsconf-publish.el
@@ -336,6 +336,16 @@
:video-id video-id
:video-file-size (if (and (stringp video-file) (file-exists-p video-file))
(file-size-human-readable (file-attribute-size (file-attributes video-file))))
+ :links
+ (concat
+ (emacsconf-surround "<li><a href=\"" (plist-get talk :pad-url) "\">Open Etherpad</a></li>" "")
+ (emacsconf-surround "<li><a href=\""
+ (and (plist-get talk :backstage) (plist-get talk :bbb-room)
+ (plist-get talk :bbb-backstage))
+ "\">Open backstage BigBlueButton</a></li>" "")
+ (emacsconf-surround "<li><a href=\""
+ (plist-get talk :qa-url)
+ "\">Open public Q&A</a></li>" ""))
:other-files
(mapconcat
(lambda (s)
@@ -373,7 +383,7 @@
:resources
(emacsconf-replace-plist-in-string
info
- "<div class=\"files resources\"><ul>${other-files}${toobnix-info}</ul></div>"))))
+ "<div class=\"files resources\"><ul>${links}${other-files}${toobnix-info}</ul></div>"))))
(defun emacsconf-publish-format-public-email (o &optional email)
(format "[%s](mailto:%s?subject=%s)"
@@ -503,21 +513,16 @@ resources."
:format
(concat (or (plist-get o :video-time)
(plist-get o :time))
- "-min talk"
- (if (plist-get o :q-and-a)
- (format " followed by %s Q&A%s"
- (plist-get o :q-and-a)
- (if (eq emacsconf-publishing-phase 'conference)
- (format " (%s)"
- (if (string-match "live" (plist-get o :q-and-a))
- (if (eq 'after (emacsconf-bbb-status o))
- "done"
- (format "<https://emacsconf.org/current/%s/room>" (plist-get o :slug)))
- (emacsconf-publish-webchat-link o)))
- ""))
- ""))
+ "-min talk; Q&A: "
+ (pcase (plist-get o :qa-type)
+ ("none" "ask questions via Etherpad/IRC; we'll e-mail the speaker and post answers on this wiki page after the conference")
+ ("live" "BigBlueButton conference room")
+ ("pad" "Etherpad")
+ ("irc" "IRC")
+ (_ (plist-get o :qa-type)))
+ (emacsconf-surround " <" (plist-get o :qa-url) ">" ""))
:pad-info
- (if emacsconf-publish-include-pads
+ (if (and emacsconf-publish-include-pads (not (string= (plist-get o :qa-type) "etherpad")))
(format "Etherpad: <https://pad.emacsconf.org/%s-%s> \n" emacsconf-year (plist-get o :slug))
"")
:irc-info
@@ -1105,7 +1110,18 @@ Use FILES as the file list, or look in the cache directory."
(directory-files emacsconf-cache-dir))))
(defun emacsconf-sum (field talks)
- (apply '+ (seq-map (lambda (talk) (string-to-number (or (plist-get talk field) "0"))) talks)))
+ (apply '+ (seq-map (lambda (talk)
+ (string-to-number
+ (or
+ (if (listp field)
+ (car
+ (seq-keep
+ (lambda (f)
+ (plist-get talk f))
+ field))
+ (plist-get talk field))
+ "0")))
+ talks)))
(defun emacsconf-publish-backstage-org-on-state-change (talk)
(save-window-excursion
@@ -1120,102 +1136,64 @@ Use FILES as the file list, or look in the cache directory."
(when (member org-state '("WAITING_FOR_PREREC" "TO_ASSIGN" "TO_CAPTION" "TO_STREAM"))
(emacsconf-publish-backstage-index)))))
-(defun emacsconf-publish-backstage-processing (by-status files)
- (let ((list (append
- (assoc-default "TO_PROCESS" by-status)
- (assoc-default "PROCESSING" by-status)
- (assoc-default "TO_AUTOCAP" by-status))))
- (format "<h1>%s talk(s) being processed (%d minutes)</h1>Not ready for captioning yet, but they will be eventually<ul class=\"videos\">%s</ul>"
- (length list)
- (emacsconf-sum :video-time list)
- (mapconcat
- (lambda (f)
- (setq f (append
- f
- (list :extra
- (if (plist-get f :caption-note) (concat "<div class=\"caption-note\">" (plist-get f :caption-note) "</div>") "")
- :files
- (emacsconf-publish-talk-files f files))))
- (format "<li><a name=\"%s\"></a><strong><a href=\"%s\">%s</a></strong><br />%s (id:%s)<br />%s</li>"
- (plist-get f :slug)
- (plist-get f :absolute-url)
- (plist-get f :title)
- (plist-get f :speakers)
- (plist-get f :slug)
- (emacsconf-publish-index-card f)))
- list
- "\n"))))
-
(defun emacsconf-publish-backstage-to-assign (by-status files)
- (let ((list (assoc-default "TO_ASSIGN" by-status)))
- (format "<h1>%s talk(s) to be captioned, waiting for volunteers (%d minutes)</h1><p>You can e-mail <a href=\"mailto:sacha@sachachua.com\">sacha@sachachua.com</a> to call dibs on editing the captions for one of these talks. We use OpenAI Whisper to provide auto-generated VTT that you can use as a starting point, but you can also write the captions from scratch if you like. The starting point for the main video ends in --main.vtt. If you're writing the captions from scratch, you can choose to include timing information, or we can probably figure them out afterwards with a forced alignment tool. More info: <a href=\"https://emacsconf.org/captioning/\">captioning tips</a></p><ul class=\"videos\">%s</ul>"
- (length list)
- (emacsconf-sum :video-time list)
- (mapconcat
- (lambda (f)
- (setq f (append
- f
- (list :extra
- (if (plist-get f :caption-note) (concat "<div class=\"caption-note\">" (plist-get f :caption-note) "</div>") "")
- :files
- (emacsconf-publish-talk-files f files))))
- (format "<li><a name=\"%s\"></a><strong><a href=\"%s\">%s</a></strong><br />%s (id:%s)<br />%s</li>"
- (plist-get f :slug)
- (plist-get f :absolute-url)
- (plist-get f :title)
- (plist-get f :speakers)
- (plist-get f :slug)
- (emacsconf-publish-index-card f)))
- list
- "\n"))))
+ (emacsconf-publish-backstage-list
+ (assoc-default "TO_ASSIGN" by-status)
+ files
+ "to be captioned, waiting for volunteers"
+ "<p>You can e-mail <a href=\"mailto:sacha@sachachua.com\">sacha@sachachua.com</a> to call dibs on editing the captions for one of these talks. We use OpenAI Whisper to provide auto-generated VTT that you can use as a starting point, but you can also write the captions from scratch if you like. The starting point for the main video ends in --main.vtt. If you're writing the captions from scratch, you can choose to include timing information, or we can probably figure them out afterwards with a forced alignment tool. More info: <a href=\"https://emacsconf.org/captioning/\">captioning tips</a></p>"
+ (lambda (f)
+ (append
+ f
+ (list :extra
+ (if (plist-get f :caption-note) (concat "<div class=\"caption-note\">" (plist-get f :caption-note) "</div>") "")
+ :files
+ (emacsconf-publish-talk-files f files))))))
(defun emacsconf-publish-backstage-to-caption (by-status files)
+ (emacsconf-publish-backstage-list
+ (assoc-default "TO_CAPTION" by-status)
+ files
+ "being captioned"
+ "People are working on these ones, yay! <a href=\"https://emacsconf.org/captioning\">Captioning process/tips</a>"
+ (lambda (f)
+ (append
+ f
+ (list :extra
+ (concat "<div class=\"caption-note\">"
+ (emacsconf-surround "Being captioned by " (plist-get f :captioner) " " "")
+ (emacsconf-surround "Note: " (plist-get f :caption-note) "" "")
+ "</div>")
+ :files
+ (emacsconf-publish-talk-files f files))))))
+
+(defun emacsconf-publish-backstage-list (talks files header-description &optional description modify-func)
+ "Display a list of TALKS.
+Use the files listed in FILES.
+Start the header with HEADER-DESCRIPTION.
+If MODIFY-FUNC is specified, use it to modify the talk."
(format
- "<h1>%d talk(s) being captioned (%s minutes)</h1>People are working on these ones, yay!<ul>%s</ul>"
- (length (assoc-default "TO_CAPTION" by-status))
- (emacsconf-sum :video-time (assoc-default "TO_CAPTION" by-status))
- (mapconcat
- (lambda (f)
- (setq f (append
- f
- (list :extra
- (concat "<div class=\"caption-note\">"
- (emacsconf-surround "Being captioned by " (plist-get f :captioner) " " "")
- (emacsconf-surround "Note: " (plist-get f :caption-note) "" "")
- "</div>")
- :files
- (emacsconf-publish-talk-files f files))))
- (format "<li><a name=\"%s\"></a><strong><a href=\"%s%s\">%s</a></strong><br />%s (id:%s)<br />%s</li>"
- (plist-get f :slug)
- emacsconf-base-url
- (plist-get f :url)
- (plist-get f :title)
- (plist-get f :speakers-with-pronouns)
- (plist-get f :slug)
- (emacsconf-publish-index-card f)))
- (assoc-default "TO_CAPTION" by-status)
- "\n")))
-
-(defun emacsconf-publish-backstage-to-stream (by-status files)
- (format
- "<h1>%d captioned talk(s) ready for enjoyment (%d minutes)</h1><ol class=\"videos\">%s</ol>"
- (length (assoc-default "TO_STREAM" by-status))
- (emacsconf-sum :video-time (assoc-default "TO_STREAM" by-status))
- (mapconcat (lambda (f)
- (format "<li><a name=\"%s\"></a><strong><a href=\"%s%s\">%s</a></strong><br />%s (id:%s)<br />%s</li>"
- (plist-get f :slug)
- emacsconf-base-url
- (plist-get f :url)
- (plist-get f :title)
- (plist-get f :speakers-with-pronouns)
- (plist-get f :slug)
- (emacsconf-publish-index-card (append f
- (list :extra
- (concat "Captioned by " (plist-get f :captioner))
- :files (emacsconf-publish-talk-files f files))))))
- (assoc-default "TO_STREAM" by-status) "\n")))
+ "<h1>%d talk(s) %s (%d minutes)</h1>%s<ol class=\"videos\">%s</ol>"
+ (length talks)
+ header-description
+ (emacsconf-sum '(:video-time :time) talks)
+ (or description "")
+ (mapconcat (lambda (f)
+ (format "<li><a name=\"%s\"></a><strong><a href=\"%s%s\">%s</a></strong><br />%s (id:%s)<br />%s</li>"
+ (plist-get f :slug)
+ emacsconf-base-url
+ (plist-get f :url)
+ (plist-get f :title)
+ (plist-get f :speakers-with-pronouns)
+ (plist-get f :slug)
+ (emacsconf-publish-index-card
+ (if (functionp modify-func)
+ (funcall modify-func f)
+ f))))
+ talks "\n")))
(defun emacsconf-publish-backstage-index (&optional filename)
+ "Render the backstage index to FILENAME."
(interactive)
(setq filename (or filename (expand-file-name "index.html" emacsconf-backstage-dir)))
(let ((info (or emacsconf-schedule-draft (emacsconf-publish-prepare-for-display (emacsconf-get-talk-info)))))
@@ -1223,7 +1201,8 @@ Use FILES as the file list, or look in the cache directory."
(let* ((talks
(mapcar
(lambda (o) (append
- (list :captions-edited t) o))
+ (list :captions-edited t
+ :backstage t) o))
(seq-filter (lambda (o) (plist-get o :speakers))
(emacsconf-active-talks (emacsconf-filter-talks info)))))
(by-status (seq-group-by (lambda (o) (plist-get o :status)) talks))
@@ -1259,7 +1238,7 @@ Use FILES as the file list, or look in the cache directory."
"TO_ASSIGN (waiting for captioning volunteers)"
status)
(length (assoc-default status by-status))
- (emacsconf-sum :video-time (assoc-default status by-status))
+ (emacsconf-sum '(:video-time :time) (assoc-default status by-status))
(mapconcat (lambda (o) (format "<a href=\"#%s\">%s</a>%s"
(plist-get o :slug)
(plist-get o :slug)
@@ -1267,17 +1246,31 @@ Use FILES as the file list, or look in the cache directory."
(assoc-default status by-status)
", ")))
(pcase emacsconf-backstage-phase
- ('prerec '("PROCESSING" "TO_ASSIGN" "TO_CAPTION" "TO_STREAM"))
+ ('prerec '("WAITING_FOR_PREREC" "PROCESSING" "TO_ASSIGN" "TO_CAPTION" "TO_STREAM"))
('harvest '("TO_ARCHIVE" "TO_REVIEW_QA" "TO_INDEX_QA" "TO_CAPTION_QA")))
"")
"</ul>"
(pcase emacsconf-backstage-phase
('prerec
(concat
- (emacsconf-publish-backstage-processing by-status files)
+ (emacsconf-publish-backstage-list
+ (append
+ (assoc-default "TO_PROCESS" by-status)
+ (assoc-default "PROCESSING" by-status)
+ (assoc-default "TO_AUTOCAP" by-status))
+ files
+ "being processed"
+ "Not ready for captioning yet, but they will be eventually")
(emacsconf-publish-backstage-to-assign by-status files)
(emacsconf-publish-backstage-to-caption by-status files)
- (emacsconf-publish-backstage-to-stream by-status files)))
+ (emacsconf-publish-backstage-list
+ (assoc-default "TO_STREAM" by-status)
+ files
+ "ready to be streamed")
+ (emacsconf-publish-backstage-list
+ (assoc-default "WAITING_FOR_PREREC" by-status) files
+ "we're waiting for"
+ "Speakers might submit these, do them live, or cancel the talks.")))
('harvest
(let ((stages
'(("TO_REVIEW_QA" .
@@ -1720,6 +1713,16 @@ ${include}
(save-buffer)))
(browse-url-of-file "pad-template.html"))
+(defun emacsconf-publish-format-files-as-playlist (playlist-name files)
+ (format "#EXTM3U\n#PLAYLIST: %s\n#EXTALB: %s\n#EXTGENRE: Speech\n%s"
+ playlist-name playlist-name
+ (mapconcat
+ (lambda (file)
+ (format "#EXTINF:-1,%s\n%s\n"
+ file
+ file))
+ files
+ "")))
(defun emacsconf-publish-playlist (filename playlist-name talks &optional base-url)
(with-temp-file filename
@@ -1747,6 +1750,7 @@ ${include}
"")))))
(defun emacsconf-get-preferred-video (file-prefix &optional files)
+ (when (listp file-prefix) (setq file-prefix (plist-get file-prefix :file-prefix)))
(or
(car
(mapcar
@@ -1763,11 +1767,13 @@ ${include}
(expand-file-name (concat file-prefix "--" suffix ".webm")
emacsconf-cache-dir))
'("main" "captioned" "normalized" "reencoded" "compressed" "original")))
- (car (directory-files emacsconf-cache-dir
- nil
- (concat (regexp-quote file-prefix)
- ".*\\."
- (regexp-opt emacsconf-media-extensions))))))
+ (car
+ (seq-remove (lambda (o) (string-match "--intro" o))
+ (directory-files emacsconf-cache-dir
+ nil
+ (concat (regexp-quote file-prefix)
+ ".*\\."
+ (regexp-opt emacsconf-media-extensions)))))))
(defun emacsconf-check-video-formats ()
(interactive)
@@ -1862,10 +1868,9 @@ This video is available under the terms of the Creative Commons Attribution-Shar
emacsconf-cache-dir)))
(when (emacsconf-captions-edited-p caption-file)
(org-entry-put (point) "CAPTIONS_EDITED" "1"))))
- (unless (plist-get talk :video-duration)
- (setq duration (/ (compile-media-get-file-duration-ms video-file) 1000))
- (org-entry-put (point) "VIDEO_DURATION" (format-seconds "%h:%z%.2m:%.2s" duration))
- (org-entry-put (point) "VIDEO_TIME" (number-to-string (ceiling (/ duration 60))))))
+ (setq duration (/ (compile-media-get-file-duration-ms video-file) 1000))
+ (org-entry-put (point) "VIDEO_DURATION" (format-seconds "%h:%z%.2m:%.2s" duration))
+ (org-entry-put (point) "VIDEO_TIME" (number-to-string (ceiling (/ duration 60)))))
(when qa-file
(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))))