diff --git a/src/rss_thread_watch/feed_generator.clj b/src/rss_thread_watch/feed_generator.clj new file mode 100644 index 0000000..9a11eda --- /dev/null +++ b/src/rss_thread_watch/feed_generator.clj @@ -0,0 +1,80 @@ +;; Copyright (C) 2023 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 . + +(ns rss-thread-watch.feed-generator + "Generates feed for requests" + (:require [ring.middleware.params :as rp] + [clj-rss.core :as rss] + [clojure.string :as s] + [rss-thread-watch.watcher :as cache]) + (:gen-class)) + + +(defn indices + ;; https://stackoverflow.com/questions/8641305/find-index-of-an-element-matching-a-predicate-in-clojure + "Returns indexes of elements passing predicate" + [pred coll] + (keep-indexed #(when (pred %2) %1) coll)) + +(defn new-guid-always + "Generates always unique GUID for Feed item. + This is used when user wants notification on every server update, + no matter whether thread actually changed it's position. + + This is done by always making new GUID - (concat thread-number UNIX-time-of-data-update)" + [thread time] + (assoc thread guid (str (:no thread) + "-" + time))) + +(defn update-only-guid + "Generates new GUID for feed item ONLY if the threads ChoD increased + + This is done by concating thread-number and it's rounded chod" + [thread] + (assoc thread :guid (format "%d-%.2f" + (:no thread) + :chod thread))) + +(defn filter-chod-posts + "Return list of all threads with equal or higher ChoD than requested" + [query-vec chod-treshold repeat?] + (let [time-of-generation (System/currentTimeMillis) + guid-fn (if repeat? (fn [x] (new-guid-always x time-of-generation)) + update-only-guid) + cache-start-index (first (indices (fn [x] (>= x chod-treshold)) + @cache/chod-threads-cache)) + ;; So we don't have to search thru everything we have cached + needed-cache-part (subvec @cache/chod-threads-cache cache-start-index) + actuall-matches (keep (fn [t] + (let [title (:title t)] + (when (some (fn [querry] + (s/includes? title querry)) + query-vec) + t))) + needed-cache-part)] + ;; Finally generate and append GUIDs + (map guid-fn actuall-matches))) + +(defn http-handler + "Handles HTTP requests, returns generated feed + + READS FROM GLOBALS: + rss-thread-watch.watcher.chod-threads-cache + rss-thread-watch.core.CONFIG" + [rqst] + {:status 200 + :header {"Content-Type" "text/html"} + :body "All pony here ^:)"}) + diff --git a/src/rss_thread_watch/watcher.clj b/src/rss_thread_watch/watcher.clj index 56489a2..0e1b841 100644 --- a/src/rss_thread_watch/watcher.clj +++ b/src/rss_thread_watch/watcher.clj @@ -35,7 +35,7 @@ (inc index) (conj! ret {:title (or (:sub thread) ;We use thread title if thread has it (:com thread) ;we use body if thread has it - "") ;Thread has nothing, this prevents null pointer + "") ;Thread has neither, this prevents null pointer :no (:no thread) :chod (* 100 (float (/ index threads-total)))})))))) @@ -49,8 +49,6 @@ (process-page (:threads single-page) threads-total (inc (* page-number threads-per-page))))) pages-to-index)))) - - (defn update-thread-cache! "Updates cache of near-death threads. Writes to chod-threads-cache as side effect. [url] - Url to download data from