1
0
Fork 0
elfeed-export/elfeed-export.el

185 lines
6.5 KiB
EmacsLisp
Raw Normal View History

;;; elfeed-export.el --- Elfeed database export -*- lexical-binding: t; -*-
;; Copyright (C) 2024 Bram Schoenmakers
;; Author: Bram Schoenmakers <me@bramschoenmakers.nl>
;; Maintainer: Bram Schoenmakers <me@bramschoenmakers.nl>
;; Created: 1 August 2024
;; Package-Version: 0.1
2024-08-08 19:35:59 +00:00
;; Package-Requires: ((emacs "29.1") (elfeed "3.4.2"))
;; Keywords:
2024-08-08 19:35:59 +00:00
;; URL: https://codeberg.org/bram85/elfeed-export
;; This file is not part of GNU Emacs.
;; MIT License
;; Copyright (c) 2024 Bram Schoenmakers
;; Permission is hereby granted, free of charge, to any person obtaining a copy
;; of this software and associated documentation files (the "Software"), to deal
;; in the Software without restriction, including without limitation the rights
;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
;; copies of the Software, and to permit persons to whom the Software is
;; furnished to do so, subject to the following conditions:
;; The above copyright notice and this permission notice shall be included in all
;; copies or substantial portions of the Software.
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;; SOFTWARE.
;;; Commentary:
;;; Code:
2024-08-01 21:17:54 +00:00
(require 'elfeed)
(require 'json)
2024-08-01 21:17:54 +00:00
2024-08-01 20:05:19 +00:00
(defcustom elfeed-export-fields
'((title . elfeed-entry-title)
(date . elfeed-export--entry-date)
(url . elfeed-entry-link)
(tags . elfeed-entry-tags)
(feed-title . elfeed-export--feed-title)
(feed . elfeed-export--entry-feed)
(content . elfeed-export--entry-content))
"Which fields to export per entry and a function to obtain the value.
The function takes an entry argument for extracting the desired value."
:type '(alist :key-type symbol :value-type function)
:group 'elfeed-export)
(defcustom elfeed-export-predicates
2024-08-03 19:50:00 +00:00
(list #'elfeed-export--include-entry-by-tag-p)
"Entries that match all of these predicates are exported.
Each predicate accepts an entry object and should return t when
the entry should be exported."
:group 'elfeed-export
:type '(repeat function))
(defcustom elfeed-export-include-tags nil
"Export entries that have any of these tags."
:group 'elfeed-export
:type '(repeat symbol))
(defcustom elfeed-export-exclude-tags '(noexport)
"Do not export entries that have any of these tags."
:group 'elfeed-export
:type '(repeat symbol))
(defun elfeed-export--include-entry-by-tag-p (entry)
(let ((tags (elfeed-entry-tags entry)))
(and
(or (not elfeed-export-include-tags)
(seq-intersection elfeed-export-include-tags tags))
(or (not elfeed-export-exclude-tags)
(not (seq-intersection elfeed-export-exclude-tags tags))))))
(defun elfeed-export--entry-date (entry)
2024-08-02 13:29:54 +00:00
"Return an ISO formatted date string for the given ENTRY."
(format-time-string "%F %T" (elfeed-entry-date entry)))
(defun elfeed-export--feed-title (entry)
2024-08-02 13:29:54 +00:00
"Return the feed title for the given ENTRY."
(elfeed-feed-title (elfeed-entry-feed entry)))
(defun elfeed-export--entry-feed (entry)
2024-08-02 13:29:54 +00:00
"Return the feed URL for the given ENTRY."
(elfeed-feed-url (elfeed-entry-feed entry)))
(defun elfeed-export--entry-content (entry)
2024-08-02 13:29:54 +00:00
"Return the content of the ENTRY."
(elfeed-deref (elfeed-entry-content entry)))
2024-08-01 20:03:45 +00:00
(defun elfeed-export--entry-to-alist (entry)
2024-08-02 13:29:54 +00:00
"Convert an ENTRY to an alist."
(mapcar (lambda (field)
(cons (symbol-name (car field))
(funcall (cdr field) entry)))
elfeed-export-fields))
(defun elfeed-export-filter-entries (entries)
2024-08-03 19:50:46 +00:00
"Filter ENTRIES according to all predictates in `elfeed-export-predicates'."
(seq-filter (lambda (entry)
(seq-every-p (lambda (pred)
(funcall pred entry))
elfeed-export-predicates))
entries))
2024-08-01 20:32:25 +00:00
(defun elfeed-export--entries ()
2024-08-02 13:29:54 +00:00
"Return all entries that need to be exported."
(let ((entries)
(feeds (elfeed-feed-list)))
2024-08-01 20:32:25 +00:00
(dolist (feed feeds)
(setq entries
(append entries
(elfeed-feed-entries feed))))
(mapcar #'elfeed-export--entry-to-alist
(elfeed-export-filter-entries entries))))
2024-08-01 20:32:25 +00:00
2024-08-03 19:58:08 +00:00
;;;###autoload
2024-08-01 20:32:25 +00:00
(defun elfeed-export-to-json ()
2024-08-02 13:29:54 +00:00
"Return the JSON string for all entries that should be exported."
(json-encode (elfeed-export--entries)))
2024-08-03 19:58:08 +00:00
;;;###autoload
2024-08-03 19:48:37 +00:00
(defun elfeed-export-to-lisp ()
"Return the Lisp data string for all entries that should be exported."
(prin1-to-string (elfeed-export--entries)))
2024-08-06 04:12:12 +00:00
(defun elfeed-export--format-csv-value (value)
(let* ((string-value (if (listp value)
(format "[%s]"
(mapconcat (lambda (elm)
(format "%s" elm))
value ";"))
(format "%s" value)))
(escaped-string (string-replace "\"" "\"\"" string-value)))
(format "\"%s\"" escaped-string)))
;;;###autoload
(defun elfeed-export-to-csv ()
"Return the CSV string for all entries that should be exported."
(let* ((entries (elfeed-export--entries))
(columns (map-keys (seq-first entries))))
(concat
;; header
(string-join columns ",")
"\n"
;; data
(mapconcat (lambda (entry)
(mapconcat (lambda (column)
(elfeed-export--format-csv-value (alist-get column entry)))
columns
","))
entries
"\n"))))
(defmacro elfeed-export--to (format)
"Define an interactive command to export the elfeed database to FORMAT."
(let* ((function-name (intern (format "elfeed-export-to-%s-file" format)))
(payload-function (intern (format "elfeed-export-to-%s" format)))
(upcased-format (upcase (format "%s" format)))
(docstring (format "Export the elfeed database as %s to PATH." upcased-format)))
`(progn
(defun ,function-name (path)
,docstring
(interactive "F")
(write-region (,payload-function) nil path nil nil nil t))
(autoload ',function-name "elfeed-export" ,docstring t))))
(elfeed-export--to csv)
(elfeed-export--to lisp)
(elfeed-export--to json)
2024-08-06 04:12:12 +00:00
(provide 'elfeed-export)
;;; elfeed-export.el ends here