summaryrefslogtreecommitdiffstats
path: root/emacsconf-publish.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacsconf-publish.el')
-rw-r--r--emacsconf-publish.el194
1 files changed, 167 insertions, 27 deletions
diff --git a/emacsconf-publish.el b/emacsconf-publish.el
index 31ff72b..3204da9 100644
--- a/emacsconf-publish.el
+++ b/emacsconf-publish.el
@@ -30,7 +30,7 @@
:type 'string
:group 'emacsconf)
-(defcustom emacsconf-main-extensions '("--main.webm" "--main.opus" "--main.org" ".org" ".odp" ".pdf" ".pptx" ".el" "--compressed56.webm" "--main.vtt" "--main_fr.vtt" "--main_ja.vtt" "--main_es.vtt" "--main--chapters.vtt" "--script.fountain" "--main.pdf" "--slides.pdf")
+(defcustom emacsconf-main-extensions '("--main.webm" "--main.opus" "--main.org" ".org" ".odp" ".pdf" ".pptx" ".el" "--compressed56.webm" "--main.vtt" "--main_fr.vtt" "--main_ja.vtt" "--main_es.vtt" "--main--chapters.vtt" "--script.fountain" "--main.pdf" "--slides.pdf" "--answers.vtt" "--answers.webm")
"Extensions to list on public pages."
:type '(repeat string)
:group 'emacsconf)
@@ -145,13 +145,14 @@
(video (and file-prefix
(emacsconf-publish-index-card-video
(or (plist-get talk :video-id)
- (concat (plist-get talk :slug) "-mainVideo"))
+ (concat "mainVideo-" (plist-get talk :slug)))
video-file talk))))
;; Add extra information to the talk
(setq talk
(append
talk
(list
+ :video-type (or (plist-get talk :video-type) "mainVideo")
:time-info (emacsconf-surround "Duration: " (plist-get talk :video-duration) " minutes" "")
:video-html (or (plist-get video :video) "")
:audio-html (or (plist-get video :audio) "")
@@ -161,7 +162,7 @@
:speaker-info (or (plist-get talk :speakers-with-pronouns) ""))))
(emacsconf-replace-plist-in-string
talk
- "<div class=\"vid\">${video-html}${audio-html}<div>${extra}</div>${time-info}${resources}${chapter-list}</div>")))
+ "<div class=\"vid ${video-type}\">${video-html}${audio-html}<div>${extra}</div>${time-info}${resources}${chapter-list}</div>")))
;; (emacsconf-publish-format-track-as-org (car emacsconf-tracks) "US/Eastern")
;; (emacsconf-get-talk-info)
@@ -364,10 +365,10 @@
(list
:source-src
(when (stringp video-file)
- (if (plist-get talk :public)
- (format "%s%s/%s" emacsconf-media-base-url (plist-get talk :conf-year)
- (file-name-nondirectory video-file))
- (file-name-nondirectory video-file)))
+ (if (plist-get talk (if (string-match "--answers" video-file) :qa-public :public))
+ (format "%s%s/%s" emacsconf-media-base-url (plist-get talk :conf-year)
+ (file-name-nondirectory video-file))
+ (file-name-nondirectory video-file)))
:captions
(or
(and (stringp video-file)
@@ -428,6 +429,11 @@
(concat "<li>" s "</li>"))
(emacsconf-publish-link-file-formats-as-list talk)
"")
+ :youtube-info (if (plist-get talk :youtube-url)
+ (format
+ "<li><a href=\"%s\">View on Youtube</a></li>"
+ (plist-get talk :youtube-url))
+ "")
:toobnix-info (if (plist-get talk :toobnix-url)
(format
"<li><a href=\"%s\">View on Toobnix</a></li>"
@@ -457,7 +463,7 @@
:resources
(emacsconf-replace-plist-in-string
info
- "<div class=\"files resources\"><ul>${links}${other-files}${toobnix-info}</ul></div>"))))
+ "<div class=\"files resources\"><ul>${links}${other-files}${toobnix-info}${youtube-info}</ul></div>"))))
(defun emacsconf-publish-format-public-email (o &optional email)
(format "[%s](mailto:%s?subject=%s)"
@@ -469,9 +475,15 @@
(let ((extra-info (mapconcat #'identity
(delq nil (list
(unless (string= (plist-get o :pronunciation) "nil")
- (emacsconf-surround "Pronunciation: " (plist-get o :pronunciation) ""))
+ (emacsconf-surround "Pronunciation: "
+ (if (string-match "\\[" (or (plist-get o :pronunciation) ""))
+ (org-export-string-as (plist-get o :pronunciation) 'md t)
+ (plist-get o :pronunciation))
+ ""))
(when (plist-get o :irc) (format "IRC: %s" (plist-get o :irc)))
- (plist-get o :public-contact)
+ (if (string-match "\\[" (or (plist-get o :public-contact) ""))
+ (org-export-string-as (plist-get o :public-contact) 'md t)
+ (plist-get o :public-contact))
(when (plist-get o :public-email) (format "<mailto:%s>" (plist-get o :public-email)))))
", ")))
(concat (plist-get o :speakers-with-pronouns)
@@ -563,8 +575,10 @@ ${categories}
(emacsconf-publish-index-card (append
(list
:public 1
- :video-id (concat (plist-get o :slug) "-qanda")
- :toobnix-url nil
+ :video-type "qanda"
+ :video-id (concat "qanda-" (plist-get o :slug))
+ :youtube-url (plist-get o :qa-youtube)
+ :toobnix-url (plist-get o :qa-toobnix)
:captions-edited (plist-get o :qa-captions-edited)
:caption-file (emacsconf-talk-file o "--answers.vtt")
:video-file (emacsconf-talk-file o "--answers.webm")
@@ -605,7 +619,10 @@ ${categories}
(emacsconf-surround " <" (and (member emacsconf-publishing-phase '(schedule conference))
(plist-get o :qa-url)) ">" ""))
(concat (or (plist-get o :video-time)
- (plist-get o :time)) "-min talk cancelled"))
+ (plist-get o :time))
+ (if (string= (plist-get o :status) "CANCELLED")
+ "-min talk cancelled"
+ "-min talk")))
:pad-info
(if (and talk-p emacsconf-publish-include-pads (not (and (member emacsconf-publishing-phase '(schedule conference))
(string= (plist-get o :qa-type) "etherpad"))))
@@ -720,7 +737,7 @@ This includes the intro note, the schedule, and talk resources."
(setq info (or info (emacsconf-publish-prepare-for-display (emacsconf-get-talk-info))))
(with-temp-file (expand-file-name (format "%s-before.md" (plist-get talk :slug))
(expand-file-name "info" (expand-file-name emacsconf-year emacsconf-directory)))
-
+ (hack-dir-local-variables-non-file-buffer)
(insert "<!-- Automatically generated by emacsconf-publish-before-page -->\n")
(insert (emacsconf-surround "" (plist-get talk :intro-note) "\n\n" ""))
(let ((is-live (emacsconf-talk-live-p talk)))
@@ -743,7 +760,7 @@ This includes the intro note, the schedule, and talk resources."
(let ((msecs (elt sub 1)))
(concat
(if (and (elt sub 4) (not (string= (elt sub 4) "")))
- (format "\n[[!template new=\"1\" text=\"\"\"%s\"\"\" start=\"%s\" video=\"%s\" id=\"subtitle\"%s]]\n\n"
+ (format "\n<div class=\"transcript-heading\">[[!template new=\"1\" text=\"\"\"%s\"\"\" start=\"%s\" video=\"%s\" id=\"subtitle\"%s]]</div>"
(string-trim (replace-regexp-in-string "^NOTE[ \n]" "" (elt sub 4)))
(concat (format-seconds "%02h:%02m:%02s" (/ (floor msecs) 1000))
"." (format "%03d" (mod (floor msecs) 1000)))
@@ -763,6 +780,7 @@ This includes the intro note, the schedule, and talk resources."
(defun emacsconf-publish-format-transcript (talk &optional video-id lang title)
"Format the transcript for TALK, adding paragraph markers when possible."
(require 'subed)
+ (setq video-id (or video-id "mainVideo"))
(let* ((subtitles
(subed-parse-file (if lang
(format "%s_%s.vtt"
@@ -771,14 +789,14 @@ This includes the intro note, the schedule, and talk resources."
lang)
(plist-get talk :caption-file)))))
(if subtitles
- (format "<a name=\"%s-%s-transcript%s\"></a>
-# %s%s
+ (format "<div class=\"transcript%s\"><a name=\"%s-%s-transcript%s\"></a><h1>%s%s</h1>
%s
-"
+</div>"
+ (if video-id (concat " transcript-" video-id) "")
(plist-get talk :slug)
- (or video-id "mainVideo")
+ video-id
(emacsconf-surround "-" lang "" "")
(if lang (assoc-default lang emacsconf-publish-subtitle-languages) (or title "Transcript"))
(if (emacsconf-captions-edited-p (plist-get talk :caption-file))
@@ -827,12 +845,13 @@ This includes captions, contact, and an invitation to participate."
;; Contact information
(with-temp-file (expand-file-name (format "%s-after.md" (plist-get talk :slug))
(expand-file-name "info" (expand-file-name emacsconf-year emacsconf-directory)))
+ (hack-dir-local-variables-non-file-buffer)
(insert
"<!-- Automatically generated by emacsconf-publish-after-page -->\n"
"\n\n"
;; main transcript
(if (plist-get talk :public) (emacsconf-publish-format-captions talk) "")
- (if (emacsconf-talk-file talk "--answers.vtt")
+ (if (and (plist-get talk :qa-public) (emacsconf-talk-file talk "--answers.vtt"))
(emacsconf-publish-format-transcript
(append
(list :chapter-file (emacsconf-talk-file talk "--answers--chapters.vtt")
@@ -1180,7 +1199,7 @@ You can also get this schedule as iCalendar files: ${icals}. Importing that into
(with-temp-file (expand-file-name "schedule-details.md"
(expand-file-name emacsconf-year emacsconf-directory))
(emacsconf-publish-schedule-with-times info)))
- ((or 'cfp 'program)
+ ((or 'cfp 'program 'harvest 'resources)
(with-temp-file (expand-file-name "schedule-details.md"
(expand-file-name emacsconf-year emacsconf-directory))
(emacsconf-publish-program-without-times info))
@@ -1278,6 +1297,8 @@ You can also get this schedule as iCalendar files: ${icals}. Importing that into
(or (plist-get o :toobnix-url)
(plist-get o :video-file)))
"video posted")
+ (when (plist-get o :qa-public)
+ "Q&A posted")
(emacsconf-surround "video: " (plist-get o :video-duration) "" nil)
(emacsconf-surround "answers: " (and (plist-get o :qa-public)
(plist-get o :qa-video-duration))
@@ -1574,7 +1595,7 @@ answers without needing to listen to everything again. You can see <a href=\"htt
;; further tests
(pcase f
((rx (seq "--"
- (or "reencoded" "normalized" "final" "old" "bbb" "backstage")))
+ (or "reencoded" "normalized" "final" "old" "bbb" "backstage" "pad" "silences")))
nil)
((rx ".diff") nil)
((rx "--original")
@@ -2653,17 +2674,19 @@ The Q&A room for ${title} has finished. You can find more information about the
There is no live Q&A room for ${title}. You can find more information about the talk at <a href=\"${base-url}${url}\">${base-url}${url}</a>.</body></html>"
)))))))
-(defun emacsconf-publish-media-files-on-change (talk)
+(defun emacsconf-publish-media-files-on-change (talk &optional always-update)
"Publish the files and update the index."
- (interactive (list (emacsconf-complete-talk-info)))
+ (interactive (list (emacsconf-complete-talk-info) current-prefix-arg))
(let ((org-state (if (boundp 'org-state) org-state (plist-get talk :status))))
(if (plist-get talk :public)
;; Copy main files from backstage to public
(let ((public-files (emacsconf-publish-filter-public-files talk)))
(mapc (lambda (file)
- (when (not (file-exists-p (expand-file-name file emacsconf-public-media-directory)))
- (copy-file (expand-file-name file emacsconf-backstage-dir)
- (expand-file-name file emacsconf-public-media-directory) t)))
+ (when (or always-update (not (file-exists-p (expand-file-name file emacsconf-public-media-directory))))
+ (copy-file (if (file-exists-p (expand-file-name file emacsconf-backstage-dir))
+ (expand-file-name file emacsconf-backstage-dir)
+ (expand-file-name file emacsconf-cache-dir))
+ (expand-file-name file emacsconf-public-media-directory) t)))
public-files))
;; Remove files from public
(let ((files (directory-files emacsconf-public-media-directory nil
@@ -2814,6 +2837,9 @@ Tends to be quota-limited, though."
arguments) " "))
(with-current-buffer (get-buffer-create "*YouTube*")
(erase-buffer)
+ (kill-new (concat (car emacsconf-publish-youtube-upload-command)
+ " "
+ (mapconcat #'shell-quote-argument arguments " ")))
(apply #'call-process
(car emacsconf-publish-youtube-upload-command)
nil t t
@@ -3020,5 +3046,119 @@ Tends to be quota-limited, though."
(expand-file-name (concat (plist-get talk :file-prefix) "--intro.webm")
emacsconf-backstage-dir)
t))))
+
+(defun emacsconf-publish-update-transcript ()
+ (interactive)
+ (emacsconf-subed-make-chapter-file-based-on-comments)
+ (let ((talk (emacsconf-resolve-talk (emacsconf-get-slug-from-string (buffer-file-name)))))
+ (emacsconf-publish-media-files-on-change talk)
+ (emacsconf-publish-with-wiki-change
+ (emacsconf-publish-captions-in-wiki talk)
+ (emacsconf-publish-info-pages-for-talk talk))))
+
+;; for emacs.tv
+(defun emacsconf-publish-insert-video-entries (&optional info tags)
+ (interactive)
+ (setq tags (or tags (format ":emacsconf:emacsconf%s:" emacsconf-year)))
+ (dolist (talk (emacsconf-publish-prepare-for-display (or info (emacsconf-get-talk-info))))
+ (when (emacsconf-talk-file talk "--main.webm")
+ (let ((new-entry (emacsconf-replace-plist-in-string
+ (append
+ (list
+ :conf-name emacsconf-name
+ :conf-year emacsconf-year
+ :media-url (format "https://media.emacsconf.org/%s/%s--main.webm"
+ emacsconf-year
+ (plist-get talk :file-prefix))
+ :transcript-url
+ (if (emacsconf-talk-file "--main.vtt"
+ (format "https://media.emacsconf.org/%s/%s--main.vtt"
+ emacsconf-year
+ (plist-get talk :file-prefix)))
+ "")
+ :duration (or (plist-get talk :qa-video-duration)
+ (emacsconf-format-seconds
+ (/ (compile-media-get-file-duration-ms (emacsconf-talk-file talk "--main.webm"))
+ 1000)))
+ :url (concat emacsconf-base-url (plist-get talk :url))
+ :tags (if (plist-get talk :tags) (concat tags (substring (plist-get talk :tags) 1)) tags)
+ :date (format-time-string "%FT%T%z" (plist-get talk :start-time) t))
+ talk
+ (list :youtube-url "" :toobnix-url "" :speakers ""))
+ "* ${title} ${tags}
+:PROPERTIES:
+:DATE: ${date}
+:URL: ${url}
+:DURATION: ${duration}
+:MEDIA_URL: ${media-url}
+:YOUTUBE_URL: ${youtube-url}
+:TOOBNIX_URL: ${toobnix-url}
+:TRANSCRIPT_URL: ${transcript-url}
+:SPEAKERS: ${speakers}
+:SERIES: ${conf-name} ${conf-year}
+:END:
+"
+ )))
+ (with-current-buffer (find-file-noselect emacstv-index-org)
+ (if (and (plist-get talk :youtube-url) (emacstv-find-by-youtube-url (plist-get talk :youtube-url)))
+ (org-entry-put (point) "DATE" (format-time-string "%FT%T%z" (plist-get talk :start-time) t))
+ (goto-char (point-max))
+ (insert new-entry)))))))
+
+(defun emacsconf-publish-insert-video-entries-for-answers (&optional info tags)
+ (interactive)
+ (setq tags (or tags (format ":answers:emacsconf:emacsconf%s:" emacsconf-year)))
+ (dolist (talk (emacsconf-publish-prepare-for-display (or info (emacsconf-get-talk-info))))
+ (when (emacsconf-talk-file talk "--answers.webm")
+ (let ((new-entry (emacsconf-replace-plist-in-string
+ (append
+ (list
+ :conf-name emacsconf-name
+ :conf-year emacsconf-year
+ :youtube-url (plist-get talk :qa-youtube)
+ :toobnix-url (plist-get talk :qa-toobnix)
+ :media-url (format "https://media.emacsconf.org/%s/%s--answers.webm"
+ emacsconf-year
+ (plist-get talk :file-prefix))
+ :transcript-url (if (emacsconf-talk-file talk "--answers.vtt")
+ (format "https://media.emacsconf.org/%s/%s--answers.vtt"
+ emacsconf-year
+ (plist-get talk :file-prefix))
+ "")
+ :url (concat emacsconf-base-url (plist-get talk :url))
+ :duration (or (plist-get talk :qa-video-duration)
+ (emacsconf-format-seconds
+ (/ (compile-media-get-file-duration-ms (emacsconf-talk-file talk "--answers.webm"))
+ 1000)))
+ :tags (if (plist-get talk :tags) (concat tags (substring (plist-get talk :tags) 1)) tags)
+ :date (format-time-string "%FT%T%z" (plist-get talk :start-time) t))
+ talk
+ (list :youtube-url "" :toobnix-url "" :speakers ""))
+ "* Q&A: ${title} ${tags}
+:PROPERTIES:
+:DATE: ${date}
+:URL: ${url}
+:DURATION: ${duration}
+:MEDIA_URL: ${media-url}
+:YOUTUBE_URL: ${youtube-url}
+:TOOBNIX_URL: ${toobnix-url}
+:TRANSCRIPT_URL: ${transcript-url}
+:SPEAKERS: ${speakers}
+:SERIES: ${conf-name} ${conf-year}
+:END:
+"
+ )))
+ (with-current-buffer (find-file-noselect emacstv-index-org)
+ (if (and (plist-get talk :qa-youtube) (emacstv-find-by-youtube-url (plist-get talk :qa-youtube)))
+ (progn
+ (org-entry-put (point) "DATE" (format-time-string "%FT%T%z" (plist-get talk :start-time) t))
+ (org-entry-put (point)
+ "TRANSCRIPT_URL"
+ (if (emacsconf-talk-file talk "--answers.vtt")
+ (format "https://media.emacsconf.org/%s/%s--answers.vtt"
+ emacsconf-year
+ (plist-get talk :file-prefix))
+ "")))
+ (insert new-entry)))))))
;;
(provide 'emacsconf-publish)