(define-module (vcomponent util instance methods) :use-module (hnh util) :use-module (hnh util uuid) :use-module (srfi srfi-1) :use-module (srfi srfi-41) :use-module (srfi srfi-41 util) :use-module (datetime) :use-module (vcomponent base) ;; :use-module (vcomponent parse) :use-module ((vcomponent util parse-cal-path) :select (parse-cal-path)) :use-module ((vcomponent recurrence) :select (generate-recurrence-set repeating?)) :use-module ((vcomponent datetime) :select (ev-time () ;; Files which calendars where loaded from (calendar-files init-keyword: calendar-files: init-value: '()) ;; calendar objects (calendars getter: get-calendars init-value: '()) ;; events, which should all be children of the calendars (events getter: get-events) ;; subset of events (repeating-events getter: get-repeating-events) ;; subset of events (fixed-events getter: get-fixed-events) ;; events again, but as stream with repeating events realised (event-set getter: get-event-set) ;; hash-table from event UID:s, to the events uid-map ) (define-method (get-event-by-uid (this ) uid) (hash-ref (slot-ref this 'uid-map) uid)) (define-method (fixed-events-in-range (this ) start end) (filter-sorted (lambda (ev) ((in-date-range? start end) (as-date (prop ev 'DTSTART)))) (slot-ref this 'fixed-events))) (define-method (initialize (this ) args) (next-method) (format (current-error-port) "Building from~%") (for calendar in (slot-ref this 'calendar-files) (format (current-error-port) " - ~a~%" calendar)) (slot-set! this 'calendars (load-calendars (slot-ref this 'calendar-files))) (let* ((groups (group-by type (concatenate (map children (slot-ref this 'calendars))))) (events (awhen (assoc-ref groups 'VEVENT) (car it))) (removed remaining (partition (extract 'X-HNH-REMOVED) events))) ;; TODO figure out what to do with removed events (slot-set! this 'events (append #|removed|# remaining))) (let* ((repeating regular (partition repeating? (slot-ref this 'events)))) (slot-set! this 'fixed-events (sort*! regular date/-timestream (slot-ref this 'fixed-events)) (map generate-recurrence-set (slot-ref this 'repeating-events))))) (slot-set! this 'uid-map (let ((ht (make-hash-table))) (for-each (lambda (event) (hash-set! ht (prop event 'UID) event)) (slot-ref this 'events)) ht))) ;;; TODO what should happen when an event with that UID already exists ;;; in the calendar? Fail? Overwrite? Currently it adds a second element ;;; with the same UID, which is BAD. (define-method (add-event (this ) calendar event) (add-child! calendar event) (unless (prop event 'UID) (set! (prop event 'UID) (uuid))) (slot-set! this 'events (cons event (slot-ref this 'events))) (let* ((slot-name (if (repeating? event) 'repeating-events 'fixed-events)) (events (slot-ref this slot-name))) (slot-set! this slot-name (insert-ordered event events ev-time) event) ;; cons #f so delq1! can delete the first element (delq1! event (cons #f (slot-ref this 'events))) (let ((slot-name (if (repeating? event) 'repeating-events 'fixed-events))) (delq1! event (cons #f (slot-ref this slot-name)))) (slot-set! this 'event-set (stream-remove (lambda (ev) (equal? (prop ev 'UID) (prop event 'UID))) (slot-ref this 'event-set))) (hash-set! (slot-ref this 'uid-map) (prop event 'UID) #f))