# Code used for navigating and transforming
# the brush. Plus some utilities.
(use eleanor bearimy bearimy/utils marble manisha fzy)
(import /neil/appraisers :prefix "" :export true)
(defn sort-by-timestamp
```
Sorts `ds` by the `:timestamp` member.
```
[ds]
(sort-by (fn [i] (- (or (i :pin) (i :timestamp)))) ds))
(def state-weights
@{"active" 2 "completed" 1})
(defn sort-by-state-timestamp
```
Sorts `ds` by the `:timestamp` and `state-weights` member.
```
[ds]
(sort-by (fn [i]
(- (* (or (i :pin) (i :timestamp))
(state-weights (i :state))))) ds))
(defn name-has-match
```
Checks if the name has match with `q`.
```
[q]
(if (empty? q)
(fn [&] true)
(fn [i] (has-match q (. (i :uuid) " " (i :name))))))
(defn match-n-sort
```
Constructs function that will match and sort its `d` argument.
against `s` query.
All the members of `d` must have `:name` and `:uuid` keys if `s`
is not empty or `:timestamp` or `:order` if it is empty.
```
[s]
(if (empty? s)
(fn n-sort [d]
(->> d
(map |[$ (or ($ :timestamp) (- ($ :order)))])
(sort-by |(- ($ 1)))))
(fn match-n-sort [d]
(->>
(seq [t :in d
:let [n (. (t :uuid) " " (t :name))
sc (score s n)]
:when (and sc (> sc score-min))]
[t sc])
(sort-by |(- ($ 1)))))))
(defn next-id
```
Gets next id by counter from `brush`.
```
[brush]
(def nid (inc (:soak brush :counter)))
(:paint brush nid :counter)
(. nid))
(defn load
```
Loads instance with `id` from `brush`.
```
[brush id] (:soak-ident brush id))
(defn stamp
```
Constructs table with timestamp of `dt`
under `:timestamp` key.
```
[&opt dt]
(default dt (now))
(def t
(case (type dt)
:number dt
(:epoch dt)))
{:timestamp t})
(defn populate
```
Populates `data` with basic info.
```
[data]
(def dt (now))
(merge
{:created dt :state "active"}
data (stamp dt)))
(defn save
```
Saves `data` of type `what` on optional `path`.
```
[brush what & path]
(def w (populate what))
(unless (w :uuid)
(put w :uuid (next-id brush))
(when (and (= (last path) :tasks)
(not (w :work-intervals)))
(put w :work-intervals @[])
(:paint brush (w :uuid) :task/last)))
(:paint brush w
;(array/concat @[] path (w :uuid)))
(:dry brush)
(w :uuid))
(defmacro retrieve
```
Retrieves by `path` from `brush`.
```
[brush path]
~(:soak ,brush (guide ;,path)))
(defn tasks-by
```
Constructs the guide path for all tasks of the `project`.
```
[brush project]
(def project (load brush project))
[:clients (project :client)
:projects (project :uuid)
:tasks])
(def all-clients
```
Path to all clients.
```
[:clients values])
(def all-projects-table
```
Path to all projects in one table.
```
[;all-clients (>: :projects) merged])
(def all-projects
```
Path to all projects.
```
[;all-clients (>: :projects) flatvals])
(def all-tasks
```
Path to all tasks.
```
[;all-projects (>: :tasks) (>Y present?) flatvals])
(defn workeds
```
Constructs string with count and lenght of intervals in `wis`.
```
[wis]
(def ic (length wis))
(def ts (os/time))
(if (pos? ic)
(. ic "x "
(format-interval
(reduce
(fn [a w]
(+ a (- (get w :end ts)
(w :start)))) 0 wis)))))
(defn task-with-project-name
```
Construct new table from `task` with `projects-name`.
```
[project-name task]
(def wis (task :work-intervals))
(def ts (task :timestamp))
(merge task
{:label (. "#" (task :uuid) " " (task :name))
:intervals-count wis
:project-name project-name
:date-time (format-date-time ts)
:human-ts (human ts)
:worked (workeds wis)}))
(defn task-for-project
```
Construsts new table from `task` with computed
fields from its work intervals.
```
[task _]
(def wis (task :work-intervals))
(def ts (task :timestamp))
(merge task
{:label (. "#" (task :uuid) " " (task :name))
:intervals-count wis
:date-time (format-date-time ts)
:human-ts (human ts)
:worked (workeds wis)}))
(defn task-with-project-name-view
```
View for `task` with project name from `projects`.
```
[task [projects]]
(task-with-project-name (get-in projects [(task :project) :name]) task))
(defn all-tasks-with-project-name
```
Retrieves all tasks with project name set
```
[brush]
(retrieve brush [;all-clients (>: :projects)
(<- merged) flatvals
(>: :tasks) (>Y present?)
flatvals sort-by-timestamp
(<o> task-with-project-name-view)
<x]))
(defn tasks-with-filter
```
Retrieves all the tasks with given `filter` and optional `limt`.
```
[brush filtr &opt limt]
(default limt math/inf)
(retrieve brush [;all-clients (>: :projects)
(<- merged) flatvals
(>: :tasks) (>Y present?) flatvals
(>Y filtr) sort-by-timestamp (>n limt)
(<o> task-with-project-name-view)
<x]))
(defn last-ten-active-tasks
```
Retrieves last ten active tasks from `brush`.
```
[brush]
(tasks-with-filter brush (state= "active") 10))
(defn last-ran-task
```
Loads last ran task from `brush`.
```
[brush]
(load brush (:soak brush :task/last-ran)))
(defn clients-ts-sorted
```
Retrieves all clients sorted by `:timestamp`.
```
[brush]
(retrieve brush [;all-clients sort-by-timestamp]))
(defn projects-ts-sorted
```
Retrieves all projects sorted by `:timestamp`.
```
[brush]
(retrieve brush [;all-projects (>Y active?) sort-by-timestamp]))
(defn projects-ts-state-sorted
```
Retrieves all projects sorted by `:timestamp` and `:state`.
```
[brush]
(retrieve brush [;all-projects sort-by-state-timestamp]))
(defn project-with-client-view
```
Contructs new table from `project` with the `:name` containing
its client name.
```
[project [clients]]
(merge project
{:name (. "" (project :name)
" $" (get-in clients [(project :client) :abbrev]))}))
(defn projects-with-client
```
Retrieve all projects with their client.
```
[brush]
(retrieve
brush
[:clients (<-) values
(>: :projects) flatvals (>Y active?)
(<o> project-with-client-view) <x
sort-by-timestamp]))
(defn project-tasks-with-filter
```
Retrieves all tasks from `project` filtered by `filtr`.
```
[project filtr]
((=> :tasks values (>Y filtr)
(<o> task-for-project)
sort-by-timestamp) project))
(defn state-or-not-canceled
```
Contstructs function with `state` predicate
or not canceled state predicate.
```
[state]
(if state
(state= state)
(fn [s] (not ((state= "canceled") s)))))
(defn projects-or-all
```
Returns all tasks for `project` or all if it is not set
```
[brush project]
(if project [;(tasks-by brush project) flatten] all-tasks))
(defn worked-tasks
```
Returns all tasks that were worked on for the optional
`project` and `state`.
```
[brush project state & ts]
(retrieve
brush
[;(projects-or-all brush project)
(>Y (state-or-not-canceled state))
(>Y (timestamp-appraiser (ts 0)))
(>Y present?)
(>Y (??? {:work-intervals (>?? some (start-appraiser ts))}))]))
(defn list-worked
```
Retrieves list of all worked tasks for optional `projects` and `state`.
```
[brush project state & ts]
(retrieve
brush
[;(projects-or-all brush project)
(>Y (state-or-not-canceled state))
(>Y (timestamp-appraiser (ts 0)))
(>: :work-intervals) flatvals
(>Y (start-appraiser ts))]))
(defn running-task
```
Retrieves the running task.
```
[brush]
(-?>> (:soak brush :task/running)
(load brush)))
(defn active-tasks-match
```
Path to all active tasks that match `q`.
```
[q]
[;all-clients (>: :projects)
(<- merged) flatvals
(>: :tasks) (>Y present?) flatvals
(>Y active?) (>Y (name-has-match q)) (match-n-sort q)
(limit 20) (>: 0) (<o> task-with-project-name-view)
<x])
(defn active-projects-match
```
Path to all active projects that match `q`.
```
[q]
[;all-projects (>Y active?) (>Y (name-has-match q))
(match-n-sort q) (limit 20) (>: 0)])