summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.org6
-rw-r--r--yeetube.el135
2 files changed, 112 insertions, 29 deletions
diff --git a/CONTRIBUTING.org b/CONTRIBUTING.org
index 6454f5d..109d52d 100644
--- a/CONTRIBUTING.org
+++ b/CONTRIBUTING.org
@@ -29,3 +29,9 @@ $ git format-patch HEAD^1
** DONE Add sorting for tabulated list views/date/title/duration
CLOSED: [2024-02-10 Sat 11:38]
+ With the help of Boruch Baum <[email protected]>
+
+** Improve interactivity
++ Sort columns interactively
+
+** Improve torsocks support
++ Use =socks= to route all traffic from =url= to tor, this should be an opt-in feature
diff --git a/yeetube.el b/yeetube.el
index ff6c16d..bdd772b 100644
--- a/yeetube.el
+++ b/yeetube.el
@@ -1,11 +1,11 @@
-;;; yeetube.el --- YouTube Front End -*- lexical-binding: t; -*-
+;;; yeetube.el --- YouTube Front End | Interface for yt-dlp | mpv control | -*- lexical-binding: t; -*-
;; Copyright (C) 2023 Thanos Apollo
;; Author: Thanos Apollo <[email protected]>
;; Keywords: extensions youtube videos
;; URL: https://thanosapollo.org/projects/yeetube/
-;; Version: 2.1.2
+;; Version: 2.1.3
;; Package-Requires: ((emacs "27.2") (compat "29.1.4.2"))
@@ -41,6 +41,9 @@
(require 'url)
(require 'tabulated-list)
(require 'cl-lib)
+(require 'socks)
+(require 'iimage)
+
(require 'yeetube-mpv)
(defgroup yeetube nil
@@ -97,12 +100,32 @@ Valid options include:
:type 'boolean
:group 'yeetube)
+(defcustom yeetube-enable-tor nil
+ "Enable routing through tor"
+ :type 'boolean
+ :group 'yeetube)
+
(defgroup yeetube-faces nil
"Faces used by yeetube."
:group 'yeetube
:tag "Yeetube Faces"
:prefix 'yeetube-face)
+(defcustom yeetube-thumbnail-height 80
+ "Height of the thumbnail."
+ :type 'number
+ :group 'yeetube)
+
+(defcustom yeetube-thumbnail-width 80
+ "Width of the thumbnail."
+ :type 'number
+ :group 'yeetube)
+
+(defcustom yeetube-display-thumbnails t
+ "asdf"
+ :type 'boolean
+ :group 'yeetube)
+
(defface yeetube-face-header-query
'((t :inherit font-lock-function-name-face))
"Face used for the video published date."
@@ -268,16 +291,23 @@ WHERE indicates where in the buffer the update should happen."
This is used to download thumbnails from `yeetube-content', within
`yeetube-search'. We can't as of now use images with tabulated-list."
(interactive)
- (let ((wget-exec (executable-find "wget"))
- (default-directory temporary-file-directory))
- (unless wget-exec
- (error "Please install `wget', to download thumbnails"))
- (cl-loop for item in content
- do (let ((title (plist-get item :title))
- (thumbnail (plist-get item :thumbnail)))
- (call-process-shell-command
- (concat "wget " (shell-quote-argument thumbnail) " -O" (shell-quote-argument title))
- nil 0)))))
+ (when yeetube-display-thumbnails
+ (let ((wget-exec (executable-find "wget"))
+ (default-directory temporary-file-directory))
+ (unless wget-exec
+ (error "Please install `wget', to download thumbnails"))
+ (cl-loop for item in content
+ do (let ((thumbnail (plist-get item :thumbnail)))
+ (call-process-shell-command
+ (format "%s %s %s %s" wget-exec
+ (shell-quote-argument thumbnail)
+ "-O"
+ (concat (replace-regexp-in-string
+ "\\(.*\\)\\(\\(.\\{10\\}\\)\\)$"
+ "\\2"
+ thumbnail)
+ ".jpg"))
+ nil 0))))))
(defvar yeetube-filter-code-alist
'(("Relevance" . "EgIQAQ%253D%253D")
@@ -296,27 +326,34 @@ This is used to download thumbnails from `yeetube-content', within
"Get filter code for sorting search results."
(cdr (assoc filter yeetube-filter-code-alist)))
+(defmacro yeetube-with-tor-socks (&rest body)
+ `(let ((url-gateway-method 'socks)
+ (socks-noproxy '("localhost"))
+ (socks-server '("Default server" "127.0.0.1" 9050 5)))
+ ,@body))
+
;;;###autoload
(defun yeetube-search (query)
"Search for QUERY."
(interactive "sYeetube Search: ")
- (let ((url-request-extra-headers yeetube-request-headers))
+ (let* ((url-request-extra-headers yeetube-request-headers)
+ (search-url (concat "https://youtube.com/search?q="
+ (replace-regexp-in-string " " "+" query)
+ ;; Filter parameter to remove live videos.
+ "&sp="
+ (yeetube-get-filter-code yeetube-filter))))
(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)
+ (if yeetube-enable-tor
+ (yeetube-with-tor-socks (url-retrieve-synchronously search-url 'silent 'inhibit-cookies 30))
+ (url-retrieve-synchronously search-url '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
+ (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*")))
+ (pop-to-buffer-same-window "*yeetube*")
(yeetube-mode)))
;;;###autoload
@@ -380,7 +417,15 @@ SUBSTRING-END is the end of the string to return, interger."
:duration video-duration
:channel channel
:thumbnail thumbnail
- :date (replace-regexp-in-string "Streamed " "" date))
+ :date (replace-regexp-in-string "Streamed " "" date)
+ :image (if yeetube-display-thumbnails
+ (format "[[%s.jpg]]" (expand-file-name
+ (replace-regexp-in-string
+ "\\(.*\\)\\(\\(.\\{10\\}\\)\\)$"
+ "\\2"
+ thumbnail)
+ temporary-file-directory))
+ "nil"))
yeetube-content))))))
(add-variable-watcher 'yeetube-saved-videos #'yeetube-update-saved-videos-list)
@@ -421,7 +466,8 @@ Optional values:
(unless yeetube-ytdlp
(error "Executable for yt-dlp not found. Please install yt-dlp"))
(call-process-shell-command
- (concat "yt-dlp " (shell-quote-argument url)
+ (concat (when yeetube-enable-tor "torsocks ")
+ "yt-dlp " (shell-quote-argument url)
(when name
" -o "(shell-quote-argument name))
(when audio-format
@@ -526,7 +572,35 @@ column."
(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))))
+ (> units-a units-b))))
+
+(defun yeetube-iimage-mode-buffer (arg)
+ "Display images if ARG is non-nil, undisplay them otherwise.
+
+Modified version of `iimage-mode-buffer' to specify height, width and
+image-path."
+ (let ((image-path (list (expand-file-name temporary-file-directory)))
+ file)
+ (with-silent-modifications
+ (save-excursion
+ (cl-loop for pair in iimage-mode-image-regex-alist do
+ (goto-char (point-min))
+ (while (re-search-forward (car pair) nil t)
+ (when (and (setq file (match-string (cdr pair)))
+ (setq file (locate-file file image-path)))
+ (if arg
+ (add-text-properties
+ (match-beginning 0) (match-end 0)
+ `(display
+ ,(create-image file nil nil
+ :max-width yeetube-thumbnail-width
+ :max-height yeetube-thumbnail-height)
+ keymap ,image-map
+ modification-hooks
+ (iimage-modification-hook)))
+ (remove-list-of-text-properties
+ (match-beginning 0) (match-end 0)
+ '(display modification-hooks))))))))))
(define-derived-mode yeetube-mode tabulated-list-mode "Yeetube"
"Yeetube mode."
@@ -536,7 +610,8 @@ column."
("Views" 11 yeetube--sort-views)
("Duration" 9 yeetube--sort-duration)
("Date" 13 yeetube--sort-date)
- ("Channel" 8 t)]
+ ("Channel" 12 t)
+ ("Thumbnail" 0 t)]
tabulated-list-entries
(cl-map 'list
(lambda (content)
@@ -546,13 +621,15 @@ column."
:view-count 'yeetube-face-view-count
:duration 'yeetube-face-duration
:date 'yeetube-face-date
- :channel 'yeetube-face-channel)))
+ :channel 'yeetube-face-channel
+ :image nil)))
(reverse yeetube-content))
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))
+ (tabulated-list-print)
+ (yeetube-iimage-mode-buffer yeetube-display-thumbnails))
(provide 'yeetube)
;;; yeetube.el ends here