diff options
-rw-r--r-- | emacsconf-pad.el | 43 | ||||
-rw-r--r-- | emacsconf-publish.el | 206 | ||||
-rw-r--r-- | emacsconf-schedule.el | 13 | ||||
-rw-r--r-- | emacsconf-stream.el | 37 | ||||
-rw-r--r-- | emacsconf.el | 3 |
5 files changed, 211 insertions, 91 deletions
diff --git a/emacsconf-pad.el b/emacsconf-pad.el index 4d319cd..abe8d64 100644 --- a/emacsconf-pad.el +++ b/emacsconf-pad.el @@ -372,7 +372,7 @@ ${next-talk-list} :year emacsconf-year) shift) (concat - "Back to ${index}<br />In case of ...: https://emacsconf.org/${year}/organizers-notebook/#exceptions<br />" + "Back to ${index}<br />In case of ...: https://pad.emacsconf.org/exceptions<br />" "<h1><strong>" (plist-get shift :id) "</strong></h1>" "<p>Host: ${host}, Streamer: ${streamer}, IRC: ${irc}, Pad: ${pad}, Check-in: ${checkin}, Coord: ${coord}</p>")) (emacsconf-replace-plist-in-string @@ -456,11 +456,11 @@ ${next-talk-list} (emacsconf-surround " (" (plist-get talk :irc) ")" "") "</strong>") :time - (format-time-string "%H:%M" (plist-get talk :checkin-time) emacsconf-timezone) + (format-time-string "%-l:%M %p" (plist-get talk :checkin-time) emacsconf-timezone) :live - (format-time-string "%H:%M" (plist-get talk :live-time) emacsconf-timezone) + (format-time-string "%-l:%M %p" (plist-get talk :live-time) emacsconf-timezone) :start - (format-time-string "%H:%M" (plist-get talk :start-time) emacsconf-timezone) + (format-time-string "%-l:%M %p" (plist-get talk :start-time) emacsconf-timezone) :bbb-checklist (emacsconf-replace-plist-in-string (list :backstage-url-with-password (emacsconf-backstage-url (plist-get talk :bbb-backstage)) @@ -469,7 +469,12 @@ ${next-talk-list} (concat (emacsconf-surround "" (plist-get talk :pronunciation) " or listen to " "Refer to ") (format "%s%s/backstage/%s--intro.webm" emacsconf-media-base-url emacsconf-year (plist-get talk :file-prefix))) :backstage-password emacsconf-backstage-password - :backstage-url (plist-get talk :bbb-backstage)) + :backstage-url (plist-get talk :bbb-backstage) + :live + (emacsconf-timezone-strings-combined + (plist-get talk :live-time) + (plist-get talk :timezone) + "%-l:%M %p")) "<ul> <li>Message for the speaker: Thanks for checking in! Your BigBlueButton web conference room is at ${backstage-url}. If you don't have the backstage username and password saved, let me know and I can send you a direct message with the info. Please join me there so that I can set you as a moderator and go through the preflight checklist with you. <li>Direct message for the speaker if needed: Your BigBlueButton web conference room is at ${backstage-url-with-password}, or username \"${backstage-user}\" and password \"${backstage-password}\".</li> @@ -483,7 +488,7 @@ ${next-talk-list} <ul><li>[ ] Window or screen can be shared <li>[ ] Text is readable</li></ul> <li>[ ] Webcam sharing (optional)</li></ul></li> -<li>OK to do other things until the prerec ends</li> +<li>OK to do other things until going live at <strong>${live}</strong></li> <li>People will add questions to the pad or IRC channel; host can read them to you, or you can read them</li> <li>You can answer questions in any order, and you can skip questions if you want. Feel free to take your time to think about answers or to save some for following up later</li> <li>Host and streamer will join after prerec ends and give you the signal when you're good to go</li> @@ -573,7 +578,7 @@ ${bbb-checklist}</li>") "") ) - "<p>Things to do in case of... ${base-url}${year}/organizers-notebook/#exceptions</p> + "<p>Things to do in case of... https://pad.emacsconf.org/exceptions</p> <div>Checkin: <ul>${checkin-list}</ul></div> @@ -640,25 +645,25 @@ ${bbb-checklist}</li>") (let ((next-talk (car (plist-get talk :next-talks)))) (emacsconf-replace-plist-in-string (append - (list :start-hhmm (format-time-string "%H:%M" (plist-get talk :start-time) emacsconf-timezone) + (list :start-hhmm (format-time-string "%-l:%M %p" (plist-get talk :start-time) emacsconf-timezone) :expanded-intro (emacsconf-pad-expand-intro talk) :intro-url (format "%s%s/backstage/%s--intro.webm" emacsconf-media-base-url emacsconf-year (plist-get talk :file-prefix)) :mumble (concat emacsconf-id "-" (plist-get (emacsconf-get-track talk) :id)) :open-qa (if emacsconf-qa-start-open "" "<li>Decide when to open the Q&A BBB up to everyone. Let ${coord} know.</li>") - :end-of-qa (if next-talk (format-time-string "%H:%M" (plist-get next-talk :start-time) emacsconf-timezone) + :end-of-qa (if next-talk (format-time-string "%-l:%M %p" (plist-get next-talk :start-time) emacsconf-timezone) "end of shift") :pronunciation (concat (emacsconf-surround "" (plist-get talk :pronunciation) " or listen to " "Refer to ") (format "%s%s/backstage/%s--intro.webm" emacsconf-media-base-url emacsconf-year (plist-get talk :file-prefix))) - :qa-hhmm (format-time-string "%H:%M" (plist-get talk :qa-time) emacsconf-timezone) + :qa-hhmm (format-time-string "%-l:%M %p" (plist-get talk :qa-time) emacsconf-timezone) :hyperlist-note-info (emacsconf-surround (format "<li><strong>%s NOTE for ${slug}:</strong> " - (format-time-string "%H:%M" (plist-get talk :start-time) emacsconf-timezone)) + (format-time-string "%-l:%M %p" (plist-get talk :start-time) emacsconf-timezone)) (plist-get talk :hyperlist-note) "</li>" "") - :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) "")) + :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-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 "${hyperlist-note-info}" @@ -667,7 +672,7 @@ ${bbb-checklist}</li>") (null (plist-get talk :video-file)) "<li><strong>${start-hhmm} ${slug} live talk</strong>: it should play a prerecorded intro, but if it doesn't, join ${bbb-backstage} and introduce talk, then turn it over to speaker for <strong>live talk</strong>: ${expanded-intro} (pronunciation: ${pronunciation})</li>") (t ;; prerecorded talk - "<li>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})</li>")) + "<li>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 <em>play ${slug}</em></li>")) ;; Q&A (if (and (null (plist-get talk :video-file)) (not (string= (or (plist-get talk :q-and-a) "none") "none"))) "<li>Continue in the BBB room for live Q&A because the talk was live</li>" @@ -764,10 +769,10 @@ ${bbb-checklist}</li>") (emacsconf-pad-expand-intro talk) :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) "") - :qa-start (format-time-string "%H:%M" (plist-get talk :qa-time) emacsconf-timezone) - :qa-end (if next-talk (format-time-string "%H:%M" (plist-get next-talk :start-time)) + :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-1 (if next-talk (format-time-string "%-l:%M %p" (time-subtract (plist-get next-talk :start-time) (seconds-to-time 60)) emacsconf-timezone) "") + :qa-start (format-time-string "%-l:%M %p" (plist-get talk :qa-time) emacsconf-timezone) + :qa-end (if next-talk (format-time-string "%-l:%M %p" (plist-get next-talk :start-time)) "end of shift") :ssh "ssh orga@res.emacsconf.org -p 46668 " :ssh-track (format "ssh %s-%s@res.emacsconf.org -p 46668 " emacsconf-id track-id) @@ -787,7 +792,7 @@ ${bbb-checklist}</li>") (emacsconf-replace-plist-in-string modified-talk (format "<li><strong>%s %s (intro: %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) + (format-time-string "%-l:%M %p" (plist-get talk :start-time) emacsconf-timezone) (plist-get talk :slug) (if (plist-get talk :recorded-intro) "recorded" "live") (if (plist-get talk :video-file) "recorded" "live") diff --git a/emacsconf-publish.el b/emacsconf-publish.el index bedc40f..650173b 100644 --- a/emacsconf-publish.el +++ b/emacsconf-publish.el @@ -104,6 +104,8 @@ (emacsconf-ical-generate-all) (emacsconf-publish-schedule-org-files) (emacsconf-publish-watch-pages) + (emacsconf-pad-prepopulate-all-talks) + (emacsconf-pad-prepopulate-hyperlists) (when (functionp 'emacsconf-pentabarf-generate) (emacsconf-pentabarf-generate)))) @@ -856,21 +858,6 @@ Back to the [[talks]] \n" (emacsconf-publish-before-page o info)) info))) -(defun emacsconf-publish-talks-page (&optional emacsconf-info) - "Generate a list of talks." - (interactive) - (let ((info (or emacsconf-info - (sort - (seq-filter #'emacsconf-publish-talk-p - (or emacsconf-schedule-draft (emacsconf-get-talk-info))) - #'emacsconf-sort-by-track-then-schedule))) - (range (format "<%s %s-%s>" - emacsconf-date - (plist-get (car emacsconf-tracks) :start) - (plist-get (car emacsconf-tracks) :end)))) - (with-temp-file (expand-file-name "talk-details.md" (expand-file-name emacsconf-year emacsconf-directory)) -)) - (defun emacsconf-generate-main-schedule-with-tracks (&optional info) (interactive (list nil)) (setq info (or info (emacsconf-publish-prepare-for-display info))) @@ -1041,7 +1028,12 @@ Entries are sorted chronologically, with different tracks interleaved." :timezone emacsconf-timezone :gmt-offset emacsconf-timezone-offset :alternative-timezones - (string-join (emacsconf-timezone-strings range nil "~%-l:%M %p") + (string-join (emacsconf-timezone-strings + (format "<%s %s-%s>" + emacsconf-date + (plist-get (car emacsconf-tracks) :start) + (plist-get (car emacsconf-tracks) :end)) + nil "~%-l:%M %p") " / ") :icals (concat @@ -1679,7 +1671,15 @@ ${include} :qa-url :qa-type :qa-backstage-url)))) - (emacsconf-filter-talks (emacsconf-get-talk-info))))))) + (emacsconf-filter-talks (emacsconf-get-talk-info))) + :tracks + (mapcar + (lambda (o) + (mapcar + (lambda (field) + (cons field (plist-get o field))) + '(:name :color :id :channel :webchat-url :stream :480p :start :end))) + emacsconf-tracks))))) (defun emacsconf-publish-talks-json-to-files () "Export talk information as JSON so that we can use it in shell scripts." @@ -2082,8 +2082,14 @@ This video is available under the terms of the Creative Commons Attribution-Shar (defun emacsconf-publish-format-watch-index (info) (concat "<!-- Automatically generated by emacsconf-publish-watch-pages -->\n -<h2>Tracks</h2>" - "<table width=\"100%\"><tr><th>Watch page</th><th>IRC channel (libera.chat)</th><th>URL for streaming player (ex: mpv, vlc, ffplay)</th><th>Low res</th></tr>\n" +<h2>Tracks</h2> +We recommend using a streaming player like mpv to watch the livestreams. Example: <pre> +" + (mapconcat (lambda (track) + (concat "mpv " (plist-get track :stream) "\n")) + emacsconf-tracks + "") + "</pre><table width=\"100%\"><tr><th>Watch page</th><th>IRC channel (libera.chat)</th><th>URL for streaming player (ex: mpv, vlc, ffplay)</th><th>Low res</th></tr>\n" (mapconcat (lambda (track) (emacsconf-replace-plist-in-string (append (list :year emacsconf-year) track) @@ -2485,68 +2491,90 @@ This video is available under the terms of the Creative Commons Attribution-Shar (emacsconf-with-talk-heading talk)) result)) -(defvar emacsconf-publish-toobnix-upload-command '("node" "/home/sacha/vendor/PeerTube/dist/server/tools/peertube.js")) +(defvar emacsconf-publish-toobnix-upload-command "peertube-cli") +(defvar emacsconf-publish-toobnix-channel "EmacsConf") +;; (defun emacsconf-publish-get-toobnix-token () +;; (let ((secrets (plz 'get "https://toobnix.org/api/v1/oauth-clients/local" :as #'json-read))) + +;; ) + +;; ) (defun emacsconf-publish-upload-to-toobnix (properties) + "Uses peertube-cli: https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/tools.md" (with-temp-buffer - (apply #'call-process - (car emacsconf-publish-toobnix-upload-command) - nil t t + (let ((arguments (append - (cdr emacsconf-publish-toobnix-upload-command) (list "upload" "-f" (plist-get properties :file)) (when (plist-get properties :title) (list "-n" (plist-get properties :title))) (when (plist-get properties :description) (list "-d" (plist-get properties :description))) - (list "-l" "2" "-c" "15" "-P" (if (string= (plist-get properties :privacy) "unlisted") "2" "1") "-t" + (list "-L" "en" + "-C" emacsconf-publish-toobnix-channel + "-l" "2" + "-c" "15" + "-P" (if (string= (plist-get properties :privacy) "public") "1" "2") "-t" (cond ((stringp (plist-get properties :tags)) (plist-get properties :tags)) ((listp (plist-get properties :tags)) (string-join (plist-get properties :tags) ",")) - (t "emacs"))))) - (buffer-string))) + (t "emacs")))))) + (kill-new (mapconcat + #'shell-quote-argument + (append (list emacsconf-publish-toobnix-upload-command) arguments) + " ")) + (apply #'call-process + emacsconf-publish-toobnix-upload-command + nil t t arguments) + (buffer-string)))) ;; YouTube (defvar emacsconf-publish-youtube-upload-command '("python3" "/home/sacha/vendor/youtube-upload/bin/youtube-upload")) (defun emacsconf-publish-upload-to-youtube (properties) - (with-temp-buffer - (apply #'call-process - (car emacsconf-publish-youtube-upload-command) - nil t t - (append - (cdr emacsconf-publish-youtube-upload-command) - (when (plist-get properties :title) - (list "--title" (plist-get properties :title))) - (when (plist-get properties :description) - (list "--description" (plist-get properties :description))) - (delq - nil - (list - (concat "--tags=" - (cond - ((stringp (plist-get properties :tags)) - (plist-get properties :tags)) - ((listp (plist-get properties :tags)) - (string-join (plist-get properties :tags) ",")) - (t "emacs"))) - (concat "--category=" (or (plist-get properties :category) "Science & Technology")) - (concat "--license=" (or (plist-get properties :license) "creativeCommon")) - (when (plist-get properties :date) - (concat "--recording-date=" - (format-time-string "%Y-%m-%dT%H:%M:%SZ" - (plist-get properties :date) t))) - (concat "--default-language=" - (or (plist-get properties :lang) "en")) - (concat "--default-audio-language=" - (or (plist-get properties :lang) "en")) - (when (plist-get properties :playlist) - (concat "--playlist=" (plist-get properties :playlist))) - "--embeddable=true")) - (list (plist-get properties :file)))) - (buffer-string))) + (let ((arguments (append + (cdr emacsconf-publish-youtube-upload-command) + (when (plist-get properties :title) + (list "--title" (plist-get properties :title))) + (when (plist-get properties :description) + (list "--description" (plist-get properties :description))) + (delq + nil + (list + (concat "--tags=" + (cond + ((stringp (plist-get properties :tags)) + (plist-get properties :tags)) + ((listp (plist-get properties :tags)) + (string-join (plist-get properties :tags) ",")) + (t "emacs"))) + (concat "--category=" (or (plist-get properties :category) "Science & Technology")) + (concat "--privacy=" (or (plist-get properties :privacy) "unlisted")) + (concat "--license=" (or (plist-get properties :license) "creativeCommon")) + (when (plist-get properties :date) + (concat "--recording-date=" + (format-time-string "%Y-%m-%dT%H:%M:%SZ" + (plist-get properties :date) t))) + (concat "--default-language=" + (or (plist-get properties :lang) "en")) + (concat "--default-audio-language=" + (or (plist-get properties :lang) "en")) + (when (plist-get properties :playlist) + (concat "--playlist=" (plist-get properties :playlist))) + "--embeddable=true")) + (list (plist-get properties :file))))) + (kill-new (mapconcat 'shell-quote-argument (append (seq-take emacsconf-publish-youtube-upload-command 1) + arguments) " ")) + (with-current-buffer (get-buffer-create "*YouTube*") + (erase-buffer) + (apply #'call-process + (car emacsconf-publish-youtube-upload-command) + nil t t + arguments) + (display-buffer (current-buffer)) + (buffer-string)))) (defun emacsconf-publish-answers-title (talk &optional len) (let ((title (concat emacsconf-name " " emacsconf-year " Q&A: " (plist-get talk :title)))) @@ -2554,6 +2582,29 @@ This video is available under the terms of the Creative Commons Attribution-Shar title (concat (substring title 0 (- len 3)) "...")))) +(defun emacsconf-publish-talk-description (talk platform) + (let ((title (concat emacsconf-name " " emacsconf-year ": " (plist-get talk :title)))) + (concat + (if (< (length title) 100) "" (concat title "\n")) + (plist-get talk :speakers-with-pronouns) "\n\n" + (plist-get talk :absolute-url) "\n\n" + (if (emacsconf-talk-file talk "--main--chapters.vtt") + (let ((chapters (subed-parse-file (emacsconf-talk-file talk "--main--chapters.vtt")))) + (concat + (mapconcat + (lambda (chapter) + (concat + (if (= (elt chapter 1) 0) + "00:00" + (format-seconds "%.2h:%z%.2m:%.2s" (floor (/ (elt chapter 1) 1000)))) + " " (elt chapter 3) "\n")) + chapters + "") + "\n")) + "") + "You can view this and other resources using free/libre software at " (plist-get talk :absolute-url) " .\n" + "This video is available under the terms of the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.\n"))) + (defun emacsconf-publish-answers-description (talk platform) (let ((title (concat emacsconf-name " " emacsconf-year " Q&A: " (plist-get talk :title)))) (concat @@ -2571,7 +2622,6 @@ This video is available under the terms of the Creative Commons Attribution-Shar (if (= (elt chapter 1) 0) "00:00" (format-seconds "%.2h:%z%.2m:%.2s" (floor (/ (elt chapter 1) 1000)))) - (format ".%03d" (% (elt chapter 1) 1000)) " " (elt chapter 3) "\n")) chapters "") @@ -2581,7 +2631,37 @@ This video is available under the terms of the Creative Commons Attribution-Shar "This video is available under the terms of the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.\n"))) ;; (emacsconf-publish-answers-description (emacsconf-resolve-talk "async") 'toobnix) +(defvar emacsconf-publish-talk-video-tags (format "emacs,%s,%s%s" emacsconf-id emacsconf-id emacsconf-year) + "Comma-separated tags to add to the talk videos.") +(defun emacsconf-publish-upload-talk (talk platform) + (interactive + (list (emacsconf-complete-talk-info) + (intern (completing-read "Platform: " '("youtube" "toobnix"))))) + (let ((file (emacsconf-talk-file talk "--main.webm")) + (title (concat emacsconf-name " " emacsconf-year ": " + (plist-get talk :title) " - " (plist-get talk :speakers))) + output) + (when (and file (not (plist-get talk (if (eq platform 'toobnix) :toobnix-url :youtube-url)))) + (setq output + (funcall + (if (eq platform 'toobnix) + #'emacsconf-publish-upload-to-toobnix + #'emacsconf-publish-upload-to-youtube) + (list + :file file + :tags emacsconf-publish-talk-video-tags + :playlist (concat emacsconf-name " " emacsconf-year) + :date (plist-get talk :start-time) + :privacy (if (plist-get talk :public) "public" "unlisted") + :title (if (< (length title) 100) title (concat (substring title 0 97) "...")) + :description (emacsconf-publish-talk-description talk platform)))) + (when (and (string-match "Video URL: \\(.*+\\)" output) (eq platform 'youtube)) + (setq output (match-string 1 output)) + (save-window-excursion + (emacsconf-go-to-talk talk) + (org-entry-put (point) "YOUTUBE_URL" output))) + output))) (defun emacsconf-publish-upload-answers (talk platform) (let ((file (emacsconf-talk-file talk "--answers.webm")) diff --git a/emacsconf-schedule.el b/emacsconf-schedule.el index 145134b..9597508 100644 --- a/emacsconf-schedule.el +++ b/emacsconf-schedule.el @@ -130,6 +130,8 @@ Each function should take the info and manipulate it as needed, returning the ne o) info)) +(defun emacsconf-schedule-ignore-fixed (info) + (mapcar (lambda (o) (plist-put o :fixed-time nil)) info)) (defun emacsconf-schedule-dump-sexp (info &optional include-time) (mapcar (lambda (o) (cond @@ -267,15 +269,18 @@ Pairs with `emacsconf-schedule-dump-sexp'." (org-entry-put (point) "TIME" (plist-get talk :time))) (emacsconf-filter-talks info))))) -(defun emacsconf-schedule-save-emailed-times (info &optional force) - (interactive (list (or emacsconf-schedule-draft (emacsconf-get-talk-info)) current-prefix-arg)) +(defun emacsconf-schedule-save-emailed-times (info &optional field force) + (interactive (list (or emacsconf-schedule-draft (emacsconf-get-talk-info)) + (read-string "Field: ") current-prefix-arg)) (save-window-excursion (save-excursion (mapc (lambda (talk) (emacsconf-go-to-talk (plist-get talk :slug)) (when (and (plist-get talk :scheduled) - (or force (null (org-entry-get (point) "ORIGINAL_SCHEDULE")))) - (org-entry-put (point) "ORIGINAL_SCHEDULE" + (or force (null (org-entry-get (point) + (or field "ORIGINAL_SCHEDULE"))))) + (org-entry-put (point) + (or field "ORIGINAL_SCHEDULE") (replace-regexp-in-string "[<>]" "" (plist-get talk :scheduled))))) (emacsconf-filter-talks info))))) diff --git a/emacsconf-stream.el b/emacsconf-stream.el index a347c81..a09d43c 100644 --- a/emacsconf-stream.el +++ b/emacsconf-stream.el @@ -20,7 +20,7 @@ ;;; Commentary: -;; +;; ;;; Code: @@ -459,7 +459,7 @@ With a prefix argument (\\[universal-argument]), clear the overlay." (global-hl-line-mode -1)) (set-window-margins nil 10 10))) -(defun emacsconf-stream-generate-title-page (talk) +(defun emacsconf-stream-generate-title-page-in-emacs (talk) (interactive (list (emacsconf-complete-talk-info))) (emacsconf-stream-display-talk-info talk) (message nil) @@ -471,7 +471,7 @@ With a prefix argument (\\[universal-argument]), clear the overlay." (shell-quote-argument (expand-file-name (concat (plist-get talk :slug) "-title.svg") (expand-file-name "titles" emacsconf-stream-asset-dir)))))) -(defun emacsconf-stream-generate-title-pages (&optional info) +(defun emacsconf-stream-generate-title-pages-in-emacs (&optional info) (interactive) (setq info (emacsconf-publish-prepare-for-display (or info (emacsconf-get-talk-info)))) (let ((title-dir (expand-file-name "titles" emacsconf-stream-asset-dir))) @@ -579,6 +579,37 @@ With a prefix argument (\\[universal-argument]), clear the overlay." (emacsconf-filter-talks (cdr track))))) by-track))) +(defun emacsconf-stream-generate-titles (&optional info) + (interactive) + (setq info (or emacsconf-schedule-draft (emacsconf-publish-prepare-for-display (emacsconf-filter-talks (or info (emacsconf-get-talk-info)))))) + (let* ((by-track (seq-group-by (lambda (o) (plist-get o :track)) info)) + (dir (expand-file-name "titles" emacsconf-stream-asset-dir)) + (template (expand-file-name "template.svg" (expand-file-name "in-between" + emacsconf-stream-asset-dir)))) + (unless (file-directory-p dir) + (make-directory dir t)) + (mapc (lambda (track) + (let (prev) + (mapc (lambda (talk) + (let ((dom (xml-parse-file template))) + ;; hide all the previous stuff + (svg-remove dom "g-prev") + (svg-remove dom "divider") + (svg-remove dom "current-qa") + (emacsconf-stream-svg-set-text dom "current-title" (plist-get talk :title)) + (emacsconf-stream-svg-set-text dom "current-speakers" (plist-get talk :speakers)) + (emacsconf-stream-svg-set-text dom "current-url" (plist-get talk :absolute-url)) + (with-temp-file (expand-file-name (concat (plist-get talk :slug) ".svg") dir) + (dom-print dom)) + (shell-command + (concat "inkscape --export-type=png -w 1280 -h 720 --export-background-opacity=0 " + (shell-quote-argument (expand-file-name (concat (plist-get talk :slug) ".svg") + dir))))) + (setq prev talk)) + (emacsconf-filter-talks (cdr track))))) + by-track))) + + (defun emacsconf-stream-generate-test-subtitles (&optional info) (interactive) (setq info (emacsconf-filter-talks (or info (emacsconf-get-talk-info)))) diff --git a/emacsconf.el b/emacsconf.el index 722a300..31e1119 100644 --- a/emacsconf.el +++ b/emacsconf.el @@ -760,7 +760,6 @@ The subheading should match `emacsconf-abstract-heading-regexp'." (defun emacsconf-add-checkin-time (o) (unless (or (null (plist-get o :status)) - (null (plist-get o :email)) (string= (plist-get o :status) "CANCELLED") (string-match "after" (or (plist-get o :q-and-a) ""))) (if (null (plist-get o :video-file)) @@ -1443,7 +1442,7 @@ NAME could be a track name, a talk name, or a list." info)) (defvar emacsconf-shifts - (list (list :id "sat-am-gen" :track "General" :start "2022-12-03T08:00:00-0500" :end "2022-12-03T12:00:00-0500" :host "zaeph" :streamer "sachac" :checkin "corwin" :irc "dto" :pad "publicvoit" :coord "sachac") (list :id "sat-pm-gen" :track "General" :start "2022-12-03T13:00:00-0500" :end "2022-12-03T18:00:00-0500" :host "zaeph" :streamer "sachac" :checkin "FlowyCoder" :irc "bandali" :pad "publicvoit" :coord "sachac") (list :id "sat-am-dev" :track "Development" :start "2022-12-03T08:00:00-0500" :end "2022-12-03T12:00:00-0500" :host "bandali" :streamer "sachac" :checkin "corwin" :irc "dto" :coord "sachac") (list :id "sat-pm-dev" :track "Development" :start "2022-12-03T13:00:00-0500" :end "2022-12-03T18:00:00-0500" :host "bandali" :streamer "sachac" :checkin "FlowyCoder" :irc "bandali" :coord "sachac") (list :id "sun-am-gen" :track "General" :start "2022-12-04T08:00:00-0500" :end "2022-12-04T12:00:00-0500" :host "zaeph" :streamer "sachac" :checkin "corwin" :irc "dto" :pad "publicvoit" :coord "sachac") (list :id "sun-pm-gen" :track "General" :start "2022-12-04T13:00:00-0500" :end "2022-12-04T18:00:00-0500" :host "zaeph" :streamer "jman" :checkin "FlowyCoder" :irc "bandali" :pad "publicvoit" :coord "sachac") (list :id "sun-am-dev" :track "Development" :start "2022-12-04T08:00:00-0500" :end "2022-12-04T12:00:00-0500" :host "bandali" :streamer "sachac" :checkin "corwin" :irc "dto" :coord "sachac") (list :id "sun-pm-dev" :track "Development" :start "2022-12-04T13:00:00-0500" :end "2022-12-04T18:00:00-0500" :host "bandali" :streamer "sachac" :checkin "FlowyCoder" :irc "bandali" :coord "sachac"))) + (list (list :id "sat-am-gen" :track "General" :start "2023-12-02T08:00:00-0500" :end "2023-12-02T12:00:00-0500" :host "zaeph" :streamer "sachac" :checkin "FlowyCoder" :coord "sachac") (list :id "sat-pm-gen" :track "General" :start "2023-12-02T13:00:00-0500" :end "2023-12-02T18:00:00-0500" :host "zaph" :streamer "sachac" :checkin "FlowyCoder" :coord "sachac") (list :id "sat-am-dev" :track "Development" :start "2023-12-02T08:00:00-0500" :end "2023-12-02T12:00:00-0500" :host "bandali" :streamer "sachac" :checkin "FlowyCoder" :coord "sachac") (list :id "sat-pm-dev" :track "Development" :start "2023-12-02T13:00:00-0500" :end "2023-12-02T18:00:00-0500" :host "bandali" :streamer "sachac" :checkin "FlowyCoder" :coord "sachac") (list :id "sun-am-gen" :track "General" :start "2023-12-03T08:00:00-0500" :end "2023-12-03T12:00:00-0500" :host "zaeph" :streamer "sachac" :checkin "FlowyCoder" :coord "sachac") (list :id "sun-pm-gen" :track "General" :start "2023-12-03T13:00:00-0500" :end "2023-12-03T18:00:00-0500" :host "zaeph" :streamer "sachac" :checkin "FlowyCoder" :coord "sachac") (list :id "sun-am-dev" :track "Development" :start "2023-12-03T08:00:00-0500" :end "2023-12-03T12:00:00-0500" :host "bandali" :streamer "sachac" :checkin "FlowyCoder" :coord "sachac") (list :id "sun-pm-dev" :track "Development" :start "2023-12-03T13:00:00-0500" :end "2023-12-03T18:00:00-0500" :host "bandali" :streamer "sachac" :checkin "FlowyCoder" :coord "sachac"))) (defun emacsconf-filter-talks-by-time (start-time end-time info) "Return talks that are between START-TIME and END-TIME (inclusive) in INFO." |