;;; elfeed-export.el --- Elfeed database export -*- lexical-binding: t; -*- ;; Copyright (C) 2024 Bram Schoenmakers ;; Author: Bram Schoenmakers ;; Maintainer: Bram Schoenmakers ;; Created: 1 August 2024 ;; Package-Version: 0.1 ;; Package-Requires: ((emacs "29.1")) ;; Keywords: ;; URL: ;; 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: (require 'elfeed) (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 :group 'elfeed-export) (defcustom elfeed-export-predicates (list #'elfeed-export--include-entry-by-tag-p) "Entries that match all of these predicates are exported. Each predicate accepts an entry and a feed 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) "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) "Return the feed title for the given ENTRY." (elfeed-feed-title (elfeed-entry-feed entry))) (defun elfeed-export--entry-feed (entry) "Return the feed URL for the given ENTRY." (elfeed-feed-url (elfeed-entry-feed entry))) (defun elfeed-export--entry-content (entry) "Return the content of the ENTRY." (elfeed-deref (elfeed-entry-content entry))) (defun elfeed-export--entry-to-alist (entry) "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) "Filter ENTRIES according to all predictates in `elfeed-export-predicates'." (seq-filter (lambda (entry) (let ((feed (elfeed-entry-feed entry))) (seq-every-p (lambda (pred) (funcall pred entry feed)) elfeed-export-predicates))) entries)) (defun elfeed-export--entries () "Return all entries that need to be exported." (let ((entries) (feeds (elfeed-feed-list))) (dolist (feed feeds) (setq entries (append entries (elfeed-feed-entries feed)))) (mapcar #'elfeed-export--entry-to-alist (elfeed-export-filter-entries entries)))) (defun elfeed-export-to-json () "Return the JSON string for all entries that should be exported." (json-encode (elfeed-export--entries))) (defun elfeed-export-to-lisp () "Return the Lisp data string for all entries that should be exported." (prin1-to-string (elfeed-export--entries))) (defun elfeed-export-to-json-file (path) "Write the JSON string to a file at PATH." (interactive "F") (write-region (elfeed-export-to-json) nil path nil nil nil t)) (defun elfeed-export-to-lisp-file (path) "Write the JSON string to a file at PATH." (interactive "F") (write-region (elfeed-export-to-lisp) nil path nil nil nil t)) (provide 'elfeed-export) ;;; elfeed-export.el ends here