(defun gptel-template-summarize-url ()
"Read a URL and summarize its contents."
(let* ((url (read-string "URL: " (thing-at-point 'url)))
(content
(let* ((eww-retrieve-command 'sync)
(data-buf (url-retrieve-synchronously url t nil 8)))
(unless data-buf
(user-error "Request canceled: Could not retrieve url %s" url))
(eww url nil data-buf)
(eww-readable)
(prog1 (buffer-substring-no-properties (point-min) (point-max))
(kill-buffer (current-buffer))))))
`("You are Summarizer AI. You help summarize websites. I'll provide you with the content and the url.
Give a 2 line summary at the top with a point by point breakdown of the article (max 10 points).
- Use markdown when necessary.
- Retain the relative order in which data is presented in the article.
- No need to have headers like Article summary or point by point breakdown."
nil
"Give me the content to summarize." ,content
"What is the URL? I'll only use it for additional context." ,url)))
(defun gptel-template-summarize-youtube ()
"Read a Youtube video URL and summarize it."
(unless (executable-find "yt-dlp")
(user-error "Could not find `yt-dlp' in the path."))
(if-let* ((url (read-string "URL: " (thing-at-point 'url)))
(url-regexp "^\\(?:http\\(?:s?://\\)\\)?\\(?:www\\.\\)?\\(?:youtu\\(?:\\(?:\\.be\\|be\\.com\\)/\\)\\)")
((string-match-p url-regexp url))
(id (and (string-match (concat url-regexp "\\(?:watch\\?v=\\)?" "\\([^?&]+\\)") url)
(match-string 1 url)))
(dir (file-name-concat temporary-file-directory "gptel"))
(default-directory (prog1 dir
(unless (file-directory-p dir)
(make-directory dir)))))
(let ((subs-file (format "gptel-%s.en.vtt" id))
(info-file (format "gptel-%s.info.json" id))
subs-data info-data)
(if (or (seq-every-p #'file-readable-p (list subs-file info-file))
(= 0 (call-process (executable-find "yt-dlp") nil "*gptel-template-output*" nil
"--write-subs" "--write-auto-subs" "--write-info-json"
"--sub-lang" "en" "--skip-download" "--sub-format" "srt"
"--output" "gptel-%(id)s" url)))
(progn
(if (file-readable-p subs-file)
(setq subs-data (with-temp-buffer
(insert-file-contents subs-file)
(buffer-string)))
(user-error "Could not read transcript for %s" url))
(when (file-readable-p info-file)
(setq info-data
(with-temp-buffer
(save-excursion
(insert-file-contents info-file))
(gptel--json-read)))
(setq info-data
(concat "```json\n"
(gptel--json-encode
(mapcan (lambda (key) (list key (plist-get info-data key)))
'(:title :description :channel :upload_date
:original_url :categories :chapters :language)))
"\n```\n")))
(list "You are a summarizer AI. You help summarize videos.
I will provide the following:
- video metadata like the title and description (if available), and
- the video transcript (if available).
Provide a 2-line summary at the top with a point-by-point breakdown of the video (max 10 points).
- Use markdown when necessary.
- Retain the relative order in which information is presented in the video.
- No need to have headers for each video chapter."
nil
"What video metadata is available?" info-data
"What is the transcript?" (concat "\n```vtt\n" subs-data "\n```\n")
"What is the URL? I will only use it for additonal context" url))
(user-error "Could not download transcript for %s" url)))
(user-error "%s is not a Youtube URL" url)))
(setq gptel-templates
`((summarize-url . ,#'gptel-template-summarize-url)
(summarize-youtube . ,#'gptel-template-summarize-youtube)))
(provide 'gptel-templates)