add storage system, also parse groups

This commit is contained in:
Aidan 2020-11-30 22:04:43 -08:00
parent 85b3346f5d
commit 170c4cb559
No known key found for this signature in database
GPG key ID: 327711E983899316
5 changed files with 121 additions and 26 deletions

View file

@ -11,7 +11,8 @@
[org.clojure/tools.logging "1.1.0"] [org.clojure/tools.logging "1.1.0"]
[org.clojure/core.cache "1.0.207"] [org.clojure/core.cache "1.0.207"]
[org.clojure/core.async "1.3.610"] [org.clojure/core.async "1.3.610"]
[clj.qrgen "0.4.0"]] [clj.qrgen "0.4.0"]
[codax "1.3.1"]]
:main ^:skip-aot whisper.core :main ^:skip-aot whisper.core
:target-path "target/%s" :target-path "target/%s"
:profiles {:uberjar {:aot :all}}) :profiles {:uberjar {:aot :all}})

View file

@ -9,8 +9,12 @@
(:import (java.io BufferedReader InputStreamReader)) (:import (java.io BufferedReader InputStreamReader))
(:use [whisper.ui] (:use [whisper.ui]
[whisper.signald])) [whisper.signald]
[whisper.storage]))
;; TODO: config management
;; TODO: make config dir
(def dbpath "/tmp/temp_db")
(def sockpath "/var/run/signald/signald.sock") (def sockpath "/var/run/signald/signald.sock")
(def user (atom {})) (def user (atom {}))
@ -23,6 +27,15 @@
(reset! user (first users))) (reset! user (first users)))
(disassoc-callback-type "account_list")) (disassoc-callback-type "account_list"))
(defn digest-group-or-contact-list
[list db]
;; Should we iter in a background thread?
(doseq [contact list]
(let [id (get-id-from-contact-or-group contact)
name (get contact "name")]
(store-contact db id contact)
(add-json-contact {:id id :name name}))))
(defn -main (defn -main
"packs and shows main window with signald version string" "packs and shows main window with signald version string"
[& args] [& args]
@ -30,6 +43,15 @@
;; paint main chat window ;; paint main chat window
(paint-main) (paint-main)
;; prep to read signald
;; also open storage
(let [sigd (get-signald-sock sockpath)
db (init-db dbpath)]
;; check if signald conn failed
(if (nil? sigd)
(add-str-flag "No signald connection."))
;; register callbacks between the UI and signald ;; register callbacks between the UI and signald
(assoc-callback-type "version" (fn [x] (add-str-flag (get-version-from-version-message x)))) (assoc-callback-type "version" (fn [x] (add-str-flag (get-version-from-version-message x))))
(assoc-callback-type "linking_uri" (fn [x] (paint-linking x))) (assoc-callback-type "linking_uri" (fn [x] (paint-linking x)))
@ -39,18 +61,12 @@
(add-str-flag "Linking returned Error"))) (add-str-flag "Linking returned Error")))
(assoc-callback-type "unexpected_error" (fn [x] (add-str-flag (str "Unexpected error: " (assoc-callback-type "unexpected_error" (fn [x] (add-str-flag (str "Unexpected error: "
(get-in x ["data" "message"]))))) (get-in x ["data" "message"])))))
(assoc-callback-type "contacts_list" (fn [x] (let [contacts (get x "data")] (assoc-callback-type "contacts_list" (fn [x] (digest-group-or-contact-list
;; Should we iter in a background thread? (get-in x ["data"]) db)))
(doseq [contact contacts] (assoc-callback-type "group_list" (fn [x] (digest-group-or-contact-list
;; TODO: sync with storage (get-in x ["data" "groups"]) db)))
(add-json-contact contact)))))
;; prep to read signald ;; get io channels for signald
(let [sigd (get-signald-sock sockpath)]
(if (nil? sigd)
(add-str-flag "No signald connection.")
;; else, we have connection to signald
(let [sigd-input (io/writer (.getOutputStream sigd)) (let [sigd-input (io/writer (.getOutputStream sigd))
sigd-output (BufferedReader. (InputStreamReader. (.getInputStream sigd))) sigd-output (BufferedReader. (InputStreamReader. (.getInputStream sigd)))
sigd-loop (thread (callback-loop sigd-output))] sigd-loop (thread (callback-loop sigd-output))]
@ -88,10 +104,11 @@
(do (do
(make-subscribe-req sigd-input new-user) (make-subscribe-req sigd-input new-user)
(make-contact-sync-req sigd-input new-user) (make-contact-sync-req sigd-input new-user)
(make-contact-list-req sigd-input new-user)))))) (make-contact-list-req sigd-input new-user)
(make-group-list-req sigd-input new-user))))))
;; find avail accounts ;; find avail accounts
(make-list-accounts-req sigd-input) (make-list-accounts-req sigd-input)
;; finally, block on signald loop till return ;; finally, block on signald loop till return
(<!! sigd-loop))))) (<!! sigd-loop))))

