diff options
Diffstat (limited to 'yeetube.el')
-rw-r--r-- | yeetube.el | 109 |
1 files changed, 85 insertions, 24 deletions
@@ -4,9 +4,8 @@ ;; Author: Thanos Apollo <[email protected]> ;; Keywords: extensions youtube videos -;; URL: https://git.thanosapollo.org/yeetube -;; Version: 2.1.1 - +;; URL: https://thanosapollo.org/projects/yeetube/ +;; Version: 2.1.2 ;; Package-Requires: ((emacs "27.2") (compat "29.1.4.2")) @@ -83,7 +82,19 @@ Valid options include: :type '(radio (const "Relevance") (const "Date") (const "Views") - (const "Rating")) + (const "Rating"))) + +(defcustom yeetube-default-sort-column nil + "Which column to sort the search results table." + :type '(radio (const "Title") + (const "Views") + (const "Duration") + (const "Channel")) + :group 'yeetube) + +(defcustom yeetube-default-sort-ascending nil + "Whether to sort the search results in ascending order." + :type 'boolean :group 'yeetube) (defgroup yeetube-faces nil @@ -117,6 +128,11 @@ Valid options include: "Face used for video channel name." :group 'yeetube-faces) +(defface yeetube-face-date + '((t :inherit font-lock-doc-face)) + "Face used for published date." + :group 'yeetube-faces) + (defvar yeetube-invidious-instances '("vid.puffyan.us" "invidious.flokinet.to" @@ -264,10 +280,17 @@ This is used to download thumbnails from `yeetube-content', within nil 0))))) (defvar yeetube-filter-code-alist - '(("Relevance" . "CAASAhAB") + '(("Relevance" . "EgIQAQ%253D%253D") ("Date" . "CAISAhAB") ("Views" . "CAMSAhAB") - ("Rating" . "CAESAhAB"))) + ("Rating" . "CAESAhAB")) + "Filter codes.") + +(defvar yeetube-request-headers + '(("Accept-Language" . "Accept-Language: en-US,en;q=0.9") + ("Accept" . "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8") + ("User-Agent" . "Mozilla/5.0 (Windows NT 10.0; rv:122.0) Gecko/20100101 Firefox/122.0")) + "HTTP Request extra headers") (defun yeetube-get-filter-code (filter) "Get filter code for sorting search results." @@ -277,20 +300,21 @@ This is used to download thumbnails from `yeetube-content', within (defun yeetube-search (query) "Search for QUERY." (interactive "sYeetube Search: ") - (with-current-buffer - (url-retrieve-synchronously - (concat "https://youtube.com/search?q=" - (replace-regexp-in-string " " "+" query) - ;; Filter parameter to remove live videos. - "&sp=" - (yeetube-get-filter-code yeetube-filter)) - 'silent 'inhibit-cookies 30) - (decode-coding-region (point-min) (point-max) 'utf-8) - (goto-char (point-min)) - (toggle-enable-multibyte-characters) - (yeetube-get-content)) - ;; (yeetube-get-thumbnails yeetube-content) ;; download thumbnails - ;; unfortunately we can't use images them with tabulated list + (let ((url-request-extra-headers yeetube-request-headers)) + (with-current-buffer + (url-retrieve-synchronously + (concat "https://youtube.com/search?q=" + (replace-regexp-in-string " " "+" query) + ;; Filter parameter to remove live videos. + "&sp=" + (yeetube-get-filter-code yeetube-filter)) + 'silent 'inhibit-cookies 30) + (decode-coding-region (point-min) (point-max) 'utf-8) + (goto-char (point-min)) + (toggle-enable-multibyte-characters) + (yeetube-get-content))) + ;; (yeetube-get-thumbnails yeetube-content) ;; download thumbnails + ;; unfortunately we can't use images them with tabulated list (with-current-buffer (switch-to-buffer (get-buffer-create (concat "*yeetube*"))) (yeetube-mode))) @@ -348,13 +372,15 @@ SUBSTRING-END is the end of the string to return, interger." (view-count (yeetube-scrape-item :item "viewcounttext" :item-end " " :substring-end 0)) (video-duration (yeetube-scrape-item :item "lengthtext" :item-end "}," :substring-end 3)) (channel (yeetube-scrape-item :item "longbylinetext" :item-end "," :substring-end 2)) - (thumbnail (yeetube-scrape-item :item "thumbnail" :item-start "url" :item-end ",\"" :substring-end 5))) + (thumbnail (yeetube-scrape-item :item "thumbnail" :item-start "url" :item-end ",\"" :substring-end 5)) + (date (yeetube-scrape-item :item "publishedtimetext" :item-end ",\"" :substring-end 4))) (push (list :title title :videoid videoid :view-count (yeetube-view-count-format view-count) :duration video-duration :channel channel - :thumbnail thumbnail) + :thumbnail thumbnail + :date (replace-regexp-in-string "Streamed " "" date)) yeetube-content)))))) (add-variable-watcher 'yeetube-saved-videos #'yeetube-update-saved-videos-list) @@ -472,12 +498,45 @@ FIELDS-FACE-PAIRS is a list of fields and faces." "r" #'yeetube-replay "t" #'yeetube-view-thumbnail "T" #'yeetube-mpv-toggle-torsocks + "C-q" #'yeetube-mpv-change-video-quality "q" #'quit-window) +(defun yeetube--sort-views (a b) + "PREDICATE for function 'sort'. +Used by variable 'tabulated-list-format' to sort the \"Views\" +column." + (< (string-to-number (replace-regexp-in-string "," "" (aref (cadr a) 1))) + (string-to-number (replace-regexp-in-string "," "" (aref (cadr b) 1))))) + +(defun yeetube--sort-duration (a b) + "PREDICATE for function 'sort'. +Used by variable 'tabulated-list-format' to sort the \"Duration\" +column." + (< (string-to-number (replace-regexp-in-string ":" "" (aref (cadr a) 2))) + (string-to-number (replace-regexp-in-string ":" "" (aref (cadr b) 2))))) + +(defun yeetube--sort-date (a b) + "PREDICATE for function 'sort'. +Used by variable 'tabulated-list-format' to sort the \"Date\" +column." + (let* ((intervals '("second" "minute" "hour" "day" "week" "month" "year")) + (split-a (split-string (replace-regexp-in-string "s" "" (aref (cadr a) 3)))) + (split-b (split-string (replace-regexp-in-string "s" "" (aref (cadr b) 3)))) + (units-a (length (member (nth 1 split-a) intervals))) + (units-b (length (member (nth 1 split-b) intervals)))) + (if (= units-a units-b) + (< (string-to-number (nth 0 split-a)) (string-to-number (nth 0 split-b))) + (> units-a units-b)))) + (define-derived-mode yeetube-mode tabulated-list-mode "Yeetube" "Yeetube mode." :keymap yeetube-mode-map - (setf tabulated-list-format [("Title" 60 t) ("Views" 12 t) ("Duration" 12 t) ("Channel" 12 t)] + (setf tabulated-list-format + [("Title" 60 t) + ("Views" 11 yeetube--sort-views) + ("Duration" 9 yeetube--sort-duration) + ("Date" 13 yeetube--sort-date) + ("Channel" 8 t)] tabulated-list-entries (cl-map 'list (lambda (content) @@ -486,9 +545,11 @@ FIELDS-FACE-PAIRS is a list of fields and faces." :title 'yeetube-face-title :view-count 'yeetube-face-view-count :duration 'yeetube-face-duration + :date 'yeetube-face-date :channel 'yeetube-face-channel))) (reverse yeetube-content)) - tabulated-list-sort-key nil) + tabulated-list-sort-key (cons yeetube-default-sort-column + yeetube-default-sort-ascending)) (display-line-numbers-mode 0) (tabulated-list-init-header) (tabulated-list-print)) |