enable unqalified keywords again
This commit is contained in:
parent
af85887931
commit
1ebb0e71f5
3 changed files with 57 additions and 69 deletions
65
README.md
65
README.md
|
@ -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.
|
||||
|
||||
```clojure
|
||||
#:mastodon-bot.core
|
||||
{;; add Twitter config to mirror Twitter accounts
|
||||
:twitter {:access-keys
|
||||
{: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
|
||||
:rss {"Hacker News" "https://hnrss.org/newest"
|
||||
"r/Clojure" "https://www.reddit.com/r/clojure/.rss"}
|
||||
:mastodon
|
||||
#:mastodon-bot.mastodon-api
|
||||
{:access_token "XXXX"
|
||||
;; account number you see when you log in and go to your profile
|
||||
;; e.g: https://mastodon.social/web/accounts/294795
|
||||
:account-id "XXXX"
|
||||
:api_url "https://botsin.space/api/v1/"
|
||||
;; optional boolean to mark content as sensitive
|
||||
:sensitive? true
|
||||
;; optional boolean defaults to false
|
||||
;; only sources containing media will be posted when set to true
|
||||
:media-only? true
|
||||
;; optional visibility flag: direct, private, unlisted, public
|
||||
;; defaults to public
|
||||
:visibility "unlisted"
|
||||
;; optional limit for the post length
|
||||
:max-post-length 300
|
||||
;; optional flag specifying wether the name of the account
|
||||
;; will be appended in the post, defaults to false
|
||||
:append-screen-name? false
|
||||
;; optional signature for posts
|
||||
:signature "#newsbot"
|
||||
;; optionally try to resolve URLs in posts to skip URL shorteners
|
||||
;; defaults to false
|
||||
:resolve-urls? true
|
||||
;; optional content filter regexes
|
||||
;; any posts matching the regexes will be filtered out
|
||||
:content-filters [".*bannedsite.*"]
|
||||
;; optional keyword filter regexes
|
||||
;; any posts not matching the regexes will be filtered out
|
||||
:keyword-filters [".*clojure.*"]
|
||||
;; Replace Twitter links by Nitter
|
||||
:nitter-urls? false}}
|
||||
:mastodon {:access_token "XXXX"
|
||||
;; account number you see when you log in and go to your profile
|
||||
;; e.g: https://mastodon.social/web/accounts/294795
|
||||
:account-id "XXXX"
|
||||
:api_url "https://botsin.space/api/v1/"
|
||||
;; optional boolean to mark content as sensitive
|
||||
:sensitive? true
|
||||
;; optional boolean defaults to false
|
||||
;; only sources containing media will be posted when set to true
|
||||
:media-only? true
|
||||
;; optional visibility flag: direct, private, unlisted, public
|
||||
;; defaults to public
|
||||
:visibility "unlisted"
|
||||
;; optional limit for the post length
|
||||
:max-post-length 300
|
||||
;; optional flag specifying wether the name of the account
|
||||
;; will be appended in the post, defaults to false
|
||||
:append-screen-name? false
|
||||
;; optional signature for posts
|
||||
:signature "#newsbot"
|
||||
;; optionally try to resolve URLs in posts to skip URL shorteners
|
||||
;; defaults to false
|
||||
:resolve-urls? true
|
||||
;; optional content filter regexes
|
||||
;; any posts matching the regexes will be filtered out
|
||||
:content-filters [".*bannedsite.*"]
|
||||
;; optional keyword filter regexes
|
||||
;; any posts not matching the regexes will be filtered out
|
||||
:keyword-filters [".*clojure.*"]
|
||||
;; 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
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
[clojure.spec.test.alpha :as st]
|
||||
[orchestra.core :refer-macros [defn-spec]]
|
||||
[cljs.core :refer [*command-line-args*]]
|
||||
[cljs.reader :as edn]
|
||||
[clojure.string :as string]
|
||||
["fs" :as fs]
|
||||
["rss-parser" :as rss]
|
||||
["tumblr" :as tumblr]
|
||||
["twitter" :as twitter]
|
||||
|
@ -20,23 +18,14 @@
|
|||
(s/def ::tumblr map?)
|
||||
(s/def ::rss map?)
|
||||
|
||||
(def config? (s/keys :req [::mastodon-config]
|
||||
:opt [::twitter ::tumblr ::rss]))
|
||||
(def config? (s/keys :req-un [::mastodon-config]
|
||||
: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
|
||||
[config config?]
|
||||
(::mastodon-config config))
|
||||
(:mastodon-config config))
|
||||
|
||||
(defn find-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))
|
||||
(def config (infra/load-config))
|
||||
|
||||
(defn trim-text [text]
|
||||
(let [max-post-length (masto/max-post-length (mastodon-config config))]
|
||||
|
@ -139,7 +128,7 @@
|
|||
(fn [timeline]
|
||||
(let [last-post-time (-> timeline first :created_at (js/Date.))]
|
||||
;;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
|
||||
client (twitter-client access-keys)]
|
||||
(doseq [account accounts]
|
||||
|
|
|
@ -29,33 +29,33 @@
|
|||
|
||||
(s/def ::content-filters (s/* ::content-filter))
|
||||
(s/def ::keyword-filters (s/* ::keyword-filter))
|
||||
(s/def ::mastodon-js-config (s/keys :req [::access_token ::api_url]))
|
||||
(s/def ::mastodon-clj-config (s/keys :req [::account-id ::content-filters ::keyword-filters
|
||||
::max-post-length ::signature ::visibility
|
||||
::append-screen-name? ::sensitive? ::resolve-urls?
|
||||
::nitter-urls? ::replacements]))
|
||||
(s/def ::mastodon-js-config (s/keys :req-un [::access_token ::api_url]))
|
||||
(s/def ::mastodon-clj-config (s/keys :req-un [::account-id ::content-filters ::keyword-filters
|
||||
::max-post-length ::signature ::visibility
|
||||
::append-screen-name? ::sensitive? ::resolve-urls?
|
||||
::nitter-urls? ::replacements]))
|
||||
(def mastodon-config? (s/merge ::mastodon-js-config ::mastodon-clj-config))
|
||||
|
||||
(defn-spec content-filter-regexes ::content-filters
|
||||
[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
|
||||
[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?
|
||||
[mastodon-config mastodon-config?]
|
||||
(boolean (::append-screen-name? mastodon-config)))
|
||||
(boolean (:append-screen-name? mastodon-config)))
|
||||
|
||||
(defn-spec max-post-length ::max-post-length
|
||||
[mastodon-config mastodon-config?]
|
||||
(::max-post-length mastodon-config))
|
||||
(:max-post-length mastodon-config))
|
||||
|
||||
(defn-spec perform-replacements string?
|
||||
[mastodon-config mastodon-config?
|
||||
text string?]
|
||||
(reduce-kv string/replace text (::replacements mastodon-config)))
|
||||
(reduce-kv string/replace text (:replacements mastodon-config)))
|
||||
|
||||
(defn-spec mastodon-client any?
|
||||
[mastodon-config mastodon-config?]
|
||||
|
@ -94,15 +94,15 @@
|
|||
[mastodon-config mastodon-config?
|
||||
text string?]
|
||||
(cond-> text
|
||||
(::resolve-urls? mastodon-config)
|
||||
(:resolve-urls? mastodon-config)
|
||||
(string/replace shortened-url-pattern resolve-url)
|
||||
(::nitter-urls? mastodon-config)
|
||||
(:nitter-urls? mastodon-config)
|
||||
(string/replace #"https://twitter.com" "https://nitter.net")))
|
||||
|
||||
(defn-spec set-signature string?
|
||||
[mastodon-config mastodon-config?
|
||||
text string?]
|
||||
(if-let [signature (::signature mastodon-config )]
|
||||
(if-let [signature (:signature mastodon-config )]
|
||||
(str text "\n" signature)
|
||||
text))
|
||||
|
||||
|
@ -112,7 +112,7 @@
|
|||
([mastodon-config status-text media-ids]
|
||||
(post-status mastodon-config status-text media-ids print))
|
||||
([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"
|
||||
(clj->js (merge {:status (->> status-text
|
||||
(resolve-urls mastodon-config)
|
||||
|
@ -134,22 +134,24 @@
|
|||
|
||||
(defn post-status-with-images
|
||||
([mastodon-config status-text urls]
|
||||
(post-status-with-images mastodon-config status-text urls []))
|
||||
([mastodon-config status-text [url & urls] ids]
|
||||
(post-status-with-images mastodon-config status-text urls [] print))
|
||||
([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
|
||||
(-> request
|
||||
(.get url)
|
||||
(.on "response"
|
||||
(fn [image-stream]
|
||||
(post-image mastodon-config image-stream status-text
|
||||
#(post-status-with-images status-text urls (conj ids %))))))
|
||||
(post-status mastodon-config status-text (not-empty ids)))))
|
||||
#(post-status-with-images status-text urls (conj ids %) callback)))))
|
||||
(post-status mastodon-config status-text (not-empty ids) callback))))
|
||||
|
||||
(defn-spec get-mastodon-timeline any?
|
||||
[mastodon-config mastodon-config?
|
||||
callback fn?]
|
||||
(.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)]
|
||||
(if-let [error (::error response)]
|
||||
(infra/exit-with-error error)
|
||||
|
|
Reference in a new issue