View file

@ -32,7 +32,7 @@
(let [obj (json/read-str line) (let [obj (json/read-str line)
type-tok (get obj "type") type-tok (get obj "type")
callback-func (get @callback-table type-tok)] callback-func (get @callback-table type-tok)]
(log/info "Signald: " line) (log/info "Received message from signald (type: " type-tok ").")
(if (nil? callback-func) (if (nil? callback-func)
(log/error "No callback for message type: " type-tok) (log/error "No callback for message type: " type-tok)
(callback-func obj)))))) (callback-func obj))))))
@ -44,6 +44,16 @@
(get data "version") " " (get data "version") " "
(get data "branch")))) (get data "branch"))))
(defn get-id-from-contact-or-group
[contact]
(let [c-id (get-in contact ["address" "number"])
g-id (get-in contact ["groupId"])]
(if (nil? c-id)
(if (nil? g-id)
(log/error "Document had no contact id or group id")
g-id)
c-id)))
;; sends data to signal socket ;; sends data to signal socket
;; adds a newline ;; adds a newline
(defn -make-req (defn -make-req
@ -81,3 +91,8 @@
(-make-req output-stream (-make-req output-stream
(json/write-str {"type" "list_contacts" (json/write-str {"type" "list_contacts"
"username" username}))) "username" username})))
(defn make-group-list-req
[output-stream username]
(-make-req output-stream
(json/write-str {"type" "list_groups"
"username" username})))

59
src/whisper/storage.clj Normal file
View file

@ -0,0 +1,59 @@
(ns whisper.storage
"Whisper storage module"
(:require [clojure.tools.logging :as log]
[codax.core :as c]))
(defn init-db
"opens db at filepath and makes sure schema is in place"
[filepath]
(let [db (c/open-database! filepath)]
(if (nil? (c/get-at! db [:contacts]))
(c/assoc-at! db [:contacts] {}))
(if (nil? (c/get-at! db [:messages]))
(c/assoc-at! db [:messages] {}))
db))
(defn store-contact
"adds a new contact to db"
[db contact-id contact-doc]
(let [curr-doc (c/get-at! db [:contacts contact-id])]
(if (nil? curr-doc)
(c/assoc-at! db [:contacts contact-id] contact-doc)
(if (not (= curr-doc contact-doc))
(c/assoc-at! db [:contacts contact-id] contact-doc))))
(if (nil? (c/get-at! db [:messages contact-id]))
(c/assoc-at! db [:messages contact-id] [])))
(defn store-message
"adds a message to the db"
[db contact-id message-doc]
(let [curr-thread (c/get-at! db [:messages contact-id])]
;; no contact? dont bother
(if (nil? curr-thread)
(log/info "Received message for undiscovered contact (wont store).")
(c/merge-at! db [:messages contact-id] [message-doc]))))
(defn get-contacts
"retrieve all contacts"
[db]
(c/get-at! db [:contacts]))
(defn get-contact
"retrieve a specific contact"
[db contact-id]
(c/get-at! db [:contacts contact-id]))
(defn get-thread
"get all messages to and from a specific contact/group"
[db contact-id]
(c/get-at! db [:messages contact-id]))
(defn get-thread-and-contact-if-contact
"get all messages to and from a contact, as well as their contact info IF they are a stored contact"
[db contact-id]
(let [contact-doc (c/get-at! db [:contacts contact-id])]
(if (not (nil? contact-doc))
;; contact exists
{:contact contact-doc :thread (c/get-at! db [:messages contact-id])}
;; else return nil
nil)))

View file

@ -19,8 +19,11 @@
(defn paint-contact (defn paint-contact
[contact] [contact]
{:fx/type :v-box
:children [{:fx/type :label
:text (get contact "name")}
{:fx/type :label {:fx/type :label
:text (json/write-str contact)}) :text (get contact "id")}]})
(defn paint-flag (defn paint-flag
[flag] [flag]