|
@@ -8,44 +8,34 @@
|
|
|
(:use :cl :parenscript #:timeliner.utils))
|
|
(:use :cl :parenscript #:timeliner.utils))
|
|
|
(in-package #:timeliner.web)
|
|
(in-package #:timeliner.web)
|
|
|
|
|
|
|
|
-(restas::register-pkgmodule-traits 'timeliner.web :render-method (lambda () (make-instance 'timeliner.web::renderer)))
|
|
|
|
|
|
|
+(restas::register-pkgmodule-traits 'timeliner.web
|
|
|
|
|
+ :render-method (lambda () (make-instance 'timeliner.web::renderer)))
|
|
|
|
|
|
|
|
;; Cron
|
|
;; Cron
|
|
|
-
|
|
|
|
|
(defvar *run-cron* t "Controls if starting a web should run cron tasks")
|
|
(defvar *run-cron* t "Controls if starting a web should run cron tasks")
|
|
|
-
|
|
|
|
|
-(defun import-events ()
|
|
|
|
|
- (timeliner.locations:import-location-events (local-time:timestamp- (today) 1 :day)))
|
|
|
|
|
-(defun import-finance ()
|
|
|
|
|
- (timeliner.financisto:import-financisto-events))
|
|
|
|
|
|
|
+(defvar *crons* '((#'timeliner.locations:on-cron (:minute 10 :hour 0))
|
|
|
|
|
+ (#'timeliner.financisto:on-cron (:minute 0 :hour 7)))
|
|
|
|
|
+ "List of cron functions with their schedules")
|
|
|
|
|
+(defvar *cron-timers* nil)
|
|
|
|
|
|
|
|
(defmethod restas:initialize-module-instance :before ((module (eql #.*package*)) context)
|
|
(defmethod restas:initialize-module-instance :before ((module (eql #.*package*)) context)
|
|
|
(restas:with-context context
|
|
(restas:with-context context
|
|
|
(cl-mongo:mongo :host "10.8.0.6")
|
|
(cl-mongo:mongo :host "10.8.0.6")
|
|
|
(cl-mongo:db.use "timeline")
|
|
(cl-mongo:db.use "timeline")
|
|
|
- (restas:context-add-variable context '*import-places-timer*)
|
|
|
|
|
- (restas:context-add-variable context '*import-finance-timer*)
|
|
|
|
|
- (restas:with-context context
|
|
|
|
|
- (when *run-cron*
|
|
|
|
|
- (setf *import-places-timer*
|
|
|
|
|
- (clon:schedule-function #'import-events
|
|
|
|
|
- (clon:make-scheduler (clon:make-typed-cron-schedule
|
|
|
|
|
- :minute 10 :hour 0))
|
|
|
|
|
- :name "import-places"
|
|
|
|
|
- :thread t))
|
|
|
|
|
- (setf *import-finance-timer*
|
|
|
|
|
- (clon:schedule-function #'import-finance
|
|
|
|
|
- (clon:make-scheduler (clon:make-typed-cron-schedule
|
|
|
|
|
- :minute 0 :hour 7))
|
|
|
|
|
- :name "import-finance"
|
|
|
|
|
- :thread t))))))
|
|
|
|
|
|
|
+ (when *run-cron*
|
|
|
|
|
+ (restas:context-add-variable
|
|
|
|
|
+ context '*cron-timers*
|
|
|
|
|
+ (loop for (function schedule) in *crons*
|
|
|
|
|
+ collect
|
|
|
|
|
+ (clon:schedule-function function
|
|
|
|
|
+ (clon:make-scheduler
|
|
|
|
|
+ (apply #'clon:make-typed-cron-schedule schedule)
|
|
|
|
|
+ :allow-now-p t)
|
|
|
|
|
+ :thread t))))))
|
|
|
|
|
|
|
|
(defmethod restas:finalize-module-instance :after ((module (eql #.*package*)) context)
|
|
(defmethod restas:finalize-module-instance :after ((module (eql #.*package*)) context)
|
|
|
- (restas:with-context context
|
|
|
|
|
- (when *import-places-timer*
|
|
|
|
|
- (trivial-timers::unschedule-timer *import-places-timer*))
|
|
|
|
|
- (when *import-finance-timer*
|
|
|
|
|
- (trivial-timers::unschedule-timer *import-finance-timer*))))
|
|
|
|
|
|
|
+ (let ((timers (restas:context-symbol-value context '*cron-timers*)))
|
|
|
|
|
+ (mapcar #'trivial-timers::unschedule-timer timers)))
|
|
|
|
|
|
|
|
;; Static file path
|
|
;; Static file path
|
|
|
(defparameter *resources*
|
|
(defparameter *resources*
|
|
@@ -89,6 +79,7 @@
|
|
|
(who:str (getf data :menu))
|
|
(who:str (getf data :menu))
|
|
|
(:div :class "container"
|
|
(:div :class "container"
|
|
|
(who:str (getf data :content)))
|
|
(who:str (getf data :content)))
|
|
|
|
|
+ (:div :id "modal" :class "modal fade" :tabindex "-1" :role "dialog" :aria-hidden "true")
|
|
|
(who:str (apply #'scripts (list* "jquery.min.js"
|
|
(who:str (apply #'scripts (list* "jquery.min.js"
|
|
|
"bootstrap.min.js"
|
|
"bootstrap.min.js"
|
|
|
(getf data :scripts))))
|
|
(getf data :scripts))))
|
|
@@ -279,6 +270,66 @@
|
|
|
(! *backbone *collection (extend (create
|
|
(! *backbone *collection (extend (create
|
|
|
:model (@ *timeliner *models *event)))))
|
|
:model (@ *timeliner *models *event)))))
|
|
|
;; * Views
|
|
;; * Views
|
|
|
|
|
+ ;; ** Dialog box
|
|
|
|
|
+ (setf (@ *timeliner *views *dialog)
|
|
|
|
|
+ (! *backbone *view
|
|
|
|
|
+ (extend
|
|
|
|
|
+ (create
|
|
|
|
|
+ class-name "modal-dialog modal-sm"
|
|
|
|
|
+ buttons (list
|
|
|
|
|
+ (create :text "Cancel" :class "btn-default" :event "cancel"
|
|
|
|
|
+ :attrs (create :data-dismiss "modal"))
|
|
|
|
|
+ (create :text "Ok" :class "btn-primary" :event "ok"))
|
|
|
|
|
+ initialize (lambda (opts)
|
|
|
|
|
+ (! _ (extend this (! _ (pick (or opts (create))
|
|
|
|
|
+ "title" "body" "buttons")))))
|
|
|
|
|
+ render-button (lambda (btn)
|
|
|
|
|
+ (var $btn ($ (who-ps-html
|
|
|
|
|
+ (:button :class "btn"
|
|
|
|
|
+ (@ btn text)))))
|
|
|
|
|
+ (var self this)
|
|
|
|
|
+ (when (@ btn class)
|
|
|
|
|
+ (! $btn (add-class (@ btn class))))
|
|
|
|
|
+ (when (@ btn attrs)
|
|
|
|
|
+ (! $btn (attr (@ btn attrs))))
|
|
|
|
|
+ (! $btn (on "click"
|
|
|
|
|
+ (lambda (e)
|
|
|
|
|
+ (when (@ btn event)
|
|
|
|
|
+ (! self (trigger
|
|
|
|
|
+ (concatenate
|
|
|
|
|
+ 'string "button:"
|
|
|
|
|
+ (@ btn event)))))
|
|
|
|
|
+ (! ($ "#modal") (modal "hide")))))
|
|
|
|
|
+ $btn)
|
|
|
|
|
+ render (lambda ()
|
|
|
|
|
+ (! this $el (html
|
|
|
|
|
+ (who-ps-html
|
|
|
|
|
+ (:div :class "modal-content"
|
|
|
|
|
+ (:div :class "modal-header"
|
|
|
|
|
+ (:h4 :class "modal-title" (@ this title)))
|
|
|
|
|
+ (:div :class "modal-body"
|
|
|
|
|
+ (@ this body))
|
|
|
|
|
+ (:div :class "modal-footer")))))
|
|
|
|
|
+ (var self this)
|
|
|
|
|
+ (! this $el (find ".modal-footer")
|
|
|
|
|
+ (append
|
|
|
|
|
+ (loop for b in (@ self buttons)
|
|
|
|
|
+ collect (! self (render-button b)))))
|
|
|
|
|
+ this)
|
|
|
|
|
+ show (lambda ()
|
|
|
|
|
+ (! ($ "#modal") (html (! this (render) el)) (modal))
|
|
|
|
|
+ this)))))
|
|
|
|
|
+ ;; ** DeleteEventDialog
|
|
|
|
|
+ (setf (@ *timeliner *views *delete-event)
|
|
|
|
|
+ (! *timeliner *views *dialog
|
|
|
|
|
+ (extend
|
|
|
|
|
+ (create
|
|
|
|
|
+ title "Delete event?"
|
|
|
|
|
+ body "Are you sure you want to delete event?"
|
|
|
|
|
+ buttons (list
|
|
|
|
|
+ (create :text "Cancel" :class "btn-default" :event "cancel"
|
|
|
|
|
+ :attrs (create :data-dismiss "modal"))
|
|
|
|
|
+ (create :text "Delete" :class "btn-danger" :event "delete"))))))
|
|
|
;; ** Event
|
|
;; ** Event
|
|
|
(setf (@ *timeliner *views *event)
|
|
(setf (@ *timeliner *views *event)
|
|
|
(! *backbone *view
|
|
(! *backbone *view
|
|
@@ -287,7 +338,8 @@
|
|
|
tag-name "a"
|
|
tag-name "a"
|
|
|
class-name "list-group-item"
|
|
class-name "list-group-item"
|
|
|
:events (create
|
|
:events (create
|
|
|
- "click" "select")
|
|
|
|
|
|
|
+ "click" "select"
|
|
|
|
|
+ "dblclick" "delete")
|
|
|
initialize (lambda ()
|
|
initialize (lambda ()
|
|
|
(! this (listen-to (@ this model) "change" (@ this render)))
|
|
(! this (listen-to (@ this model) "change" (@ this render)))
|
|
|
(! this (listen-to (@ this model) "destroy" (@ this remove))))
|
|
(! this (listen-to (@ this model) "destroy" (@ this remove))))
|
|
@@ -317,7 +369,14 @@
|
|
|
(siblings) (remove-class "active") (end)
|
|
(siblings) (remove-class "active") (end)
|
|
|
(add-class "active"))
|
|
(add-class "active"))
|
|
|
(! *timeliner dispatcher
|
|
(! *timeliner dispatcher
|
|
|
- (trigger "event:selected" (@ this model))))))))
|
|
|
|
|
|
|
+ (trigger "event:selected" (@ this model))))
|
|
|
|
|
+ delete (lambda (e)
|
|
|
|
|
+ (! this (listen-to-once
|
|
|
|
|
+ (! (new (@ *timeliner *views *delete-event))
|
|
|
|
|
+ (show))
|
|
|
|
|
+ "button:delete"
|
|
|
|
|
+ (lambda ()
|
|
|
|
|
+ (! this model (destroy))))))))))
|
|
|
;; ** Events
|
|
;; ** Events
|
|
|
(setf
|
|
(setf
|
|
|
(@ *timeliner *views *events)
|
|
(@ *timeliner *views *events)
|