summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--emacsconf-publish.el (renamed from emacsconf-html.el)337
-rw-r--r--emacsconf-subed.el12
-rw-r--r--emacsconf.el79
3 files changed, 296 insertions, 132 deletions
diff --git a/emacsconf-html.el b/emacsconf-publish.el
index 2299db9..7a54f03 100644
--- a/emacsconf-html.el
+++ b/emacsconf-publish.el
@@ -1,48 +1,131 @@
+;;; emacsconf-publish.el --- Publishing -*- lexical-binding: t; -*-
-(defcustom conf-media-base-url "https://media.emacsconf.org/" "Base URL for published media files."
+;; Copyright (C) 2021 Sacha Chua
+
+;; Author: Sacha Chua <sacha@sachachua.com>
+;; Keywords: multimedia
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+
+(defcustom emacsconf-media-base-url "https://media.emacsconf.org/" "Base URL for published media files."
:type 'string
:group 'emacsconf)
-(defcustom conf-main-extensions '(".org" ".odp" ".pdf" ".el" "--main.vtt" "--main_fr.vtt" "--main_ja.vtt" "--chapters.vtt" "--main--chapters.vtt")
+(defcustom emacsconf-main-extensions '(".org" ".odp" ".pdf" ".el" "--main.vtt" "--main_fr.vtt" "--main_ja.vtt" "--chapters.vtt" "--main--chapters.vtt")
"Extensions to list on public pages."
:type '(repeat string)
:group 'emacsconf)
-(defcustom conf-protected-extensions '(".en.srv2" ".srt")
+(defcustom emacsconf-protected-extensions '(".en.srv2" ".srt")
"Extensions to list in the staging area."
:group 'emacsconf)
-(defcustom conf-public-media-directory nil "Can be over TRAMP" :type 'string :group 'emacsconf)
-(defcustom conf-protected-media-directory nil "Can be over TRAMP" :type 'string :group 'emacsconf)
+(defcustom emacsconf-public-media-directory nil "Can be over TRAMP" :type 'string :group 'emacsconf)
+(defcustom emacsconf-protected-media-directory nil "Can be over TRAMP" :type 'string :group 'emacsconf)
-(defun conf-index-card (talk &optional extensions)
+(defun emacsconf-update-talk ()
+ "Publish the schedule page and the page for this talk."
+ (interactive)
+ (emacsconf-upcoming-insert-or-update)
+ (emacsconf-generate-schedule-page (emacsconf-get-talk-info-for-subtree))
+ (emacsconf-generate-main-schedule))
+
+(defun emacsconf-update-conf-html ()
+ "Update the schedules and export the page so I can easily review it."
+ (interactive)
+ (cl-letf* ((new-org (>= (string-to-number (org-version)) 9.5))
+ ;; Fix bug probably introduced by org 9.5, but not investigated
+ ;; thoroughly.
+ ((symbol-function 'org-src-mode--maybe-disable-indent-tabs-mode)
+ (eval `(lambda ()
+ (when (or ,(when new-org
+ '(not org-src--tab-width))
+ (= org-src--tab-width 0))
+ (setq indent-tabs-mode nil))))))
+ (let ((org-confirm-babel-evaluate (or (null emacsconf-allow-dangerous-stuff)
+ org-confirm-babel-evaluate)))
+ (org-update-all-dblocks)
+ (org-babel-execute-buffer)
+ (org-html-export-to-html))))
+
+
+
+(defun emacsconf-update-schedules-in-wiki ()
+ (emacsconf-generate-info-pages)
+ (emacsconf-generate-main-schedule)
+ (emacsconf-generate-ical)
+ (emacsconf-pentabarf-generate))
+
+(defun emacsconf-update-and-publish ()
+ (interactive)
+ (with-current-buffer (find-file-noselect emacsconf-org-file)
+ (emacsconf-update-schedules)
+ (emacsconf-upcoming-update-file)
+ (emacsconf-update-schedules-in-wiki)
+ (emacsconf-update-conf-html)
+ (setq emacsconf-info (emacsconf-get-talk-info))))
+
+(defun emacsconf-update-media ()
+ (interactive)
+ (emacsconf-make-public-index-on-wiki)
+ (when emacsconf-public-media-directory
+ (emacsconf-make-public-index (expand-file-name "index.html" emacsconf-public-media-directory))
+ (emacsconf-generate-playlist (expand-file-name "index.m3u" emacsconf-public-media-directory)
+ "EmacsConf2021"
+ (emacsconf-public-talks emacsconf-info)
+ (format "https://media.emacsconf.org/%s/" emacsconf-year)))
+ (when emacsconf-protected-media-directory
+ (emacsconf-make-protected-index (expand-file-name "index.html" emacsconf-protected-media-directory)))
+ (emacsconf-generate-playlist (expand-file-name "index.m3u" emacsconf-protected-media-directory)
+ "EmacsConf2021" (emacsconf-filter-talks emacsconf-info)
+ (format "https://media.emacsconf.org/%s/protected/" emacsconf-year)))
+
+(defun emacsconf-index-card (talk &optional extensions)
"Format an HTML card for TALK, linking the files in EXTENSIONS."
- (let* ((video-slug (plist-get talk :video-slug))
- (video-file (and (plist-get talk :video-file) (expand-file-name (plist-get talk :video-file) conf-captions-directory)))
- (video (conf-index-card-video (or (plist-get talk :video-id) "mainVideo") video-file talk extensions)))
- ;; Add extra information to the talk
- (setq talk
- (append
- talk
- (list
- :video-html (plist-get video :video)
- :chapter-list (or (plist-get video :chapter-list) "")
- :resources (plist-get video :resources)
- :extra (or (plist-get talk :extra) "")
- :speaker-info (or (plist-get talk :speakers) ""))))
- (if (eq (plist-get talk :format) 'wiki)
- (plist-get talk :video-html)
- (conf-replace-plist-in-string
- talk
- "<div class=\"vid\">${video-html}${resources}${extra}${chapter-list}</div>"))))
-
-(defun conf-index-card-video (video-id video-file talk extensions)
+ (let* ((video-slug (plist-get talk :video-slug))
+ (video-file (and (plist-get talk :video-file) (expand-file-name (plist-get talk :video-file) emacsconf-captions-directory)))
+ (video (emacsconf-index-card-video (or (plist-get talk :video-id) "mainVideo") video-file talk extensions)))
+ ;; Add extra information to the talk
+ (setq talk
+ (append
+ talk
+ (list
+ :video-html (plist-get video :video)
+ :chapter-list (or (plist-get video :chapter-list) "")
+ :resources (plist-get video :resources)
+ :extra (or (plist-get talk :extra) "")
+ :speaker-info (or (plist-get talk :speakers) ""))))
+ (if (eq (plist-get talk :format) 'wiki)
+ (plist-get talk :video-html)
+ (emacsconf-replace-plist-in-string
+ talk
+ "<div class=\"vid\">${video-html}${resources}${extra}${chapter-list}</div>"))))
+
+(defun emacsconf-index-card-video (video-id video-file talk extensions)
(let* ((wiki-caption-dir (expand-file-name
"captions"
(expand-file-name
(plist-get talk :conf-year)
- conf-directory)))
+ emacsconf-directory)))
(chapter-info (and video-file
- (conf-make-chapter-strings
+ (emacsconf-make-chapter-strings
(expand-file-name
(concat (file-name-base video-file) "--chapters.vtt")
wiki-caption-dir)
@@ -53,12 +136,12 @@
:source-src
(when video-file
(if (plist-get talk :public)
- (format "%s%s/%s" conf-media-base-url (plist-get talk :conf-year)
+ (format "%s%s/%s" emacsconf-media-base-url (plist-get talk :conf-year)
(file-name-nondirectory video-file))
(file-name-nondirectory video-file)))
:captions
(and video-file
- (conf-video-subtitle-tracks
+ (emacsconf-video-subtitle-tracks
(expand-file-name (concat (file-name-base video-file) ".vtt") wiki-caption-dir)
(or (plist-get talk :track-base-url)
(plist-get talk :base-url))))
@@ -73,7 +156,7 @@
"")
:video-id video-id
:video-duration (if (and video-file (file-exists-p video-file))
- (format-seconds "%m:%.2s" (/ (conf-get-file-duration-ms video-file) 1000)))
+ (format-seconds "%m:%.2s" (/ (compile-media-get-file-duration-ms video-file) 1000)))
:video-file-size (if (and video-file (file-exists-p video-file))
(file-size-human-readable (file-attribute-size (file-attributes video-file))))
:other-files
@@ -82,7 +165,7 @@
(if (eq (plist-get talk :format) 'wiki)
(concat s " \n")
(concat "<li>" s "</li>")))
- (conf-link-file-formats-as-list talk (or extensions conf-published-extensions))
+ (emacsconf-link-file-formats-as-list talk (or extensions emacsconf-published-extensions))
"")
:poster (and video-file (format "https://media.emacsconf.org/%s/%s.png" (plist-get talk :conf-year) (file-name-base video-file)))
:toobnix-info (if (plist-get talk :toobnix-url)
@@ -96,7 +179,7 @@
talk)))
(list
:video
- (conf-replace-plist-in-string
+ (emacsconf-replace-plist-in-string
info
(if (and video-file (file-exists-p video-file))
(if (eq (plist-get talk :format) 'wiki)
@@ -107,21 +190,21 @@ ${chapter-list}
"<video controls preload=\"metadata\" poster=\"${poster}\" id=\"${video-id}\"><source src=\"${source-src}\" />${captions}${chapter-track}</video>")
"The video for \"${title}\" will be posted here when available. You can also subscribe to the <a href=\"https://lists.gnu.org/mailman/listinfo/emacsconf-discuss\">emacsconf-discuss mailing list</a> for updates."))
:resources
- (conf-replace-plist-in-string
+ (emacsconf-replace-plist-in-string
(append info
(list :video-download
(if video-file
- (conf-replace-plist-in-string
+ (emacsconf-replace-plist-in-string
info
"<li><a href=\"${source-src}\">Download .webm video (${video-duration}, ${video-file-size}B)</a></li>")
"")))
"<div class=\"files resources\"><ul>${video-download}${other-files}${toobnix-info}</ul></div>"))))
(when (featurep 'memoize)
- (memoize #'conf-get-file-duration-ms))
+ (memoize #'compile-media-get-file-duration-ms))
-(defun conf-create-talk-pages (conf-info)
- (interactive (list (conf-get-talk-info)))
+(defun emacsconf-create-talk-pages (emacsconf-info)
+ (interactive (list (emacsconf-get-talk-info)))
"Populate year/talks/*.md files.
These should include the nav and schedule files, which will be
rewritten as needed. After they are generated, they should be all
@@ -132,7 +215,7 @@ resources."
(mapc (lambda (o)
(when (plist-get o :talk-id)
(let ((filename (expand-file-name (format "%s.md" (plist-get o :slug))
- (expand-file-name "talks" (expand-file-name conf-year conf-directory)))))
+ (expand-file-name "talks" (expand-file-name emacsconf-year emacsconf-directory)))))
(unless (file-exists-p filename)
(with-temp-file filename
(let ((meta "!meta")
@@ -143,8 +226,8 @@ resources."
(info (or (plist-get o :info) "")))
(insert
(s-lex-format "[[${meta} title=\"${title}\"]]
-[[${meta} copyright=\"Copyright &copy; ${conf-year} ${speakers}\"]]
-[[!inline pages=\"internal(${conf-year}/info/${slug}-nav)\" raw=\"yes\"]]
+[[${meta} copyright=\"Copyright &copy; ${emacsconf-year} ${speakers}\"]]
+[[!inline pages=\"internal(${emacsconf-year}/info/${slug}-nav)\" raw=\"yes\"]]
<!-- You can manually edit this file to update the abstract, add links, etc. --->\n
@@ -153,50 +236,50 @@ ${speakers}
${info}
-[[!inline pages=\"internal(${conf-year}/info/${slug}-schedule)\" raw=\"yes\"]]
+[[!inline pages=\"internal(${emacsconf-year}/info/${slug}-schedule)\" raw=\"yes\"]]
-[[!inline pages=\"internal(${conf-year}/info/${slug}-nav)\" raw=\"yes\"]]
+[[!inline pages=\"internal(${emacsconf-year}/info/${slug}-nav)\" raw=\"yes\"]]
"))))))))
- conf-info))
+ emacsconf-info))
-(defun conf-wiki-talk-resources (o)
+(defun emacsconf-wiki-talk-resources (o)
(setq o (append (list :format 'wiki
:base-url
- (concat conf-media-base-url (plist-get o :conf-year) "/")
+ (concat emacsconf-media-base-url (plist-get o :conf-year) "/")
:track-base-url
(format "/%s/captions/" (plist-get o :conf-year)))
o))
(concat
(if (plist-get o :qa-public) "# Talk\n\n" "")
- (conf-index-card o conf-main-extensions)
+ (emacsconf-index-card o emacsconf-main-extensions)
(if (plist-get o :qa-public)
(concat "\n\n# Q&A\n\n"
- (conf-index-card (append
+ (emacsconf-index-card (append
(list
:public 1
:video-id "qanda"
:toobnix-url nil
:video-file (expand-file-name
(concat (file-name-sans-extension (plist-get o :video-slug)) "--answers.webm")
- conf-captions-directory))
+ emacsconf-captions-directory))
o)
(list "--answers.vtt" "--answers--chapters.vtt")))
"")))
-(defun conf-format-talk-schedule-info (o)
- (let ((friendly (concat "/" conf-year "/talks/" (plist-get o :slug) ))
+(defun emacsconf-format-talk-schedule-info (o)
+ (let ((friendly (concat "/" emacsconf-year "/talks/" (plist-get o :slug) ))
(timestamp (org-timestamp-from-string (plist-get o :scheduled))))
(concat
"[[!toc ]]\n"
(if (plist-get o :q-and-a) (format "Q&A: %s \n" (plist-get o :q-and-a)) "")
- (if (member conf-publishing-phase '(program schedule)) (concat "Status: " (plist-get o :status-label) " \n") "")
+ (if (member emacsconf-publishing-phase '(program schedule)) (concat "Status: " (plist-get o :status-label) " \n") "")
"Duration: " (or (plist-get o :video-duration)
(concat (plist-get o :duration) " minutes"))
" \n"
- (if (and (member conf-publishing-phase '(program schedule))
+ (if (and (member emacsconf-publishing-phase '(program schedule))
(not (member (plist-get o :status) '("DONE" "CANCELLED" "STARTED"))))
(let ((start (org-timestamp-to-time (org-timestamp-split-range timestamp)))
(end (org-timestamp-to-time (org-timestamp-split-range timestamp t))))
@@ -204,50 +287,50 @@ ${info}
"<div class=\"times\" start=\"%s\" end=\"%s\">%s<br /><a href=\"/2021/\">Find out how to watch and participate</a></div>"
(format-time-string "%Y-%m-%dT%H:%M:%SZ" start t)
(format-time-string "%Y-%m-%dT%H:%M:%SZ" end t)
- (string-join (conf-timezone-strings o) "<br />")))
+ (string-join (emacsconf-timezone-strings o) "<br />")))
"")
"\n"
(if (plist-get o :alternate-apac)
- (format "[[!inline pages=\"internal(%s/inline-alternate)\" raw=\"yes\"]] \n" conf-year)
+ (format "[[!inline pages=\"internal(%s/inline-alternate)\" raw=\"yes\"]] \n" emacsconf-year)
"")
"\n"
"If you have questions and the speaker has not indicated public contact information on this page, please feel free to e-mail us at <emacsconf-submit@gnu.org> and we'll forward your question to the speaker.\n\n"
- (if (plist-get o :public) (conf-wiki-talk-resources o) "")
+ (if (plist-get o :public) (emacsconf-wiki-talk-resources o) "")
"\n# Description\n\n")))
-(defun conf-generate-schedule-page (talk)
- (interactive (list (conf-get-talk-info-for-subtree)))
+(defun emacsconf-generate-schedule-page (talk)
+ (interactive (list (emacsconf-get-talk-info-for-subtree)))
(with-temp-file (expand-file-name (format "%s-schedule.md" (plist-get talk :slug))
- (expand-file-name "info" (expand-file-name conf-year conf-directory)))
+ (expand-file-name "info" (expand-file-name emacsconf-year emacsconf-directory)))
(insert
"<!-- Automatically generated by conf-create-info-pages -->\n\n"
- (conf-format-talk-schedule-info talk) "\n")))
+ (emacsconf-format-talk-schedule-info talk) "\n")))
-(defun conf-generate-info-pages ()
+(defun emacsconf-generate-info-pages ()
(interactive)
"Populate year/info/*-nav and *-schedule.md files."
;; TODO: No longer necessary?
(require 's)
(let* ((talks (seq-remove (lambda (o) (string= (plist-get o :status) "CANCELLED"))
- (conf-filter-talks (conf-get-talk-info))))
+ (emacsconf-filter-talks (emacsconf-get-talk-info))))
(next-talks (cdr talks))
(prev-talks (cons nil talks)))
(while talks
(let* ((o (pop talks))
- (next-talk (conf-format-talk-link (pop next-talks)))
- (prev-talk (conf-format-talk-link (pop prev-talks)))
- (friendly (concat "/" conf-year "/talks/" (plist-get o :slug) ))
+ (next-talk (emacsconf-format-talk-link (pop next-talks)))
+ (prev-talk (emacsconf-format-talk-link (pop prev-talks)))
+ (friendly (concat "/" emacsconf-year "/talks/" (plist-get o :slug) ))
(nav-links (format "Back to the [[schedule]] \n%s%s"
(if prev-talk (format "Previous: %s \n" prev-talk) "")
(if next-talk (format "Next: %s \n" next-talk) ""))))
(with-temp-file (expand-file-name (format "%s-nav.md" (plist-get o :slug))
- (expand-file-name "info" (expand-file-name conf-year conf-directory)))
+ (expand-file-name "info" (expand-file-name emacsconf-year emacsconf-directory)))
(insert nav-links))
- (conf-generate-schedule-page o)))))
+ (emacsconf-generate-schedule-page o)))))
-(defun conf-generate-talks-page (conf-info)
+(defun emacsconf-generate-talks-page (emacsconf-info)
(interactive "p")
- (let ((info conf-info))
+ (let ((info emacsconf-info))
(with-temp-buffer
(find-file "talk-details.md")
(erase-buffer)
@@ -257,34 +340,34 @@ ${info}
(let* ((title (plist-get o :title))
(speakers (plist-get o :speakers)))
(if (null (plist-get o :talk-id))
- (format "<tr><td colspan=\"3\">%s</td></tr>" (conf-format-talk-link o))
+ (format "<tr><td colspan=\"3\">%s</td></tr>" (emacsconf-format-talk-link o))
(format "<tr><td>%s</td><td>%s</td><td>%s</td><tr>"
(plist-get o :duration)
- (conf-format-talk-link o)
+ (emacsconf-format-talk-link o)
(plist-get o :speakers)))))
info "\n")))
(save-buffer))))
-(defun conf-generate-main-schedule (&optional filename)
+(defun emacsconf-generate-main-schedule (&optional filename)
(interactive)
- (with-temp-file (expand-file-name "schedule-details.md" (expand-file-name conf-year conf-directory))
- (insert (conf-format-talk-info-as-schedule (conf-get-talk-info)))))
+ (with-temp-file (expand-file-name "schedule-details.md" (expand-file-name emacsconf-year emacsconf-directory))
+ (insert (emacsconf-format-talk-info-as-schedule (emacsconf-get-talk-info)))))
-(defun conf-format-talk-link (talk)
+(defun emacsconf-format-talk-link (talk)
(and talk (if (plist-get talk :talk-id)
(format "<a href=\"/%s/talks/%s\">%s</a>"
- conf-year
+ emacsconf-year
(plist-get talk :slug)
(plist-get talk :title))
(plist-get talk :title))))
-(defun conf-format-talk-info-as-schedule (info)
+(defun emacsconf-format-talk-info-as-schedule (info)
(let* ((talks (seq-filter
(lambda (o)
(and (not (string= (plist-get o :status) "CANCELLED"))
(plist-get o :speakers)))
- (conf-filter-talks info)))
+ (emacsconf-filter-talks info)))
(captioned (seq-filter (lambda (o) (plist-get o :captioner)) talks))
(cancelled (seq-filter (lambda (o) (string= (plist-get o :status) "CANCELLED")) info))
(received (seq-remove (lambda (o)
@@ -298,7 +381,7 @@ ${info}
(length received)
(apply '+ (mapcar (lambda (info) (string-to-number (plist-get info :duration)))
received))
- (pcase conf-publishing-phase
+ (pcase emacsconf-publishing-phase
('program "<tr><th>Status</th><th>Title<th><th>Speaker(s)</th></tr>")
('schedule "<tr><th>Status</th><th>Start</th><th>Title</th><th>Speaker(s)</th></tr>")
('resources "<tr><th>Title</th><th>Speaker(s)</th><th>Resources</th></tr>"))
@@ -316,38 +399,38 @@ ${info}
("STARTED" "now playing")
(_ "")))
(speakers (or (plist-get o :speakers) "")))
- (pcase conf-publishing-phase
+ (pcase emacsconf-publishing-phase
('program
(if (eq (plist-get o :type) 'headline)
(format "<tr><td colspan=\"3\"><strong>%s<strong></td></tr>"
(if (plist-get o :slug)
- (conf-format-talk-link o)
+ (emacsconf-format-talk-link o)
title))
(format "<tr><td>%s</td><td>%s</td><td>%s</td></tr>"
status
- (conf-format-talk-link o) speakers)))
+ (emacsconf-format-talk-link o) speakers)))
('schedule
(if (eq (plist-get o :type) 'headline)
(format "<tr><td colspan=\"4\"><strong>%s<strong></td></tr>"
(if (plist-get o :slug)
- (conf-format-talk-link o)
+ (emacsconf-format-talk-link o)
title))
(format "<tr><td>%s</td><td width=100>~%s</td><td>%s</td><td>%s</td></tr>"
status
- start (conf-format-talk-link o) speakers)))
+ start (emacsconf-format-talk-link o) speakers)))
('resources
(if (eq (plist-get o :type) 'headline)
(format "<tr><td colspan=\"3\"><strong>%s<strong></td></tr>"
(if (plist-get o :slug)
- (conf-format-talk-link o)
+ (emacsconf-format-talk-link o)
title))
(format "<tr><td>%s</td><td>%s</td><td><ul>%s</ul></td></tr>"
- (conf-format-talk-link o) speakers
+ (emacsconf-format-talk-link o) speakers
(mapconcat (lambda (s) (concat "<li>" s "</li>"))
- (conf-link-file-formats-as-list
+ (emacsconf-link-file-formats-as-list
(append o
- (list :base-url (format "%s%s/" conf-media-base-url conf-year)))
- (append conf-published-extensions '("--main.webm")))
+ (list :base-url (format "%s%s/" emacsconf-media-base-url emacsconf-year)))
+ (append emacsconf-published-extensions '("--main.webm")))
"")))))))
(seq-remove (lambda (o) (string= (plist-get o :status) "CANCELLED"))
(cdr info))
@@ -355,14 +438,14 @@ ${info}
(if (> (length cancelled) 0)
(format "<div class=\"cancelled\">Cancelled:<ul>%s</ul></div>"
(mapconcat (lambda (talk) (format "<li><a href=\"/%s/talks/%s\">%s</a> - %s</li>"
- conf-year
+ emacsconf-year
(plist-get talk :slug)
(plist-get talk :title)
(plist-get talk :speakers)))
cancelled "\n"))
""))))
-(defun conf-timezone-strings (o)
+(defun emacsconf-timezone-strings (o)
(let* ((timestamp (org-timestamp-from-string (plist-get o :scheduled)))
(start (org-timestamp-to-time (org-timestamp-split-range timestamp)))
(end (org-timestamp-to-time (org-timestamp-split-range timestamp t))))
@@ -373,13 +456,13 @@ ${info}
start tz)
(format-time-string "%l:%M %p %Z"
end tz)))
- conf-timezones)))
+ emacsconf-timezones)))
-(defun conf-make-protected-index (filename)
- (interactive (list (expand-file-name "index.html" conf-protected-media-directory)))
- (setq conf-info (conf-get-talk-info))
+(defun emacsconf-make-protected-index (filename)
+ (interactive (list (expand-file-name "index.html" emacsconf-protected-media-directory)))
+ (setq emacsconf-info (emacsconf-get-talk-info))
(with-temp-file filename
- (let* ((talks (seq-filter (lambda (o) (plist-get o :video-file)) (conf-filter-talks conf-info)))
+ (let* ((talks (seq-filter (lambda (o) (plist-get o :video-file)) (emacsconf-filter-talks emacsconf-info)))
(received (seq-remove (lambda (o) (plist-get o :captioner)) talks))
(captioned (seq-filter (lambda (o) (plist-get o :captioner)) talks)))
(insert
@@ -392,12 +475,12 @@ ${info}
(format "<li><strong>%s</strong><br />%s<br />%s</li>"
(plist-get f :title)
(plist-get f :speakers)
- (conf-index-card
+ (emacsconf-index-card
(append
f
(list :extra
(if (plist-get f :caption-note) (concat "<div class=\"caption-note\">" (plist-get f :caption-note) "</div>") "")))
- (append conf-main-extensions conf-protected-extensions))))
+ (append emacsconf-main-extensions emacsconf-protected-extensions))))
received
"\n")
(format
@@ -408,38 +491,38 @@ ${info}
(mapconcat (lambda (f) (format "<li><strong>%s</strong><br />%s<br />%s</li>"
(plist-get f :title)
(plist-get f :speakers)
- (conf-index-card f conf-main-extensions)))
+ (emacsconf-index-card f emacsconf-main-extensions)))
captioned "\n")
"</ol>"
- (if (file-exists-p (expand-file-name "include-in-index.html" conf-captions-directory))
- (with-temp-buffer (insert-file-contents (expand-file-name "include-in-index.html" conf-captions-directory)) (buffer-string))
+ (if (file-exists-p (expand-file-name "include-in-index.html" emacsconf-captions-directory))
+ (with-temp-buffer (insert-file-contents (expand-file-name "include-in-index.html" emacsconf-captions-directory)) (buffer-string))
"")
"</body></html>"))))
-(defun conf-make-public-index (filename)
- (interactive (list (expand-file-name "index.html" conf-public-media-directory)))
- (setq conf-info (conf-get-talk-info))
+(defun emacsconf-make-public-index (filename)
+ (interactive (list (expand-file-name "index.html" emacsconf-public-media-directory)))
+ (setq emacsconf-info (emacsconf-get-talk-info))
(with-temp-file filename
(insert
"<html><body>"
- "<h1>" conf-name " " conf-year "</h1>"
+ "<h1>" emacsconf-name " " emacsconf-year "</h1>"
"<div class=\"m3u\"><a href=\"index.m3u\">M3U playlist for playing in MPV and other players</a></div>"
"<ol class=\"videos\">"
- (mapconcat (lambda (f) (format "<li>%s</li>" (conf-index-card f '(".org" ".pdf" "--main.vtt"))))
- (conf-public-talks conf-info)
+ (mapconcat (lambda (f) (format "<li>%s</li>" (emacsconf-index-card f '(".org" ".pdf" "--main.vtt"))))
+ (emacsconf-public-talks emacsconf-info)
"\n")
"</ol>"
- (if (file-exists-p (expand-file-name "include-in-index.html" conf-captions-directory))
- (with-temp-buffer (insert-file-contents (expand-file-name "include-in-index.html" conf-captions-directory)) (buffer-string))
+ (if (file-exists-p (expand-file-name "include-in-index.html" emacsconf-captions-directory))
+ (with-temp-buffer (insert-file-contents (expand-file-name "include-in-index.html" emacsconf-captions-directory)) (buffer-string))
"")
"</body></html>")))
-(defun conf-make-public-index-on-wiki ()
+(defun emacsconf-make-public-index-on-wiki ()
(interactive)
(let ((info (seq-filter (lambda (o)
(not (string= (plist-get o :status) "CANCELLED")))
- (conf-filter-talks (conf-get-talk-info)))))
- (with-temp-file (expand-file-name "all-include.md" (expand-file-name conf-year conf-directory))
+ (emacsconf-filter-talks (emacsconf-get-talk-info)))))
+ (with-temp-file (expand-file-name "all-include.md" (expand-file-name emacsconf-year emacsconf-directory))
(insert
"<ol class=\"videos\">"
(mapconcat
@@ -449,26 +532,26 @@ ${info}
(plist-get f :title)
(or (plist-get f :speakers) "")
(if (plist-get f :public)
- (conf-index-card
+ (emacsconf-index-card
(append (list :base-url
- (concat conf-media-base-url (plist-get f :conf-year) "/")
+ (concat emacsconf-media-base-url (plist-get f :conf-year) "/")
:track-base-url
(format "/%s/captions/" (plist-get f :conf-year)))
f)
- conf-published-extensions)
+ emacsconf-published-extensions)
"")
(if (plist-get f :qa-public)
- (conf-index-card
+ (emacsconf-index-card
(append
(list
:public 1
- :base-url (concat conf-media-base-url (plist-get f :conf-year) "/")
+ :base-url (concat emacsconf-media-base-url (plist-get f :conf-year) "/")
:video-id "qanda"
:track-base-url
(format "/%s/captions/" (plist-get f :conf-year))
:video-file (expand-file-name
(concat (file-name-sans-extension (plist-get f :video-slug)) "--answers.webm")
- conf-captions-directory))
+ emacsconf-captions-directory))
f)
(list "--answers.vtt" "--answers--chapters.vtt"))
"")))
@@ -477,12 +560,12 @@ ${info}
-(defun conf-make-chapter-strings (filename track-base-url)
+(defun emacsconf-make-chapter-strings (filename track-base-url)
(when (file-exists-p filename)
(let ((chapters (with-temp-buffer
(insert-file-contents filename)
(subed-vtt--init)
- (conf-chapters-buffer-as-list))))
+ (emacsconf-chapters-buffer-as-list))))
(list
:track (format "<track kind=\"chapters\" label=\"Chapters\" src=\"%s\"\" />"
(concat (or track-base-url "") (file-name-nondirectory filename)))
@@ -504,7 +587,7 @@ ${info}
chapters
"\n"))))))
-(defun conf-video-subtitle-tracks (filename track-base-url)
+(defun emacsconf-video-subtitle-tracks (filename track-base-url)
(concat
(if (file-exists-p filename)
(format "<track label=\"English\" kind=\"captions\" srclang=\"en\" src=\"%s\" default />"
@@ -523,19 +606,19 @@ ${info}
'(("fr" . "French") ("ja" . "Japanese"))
"")))
-(defun conf-link-file-formats (video-slug extensions)
- (string-join (conf-link-file-formats-as-list video-slug extensions) " "))
+(defun emacsconf-link-file-formats (video-slug extensions)
+ (string-join (emacsconf-link-file-formats-as-list video-slug extensions) " "))
-(defun conf-link-file-formats-as-list (talk extensions)
+(defun emacsconf-link-file-formats-as-list (talk extensions)
(let ((video-slug (plist-get talk :video-slug))
- (wiki-captions-dir (expand-file-name "captions" (expand-file-name (plist-get talk :conf-year) conf-directory))))
+ (wiki-captions-dir (expand-file-name "captions" (expand-file-name (plist-get talk :conf-year) emacsconf-directory))))
(delq nil (seq-map (lambda (ext)
(if (file-exists-p
(expand-file-name
(concat video-slug ext)
(if (string-match "\\.vtt$" ext)
wiki-captions-dir
- conf-captions-directory)))
+ emacsconf-captions-directory)))
(if (eq (plist-get talk :format) 'wiki)
(format "[Download %s](%s%s)"
ext
@@ -546,3 +629,5 @@ ${info}
(concat video-slug ext)
ext))))
extensions))))
+
+(provide 'emacsconf-publish)
diff --git a/emacsconf-subed.el b/emacsconf-subed.el
index cfb81b4..899f3a0 100644
--- a/emacsconf-subed.el
+++ b/emacsconf-subed.el
@@ -93,12 +93,12 @@
(kill-new result))
result))
-(defun conf-prepare-transcript-directives ()
+(defun emacsconf-subed-prepare-transcript-directives ()
(interactive)
(let* ((info (emacsconf-get-talk-info-for-subtree))
(wiki-file (plist-get info :wiki-file-path))
(caption-file (expand-file-name (concat (plist-get info :video-slug) "--main.vtt")
- conf-captions-directory))
+ emacsconf-captions-directory))
(chapters (emacsconf-subed-chapters-as-list info)))
(with-temp-file wiki-file
(insert
@@ -114,7 +114,7 @@
(format "youtube-dl --write-sub --write-auto-sub --no-warnings --sub-lang en --skip-download --sub-format %s %s -o %s"
f
youtube-url
- (expand-file-name video-slug conf-captions-directory)))
+ (expand-file-name video-slug emacsconf-captions-directory)))
'("vtt" "srv2")
";")))
@@ -151,7 +151,7 @@ Create it if necessary."
(require 'compile-media)
(let ((video-slug (org-entry-get (point) "VIDEO_SLUG")))
(find-file
- (or (car (directory-files conf-captions-directory
+ (or (car (directory-files emacsconf-captions-directory
t
(concat (regexp-quote video-slug)
"--main\\.\\(srt\\|vtt\\)")))
@@ -174,9 +174,9 @@ Create it if necessary."
(defun emacsconf-subed-chapters-as-list (info)
(when (file-exists-p (expand-file-name (concat (plist-get info :video-slug) "--main--chapters.vtt")
- conf-captions-directory))
+ emacsconf-captions-directory))
(with-current-buffer (find-file-noselect (expand-file-name (concat (plist-get info :video-slug) "--main--chapters.vtt")
- conf-captions-directory))
+ emacsconf-captions-directory))
(let (result)
(subed-for-each-subtitle (point-min) (point-max) nil
(setq result
diff --git a/emacsconf.el b/emacsconf.el
new file mode 100644
index 0000000..8f2be80
--- /dev/null
+++ b/emacsconf.el
@@ -0,0 +1,79 @@
+;;; emacsconf.el --- Core functions and variables for EmacsConf -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Sacha Chua
+
+;; Author: Sacha Chua <sacha@sachachua.com>
+;; Keywords: multimedia
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(defgroup emacsconf nil "EmacsConf" :group 'multimedia)
+
+(defcustom emacsconf-name "EmacsConf"
+ "Name of conference"
+ :group 'emacsconf
+ :type 'string)
+(defcustom emacsconf-year "2021"
+ "Conference year. String for easy inclusion."
+ :group 'emacsconf
+ :type 'string)
+(defcustom emacsconf-directory "~/vendor/emacsconf-wiki"
+ "Directory where the wiki files are."
+ :group 'emacsconf
+ :type 'directory)
+(defcustom emacsconf-timezones '("America/Toronto" "America/Los_Angeles" "UTC" "Europe/Paris" "Europe/Athens" "Asia/Kolkata" "Asia/Singapore" "Asia/Tokyo") "List of timezones."
+ :group 'emacsconf
+ :type '(repeat string))
+
+(defcustom emacsconf-base-url "https://emacsconf.org/" "Includes trailing slash"
+ :group 'emacsconf
+ :type 'string)
+(defcustom emacsconf-publishing-phase 'resources
+ "Controls what information to include.
+'program - don't include times
+'schedule - include times; use this leading up to the conference
+'resources - after the emacsconference, don't need status"
+ :group 'emacsconf
+ :type '(choice
+ (const :tag "Program: Don't include times" program)
+ (const :tag "Schedule: Include detailed times" schedule)
+ (const :tag "Resources: Don't include status" resources)))
+
+(defcustom emacsconf-org-file nil
+ "Path to the Org file with conference information."
+ :type 'file
+ :group 'emacsconf)
+
+(defcustom emacsconf-upcoming-file nil
+ "Path to the Org file with upcoming talks."
+ :type 'file
+ :group 'emacsconf)
+
+(defcustom emacsconf-download-directory "~/Downloads"
+ "Directory to check for downloaded files."
+ :type 'directory
+ :group 'emacsconf)
+
+(defun emacsconf-latest-file (path &optional filter)
+ "Return the newest file in PATH. Optionally filter by FILTER."
+ (car (sort (seq-remove #'file-directory-p (directory-files path 'full filter t)) #'file-newer-than-file-p)))
+
+(provide 'emacsconf)
+;;; emacsconf.el ends here