Compare commits

...

3 commits

Author SHA1 Message Date
ee3ad0a6e9 Initial filter implementation attempt 2024-09-13 21:18:23 +02:00
2464a66ac7 Add filters for q and Q params 2024-09-13 21:17:48 +02:00
454643675f Add fkmap and vectorize macro 2024-09-13 21:17:23 +02:00
3 changed files with 95 additions and 7 deletions

View file

@ -20,7 +20,8 @@
[clojure.string :as s]
[rss-thread-watch.watcher :as watcher]
[rss-thread-watch.utils :as ut]
[rss-thread-watch.config :as conf])
[rss-thread-watch.config :as conf]
[rss-thread-watch.filters :as f])
(:gen-class))
(def boards-enabled-cache
@ -56,12 +57,48 @@
(:last-modified thread)
(:chod thread))))
(defn make-filters
"Creates map of functions and filters from query string"
;; In future predicates could return matched parts of string instead of
;; t/nil values which could be used for coloring of results
[query-map]
(let [filtering-params '("q" "Q") ;Later add "r" for regex
filter-map (select-keys query-map filtering-params)]
(ut/fkmap (fn [k v]
{(case k
;; regex filter here
"q" f/case-insensitive-filter
"Q" f/case-sensitive-filter) v})
filter-map)))
(defn x [cache filters]
;;must return fitlered cache
;; {fun [key dfe dw kwd"]}
(filter
(fn [thread]
;; run every function for each thread
(let [title (get thread :title)]
(some (fn [filter]
(let [queries (get filters filter)]
(some (fn [q]
(filter title queries))
queries)
;; some again?
;; try some-map?
))
(keys filters)))
;;RESUME
) cache
))
(defn filter-chod-posts
"Return list of all threads with equal or higher ChoD than requested
;;resume
READS FROM GLOBALS: watcher.time-of-cache"
[query-vec chod-treshold repeat? board-cache]
(let [{time-of-generation :time
cache :data} board-cache
guid-fn (case repeat?
@ -72,6 +109,7 @@
cache))
;; So we don't have to search thru everything we have cached
needed-cache-part (subvec cache cache-start-index)
;; Here we gonna run fmap but not really
actuall-matches (keep (fn [t]
(let [title (:title t)]
;; Todo: Man, wouldn't it be cool to know which querry matched the thread?
@ -130,10 +168,11 @@
query :query-string
scheme :scheme
server-name :server-name} rqst
qrs (prms "q")
filters (make-filters prms)
;; qrs (prms "q")
self-uri (str (s/replace-first scheme ":" "")
"://" server-name uri "?" query)
queries (if (vector? qrs) qrs [qrs]) ; to always return vector
;; queries (if (vector? qrs) qrs [qrs]) ; to always return vector
real-chod (if-let [ch (or (and (vector? chod)
(first chod))
chod)]
@ -167,7 +206,7 @@
(when-not (prms "q")
(throw (ex-info "400" {:status 400
:header {"Content-Type" "text/plain"}
:body (str "400 You MUST specify query with one OR more'q=searchTerm' url parameter(s)\n\n\n"
:body (str "400 You MUST specify query with one OR more'q=searchTerm' (or 'Q=SeARChteRm' for case sensitive) url parameter(s)\n\n\n"
"Exmple: '" served-filename "?q=pony&q=IWTCIRD' will show in your feed all threads with 'pony' or 'IWTCIRD'"
" in their title that are about to die.")})))
;; Whether cache has been generated yet

View file

@ -0,0 +1,32 @@
;; Copyright (C) 2024 Felisp
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU Affero General Public License as published by
;; the Free Software Foundation, version 3 of the License.
;;
;; 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 Affero General Public License for more details.
;;
;; You should have received a copy of the GNU Affero General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
(ns rss-thread-watch.filters
"Functions filtering posts"
(:require [clojure.string :as cs]
[rss-thread-watch.utils :as u])
(:gen-class))
(defn case-sensitive-filter
"Returns true if string [s] is matched by any query. It's case insensitive"
[s queries]
(some (fn [querry]
(cs/includes? s querry))
queries))
(defn case-insensitive-filter
"Returns true if string [s] is case-matched by query"
[s queries]
(basic-filter (cs/lower-case s) (cs/lower-case s)))

View file

@ -47,6 +47,11 @@
~x
result#)))
(defmacro vectorize
"If arg is not a vector, put into vector, otherwise return it"
[v]
(if (vector? v) v [v]))
;; ===== Generic functions ====
(defn indices
@ -71,13 +76,25 @@
(defn fmap
"Applies function [f] to every key and value in map [m]
Function signature should be (f [key value])."
Function signature should be (f [key value]).
Key stays unchanged"
[f m]
(into
(empty m)
(for [[key val] m]
[key (f key val)])))
(defn fkmap
;; I am horrible with docstrings, I don't deny that
"Applies function [f] to every key and value in map [m]
Function signature should be (f [key value]).
Unlike fmap, you can change key too, so return both {key value} in map"
[f m]
(into
(empty m)
(for [[key val] m]
(f key val))))
(defn expand-home
"Expands ~ to home directory"
;;modified from sauce: https://stackoverflow.com/questions/29585928/how-to-substitute-path-to-home-for