mhc 1.0.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 +7 -0
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/COPYRIGHT +28 -0
- data/Gemfile +8 -0
- data/README.org +209 -0
- data/Rakefile +13 -0
- data/bin/mhc +312 -0
- data/emacs/Cask +25 -0
- data/emacs/Makefile +58 -0
- data/emacs/mhc-calendar.el +1723 -0
- data/emacs/mhc-calfw.el +135 -0
- data/emacs/mhc-compat.el +90 -0
- data/emacs/mhc-date.el +642 -0
- data/emacs/mhc-day.el +149 -0
- data/emacs/mhc-db.el +158 -0
- data/emacs/mhc-draft.el +211 -0
- data/emacs/mhc-e21.el +167 -0
- data/emacs/mhc-face.el +236 -0
- data/emacs/mhc-file.el +224 -0
- data/emacs/mhc-guess.el +648 -0
- data/emacs/mhc-header.el +176 -0
- data/emacs/mhc-logic.el +563 -0
- data/emacs/mhc-message.el +130 -0
- data/emacs/mhc-minibuf.el +466 -0
- data/emacs/mhc-misc.el +248 -0
- data/emacs/mhc-mua.el +260 -0
- data/emacs/mhc-parse.el +286 -0
- data/emacs/mhc-process.el +35 -0
- data/emacs/mhc-ps.el +1174 -0
- data/emacs/mhc-record.el +201 -0
- data/emacs/mhc-schedule.el +202 -0
- data/emacs/mhc-summary.el +763 -0
- data/emacs/mhc-sync.el +158 -0
- data/emacs/mhc-vars.el +149 -0
- data/emacs/mhc.el +1114 -0
- data/icons/Anniversary.xbm +6 -0
- data/icons/Anniversary.xpm +27 -0
- data/icons/Birthday.xbm +6 -0
- data/icons/Birthday.xpm +25 -0
- data/icons/Business.xbm +6 -0
- data/icons/Business.xpm +24 -0
- data/icons/CheckBox.xbm +6 -0
- data/icons/CheckBox.xpm +24 -0
- data/icons/CheckedBox.xbm +6 -0
- data/icons/CheckedBox.xpm +25 -0
- data/icons/Conflict.xbm +6 -0
- data/icons/Conflict.xpm +22 -0
- data/icons/Date.xbm +6 -0
- data/icons/Date.xpm +29 -0
- data/icons/Holiday.xbm +6 -0
- data/icons/Holiday.xpm +25 -0
- data/icons/Link.xbm +6 -0
- data/icons/Link.xpm +25 -0
- data/icons/Other.xbm +6 -0
- data/icons/Other.xpm +28 -0
- data/icons/Party.xbm +6 -0
- data/icons/Party.xpm +23 -0
- data/icons/Private.xbm +6 -0
- data/icons/Private.xpm +26 -0
- data/icons/Recurrence.xbm +6 -0
- data/icons/Recurrence.xpm +98 -0
- data/icons/Vacation.xbm +6 -0
- data/icons/Vacation.xpm +26 -0
- data/lib/mhc.rb +45 -0
- data/lib/mhc/builder.rb +64 -0
- data/lib/mhc/caldav.rb +304 -0
- data/lib/mhc/calendar.rb +106 -0
- data/lib/mhc/command.rb +13 -0
- data/lib/mhc/command/cache.rb +14 -0
- data/lib/mhc/command/completions.rb +108 -0
- data/lib/mhc/command/init.rb +133 -0
- data/lib/mhc/command/scan.rb +33 -0
- data/lib/mhc/command/sync.rb +22 -0
- data/lib/mhc/config.rb +229 -0
- data/lib/mhc/converter.rb +330 -0
- data/lib/mhc/datastore.rb +164 -0
- data/lib/mhc/date_enumerator.rb +274 -0
- data/lib/mhc/date_frame.rb +124 -0
- data/lib/mhc/date_helper.rb +49 -0
- data/lib/mhc/etag.rb +68 -0
- data/lib/mhc/event.rb +396 -0
- data/lib/mhc/formatter.rb +312 -0
- data/lib/mhc/logger.rb +94 -0
- data/lib/mhc/modifier.rb +149 -0
- data/lib/mhc/occurrence.rb +94 -0
- data/lib/mhc/occurrence_enumerator.rb +113 -0
- data/lib/mhc/property_value.rb +33 -0
- data/lib/mhc/property_value/date.rb +190 -0
- data/lib/mhc/property_value/integer.rb +15 -0
- data/lib/mhc/property_value/list.rb +41 -0
- data/lib/mhc/property_value/period.rb +49 -0
- data/lib/mhc/property_value/range.rb +100 -0
- data/lib/mhc/property_value/recurrence_condition.rb +272 -0
- data/lib/mhc/property_value/text.rb +11 -0
- data/lib/mhc/property_value/time.rb +45 -0
- data/lib/mhc/query.rb +210 -0
- data/lib/mhc/sync.rb +46 -0
- data/lib/mhc/sync/driver.rb +108 -0
- data/lib/mhc/sync/status.rb +70 -0
- data/lib/mhc/sync/status_manager.rb +142 -0
- data/lib/mhc/sync/strategy.rb +233 -0
- data/lib/mhc/sync/syncinfo.rb +98 -0
- data/lib/mhc/templates/config.yml.erb +142 -0
- data/lib/mhc/version.rb +4 -0
- data/lib/mhc/webdav.rb +319 -0
- data/mhc.gemspec +24 -0
- data/samples/DOT.mhc-config.yml +116 -0
- data/samples/japanese-holidays.mhcc +153 -0
- data/samples/mhc-completions.zsh +11 -0
- data/spec/mhc_spec.rb +682 -0
- data/spec/spec_helper.rb +9 -0
- data/xpm/close.xpm +18 -0
- data/xpm/delete.xpm +19 -0
- data/xpm/exit.xpm +18 -0
- data/xpm/month.xpm +18 -0
- data/xpm/next.xpm +18 -0
- data/xpm/next2.xpm +18 -0
- data/xpm/next_year.xpm +18 -0
- data/xpm/open.xpm +19 -0
- data/xpm/prev.xpm +18 -0
- data/xpm/prev2.xpm +18 -0
- data/xpm/prev_year.xpm +18 -0
- data/xpm/save.xpm +19 -0
- data/xpm/today.xpm +18 -0
- metadata +214 -0
data/mhc.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mhc/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "mhc"
|
8
|
+
spec.version = Mhc::VERSION
|
9
|
+
spec.authors = ["Yoshinari Nomura"]
|
10
|
+
spec.email = ["nom@quickhack.net"]
|
11
|
+
spec.summary = %q{Message Harmonized Calendaring}
|
12
|
+
spec.description = %q{Message Harmonized Calendaring.}
|
13
|
+
spec.homepage = "http://www.quickhack.net/mhc"
|
14
|
+
spec.license = "BSD"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
################################################################
|
2
|
+
# Setup config file ~/.mhc/config.yml
|
3
|
+
#
|
4
|
+
# Google Calendar URL for CalDAV is in the form of:
|
5
|
+
# https://www.google.com/calendar/dav/{calendar_id}/events
|
6
|
+
#
|
7
|
+
# calendar_id:
|
8
|
+
# for primary calendar is just your email address.
|
9
|
+
# for others will be in the form of:
|
10
|
+
# [long-string-of-characters]@group.calendar.google.com
|
11
|
+
#
|
12
|
+
# You can get them by clicking the down arrow next to your
|
13
|
+
# calendar at calendar.google.com and selecting 'Calendar Settings'.
|
14
|
+
# Be sure to use HTTPS in your URL, as an http address will not work.
|
15
|
+
#
|
16
|
+
# for more details about Google Calendar settings:
|
17
|
+
# http://www.google.com/support/calendar/bin/answer.py?answer=99358
|
18
|
+
# and click Sunbird section.
|
19
|
+
#
|
20
|
+
# Fill in the blanks indicated as *****,
|
21
|
+
# and invoke the command:
|
22
|
+
#
|
23
|
+
# % mhc sync personal
|
24
|
+
#
|
25
|
+
# Articles in past 90 days and future 90 days in MHC
|
26
|
+
# will be mirrored to target Google Calendar.
|
27
|
+
# (Hard-coded in lib/mhc/calendar.rb for now)
|
28
|
+
# Also other articles in Google Calendar will be DELETED.
|
29
|
+
#
|
30
|
+
# Before the first try, I recommend you to
|
31
|
+
# make a new calendar on your Google Calendar,
|
32
|
+
# and backup MHC folder ~/Mai/schedule.
|
33
|
+
#
|
34
|
+
# Currently, the type of STRATEGY in SYNC_CHANNELS allows only "mirror"
|
35
|
+
# from MHC to Google Calendar. We are planning to support the
|
36
|
+
# true two-way sync soon.
|
37
|
+
#
|
38
|
+
---
|
39
|
+
################################################################
|
40
|
+
GENERAL:
|
41
|
+
################################################################
|
42
|
+
TZID: "Asia/Tokyo"
|
43
|
+
REPOSITORY: ~/MHC
|
44
|
+
|
45
|
+
################################################################
|
46
|
+
SYNC_CHANNELS:
|
47
|
+
################################################################
|
48
|
+
|
49
|
+
- NAME: personal
|
50
|
+
CALENDAR1: personal
|
51
|
+
CALENDAR2: google_personal
|
52
|
+
STRATEGY: mirror
|
53
|
+
|
54
|
+
- NAME: family
|
55
|
+
CALENDAR1: family
|
56
|
+
CALENDAR2: google_family
|
57
|
+
STRATEGY: mirror
|
58
|
+
|
59
|
+
- NAME: business
|
60
|
+
CALENDAR1: business
|
61
|
+
CALENDAR2: google_business
|
62
|
+
STRATEGY: mirror
|
63
|
+
|
64
|
+
################################################################
|
65
|
+
CALENDARS:
|
66
|
+
################################################################
|
67
|
+
|
68
|
+
################################################################
|
69
|
+
## MHC local
|
70
|
+
|
71
|
+
# MHC: Master calendar (default)
|
72
|
+
- &mhc_default
|
73
|
+
NAME: master
|
74
|
+
TYPE: mhc
|
75
|
+
|
76
|
+
# MHC: Personal calendar mirroed to my Android
|
77
|
+
- <<: *mhc_default
|
78
|
+
NAME: personal
|
79
|
+
FILTER: '!category:[birthday japanese]'
|
80
|
+
|
81
|
+
# MHC: Published calendar to my colleagues
|
82
|
+
- <<: *mhc_default
|
83
|
+
NAME: business
|
84
|
+
FILTER: '!category:[private japanese] & category:[lecture seminar conference meeting work event party trip holiday reserved task]'
|
85
|
+
MODIFIERS:
|
86
|
+
- hide_description
|
87
|
+
- hide_location
|
88
|
+
- replace_subject_by_category
|
89
|
+
|
90
|
+
# MHC: Published calendar to my family
|
91
|
+
- <<: *mhc_default
|
92
|
+
NAME: family
|
93
|
+
FILTER: '!category:[birthday japanese] & category:[work event party trip holiday private]'
|
94
|
+
MODIFIERS:
|
95
|
+
- hide_description
|
96
|
+
|
97
|
+
################################################################
|
98
|
+
## Google Calendar
|
99
|
+
|
100
|
+
# Displayname: MHC
|
101
|
+
- &google_default
|
102
|
+
NAME: google_personal
|
103
|
+
TYPE: caldav
|
104
|
+
USER: *********@gmail.com
|
105
|
+
PASSWORD: ***************
|
106
|
+
URL: https://calendar.google.com/calendar/dav/**************************@group.calendar.google.com/events/
|
107
|
+
|
108
|
+
# Displayname: For Family
|
109
|
+
- <<: *google_default
|
110
|
+
NAME: google_family
|
111
|
+
URL: https://calendar.google.com/calendar/dav/**************************@group.calendar.google.com/events/
|
112
|
+
|
113
|
+
# Displayname: For Colleagues
|
114
|
+
- <<: *google_default
|
115
|
+
NAME: google_business
|
116
|
+
URL: https://calendar.google.com/calendar/dav/**************************@group.calendar.google.com/events/
|
@@ -0,0 +1,153 @@
|
|
1
|
+
##
|
2
|
+
## Japanese Holidays
|
3
|
+
##
|
4
|
+
## Place this as ~/Mail/schedule/presets/japanese-holidays.mhcc
|
5
|
+
##
|
6
|
+
|
7
|
+
X-SC-Subject: 元日
|
8
|
+
X-SC-Category: Holiday Japanese
|
9
|
+
X-SC-Cond: 1 Jan
|
10
|
+
X-SC-Record-Id: E2BAB555-3CEB-4508-96AD-1B59AA24ADC3
|
11
|
+
|
12
|
+
X-SC-Subject: 成人の日
|
13
|
+
X-SC-Category: Holiday Japanese
|
14
|
+
X-SC-Cond: 15 Jan
|
15
|
+
X-SC-Duration: -19990115
|
16
|
+
X-SC-Record-Id: EA9F4BA5-7D5A-4794-AFB3-6AB68FCA9719
|
17
|
+
|
18
|
+
X-SC-Subject: 成人の日
|
19
|
+
X-SC-Category: Holiday Japanese
|
20
|
+
X-SC-Cond: 2nd Mon Jan
|
21
|
+
X-SC-Duration: 20000110-
|
22
|
+
X-SC-Record-Id: 0BC2CBD0-D81E-4315-B9A8-E112C8E3DC1C
|
23
|
+
|
24
|
+
X-SC-Subject: 建国記念の日
|
25
|
+
X-SC-Category: Holiday Japanese
|
26
|
+
X-SC-Cond: 11 Feb
|
27
|
+
X-SC-Record-Id: AC1B378C-BAFE-4B6E-AF9C-78C2377E8AA4
|
28
|
+
|
29
|
+
X-SC-Subject: みどりの日
|
30
|
+
X-SC-Category: Holiday Japanese
|
31
|
+
X-SC-Cond: 29 Apr
|
32
|
+
X-SC-Duration: -20060429
|
33
|
+
X-SC-Record-Id: B78EAAEE-9963-4573-9EC7-0879F8940AEE
|
34
|
+
|
35
|
+
X-SC-Subject: 昭和の日
|
36
|
+
X-SC-Category: Holiday Japanese
|
37
|
+
X-SC-Cond: 29 Apr
|
38
|
+
X-SC-Duration: 20070429-
|
39
|
+
X-SC-Record-Id: A458E14C-960C-4F01-AF73-8ACB1B51A6A1
|
40
|
+
|
41
|
+
X-SC-Subject: 憲法記念日
|
42
|
+
X-SC-Category: Holiday Japanese
|
43
|
+
X-SC-Cond: 3 May
|
44
|
+
X-SC-Record-Id: BA89778E-E8CC-4588-B5C3-56F86483DEC1
|
45
|
+
|
46
|
+
X-SC-Subject: 国民の休日
|
47
|
+
X-SC-Category: Holiday Japanese
|
48
|
+
X-SC-Cond: 4 May
|
49
|
+
X-SC-Duration: -20060504
|
50
|
+
X-SC-Record-Id: 46953810-BD72-45DE-BC11-104CBE970CFF
|
51
|
+
|
52
|
+
X-SC-Subject: みどりの日
|
53
|
+
X-SC-Category: Holiday Japanese
|
54
|
+
X-SC-Cond: 4 May
|
55
|
+
X-SC-Duration: 20070504-
|
56
|
+
X-SC-Record-Id: 47938EDA-41A5-4E51-BDCB-2D3B60F49D71
|
57
|
+
|
58
|
+
X-SC-Subject: こどもの日
|
59
|
+
X-SC-Category: Holiday Japanese
|
60
|
+
X-SC-Cond: 5 May
|
61
|
+
X-SC-Record-Id: 4AE5568A-2DFE-4B6B-92E5-C4BFADFB2CCF
|
62
|
+
|
63
|
+
X-SC-Subject: 海の日
|
64
|
+
X-SC-Category: Holiday Japanese
|
65
|
+
X-SC-Cond: 20 Jul
|
66
|
+
X-SC-Duration: -20020720
|
67
|
+
X-SC-Record-Id: 5E03776A-4280-4337-85C0-F1322A3AAE6E
|
68
|
+
|
69
|
+
X-SC-Subject: 海の日
|
70
|
+
X-SC-Category: Holiday Japanese
|
71
|
+
X-SC-Cond: 3rd Mon Jul
|
72
|
+
X-SC-Duration: 20030701-
|
73
|
+
X-SC-Record-Id: BD4156C2-5546-4146-8297-09CF4210A346
|
74
|
+
|
75
|
+
X-SC-Subject: 敬老の日
|
76
|
+
X-SC-Category: Holiday Japanese
|
77
|
+
X-SC-Cond: 15 Sep
|
78
|
+
X-SC-Duration: -20020915
|
79
|
+
X-SC-Record-Id: 29BC6E4E-0D70-4EF8-8AF0-7000254D3CDB
|
80
|
+
|
81
|
+
X-SC-Subject: 敬老の日
|
82
|
+
X-SC-Category: Holiday Japanese
|
83
|
+
X-SC-Cond: 3rd Mon Sep
|
84
|
+
X-SC-Duration: 20030901-
|
85
|
+
X-SC-Record-Id: F303C1C9-01B0-437C-A2E2-BCD1ADD901F2
|
86
|
+
|
87
|
+
X-SC-Subject: 体育の日
|
88
|
+
X-SC-Category: Holiday Japanese
|
89
|
+
X-SC-Cond: 10 Oct
|
90
|
+
X-SC-Duration: -19991010
|
91
|
+
X-SC-Record-Id: AFABC42C-2E9D-4093-A4AF-DA12D4D4B9D7
|
92
|
+
|
93
|
+
X-SC-Subject: 体育の日
|
94
|
+
X-SC-Category: Holiday Japanese
|
95
|
+
X-SC-Cond: 2nd Mon Oct
|
96
|
+
X-SC-Duration: 20001009-
|
97
|
+
X-SC-Record-Id: C17D9CA5-28AF-4826-AD33-8B75473E5B52
|
98
|
+
|
99
|
+
X-SC-Subject: 文化の日
|
100
|
+
X-SC-Category: Holiday Japanese
|
101
|
+
X-SC-Cond: 3 Nov
|
102
|
+
X-SC-Record-Id: A76779D2-BB44-4ED5-ACF9-B646E10C7313
|
103
|
+
|
104
|
+
X-SC-Subject: 勤労感謝の日
|
105
|
+
X-SC-Category: Holiday Japanese
|
106
|
+
X-SC-Cond: 23 Nov
|
107
|
+
X-SC-Record-Id: 97E6F125-2625-44A9-8D43-A6FCA9670D8D
|
108
|
+
|
109
|
+
X-SC-Subject: 天皇誕生日
|
110
|
+
X-SC-Category: Holiday Japanese
|
111
|
+
X-SC-Cond: 23 Dec
|
112
|
+
X-SC-Record-Id: 51D42B0D-EF46-4D65-B62A-6ED2F0D1F0B5
|
113
|
+
|
114
|
+
## 毎年変わる祝日と振替休日
|
115
|
+
|
116
|
+
X-SC-Subject: 春分の日
|
117
|
+
X-SC-Day: 19960320 19970320 19980321 19990321 20000320 20010320 20020321
|
118
|
+
20030321 20040320 20050320 20060321 20070321 20080320 20090320
|
119
|
+
20100321 20110321 20120320 20130320 20140321 20150321 20160320
|
120
|
+
20170320 20180321 20190321 20200320 20210320 20220321 20230321
|
121
|
+
20240320 20250320 20260320 20270321 20280320 20290320 20300320
|
122
|
+
20310321
|
123
|
+
X-SC-Category: Holiday Japanese
|
124
|
+
X-SC-Record-Id: 37616252-E6E5-4C69-9965-3F7B0236A0D8
|
125
|
+
|
126
|
+
X-SC-Subject: 秋分の日
|
127
|
+
X-SC-Day: 19960923 19970923 19980923 19990923 20000923 20010923 20020923
|
128
|
+
20030923 20040923 20050923 20060923 20070923 20080923 20090923
|
129
|
+
20100923 20110923 20120922 20130923 20140923 20150923 20160922
|
130
|
+
20170923 20180923 20190923 20200922 20210923 20220923 20230923
|
131
|
+
20240922 20250923 20260923 20270923 20280922 20290923 20300923
|
132
|
+
20310923
|
133
|
+
X-SC-Category: Holiday Japanese
|
134
|
+
X-SC-Record-Id: 54A339AD-F7FD-4E56-9B70-2D09F840E94D
|
135
|
+
|
136
|
+
X-SC-Subject: 振替休日
|
137
|
+
X-SC-Day: 19900212 19900430 19900924 19901224 19910506 19910916 19911104
|
138
|
+
19931011 19950102 19950116 19960212 19960506 19960916 19961104
|
139
|
+
19970721 19971124 19990322 19991011 20010212 20010430 20010924
|
140
|
+
20011224 20020506 20020916 20021104 20031124 20050321 20060102
|
141
|
+
20070212 20070430 20070924 20071224 20080506 20080721 20081124
|
142
|
+
20090506 20090922 20100322 20120102 20120430 20121224 20130506
|
143
|
+
20131104 20140506 20141124 20150506 20160321 20170102 20180212
|
144
|
+
20180430 20180924 20181224 20190506 20191104 20200506 20230102
|
145
|
+
20240212 20240506 20240923 20241104 20250506 20251124 20260506
|
146
|
+
20270322 20290212 20290430 20290924 20291224 20300506 20301104
|
147
|
+
20310506 20311124
|
148
|
+
X-SC-Category: Holiday Japanese
|
149
|
+
X-SC-Record-Id: E2D696DF-EB49-44D7-B06C-812B10BD99A2
|
150
|
+
|
151
|
+
## Make sure you have at least one blank line for each entry (改行で終わる)
|
152
|
+
|
153
|
+
## EOF
|
data/spec/mhc_spec.rb
ADDED
@@ -0,0 +1,682 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
### Rspec file for MHC
|
4
|
+
|
5
|
+
describe Mhc do
|
6
|
+
it 'should have a version number' do
|
7
|
+
expect(Mhc::VERSION).not_to be_nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Mhc::PropertyValue::Date do
|
12
|
+
it "should parse 'today'" do
|
13
|
+
expect(Mhc::PropertyValue::Date.parse_relative("today")).to eq(Date.today)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Mhc::Converter::Emacs do
|
18
|
+
it "should convert a Ruby Hash to Emacs plist" do
|
19
|
+
hash = {
|
20
|
+
:title => "\\a\"",
|
21
|
+
:start_date => "b\"b",
|
22
|
+
:start_time => "c",
|
23
|
+
:end_date => "d",
|
24
|
+
:end_time => "e",
|
25
|
+
:description => "f",
|
26
|
+
:location => "g",
|
27
|
+
:source => "h"
|
28
|
+
}
|
29
|
+
expect(Mhc::Converter::Emacs.new.to_emacs(hash)).to eq '(:title "\\\\a\\"" :start-date "b\\"b" :start-time "c" :end-date "d" :end-time "e" :description "f" :location "g" :source "h")'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe Mhc::Event do
|
34
|
+
before :all do
|
35
|
+
ENV["MHC_TZID"] = 'UTC'
|
36
|
+
Mhc.default_tzid = ENV["MHC_TZID"]
|
37
|
+
end
|
38
|
+
|
39
|
+
before :each do
|
40
|
+
time_now = ::Time.utc(2014, 1, 1)
|
41
|
+
allow(::Time).to receive(:now).and_return(time_now)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should parse a string and dump to the same string" do
|
45
|
+
str = <<-EOF.strip_heredoc
|
46
|
+
X-SC-Subject: Weekly Event on Monday and Thursday
|
47
|
+
X-SC-Location: Office
|
48
|
+
X-SC-Day: !20140410
|
49
|
+
X-SC-Time: 12:40-14:10
|
50
|
+
X-SC-Category: Work
|
51
|
+
X-SC-Mission-Tag: TEST-Mission
|
52
|
+
X-SC-Recurrence-Tag: TEST
|
53
|
+
X-SC-Cond: Mon Thu
|
54
|
+
X-SC-Duration: 20140401-20140430
|
55
|
+
X-SC-Alarm: 5 minutes
|
56
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
57
|
+
X-SC-Sequence: 0
|
58
|
+
|
59
|
+
this is description
|
60
|
+
EOF
|
61
|
+
ev = Mhc::Event.parse(str)
|
62
|
+
expect(ev.dump).to eq str
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should parse a string and dump to the same string even if all values are empty" do
|
66
|
+
str = <<-EOF.strip_heredoc
|
67
|
+
X-SC-Subject:
|
68
|
+
X-SC-Location:
|
69
|
+
X-SC-Day:
|
70
|
+
X-SC-Time:
|
71
|
+
X-SC-Category:
|
72
|
+
X-SC-Mission-Tag:
|
73
|
+
X-SC-Recurrence-Tag:
|
74
|
+
X-SC-Cond:
|
75
|
+
X-SC-Duration:
|
76
|
+
X-SC-Alarm:
|
77
|
+
X-SC-Record-Id:
|
78
|
+
X-SC-Sequence: 0
|
79
|
+
|
80
|
+
EOF
|
81
|
+
ev = Mhc::Event.parse(str)
|
82
|
+
expect(ev.dump).to eq str
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should parse a string and dump to the same string even if some fields has hanging strings" do
|
86
|
+
str = <<-EOF.strip_heredoc
|
87
|
+
X-SC-Subject: Autumnal Equinox Day
|
88
|
+
X-SC-Location:
|
89
|
+
X-SC-Day: 19960923 19970923 19980923 19990923 20000923 20010923 20020923
|
90
|
+
20030923 20040923 20050923 20060923 20070923 20080923 20090923
|
91
|
+
20100923 20110923 20120922 20130923 20140923 20150923 20160922
|
92
|
+
20170923 20180923 20190923 20200922 20210923 20220923 20230923
|
93
|
+
20240922 20250923 20260923 20270923 20280922 20290923 20300923
|
94
|
+
20310923
|
95
|
+
X-SC-Time:
|
96
|
+
X-SC-Category: Holiday
|
97
|
+
Japanese
|
98
|
+
X-SC-Mission-Tag:
|
99
|
+
X-SC-Recurrence-Tag:
|
100
|
+
X-SC-Cond:
|
101
|
+
X-SC-Duration:
|
102
|
+
X-SC-Alarm:
|
103
|
+
X-SC-Record-Id: 54A339AD-F7FD-4E56-9B70-2D09F840E94D
|
104
|
+
X-SC-Sequence: 0
|
105
|
+
|
106
|
+
EOF
|
107
|
+
|
108
|
+
dump_str = <<-EOF.strip_heredoc
|
109
|
+
X-SC-Subject: Autumnal Equinox Day
|
110
|
+
X-SC-Location:
|
111
|
+
X-SC-Day: 19960923 19970923 19980923 19990923 20000923 20010923 20020923 20030923 20040923 20050923 20060923 20070923 20080923 20090923 20100923 20110923 20120922 20130923 20140923 20150923 20160922 20170923 20180923 20190923 20200922 20210923 20220923 20230923 20240922 20250923 20260923 20270923 20280922 20290923 20300923 20310923
|
112
|
+
X-SC-Time:
|
113
|
+
X-SC-Category: Holiday Japanese
|
114
|
+
X-SC-Mission-Tag:
|
115
|
+
X-SC-Recurrence-Tag:
|
116
|
+
X-SC-Cond:
|
117
|
+
X-SC-Duration:
|
118
|
+
X-SC-Alarm:
|
119
|
+
X-SC-Record-Id: 54A339AD-F7FD-4E56-9B70-2D09F840E94D
|
120
|
+
X-SC-Sequence: 0
|
121
|
+
|
122
|
+
EOF
|
123
|
+
ev = Mhc::Event.parse(str)
|
124
|
+
expect(ev.dump).to eq dump_str
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
it "should occur weekly on Monday and Thursday from 2014-04-01 to 2014-04-30 with exception of 2014-04-10 (Thu)" do
|
130
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
131
|
+
X-SC-Subject: Weekly Event on Monday and Thursday
|
132
|
+
X-SC-Location: Office
|
133
|
+
X-SC-Day: !20140410
|
134
|
+
X-SC-Time: 12:40-14:10
|
135
|
+
X-SC-Category: Work
|
136
|
+
X-SC-Cond: Mon Thu
|
137
|
+
X-SC-Duration: 20140401-20140430
|
138
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
139
|
+
EOF
|
140
|
+
from = Mhc::PropertyValue::Date.new(2014,04,7)
|
141
|
+
to = Mhc::PropertyValue::Date.new(2014,04,24)
|
142
|
+
# range.first is effective in narrowing the scan region so we will not have "2014-04-03"
|
143
|
+
expect(ev.occurrences(range:from..to).take(30).map{|occurrence| occurrence.date.to_s}).to eq \
|
144
|
+
["20140407", "20140414", "20140417", "20140421", "20140424"]
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should occur yearly on March 21" do
|
148
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
149
|
+
X-SC-Subject: Yearly Event on 21 March
|
150
|
+
X-SC-Location: Office
|
151
|
+
X-SC-Day:
|
152
|
+
X-SC-Time: 12:40-14:10
|
153
|
+
X-SC-Category: Work
|
154
|
+
X-SC-Cond: Mar 21
|
155
|
+
X-SC-Duration: 20140401-20200401
|
156
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
157
|
+
EOF
|
158
|
+
expect(ev.occurrences.take(30).map{|o| o.date.to_s}).to eq \
|
159
|
+
["20150321", "20160321", "20170321", "20180321", "20190321", "20200321"]
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should show single day in X-SC-Day:" do
|
163
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
164
|
+
X-SC-Subject: Party
|
165
|
+
X-SC-Day: 20140509
|
166
|
+
X-SC-Time: 18:00-22:00
|
167
|
+
X-SC-Record-Id: 1653B99D-DED2-4758-934F-B868BFCA9E9F
|
168
|
+
EOF
|
169
|
+
expect(ev.occurrences.take(30).map{|o| o.date.to_s}).to eq \
|
170
|
+
["20140509"]
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should show three enumerated days listed in X-SC-Day:" do
|
174
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
175
|
+
X-SC-Subject: Three enumerated events in X-SC-Day:
|
176
|
+
X-SC-Day: 20140203 20140509 20140831 20140901-20140902
|
177
|
+
X-SC-Duration: 20140101-20141231
|
178
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
179
|
+
EOF
|
180
|
+
expect(ev.occurrences.take(30).map{|o| o.to_s}).to eq \
|
181
|
+
["20140203", "20140509", "20140831", "20140901-20140902"]
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should show three day's event even if scan range is started from the middle of event" do
|
185
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
186
|
+
X-SC-Subject: Three day's event
|
187
|
+
X-SC-Day: 20140514-20140516
|
188
|
+
EOF
|
189
|
+
from = Mhc::PropertyValue::Date.new(2014, 5, 15)
|
190
|
+
to = Mhc::PropertyValue::Date.new(2014, 5, 16)
|
191
|
+
expect(ev.occurrences(range:from..to).take(30).map{|o| o.to_s}).to eq \
|
192
|
+
["20140514-20140516"]
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should produce a list of occurrences, and each occurrence has different date" do
|
196
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
197
|
+
X-SC-Subject: TEST
|
198
|
+
X-SC-Time: 10:00-12:00
|
199
|
+
X-SC-Day: 20140203 20140509 20140831
|
200
|
+
X-SC-Duration: 20140101-20141231
|
201
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
202
|
+
EOF
|
203
|
+
expect(ev.occurrences.take(30).map{|o| "#{o.date} #{o.time_range} #{o.subject}"}).to eq \
|
204
|
+
["20140203 10:00-12:00 TEST", "20140509 10:00-12:00 TEST", "20140831 10:00-12:00 TEST"]
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should return true when #allday? is called if X-SC-Time: is blank" do
|
208
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
209
|
+
X-SC-Subject: TEST
|
210
|
+
X-SC-Time:
|
211
|
+
X-SC-Day: 20140203 20140509 20140831
|
212
|
+
X-SC-Duration: 20140101-20141231
|
213
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
214
|
+
EOF
|
215
|
+
expect(ev.occurrences.take(30).all? {|o| o.allday? }).to eq true
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should return false when #allday? is called if X-SC-Time: is not blank" do
|
219
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
220
|
+
X-SC-Subject: TEST
|
221
|
+
X-SC-Time: 10:00-12:00
|
222
|
+
X-SC-Day: 20140203 20140509 20140831
|
223
|
+
X-SC-Duration: 20140101-20141231
|
224
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
225
|
+
EOF
|
226
|
+
expect(ev.occurrences.take(30).all? {|o| not o.allday? }).to eq true
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should return almost infinit number of entries: 1970-1-1 to 50 years future, if X-SC-Duration: is empty" do
|
230
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
231
|
+
X-SC-Subject: New Year Day
|
232
|
+
X-SC-Cond: 1 Jan
|
233
|
+
X-SC-Duration:
|
234
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
235
|
+
EOF
|
236
|
+
times = Date.today.year + 50 - Date.new(1970, 1, 1).year + 1
|
237
|
+
expect(ev.occurrences.map{|o| o.date.to_s}.length).to eq times
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should return ``yearly by monthday'' icalendar rrule string" do
|
241
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
242
|
+
X-SC-Subject: New Year Day
|
243
|
+
X-SC-Cond: 1 Jan
|
244
|
+
X-SC-Duration:
|
245
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
246
|
+
EOF
|
247
|
+
expect(ev.recurrence_condition.to_ics).to eq "FREQ=YEARLY;INTERVAL=1;WKST=MO;BYMONTH=1;BYMONTHDAY=1"
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should return ``yearly by day'' icalendar rrule string" do
|
251
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
252
|
+
X-SC-Subject: Mother's Day
|
253
|
+
X-SC-Cond: 2nd Sun May
|
254
|
+
X-SC-Duration:
|
255
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
256
|
+
EOF
|
257
|
+
expect(ev.recurrence_condition.to_ics).to eq "FREQ=YEARLY;INTERVAL=1;WKST=MO;BYMONTH=5;BYDAY=2SU"
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should return ``weekly'' icalendar rrule string" do
|
261
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
262
|
+
X-SC-Subject: Wednesday and Sunday Weekly event
|
263
|
+
X-SC-Cond: Wed Sun
|
264
|
+
X-SC-Duration: 20140401-20140424
|
265
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
266
|
+
EOF
|
267
|
+
expect(ev.recurrence_condition.to_ics(nil, ev.duration.last)).to eq "FREQ=WEEKLY;INTERVAL=1;WKST=MO;BYDAY=WE,SU;UNTIL=20140424"
|
268
|
+
end
|
269
|
+
|
270
|
+
it "should return icalendar VEVENT string with RRULE field" do
|
271
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
272
|
+
X-SC-Subject: Wednesday and Sunday Weekly event
|
273
|
+
X-SC-Cond: Wed Sun
|
274
|
+
X-SC-Category: Work
|
275
|
+
X-SC-Location: Office
|
276
|
+
X-SC-Duration: 20140401-20140424
|
277
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
278
|
+
|
279
|
+
this is description
|
280
|
+
EOF
|
281
|
+
expect(ev.to_ics).to eq <<-'EOF'.strip_heredoc
|
282
|
+
BEGIN:VEVENT
|
283
|
+
CREATED;VALUE=DATE-TIME:20140101T000000Z
|
284
|
+
DTEND;VALUE=DATE:20140403
|
285
|
+
DTSTART;VALUE=DATE:20140402
|
286
|
+
DTSTAMP;VALUE=DATE-TIME:20140101T000000Z
|
287
|
+
CATEGORIES:Work
|
288
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140101T000000Z
|
289
|
+
UID:FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
290
|
+
DESCRIPTION:this is description\n
|
291
|
+
SUMMARY:Wednesday and Sunday Weekly event
|
292
|
+
RRULE:FREQ=WEEKLY;INTERVAL=1;WKST=MO;BYDAY=WE,SU;UNTIL=20140424
|
293
|
+
LOCATION:Office
|
294
|
+
SEQUENCE:0
|
295
|
+
END:VEVENT
|
296
|
+
EOF
|
297
|
+
end
|
298
|
+
|
299
|
+
it "should return icalendar VEVENT string taking DTSTART from the first entry of X-SC-Day: and RDATE from remains" do
|
300
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
301
|
+
X-SC-Subject: thee events on 20140203 20140509 20140831
|
302
|
+
X-SC-Day: 20140203 20140509 20140831
|
303
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
304
|
+
|
305
|
+
this is description
|
306
|
+
EOF
|
307
|
+
expect(ev.to_ics).to eq <<-'EOF'.strip_heredoc
|
308
|
+
BEGIN:VEVENT
|
309
|
+
RDATE;VALUE=DATE:20140509,20140831
|
310
|
+
CREATED;VALUE=DATE-TIME:20140101T000000Z
|
311
|
+
DTEND;VALUE=DATE:20140204
|
312
|
+
DTSTART;VALUE=DATE:20140203
|
313
|
+
DTSTAMP;VALUE=DATE-TIME:20140101T000000Z
|
314
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140101T000000Z
|
315
|
+
UID:FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
316
|
+
DESCRIPTION:this is description\n
|
317
|
+
SUMMARY:thee events on 20140203 20140509 20140831
|
318
|
+
SEQUENCE:0
|
319
|
+
END:VEVENT
|
320
|
+
EOF
|
321
|
+
end
|
322
|
+
|
323
|
+
it "should return icalendar VEVENT string taking EXDATE from the entries of X-SC-Day: !YYYYMMDD" do
|
324
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
325
|
+
X-SC-Subject: Wednesdays in 2014-04 (2, 9, 16, ..., 30) with exceptions of 2, 16
|
326
|
+
X-SC-Cond: Wed
|
327
|
+
X-SC-Duration: 20140401-20140430
|
328
|
+
X-SC-Day: !20140402 !20140416
|
329
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
330
|
+
|
331
|
+
this is description
|
332
|
+
EOF
|
333
|
+
expect(ev.to_ics).to eq <<-'EOF'.strip_heredoc
|
334
|
+
BEGIN:VEVENT
|
335
|
+
EXDATE;VALUE=DATE:20140402,20140416
|
336
|
+
CREATED;VALUE=DATE-TIME:20140101T000000Z
|
337
|
+
DTEND;VALUE=DATE:20140403
|
338
|
+
DTSTART;VALUE=DATE:20140402
|
339
|
+
DTSTAMP;VALUE=DATE-TIME:20140101T000000Z
|
340
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140101T000000Z
|
341
|
+
UID:FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
342
|
+
DESCRIPTION:this is description\n
|
343
|
+
SUMMARY:Wednesdays in 2014-04 (2\, 9\, 16\, ...\, 30) with exceptions of 2\, 16
|
344
|
+
RRULE:FREQ=WEEKLY;INTERVAL=1;WKST=MO;BYDAY=WE;UNTIL=20140430
|
345
|
+
SEQUENCE:0
|
346
|
+
END:VEVENT
|
347
|
+
EOF
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should return icalendar VEVENT string taking EXDATE from the entries of X-SC-Day: !YYYYMMDD and X-SC-Time:" do
|
351
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
352
|
+
X-SC-Subject: CS1
|
353
|
+
X-SC-Time: 08:40-10:10
|
354
|
+
X-SC-Category: Lecture
|
355
|
+
X-SC-Day: !20140514
|
356
|
+
X-SC-Cond: Wed
|
357
|
+
X-SC-Duration: 20140409-20140723
|
358
|
+
X-SC-Record-Id: 69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
359
|
+
EOF
|
360
|
+
expect(ev.to_ics).to eq <<-'EOF'.strip_heredoc
|
361
|
+
BEGIN:VEVENT
|
362
|
+
EXDATE;VALUE=DATE-TIME:20140514T084000Z
|
363
|
+
CREATED;VALUE=DATE-TIME:20140101T000000Z
|
364
|
+
DTEND;VALUE=DATE-TIME:20140409T101000Z
|
365
|
+
DTSTART;VALUE=DATE-TIME:20140409T084000Z
|
366
|
+
DTSTAMP;VALUE=DATE-TIME:20140101T000000Z
|
367
|
+
CATEGORIES:Lecture
|
368
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140101T000000Z
|
369
|
+
UID:69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
370
|
+
DESCRIPTION:
|
371
|
+
SUMMARY:CS1
|
372
|
+
RRULE:FREQ=WEEKLY;INTERVAL=1;WKST=MO;BYDAY=WE;UNTIL=20140723T084000Z
|
373
|
+
SEQUENCE:0
|
374
|
+
END:VEVENT
|
375
|
+
EOF
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should return icalendar VEVENT over 24h event" do
|
379
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
380
|
+
X-SC-Subject: CS1
|
381
|
+
X-SC-Time: 12:00-10:10
|
382
|
+
X-SC-Day: 20140508-20140509
|
383
|
+
X-SC-Record-Id: 69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
384
|
+
EOF
|
385
|
+
expect(ev.to_ics).to eq <<-'EOF'.strip_heredoc
|
386
|
+
BEGIN:VEVENT
|
387
|
+
CREATED;VALUE=DATE-TIME:20140101T000000Z
|
388
|
+
DTEND;VALUE=DATE-TIME:20140509T101000Z
|
389
|
+
DTSTART;VALUE=DATE-TIME:20140508T120000Z
|
390
|
+
DTSTAMP;VALUE=DATE-TIME:20140101T000000Z
|
391
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140101T000000Z
|
392
|
+
UID:69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
393
|
+
DESCRIPTION:
|
394
|
+
SUMMARY:CS1
|
395
|
+
SEQUENCE:0
|
396
|
+
END:VEVENT
|
397
|
+
EOF
|
398
|
+
end
|
399
|
+
|
400
|
+
it "should return icalendar VEVENT two day's allday event" do
|
401
|
+
ev = Mhc::Event.parse <<-EOF.strip_heredoc
|
402
|
+
X-SC-Subject: CS1
|
403
|
+
X-SC-Day: 20140508-20140509
|
404
|
+
X-SC-Record-Id: 69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
405
|
+
EOF
|
406
|
+
expect(ev.to_ics).to eq <<-'EOF'.strip_heredoc
|
407
|
+
BEGIN:VEVENT
|
408
|
+
CREATED;VALUE=DATE-TIME:20140101T000000Z
|
409
|
+
DTEND;VALUE=DATE:20140510
|
410
|
+
DTSTART;VALUE=DATE:20140508
|
411
|
+
DTSTAMP;VALUE=DATE-TIME:20140101T000000Z
|
412
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140101T000000Z
|
413
|
+
UID:69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
414
|
+
DESCRIPTION:
|
415
|
+
SUMMARY:CS1
|
416
|
+
SEQUENCE:0
|
417
|
+
END:VEVENT
|
418
|
+
EOF
|
419
|
+
end
|
420
|
+
|
421
|
+
it "should convert 2014-03-11 10:30-12:00 (+0900 Asia/Tokyo) event to UTC Event" do
|
422
|
+
ev = Mhc::Event.new_from_ics <<-EOF.strip_heredoc
|
423
|
+
BEGIN:VCALENDAR
|
424
|
+
PRODID;X-RICAL-TZSOURCE=TZINFO:-//Quickhack.net//MHC 0.25.0//EN
|
425
|
+
CALSCALE:GREGORIAN
|
426
|
+
VERSION:2.0
|
427
|
+
BEGIN:VEVENT
|
428
|
+
CREATED;VALUE=DATE-TIME:20140101T000000Z
|
429
|
+
DTSTART;TZID=Asia/Tokyo;VALUE=DATE-TIME:20100311T103000
|
430
|
+
DTEND;TZID=Asia/Tokyo;VALUE=DATE-TIME:20100311T120000
|
431
|
+
DTSTAMP;VALUE=DATE-TIME:20140101T000000Z
|
432
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140101T000000Z
|
433
|
+
UID:69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
434
|
+
DESCRIPTION:This is Description.
|
435
|
+
SUMMARY:CS1
|
436
|
+
SEQUENCE:0
|
437
|
+
END:VEVENT
|
438
|
+
END:VCALENDAR
|
439
|
+
EOF
|
440
|
+
expect(ev.dump).to eq <<-'EOF'.strip_heredoc
|
441
|
+
X-SC-Subject: CS1
|
442
|
+
X-SC-Location:
|
443
|
+
X-SC-Day: 20100311
|
444
|
+
X-SC-Time: 01:30-03:00
|
445
|
+
X-SC-Category:
|
446
|
+
X-SC-Mission-Tag:
|
447
|
+
X-SC-Recurrence-Tag:
|
448
|
+
X-SC-Cond:
|
449
|
+
X-SC-Duration:
|
450
|
+
X-SC-Alarm:
|
451
|
+
X-SC-Record-Id: 69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
452
|
+
X-SC-Sequence: 0
|
453
|
+
|
454
|
+
This is Description.
|
455
|
+
EOF
|
456
|
+
end
|
457
|
+
|
458
|
+
it "should convert 2014-10-18 22:00-23:00 (Asia/Tokyo) iCalendar to 2014-10-18 15:00-16:00 (Europe/Paris) MHC Event" do
|
459
|
+
Mhc.default_tzid = "Europe/Paris"
|
460
|
+
ev = Mhc::Event.new_from_ics <<-EOF.strip_heredoc
|
461
|
+
BEGIN:VCALENDAR
|
462
|
+
PRODID;X-RICAL-TZSOURCE=TZINFO:-//Quickhack.net//MHC 0.25.0//EN
|
463
|
+
CALSCALE:GREGORIAN
|
464
|
+
VERSION:2.0
|
465
|
+
BEGIN:VEVENT
|
466
|
+
DTSTART;TZID=Asia/Tokyo;VALUE=DATE-TIME:20141018T220000
|
467
|
+
DTEND;VALUE=DATE-TIME:20141018T140000Z
|
468
|
+
UID:69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
469
|
+
DESCRIPTION:This is Description.
|
470
|
+
SUMMARY:CS1
|
471
|
+
SEQUENCE:0
|
472
|
+
END:VEVENT
|
473
|
+
END:VCALENDAR
|
474
|
+
EOF
|
475
|
+
expect(ev.dump).to eq <<-'EOF'.strip_heredoc
|
476
|
+
X-SC-Subject: CS1
|
477
|
+
X-SC-Location:
|
478
|
+
X-SC-Day: 20141018
|
479
|
+
X-SC-Time: 15:00-16:00
|
480
|
+
X-SC-Category:
|
481
|
+
X-SC-Mission-Tag:
|
482
|
+
X-SC-Recurrence-Tag:
|
483
|
+
X-SC-Cond:
|
484
|
+
X-SC-Duration:
|
485
|
+
X-SC-Alarm:
|
486
|
+
X-SC-Record-Id: 69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
487
|
+
X-SC-Sequence: 0
|
488
|
+
|
489
|
+
This is Description.
|
490
|
+
EOF
|
491
|
+
end
|
492
|
+
|
493
|
+
it "should create all-day event 20140508-20140509 from iCalendar" do
|
494
|
+
ev = Mhc::Event.new_from_ics <<-EOF.strip_heredoc
|
495
|
+
BEGIN:VCALENDAR
|
496
|
+
PRODID;X-RICAL-TZSOURCE=TZINFO:-//Quickhack.net//MHC 0.25.0//EN
|
497
|
+
CALSCALE:GREGORIAN
|
498
|
+
VERSION:2.0
|
499
|
+
BEGIN:VEVENT
|
500
|
+
CREATED;VALUE=DATE-TIME:20140101T000000Z
|
501
|
+
DTEND;VALUE=DATE:20140510
|
502
|
+
DTSTART;VALUE=DATE:20140508
|
503
|
+
DTSTAMP;VALUE=DATE-TIME:20140101T000000Z
|
504
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140101T000000Z
|
505
|
+
UID:69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
506
|
+
DESCRIPTION:This is Description.
|
507
|
+
SUMMARY:CS1
|
508
|
+
SEQUENCE:0
|
509
|
+
END:VEVENT
|
510
|
+
END:VCALENDAR
|
511
|
+
EOF
|
512
|
+
expect(ev.dump).to eq <<-'EOF'.strip_heredoc
|
513
|
+
X-SC-Subject: CS1
|
514
|
+
X-SC-Location:
|
515
|
+
X-SC-Day: 20140508-20140509
|
516
|
+
X-SC-Time:
|
517
|
+
X-SC-Category:
|
518
|
+
X-SC-Mission-Tag:
|
519
|
+
X-SC-Recurrence-Tag:
|
520
|
+
X-SC-Cond:
|
521
|
+
X-SC-Duration:
|
522
|
+
X-SC-Alarm:
|
523
|
+
X-SC-Record-Id: 69CFD0DF-4058-425B-8C2B-40D81E6A2392
|
524
|
+
X-SC-Sequence: 0
|
525
|
+
|
526
|
+
This is Description.
|
527
|
+
EOF
|
528
|
+
end
|
529
|
+
|
530
|
+
it "should create recurrence condition from iCalendar string" do
|
531
|
+
ev = Mhc::Event.new_from_ics <<-EOF.strip_heredoc
|
532
|
+
BEGIN:VCALENDAR
|
533
|
+
PRODID;X-RICAL-TZSOURCE=TZINFO:-//Quickhack.net//MHC 0.25.0//EN
|
534
|
+
CALSCALE:GREGORIAN
|
535
|
+
VERSION:2.0
|
536
|
+
BEGIN:VEVENT
|
537
|
+
CREATED;VALUE=DATE-TIME:20140101T000000Z
|
538
|
+
DTEND;VALUE=DATE:20140403
|
539
|
+
DTSTART;VALUE=DATE:20140402
|
540
|
+
DTSTAMP;VALUE=DATE-TIME:20140101T000000Z
|
541
|
+
CATEGORIES:Work
|
542
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140101T000000Z
|
543
|
+
UID:FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
544
|
+
DESCRIPTION:this is description\n
|
545
|
+
SUMMARY:Wednesday and Sunday Weekly event
|
546
|
+
RRULE:FREQ=WEEKLY;INTERVAL=1;WKST=MO;BYDAY=WE,SU;UNTIL=20140424
|
547
|
+
LOCATION:Office
|
548
|
+
SEQUENCE:0
|
549
|
+
END:VEVENT
|
550
|
+
END:VCALENDAR
|
551
|
+
EOF
|
552
|
+
expect(ev.dump).to eq <<-'EOF'.strip_heredoc
|
553
|
+
X-SC-Subject: Wednesday and Sunday Weekly event
|
554
|
+
X-SC-Location: Office
|
555
|
+
X-SC-Day:
|
556
|
+
X-SC-Time:
|
557
|
+
X-SC-Category: Work
|
558
|
+
X-SC-Mission-Tag:
|
559
|
+
X-SC-Recurrence-Tag:
|
560
|
+
X-SC-Cond: Wed Sun
|
561
|
+
X-SC-Duration: 20140402-20140424
|
562
|
+
X-SC-Alarm:
|
563
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
564
|
+
X-SC-Sequence: 0
|
565
|
+
|
566
|
+
this is description
|
567
|
+
EOF
|
568
|
+
end
|
569
|
+
|
570
|
+
it "should create recurrence condition from iCalendar string with RDATE" do
|
571
|
+
Mhc.default_tzid = "Asia/Tokyo"
|
572
|
+
ev = Mhc::Event.new_from_ics <<-EOF.strip_heredoc
|
573
|
+
BEGIN:VCALENDAR
|
574
|
+
BEGIN:VEVENT
|
575
|
+
RDATE;TZID=Asia/Tokyo;VALUE=DATE-TIME:20141114T124500
|
576
|
+
EXDATE;TZID=Asia/Tokyo;VALUE=DATE-TIME:20141022T124500,20141119T124500,20
|
577
|
+
141231T124500,20150107T124500
|
578
|
+
CREATED;VALUE=DATE-TIME:20140924T004619Z
|
579
|
+
DTEND;TZID=Asia/Tokyo;VALUE=DATE-TIME:20141001T141500
|
580
|
+
DTSTART;TZID=Asia/Tokyo;VALUE=DATE-TIME:20141001T124500
|
581
|
+
DTSTAMP;VALUE=DATE-TIME:20141017T061129Z
|
582
|
+
CATEGORIES:Lecture
|
583
|
+
LAST-MODIFIED;VALUE=DATE-TIME:20140924T004619Z
|
584
|
+
UID:FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
585
|
+
DESCRIPTION:this is description\n
|
586
|
+
SUMMARY:PP
|
587
|
+
RRULE:FREQ=WEEKLY;INTERVAL=1;WKST=MO;BYDAY=WE;UNTIL=20150128T034500Z
|
588
|
+
LOCATION:Room11
|
589
|
+
SEQUENCE:4
|
590
|
+
END:VEVENT
|
591
|
+
END:VCALENDAR
|
592
|
+
EOF
|
593
|
+
expect(ev.dump).to eq <<-'EOF'.strip_heredoc
|
594
|
+
X-SC-Subject: PP
|
595
|
+
X-SC-Location: Room11
|
596
|
+
X-SC-Day: 20141114 !20141022 !20141119 !20141231 !20150107
|
597
|
+
X-SC-Time: 12:45-14:15
|
598
|
+
X-SC-Category: Lecture
|
599
|
+
X-SC-Mission-Tag:
|
600
|
+
X-SC-Recurrence-Tag:
|
601
|
+
X-SC-Cond: Wed
|
602
|
+
X-SC-Duration: 20141001-20150128
|
603
|
+
X-SC-Alarm:
|
604
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
605
|
+
X-SC-Sequence: 4
|
606
|
+
|
607
|
+
this is description
|
608
|
+
EOF
|
609
|
+
end
|
610
|
+
|
611
|
+
it "should create duration-end considering timezone" do
|
612
|
+
Mhc.default_tzid = "Asia/Tokyo"
|
613
|
+
ev = Mhc::Event.new_from_ics <<-EOF.strip_heredoc
|
614
|
+
BEGIN:VCALENDAR
|
615
|
+
BEGIN:VEVENT
|
616
|
+
EXDATE;TZID=Asia/Tokyo;VALUE=DATE-TIME:20140514T084000,20140723T084000
|
617
|
+
DTEND;TZID=Asia/Tokyo;VALUE=DATE-TIME:20140409T101000
|
618
|
+
DTSTART;VALUE=DATE-TIME:20140408T234000Z
|
619
|
+
CATEGORIES:Lecture
|
620
|
+
UID:FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
621
|
+
DESCRIPTION:this is description\n
|
622
|
+
SUMMARY:CS1
|
623
|
+
RRULE:FREQ=WEEKLY;INTERVAL=1;WKST=MO;BYDAY=WE;UNTIL=20140729T234000Z
|
624
|
+
LOCATION:Room11
|
625
|
+
SEQUENCE:4
|
626
|
+
END:VEVENT
|
627
|
+
END:VCALENDAR
|
628
|
+
EOF
|
629
|
+
expect(ev.dump).to eq <<-'EOF'.strip_heredoc
|
630
|
+
X-SC-Subject: CS1
|
631
|
+
X-SC-Location: Room11
|
632
|
+
X-SC-Day: !20140514 !20140723
|
633
|
+
X-SC-Time: 08:40-10:10
|
634
|
+
X-SC-Category: Lecture
|
635
|
+
X-SC-Mission-Tag:
|
636
|
+
X-SC-Recurrence-Tag:
|
637
|
+
X-SC-Cond: Wed
|
638
|
+
X-SC-Duration: 20140409-20140730
|
639
|
+
X-SC-Alarm:
|
640
|
+
X-SC-Record-Id: FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
641
|
+
X-SC-Sequence: 4
|
642
|
+
|
643
|
+
this is description
|
644
|
+
EOF
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
describe RiCal do
|
649
|
+
it "creates RiCal::Event form ics string" do
|
650
|
+
Mhc.default_tzid = "Asia/Tokyo"
|
651
|
+
ics = RiCal.parse_string <<-EOF.strip_heredoc
|
652
|
+
BEGIN:VCALENDAR
|
653
|
+
BEGIN:VEVENT
|
654
|
+
EXDATE;TZID=Asia/Tokyo;VALUE=DATE-TIME:20140514T084000,20140723T084000
|
655
|
+
DTEND;TZID=Asia/Tokyo;VALUE=DATE-TIME:20140409T101000
|
656
|
+
DTSTART;VALUE=DATE-TIME:20140408T234000Z
|
657
|
+
CATEGORIES:Lecture
|
658
|
+
UID:FEDA4C97-21C2-46AA-A395-075856FBD5C3
|
659
|
+
DESCRIPTION:this is description\n
|
660
|
+
SUMMARY:CS1
|
661
|
+
RRULE:FREQ=WEEKLY;INTERVAL=1;WKST=MO;BYDAY=WE;UNTIL=20140729T234000Z
|
662
|
+
LOCATION:Room11
|
663
|
+
SEQUENCE:4
|
664
|
+
END:VEVENT
|
665
|
+
END:VCALENDAR
|
666
|
+
EOF
|
667
|
+
iev = ics.first.events.first
|
668
|
+
expect(iev.occurrences.first.dtstart.tzid).to eq "UTC"
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
describe Mhc::DateFrame::Yearly do
|
673
|
+
end
|
674
|
+
|
675
|
+
describe Mhc::DateFrame::Monthly do
|
676
|
+
end
|
677
|
+
|
678
|
+
describe Mhc::DateFrame::Weekly do
|
679
|
+
end
|
680
|
+
|
681
|
+
describe Mhc::DateFrame::Daily do
|
682
|
+
end
|