mhc 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/bin/mhc +66 -3
- data/emacs/Cask +1 -1
- data/emacs/mhc-date.el +1 -1
- data/emacs/mhc-day.el +1 -1
- data/emacs/mhc-db.el +57 -38
- data/emacs/mhc-draft.el +36 -22
- data/emacs/mhc-face.el +1 -1
- data/emacs/mhc-header.el +20 -1
- data/emacs/mhc-minibuf.el +12 -7
- data/emacs/mhc-parse.el +1 -1
- data/emacs/mhc-process.el +26 -9
- data/emacs/mhc-ps.el +1 -1
- data/emacs/mhc-schedule.el +5 -2
- data/emacs/mhc-summary.el +31 -12
- data/emacs/mhc-vars.el +15 -2
- data/emacs/mhc.el +50 -24
- data/lib/mhc.rb +3 -1
- data/lib/mhc/builder.rb +5 -1
- data/lib/mhc/calendar.rb +5 -1
- data/lib/mhc/command/cache.rb +5 -4
- data/lib/mhc/converter.rb +3 -2
- data/lib/mhc/datastore.rb +52 -13
- data/lib/mhc/date_enumerator.rb +2 -2
- data/lib/mhc/event.rb +42 -21
- data/lib/mhc/formatter.rb +17 -312
- data/lib/mhc/formatter/base.rb +125 -0
- data/lib/mhc/formatter/emacs.rb +47 -0
- data/lib/mhc/formatter/howm.rb +35 -0
- data/lib/mhc/formatter/icalendar.rb +17 -0
- data/lib/mhc/formatter/json.rb +27 -0
- data/lib/mhc/formatter/mail.rb +20 -0
- data/lib/mhc/formatter/org_table.rb +24 -0
- data/lib/mhc/formatter/symbolic_expression.rb +42 -0
- data/lib/mhc/formatter/text.rb +29 -0
- data/lib/mhc/occurrence.rb +27 -5
- data/lib/mhc/occurrence_enumerator.rb +1 -1
- data/lib/mhc/property_value.rb +6 -0
- data/lib/mhc/property_value/date.rb +23 -14
- data/lib/mhc/property_value/date_time.rb +19 -0
- data/lib/mhc/property_value/integer.rb +5 -1
- data/lib/mhc/property_value/list.rb +7 -6
- data/lib/mhc/property_value/period.rb +3 -1
- data/lib/mhc/property_value/range.rb +1 -1
- data/lib/mhc/property_value/time.rb +8 -1
- data/lib/mhc/version.rb +1 -1
- data/spec/mhc_spec.rb +83 -0
- metadata +13 -3
data/emacs/mhc-ps.el
CHANGED
data/emacs/mhc-schedule.el
CHANGED
@@ -142,7 +142,10 @@
|
|
142
142
|
|
143
143
|
|
144
144
|
(defun mhc-schedule-subject-as-string (schedule)
|
145
|
-
(
|
145
|
+
(let ((subject (mhc-schedule-subject schedule)))
|
146
|
+
(if (eq (length subject) 0)
|
147
|
+
"(no subject)"
|
148
|
+
subject)))
|
146
149
|
|
147
150
|
|
148
151
|
(defun mhc-schedule-categories-as-string (schedule)
|
@@ -199,4 +202,4 @@
|
|
199
202
|
;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
200
203
|
;; OF THE POSSIBILITY OF SUCH DAMAGE.
|
201
204
|
|
202
|
-
;;; mhc-schedule.el ends here
|
205
|
+
;;; mhc-schedule.el ends here
|
data/emacs/mhc-summary.el
CHANGED
@@ -171,6 +171,8 @@ which are replaced by the given information:
|
|
171
171
|
'face mhc-tmp-day-face)
|
172
172
|
(?/ (if mhc-tmp-first "/" " ")
|
173
173
|
'face mhc-tmp-day-face)
|
174
|
+
(?- (if mhc-tmp-first "-" " ")
|
175
|
+
'face mhc-tmp-day-face)
|
174
176
|
(?S " " 'face mhc-tmp-day-face)
|
175
177
|
(?M (mhc-summary/line-month-string)
|
176
178
|
'face mhc-tmp-day-face)
|
@@ -182,7 +184,8 @@ which are replaced by the given information:
|
|
182
184
|
(make-string 5 ? )
|
183
185
|
(format "%02d:%02d" (/ mhc-tmp-begin 60) (% mhc-tmp-begin 60)))
|
184
186
|
'face 'mhc-summary-face-time)
|
185
|
-
(?e (if (null mhc-tmp-end)
|
187
|
+
(?e (if (or (null mhc-tmp-end)
|
188
|
+
(and mhc-tmp-begin (= mhc-tmp-end mhc-tmp-begin)))
|
186
189
|
(make-string 6 ? )
|
187
190
|
(format "-%02d:%02d" (/ mhc-tmp-end 60) (% mhc-tmp-end 60)))
|
188
191
|
'face 'mhc-summary-face-time)
|
@@ -498,10 +501,10 @@ If BANNER is set, it is printed on the horizontal line."
|
|
498
501
|
|
499
502
|
|
500
503
|
(defun mhc-summary/line-subject-string ()
|
501
|
-
(if mhc-tmp-
|
502
|
-
(
|
503
|
-
|
504
|
-
|
504
|
+
(if mhc-tmp-schedule
|
505
|
+
(if mhc-tmp-private
|
506
|
+
mhc-summary-string-secret
|
507
|
+
(mhc-schedule-subject-as-string mhc-tmp-schedule))))
|
505
508
|
|
506
509
|
(defun mhc-summary/line-location-string ()
|
507
510
|
(let ((location (mhc-schedule-location mhc-tmp-schedule)))
|
@@ -661,20 +664,36 @@ If BANNER is set, it is printed on the horizontal line."
|
|
661
664
|
(defun mhc-summary-buffer-p (&optional buffer)
|
662
665
|
(if buffer
|
663
666
|
(set-buffer buffer))
|
664
|
-
mhc-summary-
|
667
|
+
(eq major-mode 'mhc-summary-mode))
|
665
668
|
|
666
|
-
(defun mhc-summary-current-date ()
|
669
|
+
(defun mhc-summary-current-date (&optional p)
|
667
670
|
(when (mhc-summary-buffer-p)
|
668
|
-
(let ((
|
671
|
+
(let* ((pos (or p (point)))
|
672
|
+
(dayinfo (get-text-property pos 'mhc-dayinfo)))
|
669
673
|
(or (and dayinfo (mhc-day-date dayinfo))
|
670
674
|
(save-excursion
|
671
675
|
(end-of-line)
|
672
|
-
(while (and (
|
676
|
+
(while (and (>= pos (point-min))
|
673
677
|
(null dayinfo))
|
674
|
-
(or (setq dayinfo (get-text-property
|
675
|
-
(
|
678
|
+
(or (setq dayinfo (get-text-property pos 'mhc-dayinfo))
|
679
|
+
(setq pos (- pos 1))))
|
676
680
|
(and dayinfo (mhc-day-date dayinfo)))))))
|
677
681
|
|
682
|
+
(defun mhc-summary-region-date ()
|
683
|
+
(when (region-active-p)
|
684
|
+
(let* ((p (region-beginning))
|
685
|
+
dayinfo
|
686
|
+
(datelist ()))
|
687
|
+
(progn
|
688
|
+
(while (<= p (region-end))
|
689
|
+
(and (setq dayinfo (mhc-summary-current-date p))
|
690
|
+
(setq datelist (cons dayinfo datelist)))
|
691
|
+
(setq p (next-single-property-change p 'mhc-dayinfo)))
|
692
|
+
(setq datelist (reverse (delete-dups datelist)))
|
693
|
+
(if (< 1 (length datelist))
|
694
|
+
(cons (car datelist) (car (last datelist)))
|
695
|
+
(car datelist))))))
|
696
|
+
|
678
697
|
(defvar mhc-summary-buffer-current-date-month nil
|
679
698
|
"Indicate summary buffer's month. It is also used by mhc-summary-buffer-p")
|
680
699
|
(make-variable-buffer-local 'mhc-summary-buffer-current-date-month)
|
@@ -782,4 +801,4 @@ If BANNER is set, it is printed on the horizontal line."
|
|
782
801
|
;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
783
802
|
;; OF THE POSSIBILITY OF SUCH DAMAGE.
|
784
803
|
|
785
|
-
;;; mhc-summary.el ends here
|
804
|
+
;;; mhc-summary.el ends here
|
data/emacs/mhc-vars.el
CHANGED
@@ -13,11 +13,12 @@
|
|
13
13
|
|
14
14
|
;;; Code:
|
15
15
|
(require 'mhc-compat)
|
16
|
-
|
16
|
+
|
17
|
+
(autoload 'mhc-process-send-command "mhc-process")
|
17
18
|
|
18
19
|
|
19
20
|
;;; Constants:
|
20
|
-
(defconst mhc-version "mhc 1.
|
21
|
+
(defconst mhc-version "mhc 1.2.0") ;; MHC_VERSION
|
21
22
|
|
22
23
|
|
23
24
|
;;; Configration Variables:
|
@@ -25,6 +26,18 @@
|
|
25
26
|
"Various sorts of MH Calender."
|
26
27
|
:group 'mail)
|
27
28
|
|
29
|
+
(defcustom mhc-program-name "mhc"
|
30
|
+
"Program name of MHC."
|
31
|
+
:group 'mhc
|
32
|
+
:type 'string)
|
33
|
+
|
34
|
+
(defcustom mhc-ruby-program-name (when (eq system-type 'windows-nt) "ruby")
|
35
|
+
"When non-nil, specify ruby program name.
|
36
|
+
Nil means MHC script is called directly."
|
37
|
+
:group 'mhc
|
38
|
+
:type '(choice (const :tag "Call script directly" nil)
|
39
|
+
string))
|
40
|
+
|
28
41
|
(defcustom mhc-start-day-of-week 0
|
29
42
|
"*Day of the week as the start of the week."
|
30
43
|
:group 'mhc
|
data/emacs/mhc.el
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
;; Description: Message Harmonized Calendaring system.
|
4
4
|
;; Author: Yoshinari Nomura <nom@quickhack.net>
|
5
5
|
;; Created: 1994-07-04
|
6
|
-
;; Version: 1.
|
6
|
+
;; Version: 1.2.0
|
7
7
|
;; Keywords: calendar
|
8
8
|
;; URL: http://www.quickhack.net/mhc
|
9
9
|
;; Package-Requires: ((calfw "20150703"))
|
@@ -190,8 +190,8 @@
|
|
190
190
|
Field names using by MHC.
|
191
191
|
|
192
192
|
X-SC-Category:
|
193
|
-
Space-seperated Keywords.
|
194
|
-
You can also indicate keywords by typing '\\[mhc-rescan-month]', '\\[mhc-goto-this-month]', '\\[mhc-goto-month]', '\\[mhc-goto-date]' with
|
193
|
+
Space-seperated Keywords. You can set default category to scan.
|
194
|
+
You can also indicate keywords by typing '\\[mhc-rescan-month]', '\\[mhc-goto-this-month]', '\\[mhc-goto-month]', '\\[mhc-goto-date]' with \\[universal-argument].
|
195
195
|
"
|
196
196
|
(interactive "P")
|
197
197
|
(make-local-variable 'mhc-mode)
|
@@ -371,10 +371,15 @@ If HIDE-PRIVATE, priavate schedules are suppressed."
|
|
371
371
|
(if mhc-default-hide-private-schedules
|
372
372
|
(not current-prefix-arg)
|
373
373
|
current-prefix-arg)))
|
374
|
-
(mhc-
|
375
|
-
|
376
|
-
|
377
|
-
|
374
|
+
(let ((name (if (and (mhc-summary-buffer-p)
|
375
|
+
(not (string-match
|
376
|
+
"^[0-9][0-9][0-9][0-9]-[0-9][0-9]$" (buffer-name))))
|
377
|
+
(buffer-name))))
|
378
|
+
(mhc-scan-month date
|
379
|
+
'mhc-mua
|
380
|
+
mhc-default-category-predicate-sexp
|
381
|
+
hide-private
|
382
|
+
name)))
|
378
383
|
|
379
384
|
(defvar mhc-goto-date-func 'mhc-goto-date-calendar)
|
380
385
|
; or mhc-goto-date-summary
|
@@ -524,21 +529,22 @@ SCOPE is one of:
|
|
524
529
|
((eq scope 'wide)
|
525
530
|
(mhc-date-ww-last (mhc-date++ edge-date) mhc-start-day-of-week)))))
|
526
531
|
|
527
|
-
(defun mhc-scan-month (date mailer category-predicate secret)
|
532
|
+
(defun mhc-scan-month (date mailer category-predicate secret &optional name)
|
528
533
|
"Make summary buffer for a month indicated by DATE.
|
529
534
|
DATE can be any date of the target month.
|
530
535
|
If MAILER is 'direct, insert scanned result into current buffer.
|
531
536
|
CATEGORY-PREDICATE must be a function that can take one mhc-schedule
|
532
537
|
argument and return a boolean value indicates opacity of the article.
|
533
538
|
If SECRET is non-nil, hide articles those categories are
|
534
|
-
listed in ``mhc-category-as-private''.
|
539
|
+
listed in ``mhc-category-as-private''.
|
540
|
+
If optional NAME is non-nil, created smmary buffer has the name."
|
535
541
|
(let* ((from (mhc-date-mm-first date))
|
536
542
|
(to (mhc-date-mm-last date))
|
537
543
|
(today (mhc-date-now))
|
538
544
|
;; need three months for mini-calendar
|
539
545
|
(dayinfo-list (mhc-db-scan (mhc-date-mm-- from) (mhc-date-mm++ to))))
|
540
546
|
(unless (eq 'direct mailer)
|
541
|
-
(mhc-summary-generate-buffer date)
|
547
|
+
(mhc-summary-generate-buffer (or name date))
|
542
548
|
(setq mhc-summary-buffer-current-date-month
|
543
549
|
(mhc-date-mm-first date)))
|
544
550
|
(when mhc-use-wide-scope
|
@@ -614,7 +620,7 @@ Returns t if the importation was succeeded."
|
|
614
620
|
(list (get-buffer (read-buffer "Import buffer: "
|
615
621
|
(current-buffer))))))
|
616
622
|
(let ((draft-buffer (generate-new-buffer mhc-draft-buffer-name))
|
617
|
-
(current-date (or (mhc-summary-current-date) (mhc-calendar-get-date) (mhc-date-now)))
|
623
|
+
(current-date (or (mhc-summary-region-date) (mhc-summary-current-date) (mhc-calendar-get-date) (mhc-date-now)))
|
618
624
|
(succeed t)
|
619
625
|
msgp date time subject location category recurrence-tag priority alarm)
|
620
626
|
(and (called-interactively-p 'interactive)
|
@@ -629,9 +635,9 @@ Returns t if the importation was succeeded."
|
|
629
635
|
(mhc-header-narrowing
|
630
636
|
(setq msgp (or (mhc-header-get-value "from")
|
631
637
|
(mhc-header-get-value "x-sc-subject")))
|
632
|
-
(mhc-header-
|
638
|
+
(mhc-header-distill-header
|
633
639
|
(concat "^\\("
|
634
|
-
(mhc-regexp-opt mhc-draft-
|
640
|
+
(mhc-regexp-opt mhc-draft-import-header-list)
|
635
641
|
"\\)")
|
636
642
|
'regexp))
|
637
643
|
(mhc-highlight-message)
|
@@ -808,15 +814,35 @@ the default action of this command is changed to the latter."
|
|
808
814
|
(mhc-window-pop)))
|
809
815
|
|
810
816
|
(defun mhc-import-from-region (beg end)
|
811
|
-
"
|
817
|
+
"Create new schedule draft from region BEG END."
|
812
818
|
(interactive "r")
|
813
|
-
(
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
819
|
+
(mhc-import-from-string (buffer-substring beg end)))
|
820
|
+
|
821
|
+
(defun mhc-import-from-clipboard ()
|
822
|
+
"Create new schedule draft from clipboard text."
|
823
|
+
(interactive)
|
824
|
+
(mhc-import-from-string (current-kill 0)))
|
825
|
+
|
826
|
+
(defun mhc-import-from-string (string)
|
827
|
+
"Create new schedule draft from STRING."
|
828
|
+
(with-temp-buffer
|
829
|
+
(yank 1)
|
830
|
+
(goto-char (point-min))
|
831
|
+
(insert "X-SC-Subject: \n"
|
832
|
+
"X-SC-Location: \n"
|
833
|
+
"X-SC-Day: \n"
|
834
|
+
"X-SC-Time: \n"
|
835
|
+
"X-SC-Category: \n"
|
836
|
+
"X-SC-Priority: \n"
|
837
|
+
"X-SC-Recurrence-Tag: \n"
|
838
|
+
"X-SC-Cond: \n"
|
839
|
+
"X-SC-Duration: \n"
|
840
|
+
"X-SC-Alarm: \n"
|
841
|
+
"X-SC-Record-Id: \n"
|
842
|
+
"X-SC-Sequence: 0\n"
|
843
|
+
"\n"
|
844
|
+
string)
|
845
|
+
(mhc-import)))
|
820
846
|
|
821
847
|
(defun mhc-delete ()
|
822
848
|
"Delete the current schedule."
|
@@ -871,11 +897,11 @@ the default action of this command is changed to the latter."
|
|
871
897
|
("x-sc-time" . ,time-list)
|
872
898
|
("x-sc-day" . ,date-list)))))
|
873
899
|
|
874
|
-
(defun mhc-reuse-copy ()
|
900
|
+
(defun mhc-reuse-copy (&optional filename)
|
875
901
|
"Copy current schedule to template."
|
876
902
|
(interactive)
|
877
|
-
(let ((file (mhc-summary-filename))
|
878
|
-
|
903
|
+
(let* ((file (or filename (mhc-summary-filename)))
|
904
|
+
(record (mhc-parse-file file)))
|
879
905
|
(if (and (stringp file) (file-exists-p file))
|
880
906
|
(with-temp-buffer
|
881
907
|
(mhc-insert-file-contents-as-coding-system
|
data/lib/mhc.rb
CHANGED
@@ -5,7 +5,7 @@ require "kconv"
|
|
5
5
|
## Monkey patch to the original RiCal https://github.com/rubyredrick/ri_cal
|
6
6
|
## delived from:
|
7
7
|
## git clone https://github.com/yoshinari-nomura/ri_cal.git
|
8
|
-
## git diff 369a4ee..
|
8
|
+
## git diff 369a4ee..cdb1f75
|
9
9
|
##
|
10
10
|
module RiCal
|
11
11
|
class Component #:nodoc:
|
@@ -47,6 +47,8 @@ module RiCal
|
|
47
47
|
result = {"VALUE" => "DATE"}.merge(params)
|
48
48
|
when DateTime
|
49
49
|
result = {"VALUE" => "DATE-TIME"}.merge(params)
|
50
|
+
when Period
|
51
|
+
result = {"VALUE" => "PERIOD"}.merge(params)
|
50
52
|
end
|
51
53
|
|
52
54
|
if has_local_timezone?
|
data/lib/mhc/builder.rb
CHANGED
@@ -11,6 +11,10 @@ module Mhc
|
|
11
11
|
@config = Mhc::Config.create_from_file(config) if config.is_a?(String)
|
12
12
|
end
|
13
13
|
|
14
|
+
def datastore
|
15
|
+
Mhc::DataStore.new(@config.general.repository)
|
16
|
+
end
|
17
|
+
|
14
18
|
def calendar(calendar_name)
|
15
19
|
calendar = @config.calendars[calendar_name]
|
16
20
|
raise Mhc::ConfigurationError, "calendar '#{calendar_name}' not found" unless calendar
|
@@ -23,7 +27,7 @@ module Mhc
|
|
23
27
|
when "lastnote"
|
24
28
|
db = Mhc::LastNote::Client.new(calendar.name)
|
25
29
|
when "mhc"
|
26
|
-
db = Mhc::Calendar.new(
|
30
|
+
db = Mhc::Calendar.new(self.datastore, calendar.modifiers, &calendar.filter)
|
27
31
|
end
|
28
32
|
return db
|
29
33
|
end
|
data/lib/mhc/calendar.rb
CHANGED
@@ -19,9 +19,13 @@ module Mhc
|
|
19
19
|
occurrences(date_range, &scope_block).map(&:event).uniq
|
20
20
|
end
|
21
21
|
|
22
|
+
def tasks(&scope_block)
|
23
|
+
@datastore.entries(category: "todo")
|
24
|
+
end
|
25
|
+
|
22
26
|
def occurrences(date_range, &scope_block)
|
23
27
|
ocs = []
|
24
|
-
@datastore.entries(date_range).each do |event|
|
28
|
+
@datastore.entries(range: date_range).each do |event|
|
25
29
|
event = decorate_event(event)
|
26
30
|
event.occurrences(range:date_range).each do |oc|
|
27
31
|
ocs << oc if in_scope?(oc, &scope_block)
|
data/lib/mhc/command/cache.rb
CHANGED
@@ -2,10 +2,11 @@ module Mhc
|
|
2
2
|
module Command
|
3
3
|
class Cache
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
def initialize(datastore)
|
6
|
+
epoch = Date.new(1970, 1, 1)
|
7
|
+
puts"UID,MTIME,MIN,MAX,CATEGORIES,RECURRENCE,SUBJECT"
|
8
|
+
datastore.each_cache_entry do |uid, ent|
|
9
|
+
puts"#{ent.uid},#{ent.mtime},#{epoch + ent.range.min},#{epoch + ent.range.max},#{(ent.categories||[]).join(' ')},#{ent.recurrence},#{ent.subject}"
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
data/lib/mhc/converter.rb
CHANGED
@@ -44,8 +44,9 @@ module Mhc
|
|
44
44
|
|
45
45
|
def to_emacs_string(str)
|
46
46
|
# 1. quote " and \
|
47
|
-
# 2.
|
48
|
-
|
47
|
+
# 2. LF => \n
|
48
|
+
# 3. surround by "
|
49
|
+
'"' + str.to_s.toutf8.gsub(/[\"\\]/, '\\\\\&').gsub("\n", "\\n") + '"'
|
49
50
|
end
|
50
51
|
|
51
52
|
def to_emacs_plist(hash)
|
data/lib/mhc/datastore.rb
CHANGED
@@ -11,9 +11,9 @@ module Mhc
|
|
11
11
|
@cache = Cache.new(File.expand_path("status/cache/events.pstore", @basedir))
|
12
12
|
end
|
13
13
|
|
14
|
-
def entries(
|
15
|
-
if
|
16
|
-
int_range =
|
14
|
+
def entries(range: nil, category: nil, recurrence: nil)
|
15
|
+
if range
|
16
|
+
int_range = range.min.absolute_from_epoch .. range.max.absolute_from_epoch
|
17
17
|
end
|
18
18
|
|
19
19
|
Enumerator.new do |yielder|
|
@@ -23,13 +23,18 @@ module Mhc
|
|
23
23
|
|
24
24
|
Dir.chdir(dir) do
|
25
25
|
Dir.foreach(".") do |ent|
|
26
|
-
parse_mhcc(ent).each {|ev|
|
26
|
+
parse_mhcc(ent).each {|ev|
|
27
|
+
next if category && !ev.in_category?(category)
|
28
|
+
next if recurrence && !ev.in_recurrence?(recurrence)
|
29
|
+
yielder << ev
|
30
|
+
} if /\.mhcc$/ =~ ent
|
27
31
|
next unless /\.mhc$/ =~ ent
|
28
32
|
uid = $`
|
29
33
|
cache_entry = @cache.lookup(uid, ent)
|
30
|
-
if !
|
31
|
-
|
32
|
-
|
34
|
+
next if range && !cache_entry.in_range?(int_range)
|
35
|
+
next if category && !cache_entry.in_category?(category)
|
36
|
+
next if recurrence && !cache_entry.in_recurrence?(recurrence)
|
37
|
+
yielder << Event.parse_file(File.expand_path(ent))
|
33
38
|
end
|
34
39
|
end
|
35
40
|
end
|
@@ -78,6 +83,13 @@ module Mhc
|
|
78
83
|
end
|
79
84
|
end
|
80
85
|
|
86
|
+
# dump cache entry for debug usage
|
87
|
+
def each_cache_entry
|
88
|
+
@cache.each do |uid, ent|
|
89
|
+
yield uid, ent
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
81
93
|
################################################################
|
82
94
|
private
|
83
95
|
|
@@ -105,11 +117,21 @@ module Mhc
|
|
105
117
|
class Cache
|
106
118
|
require 'pstore'
|
107
119
|
|
120
|
+
VERSION = "1"
|
121
|
+
|
108
122
|
def initialize(cache_filename)
|
109
123
|
@pstore = PStore.new(cache_filename)
|
110
124
|
load
|
111
125
|
end
|
112
126
|
|
127
|
+
# dump cache entry for debug usage
|
128
|
+
def each
|
129
|
+
load unless @db
|
130
|
+
@db.each do |uid, ent|
|
131
|
+
yield uid, ent
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
113
135
|
def lookup(uid, filename)
|
114
136
|
unless c = get(uid) and File.mtime(filename).to_i <= c.mtime
|
115
137
|
c = CacheEntry.new(filename)
|
@@ -122,6 +144,7 @@ module Mhc
|
|
122
144
|
return self unless @dirty
|
123
145
|
@pstore.transaction do
|
124
146
|
@pstore["root"] = @db
|
147
|
+
@pstore["version"] = VERSION
|
125
148
|
end
|
126
149
|
@dirty = false
|
127
150
|
end
|
@@ -139,7 +162,7 @@ module Mhc
|
|
139
162
|
|
140
163
|
def load
|
141
164
|
@pstore.transaction do
|
142
|
-
@db = @pstore["root"] || {}
|
165
|
+
@db = (@pstore["version"] == VERSION) && @pstore["root"] || {}
|
143
166
|
end
|
144
167
|
@dirty = false
|
145
168
|
end
|
@@ -147,18 +170,34 @@ module Mhc
|
|
147
170
|
end # class Cache
|
148
171
|
|
149
172
|
class CacheEntry
|
150
|
-
attr_reader :mtime, :range
|
173
|
+
attr_reader :mtime, :uid, :subject, :location, :categories, :recurrence, :mission, :range
|
151
174
|
|
152
175
|
def initialize(filename)
|
153
|
-
@mtime
|
154
|
-
|
155
|
-
|
176
|
+
@mtime = File.mtime(filename).to_i
|
177
|
+
|
178
|
+
event = Event.parse_file(filename)
|
179
|
+
@uid = event.uid.to_s
|
180
|
+
@subject = event.subject.to_s
|
181
|
+
@location = event.location.to_s
|
182
|
+
@categories = event.categories.map {|c| c.to_s.downcase}
|
183
|
+
@recurrence = event.recurrence_tag.to_s
|
184
|
+
@mission = event.mission_tag.to_s
|
185
|
+
@range = event.range.min.absolute_from_epoch ..
|
186
|
+
event.range.max.absolute_from_epoch
|
187
|
+
end
|
188
|
+
|
189
|
+
def in_category?(category)
|
190
|
+
@categories.member?(category.downcase)
|
156
191
|
end
|
157
192
|
|
158
|
-
def
|
193
|
+
def in_range?(range)
|
159
194
|
range.min <= @range.max && @range.min <= range.max
|
160
195
|
end
|
161
196
|
|
197
|
+
def in_recurrence?(recurrence)
|
198
|
+
@recurrence && @recurrence.downcase == recurrence.downcase
|
199
|
+
end
|
200
|
+
|
162
201
|
end # class CacheEntry
|
163
202
|
|
164
203
|
end # class DataStore
|