enable unqalified keywords again

This commit is contained in:
jem 2020-05-14 08:56:50 +02:00
parent af85887931
commit 1ebb0e71f5
3 changed files with 57 additions and 69 deletions

View file

@ -27,7 +27,6 @@ If you get a [permission failure](https://github.com/anmonteiro/lumo/issues/206)
with later timestamps to avoid duplicate posts. On the first run the timestamp will default to current time. with later timestamps to avoid duplicate posts. On the first run the timestamp will default to current time.
```clojure ```clojure
#:mastodon-bot.core
{;; add Twitter config to mirror Twitter accounts {;; add Twitter config to mirror Twitter accounts
:twitter {:access-keys :twitter {:access-keys
{:consumer_key "XXXX" {:consumer_key "XXXX"
@ -52,39 +51,37 @@ with later timestamps to avoid duplicate posts. On the first run the timestamp w
;; add RSS config to follow feeds ;; add RSS config to follow feeds
:rss {"Hacker News" "https://hnrss.org/newest" :rss {"Hacker News" "https://hnrss.org/newest"
"r/Clojure" "https://www.reddit.com/r/clojure/.rss"} "r/Clojure" "https://www.reddit.com/r/clojure/.rss"}
:mastodon :mastodon {:access_token "XXXX"
#:mastodon-bot.mastodon-api ;; account number you see when you log in and go to your profile
{:access_token "XXXX" ;; e.g: https://mastodon.social/web/accounts/294795
;; account number you see when you log in and go to your profile :account-id "XXXX"
;; e.g: https://mastodon.social/web/accounts/294795 :api_url "https://botsin.space/api/v1/"
:account-id "XXXX" ;; optional boolean to mark content as sensitive
:api_url "https://botsin.space/api/v1/" :sensitive? true
;; optional boolean to mark content as sensitive ;; optional boolean defaults to false
:sensitive? true ;; only sources containing media will be posted when set to true
;; optional boolean defaults to false :media-only? true
;; only sources containing media will be posted when set to true ;; optional visibility flag: direct, private, unlisted, public
:media-only? true ;; defaults to public
;; optional visibility flag: direct, private, unlisted, public :visibility "unlisted"
;; defaults to public ;; optional limit for the post length
:visibility "unlisted" :max-post-length 300
;; optional limit for the post length ;; optional flag specifying wether the name of the account
:max-post-length 300 ;; will be appended in the post, defaults to false
;; optional flag specifying wether the name of the account :append-screen-name? false
;; will be appended in the post, defaults to false ;; optional signature for posts
:append-screen-name? false :signature "#newsbot"
;; optional signature for posts ;; optionally try to resolve URLs in posts to skip URL shorteners
:signature "#newsbot" ;; defaults to false
;; optionally try to resolve URLs in posts to skip URL shorteners :resolve-urls? true
;; defaults to false ;; optional content filter regexes
:resolve-urls? true ;; any posts matching the regexes will be filtered out
;; optional content filter regexes :content-filters [".*bannedsite.*"]
;; any posts matching the regexes will be filtered out ;; optional keyword filter regexes
:content-filters [".*bannedsite.*"] ;; any posts not matching the regexes will be filtered out
;; optional keyword filter regexes :keyword-filters [".*clojure.*"]
;; any posts not matching the regexes will be filtered out ;; Replace Twitter links by Nitter
:keyword-filters [".*clojure.*"] :nitter-urls? false}}
;; Replace Twitter links by Nitter
:nitter-urls? false}}
``` ```
* the bot looks for `config.edn` at its relative path by default, an alternative location can be specified either using the `MASTODON_BOT_CONFIG` environment variable or passing the path to config as an argument * the bot looks for `config.edn` at its relative path by default, an alternative location can be specified either using the `MASTODON_BOT_CONFIG` environment variable or passing the path to config as an argument

View file

@ -6,9 +6,7 @@
[clojure.spec.test.alpha :as st] [clojure.spec.test.alpha :as st]
[orchestra.core :refer-macros [defn-spec]] [orchestra.core :refer-macros [defn-spec]]
[cljs.core :refer [*command-line-args*]] [cljs.core :refer [*command-line-args*]]
[cljs.reader :as edn]
[clojure.string :as string] [clojure.string :as string]
["fs" :as fs]
["rss-parser" :as rss] ["rss-parser" :as rss]
["tumblr" :as tumblr] ["tumblr" :as tumblr]
["twitter" :as twitter] ["twitter" :as twitter]
@ -20,23 +18,14 @@
(s/def ::tumblr map?) (s/def ::tumblr map?)
(s/def ::rss map?) (s/def ::rss map?)
(def config? (s/keys :req [::mastodon-config] (def config? (s/keys :req-un [::mastodon-config]
:opt [::twitter ::tumblr ::rss])) :opt-un [::twitter ::tumblr ::rss]))
;this has to stay on top - only ns-keywords can be uses in spec
(defn-spec mastodon-config ::mastodon-config (defn-spec mastodon-config ::mastodon-config
[config config?] [config config?]
(::mastodon-config config)) (:mastodon-config config))
(defn find-config [] (def config (infra/load-config))
(let [config (or (first *command-line-args*)
(-> js/process .-env .-MASTODON_BOT_CONFIG)
"config.edn")]
(if (fs/existsSync config)
config
(infra/exit-with-error (str "failed to read config: " config)))))
(def config (-> (find-config) (fs/readFileSync #js {:encoding "UTF-8"}) edn/read-string))
(defn trim-text [text] (defn trim-text [text]
(let [max-post-length (masto/max-post-length (mastodon-config config))] (let [max-post-length (masto/max-post-length (mastodon-config config))]
@ -139,7 +128,7 @@
(fn [timeline] (fn [timeline]
(let [last-post-time (-> timeline first :created_at (js/Date.))] (let [last-post-time (-> timeline first :created_at (js/Date.))]
;;post from Twitter ;;post from Twitter
(when-let [twitter-config (::twitter config)] (when-let [twitter-config (:twitter config)]
(let [{:keys [access-keys accounts include-replies? include-rts?]} twitter-config (let [{:keys [access-keys accounts include-replies? include-rts?]} twitter-config
client (twitter-client access-keys)] client (twitter-client access-keys)]
(doseq [account accounts] (doseq [account accounts]

View file

@ -29,33 +29,33 @@
(s/def ::content-filters (s/* ::content-filter)) (s/def ::content-filters (s/* ::content-filter))
(s/def ::keyword-filters (s/* ::keyword-filter)) (s/def ::keyword-filters (s/* ::keyword-filter))
(s/def ::mastodon-js-config (s/keys :req [::access_token ::api_url])) (s/def ::mastodon-js-config (s/keys :req-un [::access_token ::api_url]))
(s/def ::mastodon-clj-config (s/keys :req [::account-id ::content-filters ::keyword-filters (s/def ::mastodon-clj-config (s/keys :req-un [::account-id ::content-filters ::keyword-filters
::max-post-length ::signature ::visibility ::max-post-length ::signature ::visibility
::append-screen-name? ::sensitive? ::resolve-urls? ::append-screen-name? ::sensitive? ::resolve-urls?
::nitter-urls? ::replacements])) ::nitter-urls? ::replacements]))
(def mastodon-config? (s/merge ::mastodon-js-config ::mastodon-clj-config)) (def mastodon-config? (s/merge ::mastodon-js-config ::mastodon-clj-config))
(defn-spec content-filter-regexes ::content-filters (defn-spec content-filter-regexes ::content-filters
[mastodon-config mastodon-config?] [mastodon-config mastodon-config?]
(mapv re-pattern (::content-filters mastodon-config))) (mapv re-pattern (:content-filters mastodon-config)))
(defn-spec keyword-filter-regexes ::keyword-filters (defn-spec keyword-filter-regexes ::keyword-filters
[mastodon-config mastodon-config?] [mastodon-config mastodon-config?]
(mapv re-pattern (::keyword-filters mastodon-config))) (mapv re-pattern (:keyword-filters mastodon-config)))
(defn-spec append-screen-name? ::append-screen-name? (defn-spec append-screen-name? ::append-screen-name?
[mastodon-config mastodon-config?] [mastodon-config mastodon-config?]
(boolean (::append-screen-name? mastodon-config))) (boolean (:append-screen-name? mastodon-config)))
(defn-spec max-post-length ::max-post-length (defn-spec max-post-length ::max-post-length
[mastodon-config mastodon-config?] [mastodon-config mastodon-config?]
(::max-post-length mastodon-config)) (:max-post-length mastodon-config))
(defn-spec perform-replacements string? (defn-spec perform-replacements string?
[mastodon-config mastodon-config? [mastodon-config mastodon-config?
text string?] text string?]
(reduce-kv string/replace text (::replacements mastodon-config))) (reduce-kv string/replace text (:replacements mastodon-config)))
(defn-spec mastodon-client any? (defn-spec mastodon-client any?
[mastodon-config mastodon-config?] [mastodon-config mastodon-config?]
@ -94,15 +94,15 @@
[mastodon-config mastodon-config? [mastodon-config mastodon-config?
text string?] text string?]
(cond-> text (cond-> text
(::resolve-urls? mastodon-config) (:resolve-urls? mastodon-config)
(string/replace shortened-url-pattern resolve-url) (string/replace shortened-url-pattern resolve-url)
(::nitter-urls? mastodon-config) (:nitter-urls? mastodon-config)
(string/replace #"https://twitter.com" "https://nitter.net"))) (string/replace #"https://twitter.com" "https://nitter.net")))
(defn-spec set-signature string? (defn-spec set-signature string?
[mastodon-config mastodon-config? [mastodon-config mastodon-config?
text string?] text string?]
(if-let [signature (::signature mastodon-config )] (if-let [signature (:signature mastodon-config )]
(str text "\n" signature) (str text "\n" signature)
text)) text))
@ -112,7 +112,7 @@
([mastodon-config status-text media-ids] ([mastodon-config status-text media-ids]
(post-status mastodon-config status-text media-ids print)) (post-status mastodon-config status-text media-ids print))
([mastodon-config status-text media-ids callback] ([mastodon-config status-text media-ids callback]
(let [{:mastodon-bot.mastodon-api/keys [sensitive? signature visibility]} mastodon-config] (let [{:keys [sensitive? signature visibility]} mastodon-config]
(-> (.post (mastodon-client mastodon-config) "statuses" (-> (.post (mastodon-client mastodon-config) "statuses"
(clj->js (merge {:status (->> status-text (clj->js (merge {:status (->> status-text
(resolve-urls mastodon-config) (resolve-urls mastodon-config)
@ -134,22 +134,24 @@
(defn post-status-with-images (defn post-status-with-images
([mastodon-config status-text urls] ([mastodon-config status-text urls]
(post-status-with-images mastodon-config status-text urls [])) (post-status-with-images mastodon-config status-text urls [] print))
([mastodon-config status-text [url & urls] ids] ([mastodon-config status-text urls ids]
(post-status-with-images mastodon-config status-text urls ids print))
([mastodon-config status-text [url & urls] ids callback]
(if url (if url
(-> request (-> request
(.get url) (.get url)
(.on "response" (.on "response"
(fn [image-stream] (fn [image-stream]
(post-image mastodon-config image-stream status-text (post-image mastodon-config image-stream status-text
#(post-status-with-images status-text urls (conj ids %)))))) #(post-status-with-images status-text urls (conj ids %) callback)))))
(post-status mastodon-config status-text (not-empty ids))))) (post-status mastodon-config status-text (not-empty ids) callback))))
(defn-spec get-mastodon-timeline any? (defn-spec get-mastodon-timeline any?
[mastodon-config mastodon-config? [mastodon-config mastodon-config?
callback fn?] callback fn?]
(.then (.get (mastodon-client mastodon-config) (.then (.get (mastodon-client mastodon-config)
(str "accounts/" (::account-id mastodon-config)"/statuses") #js {}) (str "accounts/" (:account-id mastodon-config)"/statuses") #js {})
#(let [response (-> % .-data infra/js->edn)] #(let [response (-> % .-data infra/js->edn)]
(if-let [error (::error response)] (if-let [error (::error response)]
(infra/exit-with-error error) (infra/exit-with-error error)