aboutsummaryrefslogtreecommitdiff
path: root/sx-filter.el
blob: 7178259a4ce4cf3307f79c873a6a96cb8e047fde (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
;;; sx-filter.el --- filters                         -*- lexical-binding: t; -*-

;; Copyright (C) 2014  Sean Allred

;; Author: Sean Allred <code@seanallred.com>

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;;

;;; Code:


;;; Dependencies

(require 'sx)
(require 'sx-cache)


;;; Customizations

(defconst sx-filter-cache-file
  "filters.el")

(defvar sx-filter
  'default
  "The current filter.
To customize the filter for the next call to `sx-request-make',
let-bind this variable to the output of a call to
`sx-filter-compile'.  Be careful!  If you're going to be using
this new filter a lot, create a variable for it.  Creation
requests count against `sx-request-remaining-api-requests'!")


;;; Compilation

;;; TODO allow BASE to be a precompiled filter name
(defun sx-filter-compile (&optional include exclude base)
  "Compile INCLUDE and EXCLUDE into a filter derived from BASE.

INCLUDE and EXCLUDE must both be lists; BASE should be a symbol
or string."
  (let ((keyword-arguments
         `((include . ,(if include (sx--thing-as-string include)))
           (exclude . ,(if exclude (sx--thing-as-string exclude)))
           (base    . ,(if base base)))))
    (let ((response (sx-request-make
                     "filter/create"
                     keyword-arguments)))
      (url-hexify-string
       (cdr (assoc 'filter
                   (elt response 0)))))))


;;; Storage and Retrieval

(defun sx-filter-get (filter)
  "Retrieve named FILTER from `sx-filter-cache-file'."
  (cdr (assoc filter (sx-cache-get sx-filter-cache-file))))

(defun sx-filter-store (name &optional filter)
  "Store NAME as FILTER in `sx-filter-cache-file'.

NAME should be a symbol and FILTER is a string as compiled by
`sx-filter-compile'.

If NAME is a cons cell, (car NAME) is taken to be the actual NAME
and (cdr NAME) is taken to be the actual FILTER.  In this case,
the second argument is simply ignored."
  (let ((name   (if (consp name) (car name) name))
        (filter (if (consp name) (cdr name) filter)))
    (unless (symbolp name)
      (error "Name must be a symbol: %S" name))
    (let* ((dict (sx-cache-get sx-filter-cache-file))
           (entry (assoc name dict)))
      (if entry (setcdr entry filter)
        (setq dict (cons (cons name filter) dict)))

      (sx-cache-set sx-filter-cache-file dict))))

(defun sx-filter-store-all (name-filter-alist)
  (mapc #'sx-filter-store name-filter-alist))

(provide 'sx-filter)
;;; sx-filter.el ends here

;; Local Variables:
;; indent-tabs-mode: nil
;; End: