From 59de795fdcdd117e671b1513474f158a7e38c313 Mon Sep 17 00:00:00 2001 From: Sacha Chua Date: Thu, 20 Oct 2022 21:49:32 -0400 Subject: Work on watch pages on live.emacsconf.org --- emacsconf-publish.el | 319 ++++++++++++++++++++++++++++++++------------------ emacsconf-schedule.el | 8 +- emacsconf.el | 12 +- 3 files changed, 221 insertions(+), 118 deletions(-) diff --git a/emacsconf-publish.el b/emacsconf-publish.el index 8d85b76..296c946 100644 --- a/emacsconf-publish.el +++ b/emacsconf-publish.el @@ -696,43 +696,43 @@ Entries are sorted chronologically, with different tracks interleaved." (defun emacsconf-publish-sched-directive (o) (format "[[!template id=sched%s%s]]" - (let ((result "") - (attrs (append - (list - :title (plist-get o :title) - :url (concat "/" (plist-get o :url)) - :speakers (plist-get o :speakers) - :q-and-a (plist-get o :q-and-a)) - (unless (eq emacsconf-publishing-phase 'program) - (list - :track (plist-get o :track) - :slug (plist-get o :slug) - :status (pcase (plist-get o :status) - ("CAPTIONED" "captioned") - ("PREREC_RECEIVED" "received") - ("DONE" "done") - ("STARTED" "now playing") - (_ nil)) - :time (plist-get o :time) - :startutc (format-time-string "%FT%T%z" (plist-get o :start-time) t) - :endutc (format-time-string "%FT%T%z" (plist-get o :end-time) t) - :start (format-time-string "%-l:%M" (plist-get o :start-time) emacsconf-timezone) - :end (format-time-string "%-l:%M" (plist-get o :end-time) emacsconf-timezone)))))) - (while attrs - (let ((field (pop attrs)) - (val (pop attrs))) - (when val - (setq result (concat result " " (substring (symbol-name field) 1) "=\"" val "\""))))) - result) - (if (eq emacsconf-publishing-phase 'resources) - (format" resources=\"\"\"\n%s\n\"\"\"" - (mapconcat (lambda (s) (concat "
  • " s "
  • ")) - (emacsconf-link-file-formats-as-list - (append o - (list :base-url (format "%s%s/" emacsconf-media-base-url emacsconf-year))) - (append emacsconf-main-extensions '("--main.webm"))) - "")) - ""))) + (let ((result "") + (attrs (append + (list + :title (plist-get o :title) + :url (concat "/" (plist-get o :url)) + :speakers (plist-get o :speakers) + :q-and-a (plist-get o :q-and-a)) + (unless (eq emacsconf-publishing-phase 'program) + (list + :track (plist-get o :track) + :slug (plist-get o :slug) + :status (pcase (plist-get o :status) + ("CAPTIONED" "captioned") + ("PREREC_RECEIVED" "received") + ("DONE" "done") + ("STARTED" "now playing") + (_ nil)) + :time (plist-get o :time) + :startutc (format-time-string "%FT%T%z" (plist-get o :start-time) t) + :endutc (format-time-string "%FT%T%z" (plist-get o :end-time) t) + :start (format-time-string "%-l:%M" (plist-get o :start-time) emacsconf-timezone) + :end (format-time-string "%-l:%M" (plist-get o :end-time) emacsconf-timezone)))))) + (while attrs + (let ((field (pop attrs)) + (val (pop attrs))) + (when val + (setq result (concat result " " (substring (symbol-name field) 1) "=\"" val "\""))))) + result) + (if (eq emacsconf-publishing-phase 'resources) + (format" resources=\"\"\"\n%s\n\"\"\"" + (mapconcat (lambda (s) (concat "
  • " s "
  • ")) + (emacsconf-link-file-formats-as-list + (append o + (list :base-url (format "%s%s/" emacsconf-media-base-url emacsconf-year))) + (append emacsconf-main-extensions '("--main.webm"))) + "")) + ""))) (defun emacsconf-format-main-schedule (info) (let* ((cancelled (seq-filter (lambda (o) (string= (plist-get o :status) "CANCELLED")) info))) @@ -1244,88 +1244,181 @@ Entries are sorted chronologically, with different tracks interleaved." (insert "")))) by-day)))) +(defvar emacsconf-publish-watch-directory "/ssh:front:/var/www/live.emacsconf.org/") + +(defun emacsconf-publish-format-watch-index (info) + (concat + "\n +

    Tracks

    " + "\n" + (mapconcat (lambda (track) + (emacsconf-replace-plist-in-string + track + "")) + emacsconf-tracks + "\n") + "
    Watch pageIRC channel (libera.chat)Alternative for streaming playerLow res
    ${name}${channel}${stream}${id}-480p.webm
    \n\n" + (with-temp-buffer + (svg-print (emacsconf-schedule-svg 800 300 info)) + (buffer-string)))) + +(defun emacsconf-publish-schedule-line (talk) + (setq talk (append talk (list + :startutc (format-time-string "%FT%T%z" (plist-get talk :start-time) t) + :endutc (format-time-string "%FT%T%z" (plist-get talk :end-time) t) + :start (format-time-string "%-l:%M" (plist-get talk :start-time) emacsconf-timezone) + :end (format-time-string "%-l:%M" (plist-get talk :end-time) emacsconf-timezone) + :base-url emacsconf-base-url))) + (emacsconf-replace-plist-in-string + (append talk (list + :start-info (emacsconf-surround "" (plist-get talk :start) "" "") + :end-info(emacsconf-surround " - " (plist-get talk :end) "" "") + :track-info (emacsconf-surround (format " " (or (plist-get talk :track) "")) (plist-get talk :track) "" "") + :q-info (emacsconf-surround " Q&A: " (plist-get talk :q-and-a) "; " "") + :slug-info (emacsconf-surround " id:" (plist-get talk :slug) "" "") + :speaker-info (emacsconf-surround "
    id:" (plist-get talk :speakers) "
    " "") + :resources-info (emacsconf-surround "" ""))) + "
    +
    ${start-info}${end-info}${track-info}${q-info}${slug-info}
    + +${speaker-info} +${resources-info} +
    +")) + +(defun emacsconf-publish-schedule-short (info) + (mapconcat (lambda (o) + (emacsconf-replace-plist-in-string + (append o (list :base-url emacsconf-base-url)) + "${slug} (pad, ${qa-link})")) + info " - ")) + +(defun emacsconf-publish-page-nav (nav &optional current sep) + (concat (if current (format "" current) "") + (mapconcat (lambda (n) + (if (string= current (car n)) + (concat "" (cdr n) "") + (concat "" (cdr n) ""))) + nav (or sep " - ")))) + +(defun emacsconf-publish-format-watch-track (track info) + (let ((nav '(("watch" . "Watch") + ("links" . "Pad and Q&A links") + ("chat" . "Chat") + ("sched" . "Schedule"))) + (track-talks (seq-filter (lambda (o) (string= (plist-get o :track) + (plist-get track :name))) + info)) + ) + (emacsconf-replace-plist-in-string + (append + (list :links (concat + "Watch - Pad and Q&A links - Chat - View schedule - \nStreams: " + ) + :sched (with-temp-buffer + (svg-print (emacsconf-schedule-svg 800 300 info)) + (buffer-string)) + :year emacsconf-year + :brief (emacsconf-publish-schedule-short + + track-talks) + :stream-nav (concat "Tracks: " (mapconcat (lambda (tr) + (if (string= (plist-get tr :name) (plist-get track :name)) + (format "%s" (plist-get track :name)) + (format "%s" + emacsconf-year + (plist-get tr :id) + (plist-get tr :name)))) + emacsconf-tracks + " - ")) + :talks + (mapconcat (lambda (entry) (format "

    %s

    \n%s\n" (car entry) + (mapconcat #'emacsconf-publish-schedule-line (cdr entry) "\n"))) + (seq-group-by (lambda (o) + (format-time-string "%A, %b %-e, %Y" (plist-get o :start-time) emacsconf-timezone)) + track-talks))) + track) + (concat + " + +

    EmacsConf ${year}: ${name} track

    +
    +
    " + (emacsconf-publish-page-nav nav "watch") + " | ${stream-nav}
    + + +
    Alternatively, load ${stream} or (low-res) in a streaming media player such as MPV.
    +
    " (emacsconf-publish-page-nav nav "links") " | ${stream-nav}
    " + "
    ${brief}
    +
    +
    " (emacsconf-publish-page-nav nav "chat") " | ${stream-nav}
    " +"
    Chat: ${channel} on libera.chat
    + +
    + +
    " (emacsconf-publish-page-nav nav "sched") " | ${stream-nav}
    " +" +
    ${sched}
    +
    ${talks}
    +")))) + (defun emacsconf-publish-watch-pages () "Update /year/watch pages." (interactive) - (emacsconf-publish-with-wiki-change - - (mapc (lambda (track) - (plist-put track :year emacsconf-year) - (plist-put track :stream (concat emacsconf-stream-base (plist-get track :id) ".webm")) - (plist-put track :480p (concat emacsconf-stream-base (plist-get track :id) "-480p.webm")) - (plist-put track :webchat-channels (concat "emacsconf,emacsconf-" (plist-get track :id))) - (plist-put track :webchat (concat emacsconf-chat-base "?join=" (plist-get track :webchat-channels))) - (plist-put track :channel (concat "#emacsconf-" (plist-get track :id)))) - emacsconf-tracks) - (let* ((info (sort (emacsconf-get-talk-info) #'emacsconf-sort-by-scheduled)) - (emacsconf-publishing-phase 'schedule) - (sched (format "[[!inline pages=\"internal(%s/schedule-image)\" raw=\"yes\"]]" emacsconf-year))) - (unless (file-directory-p (expand-file-name "watch" (expand-file-name emacsconf-year emacsconf-directory))) - (make-directory (expand-file-name "watch" (expand-file-name emacsconf-year emacsconf-directory)))) - (with-temp-file (expand-file-name "watch/info.md" (expand-file-name emacsconf-year emacsconf-directory)) - (insert - "\n[[!sidebar content=\"\"]] -# Tracks\n\n" - "\n" - (mapconcat (lambda (track) - (emacsconf-replace-plist-in-string - track - "")) - emacsconf-tracks - "\n") - "
    Watch pageIRC channel (libera.chat)Alternative for streaming playerLow res
    ${name}${channel}${stream}${id}-480p.webm
    \n\n" sched)) - + (mapc (lambda (track) + (plist-put track :year emacsconf-year) + (plist-put track :stream (concat emacsconf-stream-base (plist-get track :id) ".webm")) + (plist-put track :480p (concat emacsconf-stream-base (plist-get track :id) "-480p.webm")) + (plist-put track :webchat-channels (concat "emacsconf,emacsconf-" (plist-get track :id))) + (plist-put track :webchat (concat emacsconf-chat-base "?join=" (plist-get track :webchat-channels))) + (plist-put track :channel (concat "#emacsconf-" (plist-get track :id)))) + emacsconf-tracks) + (let* ((info (sort (emacsconf-get-talk-info) #'emacsconf-sort-by-scheduled)) + (emacsconf-publishing-phase 'schedule) + (emacsconf-use-absolute-url t)) + ;; (when emacsconf-directory + ;; (emacsconf-publish-with-wiki-change + ;; (make-directory (expand-file-name "watch" (expand-file-name emacsconf-year emacsconf-directory)) t) + ;; (with-temp-file (expand-file-name "watch/info.md" (expand-file-name emacsconf-year emacsconf-directory)) + ;; (insert "[[!sidebar content=\"\"]]" (emacsconf-publish-format-watch-index info))) + ;; (mapc (lambda (track) + ;; (with-temp-file (expand-file-name (format "%s/watch/%s.md" emacsconf-year (plist-get track :id)) + ;; emacsconf-directory) + ;; (insert (emacsconf-publish-format-watch-track track info)))) + ;; emacsconf-tracks))) + ;; Update live.emacsconf.org + (when emacsconf-publish-watch-directory + (make-directory (expand-file-name "watch" (expand-file-name emacsconf-year emacsconf-publish-watch-directory)) t) + (with-temp-file (expand-file-name "watch/index.html" (expand-file-name emacsconf-year emacsconf-publish-watch-directory)) + (insert "Watch EmacsConf" (emacsconf-publish-format-watch-index info) + +"

    + Depending on which media player you use, you may enter the stream address + in a graphical user interface or provide it as an argument to the program + when launching it from the terminal. +

    +

    + Examples: +

    +
    mpv https://live0.emacsconf.org:9001/emacsconf/gen.webm
    +vlc https://live0.emacsconf.org:9001/emacsconf/gen.webm
    +ffplay https://live0.emacsconf.org:9001/emacsconf/gen.webm
    +
    " + "")) (mapc (lambda (track) - (with-temp-file (expand-file-name (format "%s/watch/%s.md" - emacsconf-year - (plist-get track :id)) - emacsconf-directory) + (make-directory (expand-file-name (format "%s/watch/%s" emacsconf-year (plist-get track :id)) emacsconf-publish-watch-directory) t) + (with-temp-file (expand-file-name (format "%s/watch/%s/index.html" emacsconf-year (plist-get track :id)) + emacsconf-publish-watch-directory) (insert (emacsconf-replace-plist-in-string - (append - (list :links (concat - "Watch - Chat - View schedule - \nStreams: " - (mapconcat (lambda (tr) - (if (string= (plist-get tr :name) (plist-get track :name)) - (format "**%s**" (plist-get track :name)) - (format "%s" - emacsconf-year - (plist-get tr :id) - (plist-get tr :name)))) - emacsconf-tracks - " - ")) - :sched sched - :year emacsconf-year - :talks (mapconcat #'emacsconf-publish-sched-directive - (seq-filter (lambda (o) (string= (plist-get o :track) - (plist-get track :name))) - info) - "\n")) - track) - " -[[!inline pages=\"internal(${year}/watch/announce)\" raw=\"yes\"]] -[[!meta title=\"${name} stream\"]] -[[!sidebar content=\"\"]] - - -${links} -\n -Alternatively, load <${stream}> or <${480p}> (low-res) in a streaming media player such as MPV. - - -${links} - -Chat: [${channel} on libera.chat](${webchat}) - -
    - - -${links} - -${sched}\n - -${talks} -")))) + track + "Watch EmacsConf ${name} track") + (emacsconf-publish-format-watch-track track info) + ""))) emacsconf-tracks)))) (defvar emacsconf-publish-current-dir "/ssh:media:/var/www/media.emacsconf.org/2022/current" diff --git a/emacsconf-schedule.el b/emacsconf-schedule.el index 9b90faa..b8c3892 100644 --- a/emacsconf-schedule.el +++ b/emacsconf-schedule.el @@ -226,6 +226,7 @@ Each function should take the info and manipulate it as needed, returning the ne (emacsconf-filter-talks info))))) (defvar emacsconf-schedule-svg-modify-functions '(emacsconf-schedule-svg-color-by-track) "Functions to run to modify the display of each item.") +(defvar emacsconf-use-absolute-url nil "Non-nil means try to use absolute URLs.") (defun emacsconf-schedule-svg-track (svg base-x base-y width height start-time end-time info) (let ((scale (/ width (float-time (time-subtract end-time start-time))))) (mapc @@ -258,7 +259,12 @@ Each function should take the info and manipulate it as needed, returning the ne (parent (dom-node 'a (list - (cons 'href (concat "/" (plist-get o :url))) + (cons 'href + (concat + (if emacsconf-use-absolute-url + emacsconf-base-url + "/") + (plist-get o :url))) (cons 'title (plist-get o :title)) (cons 'data-slug (plist-get o :slug))) (dom-node 'title nil diff --git a/emacsconf.el b/emacsconf.el index 8183fc5..6d25045 100644 --- a/emacsconf.el +++ b/emacsconf.el @@ -75,7 +75,7 @@ :type 'file :group 'emacsconf) -(defvar emacsconf-stream-base "https://live0.emacsconf.org/") +(defvar emacsconf-stream-base "https://live0.emacsconf.org:9001/emacsconf/") (defvar emacsconf-chat-base "https://chat.emacsconf.org/") (defcustom emacsconf-download-directory "~/Downloads" @@ -422,14 +422,18 @@ (when track (plist-put o :watch-url (concat emacsconf-base-url emacsconf-year "/watch/" (plist-get track :id)))) (plist-put o :channel (plist-get track :channel)) + (plist-put o :webchat-url (concat emacsconf-chat-base "?join=emacsconf," (plist-get track :channel))) (cond ((string-match "live" (or (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-info (plist-get o :bbb-redirect)) + (plist-put o :qa-link (format "live" (plist-get o :bbb-redirect)))) ((string-match "IRC" (or (plist-get o :q-and-a) "")) (plist-put o :qa-info (concat (emacsconf-surround "nick: " (plist-get o :irc) ", " "") - (plist-get o :channel)))) - (t (plist-put o :qa-info "none"))) + (plist-get o :channel))) + (plist-put o :qa-link (format "%s" (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))) o)) -- cgit v1.2.3