summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--emacsconf-extract.el122
1 files changed, 95 insertions, 27 deletions
diff --git a/emacsconf-extract.el b/emacsconf-extract.el
index 7fb3e12..ceca898 100644
--- a/emacsconf-extract.el
+++ b/emacsconf-extract.el
@@ -1070,6 +1070,10 @@ Strategies:
(plz 'get "https://youtube.googleapis.com/youtube/v3/channels?part=contentDetails&mine=true"
:headers `(("Authorization" . ,(url-oauth-auth "https://youtube.googleapis.com/youtube/v3/")))
:as #'json-read))
+ (setq emacsconf-extract-youtube-api-playlists
+ (plz 'get "https://youtube.googleapis.com/youtube/v3/playlists?part=snippet,contentDetails&mine=true"
+ :headers `(("Authorization" . ,(url-oauth-auth "https://youtube.googleapis.com/youtube/v3/")))
+ :as #'json-read))
(setq emacsconf-extract-youtube-api-categories
(plz 'get "https://youtube.googleapis.com/youtube/v3/videoCategories?part=snippet&regionCode=CA"
:headers `(("Authorization" . ,(url-oauth-auth "https://youtube.googleapis.com/youtube/v3/")))
@@ -1086,7 +1090,7 @@ Strategies:
(defvar emacsconf-extract-youtube-tags '("emacs" "emacsconf"))
(defun emacsconf-extract-youtube-object (video-id talk &optional privacy-status)
"Format the video object for VIDEO-ID using TALK details."
- (setq privacy-status (or privacy-status "unlisted"))
+ (setq privacy-status (or privacy-status "public"))
(let ((properties (emacsconf-publish-talk-video-properties talk 'youtube)))
`((id . ,video-id)
(kind . "youtube#video")
@@ -1098,32 +1102,44 @@ Strategies:
;; Even though I set recordingDetails and status, it doesn't seem to stick.
;; I'll leave this in here in case someone else can figure it out.
(recordingDetails (recordingDate . ,(format-time-string "%Y-%m-%dT%TZ" (plist-get talk :start-time) t))))
- (status (privacyStatus . "unlisted")
+ (status (privacyStatus . ,privacy-status)
(license . "creativeCommon")))))
+(defun emacsconf-extract-youtube-get-slug-for-video (video-object)
+ (let-alist video-object
+ (cond
+ ;; not yet renamed
+ ((string-match (rx (literal emacsconf-id) " " (literal emacsconf-year) " "
+ (group (1+ (or (syntax word) "-")))
+ " ")
+ .snippet.title)
+ (match-string 1 .snippet.title))
+ ;; renamed, match the description instead
+ ((string-match (rx (literal emacsconf-base-url) (literal emacsconf-year) "/talks/"
+ (group (1+ (or (syntax word) "-"))))
+ .snippet.description)
+ (match-string 1 .snippet.description))
+ (t
+ (plist-get
+ (seq-find (lambda (o) (string-match (regexp-quote .snippet.resourceId.videoId) (or (plist-get o :youtube-url) "")))
+ (emacsconf-get-talk-info))
+ :slug)))))
+
+(defun emacsconf-extract-youtube-get-talk-for-video (video-object)
+ (when-let ((slug (emacsconf-extract-youtube-get-slug-for-video video-object)))
+ (emacsconf-resolve-talk slug)))
+
(defun emacsconf-extract-youtube-api-update-video (video-object)
"Update VIDEO-OBJECT."
(let-alist video-object
- (let* ((slug (cond
- ;; not yet renamed
- ((string-match (rx (literal emacsconf-id) " " (literal emacsconf-year) " "
- (group (1+ (or (syntax word) "-")))
- " ")
- .snippet.title)
- (match-string 1 .snippet.title))
- ;; renamed, match the description instead
- ((string-match (rx (literal emacsconf-base-url) (literal emacsconf-year) "/talks/"
- (group (1+ (or (syntax word) "-"))))
- .snippet.description)
- (match-string 1 .snippet.description))
- ;; can't find, prompt
- (t
- (when (string-match (rx (literal emacsconf-id) " " (literal emacsconf-year))
- .snippet.title)
- (completing-read (format "Slug for %s: "
- .snippet.title)
- (seq-map (lambda (o) (plist-get o :slug))
- (emacsconf-publish-prepare-for-display (emacsconf-get-talk-info))))))))
+ (let* ((slug (or (emacsconf-extract-youtube-get-slug-for-video video-object)
+ (when (string-match (rx (literal emacsconf-id) " " (literal emacsconf-year))
+ .snippet.title)
+ (completing-read (format "Slug for %s: "
+ .snippet.title)
+ (seq-map (lambda (o) (plist-get o :slug))
+ (emacsconf-publish-prepare-for-display (emacsconf-get-talk-info)))))))
+ (talk (and slug (emacsconf-resolve-talk slug)))
(video-id .snippet.resourceId.videoId)
(id .id)
result)
@@ -1136,16 +1152,68 @@ Strategies:
:headers `(("Authorization" . ,(url-oauth-auth "https://youtube.googleapis.com/youtube/v3/"))
("Accept" . "application/json")
("Content-Type" . "application/json"))
- :body (json-encode (emacsconf-extract-youtube-object video-id (emacsconf-resolve-talk slug))))))))
+ :body (json-encode (emacsconf-extract-youtube-object video-id talk)))))))
(defun emacsconf-extract-youtube-rename-videos (&optional videos)
"Rename videos and set the YOUTUBE_URL property in the Org heading."
+ (interactive)
(let ((info (emacsconf-get-talk-info)))
(mapc
(lambda (video)
- (when (string-match (rx (literal emacsconf-id) " " (literal emacsconf-year)))
- (emacsconf-extract-youtube-api-update-video video)))
- (assoc-default 'items (or videos emacsconf-extract-youtube-api-videos)))))
-
+ (let-alist video
+ (when (string-match (rx (literal emacsconf-id) " " (literal emacsconf-year) " ")
+ .snippet.title)
+ (emacsconf-extract-youtube-api-update-video video))))
+ (assoc-default
+ 'items
+ (or videos emacsconf-extract-youtube-api-videos
+ (plz 'get (concat "https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet,contentDetails,status&forMine=true&order=date&maxResults=50&playlistId="
+ (url-hexify-string
+ (let-alist (elt (assoc-default 'items emacsconf-extract-youtube-api-channels) 0)
+ .contentDetails.relatedPlaylists.uploads)
+ ))
+ :headers `(("Authorization" . ,(url-oauth-auth "https://youtube.googleapis.com/youtube/v3/")))
+ :as #'json-read))))))
+
+;; This still needed some tweaking, so maybe next time we'll try just inserting the items into the playlist
+(defun emacsconf-extract-youtube-sort-playlist ()
+ (interactive)
+ (let* ((playlist-info
+ (seq-find (lambda (o) (let-alist o (string= .snippet.title (concat emacsconf-name " " emacsconf-year))))
+ (assoc-default 'items emacsconf-extract-youtube-api-playlists)))
+ (playlist-items
+ (assoc-default 'items
+ (plz 'get (concat "https://youtube.googleapis.com/youtube/v3/playlistItems?part=snippet,contentDetails,status&forMine=true&order=date&maxResults=50&playlistId=" (url-hexify-string (assoc-default 'id playlist-info)))
+ :headers `(("Authorization" . ,(url-oauth-auth "https://youtube.googleapis.com/youtube/v3/")))
+ :as #'json-read)))
+ (info (emacsconf-publish-prepare-for-display (emacsconf-get-talk-info)))
+ (slugs (seq-map (lambda (o) (plist-get o :slug)) info))
+ last-position)
+ ;; sort items
+ (seq-map-indexed (lambda (talk position)
+ (let ((video-object (seq-find (lambda (video) (string= (plist-get talk :slug)
+ (emacsconf-extract-youtube-get-slug-for-video video)))
+ playlist-items)))
+ (let-alist video-object
+ (cond
+ ((null video-object)
+ (message "Could not find video for %s" (plist-get talk :slug)))
+ ;; not in the right position, try to move it
+ ((> .snippet.position position)
+ (let ((video-id .id)
+ (playlist-id .snippet.playlistId)
+ (resource-id .snippet.resourceId))
+ (message "Trying to move %s to %d from %d" (plist-get talk :slug) position .snippet.position)
+ (plz 'put "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet"
+ :headers `(("Authorization" . ,(url-oauth-auth "https://youtube.googleapis.com/youtube/v3/"))
+ ("Accept" . "application/json")
+ ("Content-Type" . "application/json"))
+ :body (json-encode
+ `((id . ,video-id)
+ (snippet
+ (playlistId . ,playlist-id)
+ (resourceId . ,resource-id)
+ (position . ,position)))))))))
+ )) info)))
(provide 'emacsconf-extract)
;;; emacsconf-extract.el ends here