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/core.cache "1.0.207"]
[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
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})

View file

@ -9,8 +9,12 @@
(:import (java.io BufferedReader InputStreamReader))
(: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 user (atom {}))
@ -23,6 +27,15 @@
(reset! user (first users)))
(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
"packs and shows main window with signald version string"
[& args]
@ -30,27 +43,30 @@
;; paint main chat window
(paint-main)
;; 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 "linking_uri" (fn [x] (paint-linking x)))
(assoc-callback-type "linking_successful" (fn [_] (paint-linking nil)))
(assoc-callback-type "linking_error" (fn [_]
(paint-linking nil)
(add-str-flag "Linking returned Error")))
(assoc-callback-type "unexpected_error" (fn [x] (add-str-flag (str "Unexpected error: "
(get-in x ["data" "message"])))))
(assoc-callback-type "contacts_list" (fn [x] (let [contacts (get x "data")]
;; Should we iter in a background thread?
(doseq [contact contacts]
;; TODO: sync with storage
(add-json-contact contact)))))
;; prep to read signald
(let [sigd (get-signald-sock sockpath)]
(if (nil? sigd)
(add-str-flag "No signald connection.")
;; also open storage
(let [sigd (get-signald-sock sockpath)
db (init-db dbpath)]
;; else, we have connection to signald
;; check if signald conn failed
(if (nil? sigd)
(add-str-flag "No signald connection."))
;; 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 "linking_uri" (fn [x] (paint-linking x)))
(assoc-callback-type "linking_successful" (fn [_] (paint-linking nil)))
(assoc-callback-type "linking_error" (fn [_]
(paint-linking nil)
(add-str-flag "Linking returned Error")))
(assoc-callback-type "unexpected_error" (fn [x] (add-str-flag (str "Unexpected error: "
(get-in x ["data" "message"])))))
(assoc-callback-type "contacts_list" (fn [x] (digest-group-or-contact-list
(get-in x ["data"]) db)))
(assoc-callback-type "group_list" (fn [x] (digest-group-or-contact-list
(get-in x ["data" "groups"]) db)))
;; get io channels for signald
(let [sigd-input (io/writer (.getOutputStream sigd))
sigd-output (BufferedReader. (InputStreamReader. (.getInputStream sigd)))
sigd-loop (thread (callback-loop sigd-output))]
@ -88,10 +104,11 @@
(do
(make-subscribe-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
(make-list-accounts-req sigd-input)
;; finally, block on signald loop till return
(<!! sigd-loop)))))
(<!! sigd-loop))))

View file

@ -32,7 +32,7 @@
(let [obj (json/read-str line)
type-tok (get obj "type")
callback-func (get @callback-table type-tok)]
(log/info "Signald: " line)
(log/info "Received message from signald (type: " type-tok ").")
(if (nil? callback-func)
(log/error "No callback for message type: " type-tok)
(callback-func obj))))))
@ -44,6 +44,16 @@
(get data "version") " "
(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
;; adds a newline
(defn -make-req
@ -81,3 +91,8 @@
(-make-req output-stream
(json/write-str {"type" "list_contacts"
"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
[contact]
{:fx/type :label
:text (json/write-str contact)})
{:fx/type :v-box
:children [{:fx/type :label
:text (get contact "name")}
{:fx/type :label
:text (get contact "id")}]})
(defn paint-flag
[flag]