aboutsummaryrefslogtreecommitdiffstats
path: root/livie-channel.el
blob: 147a101a95549d3305a4ff4cabe9a27e330a0f8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
;;; livie-channel.el --- Auxiliary major mode for livie -*- lexical-binding: t; -*-

;; Copyright (C) 2018 - 2021

;;; Authors:

;; Charlie Ritter <chewzerita@posteo.net>
;; Jesus E. <heckyel@hyperbola.info>
;; Gabriele Rastello <gabriele.rastello@edu.unito.it>
;; Pablo BC <pablo.barraza@protonmail.com>

;;; Commentary:

;; livie grabs a list of youtube videos based on a search.
;; the user can then select a video to watch through `livie-player'

;;; Code:

(defcustom livie-channel-sort-criterion "newest"
  "Sort videos by 'newest', 'oldest', or 'popular', as used by `livie-channel-search'."
  :type 'string
  :options '("newest" "oldest" "popular")
  :group 'livie-channel)

(defvar livie-channel-mode-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map text-mode-map)
    (define-key map "h" #'describe-mode)
    (define-key map "q" #'livie--quit-channel-buffer)
    (define-key map ">" #'livie-channel-next-page)
    (define-key map "<" #'livie-channel-previous-page)
    (define-key map (kbd "<tab>") #'next-line)
    (define-key map (kbd "<backtab>") #'previous-line)
    (define-key map "S" #'livie-channel-sort-videos)
    (define-key map (kbd "RET") #'livie-open-entry)
    (define-key map "y" #'livie-watch-this-video)
    map)
  "Keymap for `livie-channel-mode'.")

(define-derived-mode livie-channel-mode livie-mode
  "livie-channel-mode"
  "Mode for displaying livie-channel-videos.
\\{livie-channel-mode-map}"
  (buffer-disable-undo)
  (make-local-variable 'livie-videos)
  (make-local-variable 'livie-channel-author)
  (setq-local livie-type-of-results "video")
  (setf	buffer-read-only t))

(defun livie--channel-query (uid n sort)
  "Query youtube for UID videos, return the Nth page of results, sorted bv SORT."
  (let ((videos (livie--API-call (concat "channels/videos/" uid)
				 `(("page" ,n)
				   ("sort_by" ,sort)
				   ("fields" ,livie-default-video-query-fields)))))
    (dotimes (i (length videos))
      (let ((v (aref videos i)))
	(aset videos i
	      (livie-video--create :title     (assoc-default 'title v)
				   :author    (assoc-default 'author v)
				   :authorId  (assoc-default 'authorId v)
				   :length    (assoc-default 'lengthSeconds v)
				   :id        (assoc-default 'videoId v)
				   :views     (assoc-default 'viewCount v)
				   :published (assoc-default 'published v)))))
    videos))

(defun livie-channel ()
  "Open a buffer for the channel of the current entry."
  (let* ((entry (livie-get-current-video))
	 (author (funcall (livie--get-author-function entry) entry))
	 (authorId (funcall (livie--get-authorId-function entry) entry)))
    (get-buffer-create author)
    (switch-to-buffer author)
    (unless (eq major-mode 'livie-channel-mode)
      (livie-channel-mode))
    (setf livie-channel-author author)
    (setf livie-search-term authorId)
    (livie-channel-get-videos authorId)))

(defun livie-channel-get-videos (authorId)
  "Fetch videos from AUTHORID."
  (setf livie-current-page 1)
  (setf livie-videos (livie--channel-query authorId livie-current-page livie-channel-sort-criterion))
  (livie--draw-channel-buffer))

(defun livie-channel-next-page ()
  "Fetch videos from AUTHORID."
  (interactive)
  (setf livie-current-page (1+ livie-current-page))
  (setf livie-videos (livie--channel-query livie-search-term livie-current-page livie-channel-sort-criterion))
  (livie--draw-channel-buffer))

(defun livie-channel-previous-page ()
  "Fetch videos from AUTHORID."
  (interactive)
  (when (> livie-current-page 1)
    (setf livie-current-page (1- livie-current-page))
    (setf livie-videos (livie--channel-query livie-search-term livie-current-page livie-channel-sort-criterion))
    (livie--draw-channel-buffer)))

(defun livie-channel-sort-videos ()
  "Sort videos from the current channel, either by newest (default), oldest, or popular."
  (interactive)
  (setf livie-channel-sort-criterion (completing-read "Sort videos by (default value is newest): " (get 'livie-channel-sort-criterion 'custom-options)))
  (setf livie-current-page 1)
  (setf livie-videos (livie--channel-query livie-search-term livie-current-page livie-channel-sort-criterion))
  (livie--draw-channel-buffer))

(defun livie--insert-channel-video (video)
  "Insert VIDEO in the current buffer."
  (insert (livie--format-video-published (livie-video-published video))
	  " "
	  (livie--format-title (livie-video-title video))
	  " "
	  (livie--format-video-length (livie-video-length video))
	  " "
	  (livie--format-video-views (livie-video-views video))))

(defun livie--draw-channel-buffer ()
  "Draws the livie channel buffer i.e. clear everything and write down all videos in `livie-videos'."
  (let ((inhibit-read-only t)
	(current-line (line-number-at-pos)))
    (erase-buffer)
    (setq header-line-format (concat "Displaying videos from " (propertize livie-channel-author 'face 'livie-parameter-face)
				     ", page "
				     (propertize (number-to-string livie-current-page) 'face 'livie-parameter-face)
				     ", sorted by: "
				     (propertize livie-channel-sort-criterion 'face 'livie-parameter-face)))
    (seq-do (lambda (v)
	      (livie--insert-channel-video v)
	      (insert "\n"))
	    livie-videos)
    (goto-char (point-min))))

(defun livie--quit-channel-buffer ()
  "Deletes the current buffer."
  (interactive)
  (kill-buffer (current-buffer)))

(provide 'livie-channel)

;; Local Variables:
;; byte-compile-warnings: (not free-vars)
;; End:
;;; livie-channel.el ends here