(define-module (vcomponent group) #:use-module (vcomponent) #:use-module (vcomponent datetime) #:use-module (datetime) #:use-module (datetime util) #:use-module (srfi srfi-41) #:use-module (srfi srfi-41 util) #:export (group-stream get-groups-between)) ;; TODO templetize this (define-stream (group-stream in-stream) (define (ein? day) (lambda (e) (event-contains? e day))) (if (stream-null? in-stream) stream-null (let loop ((days (day-stream (as-date (attr (stream-car in-stream) 'DTSTART)))) (stream in-stream)) (let* ((day (stream-car days)) (tomorow (stream-car (stream-cdr days)))) (let ((head (stream-take-while (ein? day) stream)) (tail ;; This is a filter, instead of a stream-span together with head, ;; since events can span multiple days. ;; This starts with taking everything which end after the beginning ;; of tommorow, and finishes with the rest when it finds the first ;; object which begins tomorow (after midnight, exclusize). (filter-sorted-stream* ;; TODO Calculate Alternative DTEND better? (lambda (e) (date/-timestream (map (lambda (d) (cons d stream-null)) (date-range start-date end-date)))] [(car (stream-car good-part)) (lambda (d) (date< start-date d)) => (lambda (d) (stream-append (list->stream (map (lambda (d) (cons d stream-null)) (date-range start-date (date- d (date day: 1))))) good-part))] [else good-part])) (define-public (group->event-list group) (stream->list (cdr group)))