mirror of
https://github.com/unclebob/more-speech.git
synced 2024-09-30 10:30:56 +00:00
Get nostr: and @ working... Sorta.
This commit is contained in:
parent
4db675ca4c
commit
b3d4183dd7
@ -1,12 +1,12 @@
|
|||||||
(ns more-speech.ui.formatters-spec
|
(ns more-speech.ui.formatters-spec
|
||||||
(:require [speclj.core :refer :all]
|
(:require [more-speech.config :as config]
|
||||||
[more-speech.db.gateway :as gateway]
|
[more-speech.db.gateway :as gateway]
|
||||||
[more-speech.db.in-memory :as in-memory]
|
[more-speech.db.in-memory :as in-memory]
|
||||||
[more-speech.nostr.util :refer [hexify]]
|
|
||||||
[more-speech.ui.formatters :refer :all]
|
|
||||||
[more-speech.ui.formatter-util :refer :all]
|
|
||||||
[more-speech.mem :refer :all]
|
[more-speech.mem :refer :all]
|
||||||
[more-speech.config :as config]))
|
[more-speech.nostr.util :refer [hexify]]
|
||||||
|
[more-speech.ui.formatter-util :refer :all]
|
||||||
|
[more-speech.ui.formatters :refer :all]
|
||||||
|
[speclj.core :refer :all]))
|
||||||
|
|
||||||
(describe "Abbreviations."
|
(describe "Abbreviations."
|
||||||
(it "abbreviates pubkeys"
|
(it "abbreviates pubkeys"
|
||||||
@ -246,7 +246,25 @@
|
|||||||
|
|
||||||
(it "returns a list of :text and :url and :namereference segments"
|
(it "returns a list of :text and :url and :namereference segments"
|
||||||
(should= [[:text "Hey "] [:namereference "@bob"] [:text " Check this "] [:url "http://nostr.com"] [:text " It's cool"]]
|
(should= [[:text "Hey "] [:namereference "@bob"] [:text " Check this "] [:url "http://nostr.com"] [:text " It's cool"]]
|
||||||
(segment-article "Hey @bob Check this http://nostr.com It's cool")))
|
(segment-article "Hey @bob Check this http://nostr.com It's cool"))
|
||||||
|
(should= [[:namereference "npub1qq"] [:text " "]
|
||||||
|
[:namereference "@npub1qq"] [:text " "]
|
||||||
|
[:nostrnamereference "nostr:npub1qq"] [:text " "]
|
||||||
|
[:nostrnamereference "@nostr:npub1qq"]]
|
||||||
|
(segment-article "npub1qq @npub1qq nostr:npub1qq @nostr:npub1qq"))
|
||||||
|
(should= [[:notereference "note1qq"] [:text " "]
|
||||||
|
[:notereference "@note1qq"] [:text " "]
|
||||||
|
[:nostrnotereference "nostr:note1qq"] [:text " "]
|
||||||
|
[:nostrnotereference "@nostr:note1qq"]]
|
||||||
|
(segment-article "note1qq @note1qq nostr:note1qq @nostr:note1qq")))
|
||||||
|
(it "extracts text from segments"
|
||||||
|
(should= "name" (extract-reference "@name"))
|
||||||
|
(should= "npub1qq" (extract-reference "npub1qq"))
|
||||||
|
(should= "x" (extract-reference "nostr:x"))
|
||||||
|
(should= "x" (extract-reference "@nostr:x"))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
(describe "Format article"
|
(describe "Format article"
|
||||||
@ -257,11 +275,11 @@
|
|||||||
(should= "<a href=\"https://nostr.com\">nostr.com</a>" (reformat-article-into-html "https://nostr.com")))
|
(should= "<a href=\"https://nostr.com\">nostr.com</a>" (reformat-article-into-html "https://nostr.com")))
|
||||||
|
|
||||||
(it "should ms-link a namereference"
|
(it "should ms-link a namereference"
|
||||||
(should= "<a href=\"ms-namereference://@name\">@name</a>"
|
(should= "<a href=\"ms-namereference://name\">@name</a>"
|
||||||
(reformat-article-into-html "@name")))
|
(reformat-article-into-html "@name")))
|
||||||
|
|
||||||
(it "should ms-link an idreference"
|
(it "should ms-link an idreference"
|
||||||
(should= "<a href=\"ms-idreference://@0000000000000000000000000000000000000000000000000000000000000000\">@0000000000000000000000000000000000000000000000000000000000000000</a>"
|
(should= "<a href=\"ms-idreference://0000000000000000000000000000000000000000000000000000000000000000\">@0000000000000000000000000000000000000000000000000000000000000000</a>"
|
||||||
(reformat-article-into-html "@0000000000000000000000000000000000000000000000000000000000000000")))
|
(reformat-article-into-html "@0000000000000000000000000000000000000000000000000000000000000000")))
|
||||||
|
|
||||||
(it "should escape HTML entities and linkify url"
|
(it "should escape HTML entities and linkify url"
|
||||||
@ -274,7 +292,6 @@
|
|||||||
(it "should replace multiple spaces with  "
|
(it "should replace multiple spaces with  "
|
||||||
(should= "one two  three   ." (reformat-article-into-html "one two three .")))
|
(should= "one two  three   ." (reformat-article-into-html "one two three .")))
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
(declare db)
|
(declare db)
|
||||||
|
@ -56,13 +56,6 @@
|
|||||||
(def user-configuration-filename (atom "private/user-configuration"))
|
(def user-configuration-filename (atom "private/user-configuration"))
|
||||||
(def contact-lists-filename (atom "private/ub-contacts"))
|
(def contact-lists-filename (atom "private/ub-contacts"))
|
||||||
|
|
||||||
(def npub-reference #"npub1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]+")
|
|
||||||
(def user-reference-pattern #"(?:\@[\w\-]+)|(?:npub1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]+)")
|
|
||||||
(def id-reference-pattern #"\@[0-9a-f]{64}")
|
|
||||||
(def hex-key-pattern #"[0-9a-f]{64}")
|
|
||||||
(def user-name-chars #"[\w\-]+")
|
|
||||||
(def reference-pattern #"\#\[\d+\]")
|
|
||||||
|
|
||||||
(def proof-of-work-default 12)
|
(def proof-of-work-default 12)
|
||||||
(def max-nodes-per-tab 1000)
|
(def max-nodes-per-tab 1000)
|
||||||
(def prune-tabs-frequency-in-minutes 60)
|
(def prune-tabs-frequency-in-minutes 60)
|
||||||
@ -77,10 +70,21 @@
|
|||||||
|
|
||||||
;; https://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
;; https://daringfireball.net/2010/07/improved_regex_for_matching_urls
|
||||||
(def url-pattern #"(?i)\b(?:(?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(?:(?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))*\))+(?:\(?:(?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))")
|
(def url-pattern #"(?i)\b(?:(?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(?:(?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))*\))+(?:\(?:(?:[^\s()<>]+|(?:\(?:[^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))")
|
||||||
|
(def nostr-note-reference-pattern #"(?:\@)?nostr:note1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]+")
|
||||||
|
(def note-reference-pattern #"(?:\@)?note1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]+")
|
||||||
|
(def nostr-user-reference-pattern #"(?:\@)?nostr:npub1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]+")
|
||||||
|
(def user-reference-pattern #"(?:\@[\w\-]+)|(?:\@)?(?:npub1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]+)")
|
||||||
|
(def id-reference-pattern #"\@[0-9a-f]{64}")
|
||||||
|
|
||||||
(def email-pattern #"[\w.-]+@[\w.-]+")
|
(def email-pattern #"[\w.-]+@[\w.-]+")
|
||||||
(def relay-pattern #"ws+://[\w.-]+/?")
|
(def relay-pattern #"ws+://[\w.-]+/?")
|
||||||
(def lud16-pattern #"([a-z0-9-_.]+)@([a-z0-9-_.]+\.[a-z0-9-_]+)")
|
(def lud16-pattern #"([a-z0-9-_.]+)@([a-z0-9-_.]+\.[a-z0-9-_]+)")
|
||||||
|
|
||||||
|
(def npub-reference #"npub1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]+")
|
||||||
|
(def hex-key-pattern #"[0-9a-f]{64}")
|
||||||
|
(def user-name-chars #"[\w\-]+")
|
||||||
|
(def reference-pattern #"\#\[\d+\]")
|
||||||
|
|
||||||
(def production-db :xtdb)
|
(def production-db :xtdb)
|
||||||
(def db-type (atom nil))
|
(def db-type (atom nil))
|
||||||
|
|
||||||
|
@ -18,23 +18,38 @@
|
|||||||
date (Date. (long time))]
|
date (Date. (long time))]
|
||||||
(.format (SimpleDateFormat. "MM/dd/yyyy kk:mm:ss z") date)))
|
(.format (SimpleDateFormat. "MM/dd/yyyy kk:mm:ss z") date)))
|
||||||
|
|
||||||
|
(defn send-request [request close]
|
||||||
|
(doseq [url (keys @relays)]
|
||||||
|
(when (not= :read-none (get-in @relays [url :read]))
|
||||||
|
(let [relay (:connection (get @relays url))]
|
||||||
|
(when (some? relay)
|
||||||
|
(relay/send relay request)
|
||||||
|
(future (do (Thread/sleep 2000)
|
||||||
|
(relay/send relay close))))))))
|
||||||
|
|
||||||
|
(defn- make-request-id []
|
||||||
|
(let [r (rand-int 1000000)]
|
||||||
|
(str "ms-request-" r)))
|
||||||
|
|
||||||
|
(defn request-note [id]
|
||||||
|
(let [req-id (make-request-id)
|
||||||
|
request ["REQ" req-id {"kinds" [1] "ids" [(util/hexify id)]} ]
|
||||||
|
close ["CLOSE" req-id]]
|
||||||
|
(send-request request close))
|
||||||
|
)
|
||||||
|
|
||||||
(defn request-profiles-and-contacts-for [authors]
|
(defn request-profiles-and-contacts-for [authors]
|
||||||
(let [authors (if (coll? authors) authors [authors])
|
(let [authors (if (coll? authors) authors [authors])
|
||||||
hexified-authors (map util/hexify authors)
|
hexified-authors (map util/hexify authors)
|
||||||
trimmed-authors (if (<= (count hexified-authors) 100)
|
trimmed-authors (if (<= (count hexified-authors) 100)
|
||||||
hexified-authors
|
hexified-authors
|
||||||
(map #(subs % 0 10) (take 1000 (shuffle hexified-authors))))
|
(map #(subs % 0 10) (take 1000 (shuffle hexified-authors))))
|
||||||
r (rand-int 1000000)]
|
r (rand-int 1000000)
|
||||||
(doseq [url (keys @relays)]
|
request ["REQ" (str "ms-request-" r) {"kinds" [0 3]
|
||||||
(when (not= :read-none (get-in @relays [url :read]))
|
"authors" trimmed-authors}]
|
||||||
(let [relay (:connection (get @relays url))]
|
close ["CLOSE" (str "ms-request-" r)]]
|
||||||
(when (some? relay)
|
(send-request request close)
|
||||||
(relay/send relay
|
))
|
||||||
["REQ" (str "ms-authors-" r) {"kinds" [0 3]
|
|
||||||
"authors" trimmed-authors}])
|
|
||||||
(future (do (Thread/sleep 2000)
|
|
||||||
(relay/send relay
|
|
||||||
["CLOSE" (str "ms-authors-" r)])))))))))
|
|
||||||
|
|
||||||
(defn request-contact-lists [relay]
|
(defn request-contact-lists [relay]
|
||||||
(let [now (quot (System/currentTimeMillis) 1000)
|
(let [now (quot (System/currentTimeMillis) 1000)
|
||||||
|
@ -113,7 +113,7 @@
|
|||||||
[reply-id _ _] (events/get-references event)
|
[reply-id _ _] (events/get-references event)
|
||||||
reply-mark (if (some? reply-id) "^" " ")
|
reply-mark (if (some? reply-id) "^" " ")
|
||||||
dm-mark (if (= 4 (:kind event)) (make-dm-mark event) "")
|
dm-mark (if (= 4 (:kind event)) (make-dm-mark event) "")
|
||||||
zap-mark (if (some? zaps) "❗ " "")
|
zap-mark (if (some? zaps) "❗⚡ " "")
|
||||||
reaction-mark (make-reaction-mark event)
|
reaction-mark (make-reaction-mark event)
|
||||||
header-text (-> content (string/replace \newline \~) (abbreviate 130))
|
header-text (-> content (string/replace \newline \~) (abbreviate 130))
|
||||||
content (if (empty? subject)
|
content (if (empty? subject)
|
||||||
@ -162,7 +162,7 @@
|
|||||||
(str "<a href=\"" url "\">" uri "</a>")))
|
(str "<a href=\"" url "\">" uri "</a>")))
|
||||||
|
|
||||||
(defn ms-linkify [type subject]
|
(defn ms-linkify [type subject]
|
||||||
(str "<a href=\"" (str type "://" subject) "\">" subject "</a>"))
|
(str "<a href=\"" (str type "://" subject) "\">@" subject "</a>"))
|
||||||
|
|
||||||
(defn img-ify [seg]
|
(defn img-ify [seg]
|
||||||
(str "<a href=\"" seg "\"><img src=\"" seg "\"></a><br>" (linkify seg)))
|
(str "<a href=\"" seg "\"><img src=\"" seg "\"></a><br>" (linkify seg)))
|
||||||
@ -189,9 +189,13 @@
|
|||||||
(segment-article content []))
|
(segment-article content []))
|
||||||
|
|
||||||
([content segments]
|
([content segments]
|
||||||
(let [patterns [[:url config/url-pattern]
|
(let [patterns [[:nostrnotereference config/nostr-note-reference-pattern]
|
||||||
|
[:nostrnamereference config/nostr-user-reference-pattern]
|
||||||
|
[:notereference config/note-reference-pattern]
|
||||||
[:idreference config/id-reference-pattern]
|
[:idreference config/id-reference-pattern]
|
||||||
[:namereference config/user-reference-pattern]]
|
[:namereference config/user-reference-pattern]
|
||||||
|
|
||||||
|
[:url config/url-pattern]]
|
||||||
pattern (apply combine-patterns patterns)
|
pattern (apply combine-patterns patterns)
|
||||||
group-names (map first patterns)]
|
group-names (map first patterns)]
|
||||||
(loop [content content
|
(loop [content content
|
||||||
@ -220,12 +224,19 @@
|
|||||||
:else
|
:else
|
||||||
(concat segments (list [:text content]))))))))
|
(concat segments (list [:text content]))))))))
|
||||||
|
|
||||||
|
(defn extract-reference [s]
|
||||||
|
(cond
|
||||||
|
(.startsWith s "nostr:") (subs s 6)
|
||||||
|
(.startsWith s "@nostr:") (subs s 7)
|
||||||
|
(.startsWith s "@") (subs s 1)
|
||||||
|
:else s))
|
||||||
|
|
||||||
(defn reformat-article-into-html [article]
|
(defn reformat-article-into-html [article]
|
||||||
(let [segments (segment-article article)]
|
(let [segments (segment-article article)]
|
||||||
(reduce
|
(reduce
|
||||||
(fn [formatted-content [seg-type seg]]
|
(fn [formatted-content [seg-type seg]]
|
||||||
(condp = seg-type
|
(cond
|
||||||
:text
|
(= seg-type :text)
|
||||||
(str formatted-content
|
(str formatted-content
|
||||||
((comp
|
((comp
|
||||||
non-breaking-spaces
|
non-breaking-spaces
|
||||||
@ -234,18 +245,23 @@
|
|||||||
format-replies
|
format-replies
|
||||||
) seg)
|
) seg)
|
||||||
)
|
)
|
||||||
:url
|
|
||||||
|
(= seg-type :url)
|
||||||
(str formatted-content (linkify seg))
|
(str formatted-content (linkify seg))
|
||||||
|
|
||||||
:namereference
|
(or (= seg-type :namereference) (= seg-type :nostrnamereference))
|
||||||
(str formatted-content (ms-linkify "ms-namereference" seg))
|
(str formatted-content (ms-linkify "ms-namereference" (extract-reference seg)))
|
||||||
|
|
||||||
:idreference
|
(= seg-type :idreference)
|
||||||
(str formatted-content (ms-linkify "ms-idreference" seg))
|
(str formatted-content (ms-linkify "ms-idreference" (subs seg 1)))
|
||||||
|
|
||||||
:img
|
(or (= seg-type :notereference) (= seg-type :nostrnotereference))
|
||||||
|
(str formatted-content (ms-linkify "ms-notereference" (extract-reference seg)))
|
||||||
|
|
||||||
|
(= seg-type :img)
|
||||||
(str formatted-content (img-ify seg))
|
(str formatted-content (img-ify seg))
|
||||||
|
|
||||||
|
:else
|
||||||
formatted-content
|
formatted-content
|
||||||
))
|
))
|
||||||
""
|
""
|
||||||
|
@ -273,7 +273,7 @@
|
|||||||
(text! up-arrow "👍🏻")
|
(text! up-arrow "👍🏻")
|
||||||
(text! dn-arrow "👎🏻")))
|
(text! dn-arrow "👎🏻")))
|
||||||
(if zapped?
|
(if zapped?
|
||||||
(text! zap-icon "❗ ")
|
(text! zap-icon "❗⚡ ")
|
||||||
(text! zap-icon ""))
|
(text! zap-icon ""))
|
||||||
(swing-util/clear-popup relays-popup)
|
(swing-util/clear-popup relays-popup)
|
||||||
(swing-util/clear-popup reactions-popup)
|
(swing-util/clear-popup reactions-popup)
|
||||||
@ -328,7 +328,8 @@
|
|||||||
(.startsWith subject "npub")
|
(.startsWith subject "npub")
|
||||||
(bech32/address->number subject)
|
(bech32/address->number subject)
|
||||||
|
|
||||||
:else nil))
|
:else
|
||||||
|
(gateway/get-id-from-username (get-db) subject)))
|
||||||
|
|
||||||
(defn get-user-info [subject _e]
|
(defn get-user-info [subject _e]
|
||||||
(when-let [id (get-user-id-from-subject subject)]
|
(when-let [id (get-user-id-from-subject subject)]
|
||||||
@ -345,7 +346,7 @@
|
|||||||
(defn open-link [e]
|
(defn open-link [e]
|
||||||
(when (= HyperlinkEvent$EventType/ACTIVATED (.getEventType e))
|
(when (= HyperlinkEvent$EventType/ACTIVATED (.getEventType e))
|
||||||
(when-let [url (str (.getURL e))]
|
(when-let [url (str (.getURL e))]
|
||||||
(let [[type subject] (string/split (.getDescription e) #"://")]
|
(let [[type subject] (string/split (.getDescription e) #"\:\/\/")]
|
||||||
(cond
|
(cond
|
||||||
(or (= type "http") (= type "https"))
|
(or (= type "http") (= type "https"))
|
||||||
(try
|
(try
|
||||||
@ -355,7 +356,13 @@
|
|||||||
(log-pr 1 ex)))
|
(log-pr 1 ex)))
|
||||||
|
|
||||||
(= type "ms-idreference")
|
(= type "ms-idreference")
|
||||||
(let [id (util/unhexify (subs subject 1))]
|
(let [id (util/unhexify subject)]
|
||||||
|
(protocol/request-note id)
|
||||||
|
(swing-util/select-event id))
|
||||||
|
|
||||||
|
(= type "ms-notereference")
|
||||||
|
(let [id (bech32/address->number subject)]
|
||||||
|
(protocol/request-note id)
|
||||||
(swing-util/select-event id))
|
(swing-util/select-event id))
|
||||||
|
|
||||||
(= type "ms-namereference")
|
(= type "ms-namereference")
|
||||||
|
Loading…
Reference in New Issue
Block a user