bigtinker 0.97 → 0.98

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.
Files changed (184) hide show
  1. data/code/01rwdcore/01rwdcore.rb +6 -6
  2. data/code/01rwdcore/02helptexthashbegin.rb +13 -11
  3. data/code/01rwdcore/jumplinkcommand.rb +14 -4
  4. data/code/01rwdcore/openhelpwindow.rb +7 -0
  5. data/code/01rwdcore/runhelpabout.rb +6 -1
  6. data/code/01rwdcore/runtab.rb +15 -0
  7. data/code/01rwdcore/selectiontab.rb +2 -0
  8. data/code/01rwdcore/setuphelpaboutoptions.rb +2 -0
  9. data/code/01rwdcore/setuptinkerdocuments.rb +1 -0
  10. data/code/01rwdcore/test_cases.rb +100 -51
  11. data/code/01rwdcore/test_harness.rb +8 -1
  12. data/code/01rwdcore/uploadreturns.rb +3 -0
  13. data/code/dd0viewphoto/dd0viewphoto.rb +2 -0
  14. data/code/superant.com.rwdcalendar/gh9calendar.rb +40 -0
  15. data/code/superant.com.rwdcalendar/helptexthashrwdschedule.rb +14 -0
  16. data/code/superant.com.rwdcalendar/openhelpwindowrwdschedule.rb +17 -0
  17. data/code/superant.com.rwdtinkerbackwindow/changelocale.rb +84 -0
  18. data/code/superant.com.rwdtinkerbackwindow/initiateapplets.rb +0 -1
  19. data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +2 -0
  20. data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +2 -0
  21. data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +3 -1
  22. data/code/superant.com.rwdtinkerbackwindow/listzips.rb +4 -0
  23. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +3 -1
  24. data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +3 -1
  25. data/code/superant.com.rwdtinkerbackwindow/showlocaleoptions.rb +9 -0
  26. data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +1 -0
  27. data/code/superant.com.rwdtinkerbackwindow/viewlogfile.rb +8 -5
  28. data/code/superant.com.schedule/0uninstallapplet.rb +24 -0
  29. data/code/superant.com.schedule/archiveevent.rb +14 -0
  30. data/code/superant.com.schedule/archiveicsevent.rb +14 -0
  31. data/code/superant.com.schedule/cleareventscreendisplay.rb +19 -0
  32. data/code/superant.com.schedule/deleteeventrecord.rb +19 -0
  33. data/code/superant.com.schedule/deleteicseventrecord.rb +19 -0
  34. data/code/superant.com.schedule/deleterwdscheduleupdatefiles.rb +20 -0
  35. data/code/superant.com.schedule/downloadrwdschedulefiles.rb +37 -0
  36. data/code/superant.com.schedule/exporticseventrecord.rb +97 -0
  37. data/code/{superant.com.foldeditor → superant.com.schedule}/helptexthashload.rb +2 -2
  38. data/code/superant.com.schedule/listeventdates.rb +19 -0
  39. data/code/superant.com.schedule/listicseventdates.rb +19 -0
  40. data/code/{superant.com.foldeditor → superant.com.schedule}/loadconfigurationrecord.rb +4 -4
  41. data/code/superant.com.schedule/loadconfigurationvariables.rb +14 -0
  42. data/code/superant.com.schedule/loadeventrecord.rb +38 -0
  43. data/code/superant.com.schedule/loadicseventrecord.rb +30 -0
  44. data/code/superant.com.schedule/openhelpwindowrwdschedule.rb +43 -0
  45. data/code/superant.com.schedule/renameeventdata.rb +14 -0
  46. data/code/superant.com.schedule/renameicseventdata.rb +17 -0
  47. data/code/{superant.com.foldeditor/runrwdapplet.rb → superant.com.schedule/returntomain.rb} +3 -3
  48. data/code/superant.com.schedule/runrwdscheduleicsbackwindow.rb +10 -0
  49. data/code/superant.com.schedule/runrwdschedulemenu1.rb +34 -0
  50. data/code/superant.com.schedule/runrwdschedulesyncbackwindow.rb +10 -0
  51. data/code/{superant.com.foldeditor/rwdtinkerversion.rb → superant.com.schedule/rwdversion.rb} +2 -2
  52. data/code/{superant.com.foldeditor → superant.com.schedule}/saveconfigurationrecord.rb +5 -6
  53. data/code/superant.com.schedule/saveeventrecord.rb +25 -0
  54. data/code/superant.com.schedule/saveicseventrecord.rb +98 -0
  55. data/code/superant.com.schedule/syncrwdschedule.rb +30 -0
  56. data/code/superant.com.schedule/test_cases.rb +45 -0
  57. data/code/superant.com.schedule/uploadrwdschedulefiles.rb +30 -0
  58. data/code/superant.com.schedule/viewevent.rb +20 -0
  59. data/code/superant.com.schedule/viewicsevent.rb +20 -0
  60. data/code/superant.com.schedule/viewrwdschedulesconfiguration.rb +21 -0
  61. data/code/zz0applicationend/zz0end.rb +2 -1
  62. data/configuration/bigtinker.dist +5 -2
  63. data/configuration/rwdtinker.dist +3 -3
  64. data/configuration/rwdwschedule.dist +28 -0
  65. data/configuration/tinkerwin2variables.dist +1 -1
  66. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/1appname.rwd +5 -0
  67. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/20downloadftp.rwd +45 -0
  68. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/67viewconfiguration.rwd +29 -0
  69. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/70rwddiagnostics.rwd +16 -0
  70. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m01menubegin.rwd +18 -0
  71. data/gui/tinkerbackwindows/{superant.com.foldeditor/9end.rwd → superant.com.rwdschedulebackwindow/zvbackend.rwd} +6 -6
  72. data/gui/tinkerbackwindows/superant.com.rwdschedules/1appname.rwd +5 -0
  73. data/gui/tinkerbackwindows/superant.com.rwdschedules/gg0viewevent.rwd +27 -0
  74. data/gui/tinkerbackwindows/superant.com.rwdschedules/gl6editrecord.rwd +56 -0
  75. data/gui/tinkerbackwindows/superant.com.rwdschedules/gl8contactutilities.rwd +25 -0
  76. data/gui/tinkerbackwindows/superant.com.rwdschedules/hl9calendar.rwd +27 -0
  77. data/gui/tinkerbackwindows/superant.com.rwdschedules/m01menubegin.rwd +18 -0
  78. data/gui/tinkerbackwindows/{superant.com.slideshow/9end.rwd → superant.com.rwdschedules/zvbackend.rwd} +6 -6
  79. data/gui/tinkerbackwindows/superant.com.rwdschedulesback/1appname.rwd +5 -0
  80. data/gui/tinkerbackwindows/superant.com.rwdschedulesback/30viewevent.rwd +27 -0
  81. data/gui/tinkerbackwindows/superant.com.rwdschedulesback/40editrecord.rwd +49 -0
  82. data/gui/tinkerbackwindows/superant.com.rwdschedulesback/60eventicsutilities.rwd +25 -0
  83. data/gui/tinkerbackwindows/superant.com.rwdschedulesback/m01menubegin.rwd +18 -0
  84. data/gui/tinkerbackwindows/superant.com.rwdschedulesback/zvbackend.rwd +6 -0
  85. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/70rwddiagnostics.rwd +1 -1
  86. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/80localechanger.rwd +17 -0
  87. data/init.rb +7 -1
  88. data/installed/rwdscheduledate2.inf +6 -0
  89. data/installed/rwdwschedule.inf +20 -0
  90. data/lang/en/rwdcalendar/en.po +32 -0
  91. data/lang/en/rwdcore/en.po +31 -0
  92. data/lang/es/rwdcalendar/es.po +10 -0
  93. data/lang/es/rwdcore/es.po +27 -15
  94. data/lang/fr/rwdcalendar/fr.po +11 -0
  95. data/lang/fr/rwdcore/fr.po +4 -1
  96. data/lang/hi/rwdcalendar/hi.po +11 -0
  97. data/lang/hi/rwdcore/hi.po +39 -36
  98. data/lang/ja/rwdcalendar/ja.po +11 -0
  99. data/lang/ja/rwdcore/ja.po +3 -0
  100. data/lang/nl/rwdcalendar/nl.po +12 -0
  101. data/lang/nl/rwdcore/nl.po +4 -1
  102. data/lib/cal.rb +158 -0
  103. data/lib/icalendar.rb +18 -0
  104. data/lib/icalendar/base.rb +17 -0
  105. data/lib/icalendar/calendar.rb +44 -0
  106. data/lib/icalendar/calendar_parser.rb +237 -0
  107. data/lib/icalendar/component.rb +91 -0
  108. data/lib/icalendar/component/alarm.rb +16 -0
  109. data/lib/icalendar/component/event.rb +25 -0
  110. data/lib/icalendar/component/freebusy.rb +12 -0
  111. data/lib/icalendar/component/journal.rb +25 -0
  112. data/lib/icalendar/component/timezone.rb +26 -0
  113. data/lib/icalendar/component/todo.rb +21 -0
  114. data/lib/icalendar/helpers.rb +103 -0
  115. data/lib/icalendar/parameter.rb +25 -0
  116. data/lib/zip/ioextras.rb +43 -2
  117. data/lib/zip/stdrubyext.rb +5 -5
  118. data/lib/zip/tempfile_bugfixed.rb +2 -2
  119. data/lib/zip/zip.rb +618 -149
  120. data/lib/zip/zipfilesystem.rb +59 -8
  121. data/lib/zip/ziprequire.rb +32 -3
  122. data/rwd_files/HowTo_BigTinker.txt +15 -3
  123. data/rwd_files/HowTo_Schedule.txt +265 -0
  124. data/rwd_files/HowTo_Tinker.txt +14 -0
  125. data/rwd_files/Tinkerhelptexthash.txt +5 -2
  126. data/rwd_files/rwdapplications.html +23 -1
  127. data/rwd_files/rwdschedulehelpfiles.txt +19 -0
  128. data/rwd_files/schedules/20050120T09.ics +9 -0
  129. data/rwd_files/schedules/200505may02a.sch +4 -0
  130. data/rwd_files/schedules/Enterprise.ics +411 -0
  131. data/rwd_files/schedules/US Holidays.ics +575 -0
  132. data/rwd_files/schedules/archive/sample.archive +1 -0
  133. data/rwd_files/schedules/testics05.ics +11 -0
  134. data/rwdconfig.dist +4 -2
  135. data/{bigtinker.rb → rwdtinker.rb} +0 -0
  136. data/tests/{makedist-rwdwfoldeditor.rb → makedist-rwdwhypernote.rb} +4 -8
  137. data/tests/makedist.rb +1 -1
  138. data/updates/temp.rb +1 -0
  139. data/zips/rwdwfoldeditor-0.07.zip +0 -0
  140. data/zips/rwdwhypernote-0.16.zip +0 -0
  141. data/zips/rwdwschedule-1.07.zip +0 -0
  142. data/zips/tinkerbellw-0.04.zip +0 -0
  143. metadata +102 -54
  144. data/code/superant.com.foldeditor/0uninstallapplet.rb +0 -17
  145. data/code/superant.com.foldeditor/changehypernotename.rb +0 -21
  146. data/code/superant.com.foldeditor/chooselinkfile.rb +0 -6
  147. data/code/superant.com.foldeditor/choosenotefile.rb +0 -6
  148. data/code/superant.com.foldeditor/clearnotescreen.rb +0 -7
  149. data/code/superant.com.foldeditor/createnewnotehtml.rb +0 -31
  150. data/code/superant.com.foldeditor/hyperlinkcreatelinkfile.rb +0 -19
  151. data/code/superant.com.foldeditor/launchfoldeditorurl.rb +0 -19
  152. data/code/superant.com.foldeditor/listfoldeditorfiles.rb +0 -7
  153. data/code/superant.com.foldeditor/loadconfigurationvariables.rb +0 -14
  154. data/code/superant.com.foldeditor/loadfolddocument.rb +0 -18
  155. data/code/superant.com.foldeditor/loadnextnote.rb +0 -32
  156. data/code/superant.com.foldeditor/loadprevnote.rb +0 -32
  157. data/code/superant.com.foldeditor/loadrwdfoldeditlinkfile.rb +0 -19
  158. data/code/superant.com.foldeditor/openhelpwindowrwdhyernote.rb +0 -30
  159. data/code/superant.com.foldeditor/rwddisplayfoldlinks.rb +0 -41
  160. data/code/superant.com.foldeditor/savefoldlinkfile.rb +0 -20
  161. data/code/superant.com.foldeditor/savehtmlhypernoterecord.rb +0 -20
  162. data/configuration/rwdwfoldeditor.dist +0 -16
  163. data/gui/tinkerbackwindows/superant.com.foldeditor/10appletbegin.rwd +0 -4
  164. data/gui/tinkerbackwindows/superant.com.foldeditor/10aviewnote.rwd +0 -36
  165. data/gui/tinkerbackwindows/superant.com.foldeditor/15htmlview.rwd +0 -43
  166. data/gui/tinkerbackwindows/superant.com.foldeditor/56viewfold.rwd +0 -43
  167. data/gui/tinkerbackwindows/superant.com.foldeditor/67viewconfiguration.rwd +0 -27
  168. data/gui/tinkerbackwindows/superant.com.foldeditor/81jumplinkcommands.rwd +0 -17
  169. data/gui/tinkerbackwindows/superant.com.slideshow/10appletbegin.rwd +0 -4
  170. data/gui/tinkerbackwindows/superant.com.slideshow/11viewnamedata.rwd +0 -19
  171. data/gui/tinkerbackwindows/superant.com.slideshow/13listnamerecordfiles.rwd +0 -21
  172. data/gui/tinkerbackwindows/superant.com.slideshow/16editrecord.rwd +0 -39
  173. data/gui/tinkerbackwindows/superant.com.slideshow/17viewvcardrecord.rwd +0 -32
  174. data/gui/tinkerbackwindows/superant.com.slideshow/18contactutilities.rwd +0 -34
  175. data/gui/tinkerbackwindows/superant.com.slideshow/81jumplinkcommands.rwd +0 -17
  176. data/installed/rwdwfoldeditor.inf +0 -11
  177. data/rwd_files/HowTo_FoldEditor.txt +0 -131
  178. data/rwd_files/default.fld +0 -9
  179. data/rwd_files/rubylinks.fld +0 -6
  180. data/rwd_files/rwdfoldeditorhelpfiles.txt +0 -42
  181. data/rwd_files/rwdhypernote-0.13.fld +0 -202
  182. data/zips/rwdwfoldeditor-0.06.zip +0 -0
  183. data/zips/rwdwschedule-1.05.zip +0 -0
  184. data/zips/tinkerbellw-0.03.zip +0 -0
@@ -0,0 +1,44 @@
1
+ module Icalendar
2
+ class Calendar < Component
3
+
4
+ attr_accessor :events, :todos, :journals, :freebusys, :timezones
5
+
6
+ def initialize()
7
+ super("VCALENDAR")
8
+ @properties = {}
9
+ @property_params = {}
10
+
11
+ @events = []
12
+ @todos = []
13
+ @journals = []
14
+ @freebusys = []
15
+ @timezones = []
16
+ end
17
+
18
+ def add(component)
19
+ if component.is_a? Event
20
+ @events << component
21
+ elsif component.is_a? Todo
22
+ @todos << component
23
+ elsif component.is_a? Journal
24
+ @journals << component
25
+ elsif component.is_a? Freebusy
26
+ @freebusys << component
27
+ elsif component.is_a? Timezone
28
+ @timezones << component
29
+ else
30
+ raise InvalidComponentClass
31
+ end
32
+ end
33
+
34
+ def to_s
35
+ print_string do |s|
36
+ @events.each { |event| s << event.to_s }
37
+ @todos.each { |todo| s << todo.to_s }
38
+ @journals.each { |journal| s << journal.to_s }
39
+ @freebusys.each { |freebusy| s << freebusy.to_s }
40
+ @timezones.each { |timezone| s << timezone.to_s }
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,237 @@
1
+ module Icalendar
2
+ class CalendarParser < Icalendar::Base
3
+ # 1*(ALPHA / DIGIT / "=")
4
+ NAME = '[-a-z0-9]+'
5
+
6
+ # <"> <Any character except CTLs, DQUOTE> <">
7
+ QSTR = '"[^"]*"'
8
+
9
+ # *<Any character except CTLs, DQUOTE, ";", ":", ",">
10
+ PTEXT = '[^";:,]*'
11
+
12
+ # param-value = ptext / quoted-string
13
+ PVALUE = "#{PTEXT}|#{QSTR}"
14
+
15
+ # Contentline
16
+ LINE = "(#{NAME})([^:]*)\:(.*)"
17
+
18
+ # param = name "=" param-value *("," param-value)
19
+ # Note: v2.1 allows a type or encoding param-value to appear without the type=
20
+ # or the encoding=. This is hideous, but we try and support it, if there # is no "=", then $2 will be "", and we will treat it as a v2.1 param.
21
+ PARAM = ";(#{NAME})(=?)((?:#{PVALUE})(?:,#{PVALUE})*)"
22
+
23
+ # date = date-fullyear ["-"] date-month ["-"] date-mday
24
+ # date-fullyear = 4 DIGIT
25
+ # date-month = 2 DIGIT
26
+ # date-mday = 2 DIGIT
27
+ DATE = '(\d\d\d\d)-?(\d\d)-?(\d\d)'
28
+
29
+ # time = time-hour [":"] time-minute [":"] time-second [time-secfrac] [time-zone]
30
+ # time-hour = 2 DIGIT
31
+ # time-minute = 2 DIGIT
32
+ # time-second = 2 DIGIT
33
+ # time-secfrac = "," 1*DIGIT
34
+ # time-zone = "Z" / time-numzone
35
+ # time-numzome = sign time-hour [":"] time-minute
36
+ TIME = '(\d\d):?(\d\d):?(\d\d)(\.\d+)?(Z|[-+]\d\d:?\d\d)?'
37
+
38
+ def initialize(src)
39
+ @@logger.info("New Calendar Parser")
40
+
41
+ # Define the next line method different depending on whether
42
+ # this is a string or an IO object so we can be efficient about
43
+ # parsing large files...
44
+
45
+ # Just do the unfolding work in one shot if its a whole string
46
+ if src.respond_to?(:split)
47
+ unfolded = []
48
+
49
+ # Split into an array of lines, then unfold those into a new array
50
+ src.split(/\r?\n/).each do |line|
51
+
52
+ # If it's a continuation line, add it to the last.
53
+ # If it's an empty line, drop it from the input.
54
+ if( line =~ /^[ \t]/ )
55
+ unfolded << unfolded.pop + line[1, line.size-1]
56
+ elsif( line =~ /^$/ )
57
+ else
58
+ unfolded << line
59
+ end
60
+ end
61
+
62
+ @lines = unfolded
63
+ @index = 0
64
+
65
+ # Now that we are unfolded we can just iterate through the array.
66
+ # Dynamically define next line for a string.
67
+ def next_line
68
+ if @index == @lines.size
69
+ return nil
70
+ else
71
+ line = @lines[@index]
72
+ @index += 1
73
+ return line
74
+ end
75
+ end
76
+
77
+ # If its a file we need to read and unfold on the go to save from reading
78
+ # large amounts of data into memory.
79
+ elsif src.respond_to?(:gets)
80
+ @file = src
81
+ @prev_line = src.gets
82
+ if !@prev_line.nil?
83
+ @prev_line.chomp!
84
+ end
85
+
86
+ # Dynamically define next line for an IO object
87
+ def next_line
88
+ line = @prev_line
89
+
90
+ if line.nil?
91
+ return nil
92
+ end
93
+
94
+ # Loop through until we get to a non-continuation line...
95
+ loop do
96
+ nextLine = @file.gets
97
+ if !nextLine.nil?
98
+ nextLine.chomp!
99
+ end
100
+
101
+ # If it's a continuation line, add it to the last.
102
+ # If it's an empty line, drop it from the input.
103
+ if( nextLine =~ /^[ \t]/ )
104
+ line << nextLine[1, nextLine.size]
105
+ elsif( nextLine =~ /^$/ )
106
+ else
107
+ @prev_line = nextLine
108
+ break
109
+ end
110
+ end
111
+ line
112
+ end
113
+ else
114
+ raise ArgumentError, "CalendarParser.new cannot be called with a #{src.class} type!"
115
+ end
116
+ end
117
+
118
+ # Parse the calendar into an object representation
119
+ def parse
120
+ calendars = []
121
+
122
+ # Outer loop for Calendar objects
123
+ while (line = next_line)
124
+ fields = parse_line(line)
125
+
126
+ # Just iterate through until we find the beginning of a calendar object
127
+ if fields[:name] == "BEGIN" and fields[:value] == "VCALENDAR"
128
+ cal = parse_calendar
129
+ calendars << cal
130
+ end
131
+ end
132
+
133
+ calendars
134
+ end
135
+
136
+ # Parse a single VCALENDAR object
137
+ # -- This should consist of the PRODID, VERSION, option METHOD & CALSCALE,
138
+ # and then one or more calendar components: VEVENT, VTODO, VJOURNAL,
139
+ # VFREEBUSY, VTIMEZONE
140
+ def parse_calendar(component = Calendar.new)
141
+ while (line = next_line)
142
+ fields = parse_line(line)
143
+
144
+ name = fields[:name]
145
+
146
+ # Although properties are supposed to come before components, we should
147
+ # be able to handle them in any order...
148
+ if name == "END"
149
+ break
150
+ elsif name == "BEGIN" # New component
151
+ case(fields[:value])
152
+ when "VEVENT"
153
+ component.events << parse_calendar(Event.new)
154
+ when "VTODO"
155
+ component.todos << parse_calendar(Todo.new)
156
+ when "VJOURNAL"
157
+ component.journals << parse_calendar(Journal.new)
158
+ when "VFREEBUSY"
159
+ component.freebusys << parse_calendar(Freebusy.new)
160
+ when "VTIMEZONE"
161
+ component.timezones << parse_calendar(Timezone.new)
162
+ when "VALARM"
163
+ component.alarms << parse_calendar(Alarm.new)
164
+ end
165
+ else # If its not a component then it should be properties...
166
+
167
+ # Just set the properties ourselves so that the parser can still
168
+ # parse invalid files...
169
+ @@logger.debug("Setting #{name} => #{fields[:value]}")
170
+ component.properties[name] = fields[:value]
171
+ if not fields[:params].empty?
172
+ component.property_params[name] = fields[:params]
173
+ end
174
+
175
+ # This will generate the correctly formed calls to the dynamic method
176
+ # handler.
177
+ # component.send("#{name}=", fields[:value])
178
+ # component.send("#{name}_params=", fields[:params]) unless fields[:params].empty?
179
+ end
180
+ end
181
+
182
+ component
183
+ end
184
+
185
+ def parse_line(line)
186
+ unless line =~ %r{#{LINE}}i # Case insensitive match for a valid line
187
+ raise "Invalid line in calendar string!"
188
+ end
189
+
190
+ name = $1.upcase # The case insensitive part is upcased for easier comparison...
191
+ paramslist = $2
192
+ value = $3
193
+
194
+ params = {}
195
+
196
+ # Collect the params, if any.
197
+ if paramslist.size > 1
198
+
199
+ # v3.0 and v2.1 params
200
+ paramslist.scan( %r{#{PARAM}}i ) do
201
+
202
+ # param names are case-insensitive, and multi-valued
203
+ pname = $1
204
+ pvals = $3
205
+
206
+ # v2.1 pvals have no '=' sign, figure out what kind of param it
207
+ # is (either its a known encoding, or we treat it as a 'type'
208
+ # param).
209
+ if $2 == ""
210
+ pvals = $1
211
+ case $1
212
+ when /quoted-printable/i
213
+ pname = 'encoding'
214
+
215
+ when /base64/i
216
+ pname = 'encoding'
217
+
218
+ else
219
+ pname = 'type'
220
+ end
221
+ end
222
+
223
+ unless params.key? pname
224
+ params[pname] = []
225
+ end
226
+ pvals.scan( %r{(#{PVALUE})} ) do
227
+ if $1.size > 0
228
+ params[pname] << $1
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ {:name => name, :params => params, :value => value}
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,91 @@
1
+ module Icalendar
2
+ # The body of the iCalendar object consists of a sequence of calendar
3
+ # properties and one or more calendar components. The calendar
4
+ # properties are attributes that apply to the calendar as a whole. The
5
+ # calendar components are collections of properties that express a
6
+ # particular calendar semantic. For example, the calendar component can
7
+ # specify an event, a to-do, a journal entry, time zone information, or
8
+ # free/busy time information, or an alarm.
9
+ class Component < Icalendar::Base
10
+
11
+ attr_reader :name
12
+ attr_accessor :properties, :property_params
13
+
14
+ def initialize(name)
15
+ @name = name
16
+ @properties = {}
17
+ @property_params = {}
18
+
19
+ @@logger.info("New #{@name[1,@name.size].capitalize}...")
20
+ end
21
+
22
+ def print_string
23
+ s = ""
24
+
25
+ # Begin a new component
26
+ s << "BEGIN:#{@name.upcase}\r\n"
27
+
28
+ # Then print the properties, possible parameters and potentially
29
+ # multiple parameter values for each parameter.
30
+ @properties.each do |key,value|
31
+ # Property name
32
+ s << "#{key.upcase}"
33
+
34
+ # Possible parameters
35
+ if @property_params.has_key?(key)
36
+ params = @property_params[key]
37
+ params.each do |key,val|
38
+ s << ";#{key}"
39
+ unless val.respond_to?(:to_ary)
40
+ val = [ val ]
41
+ end
42
+
43
+ # Possible parameter values
44
+ unless val.empty?
45
+ s << "="
46
+ sep = "" # First entry comes after = sign, but then we need commas
47
+ val.each do |pval|
48
+ s << sep << pval
49
+ sep = ","
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ # Property value
56
+ s << ":#{value}\r\n"
57
+ end
58
+
59
+ # Any custom body of the derived component
60
+ yield(s)
61
+
62
+ # End of this component
63
+ s << "END:#{@name.upcase}\r\n"
64
+ end
65
+
66
+ # Dynamically execute getters and setters for properties and
67
+ # property parameters. This lets us handle all the general text properties
68
+ # as well as custom app related properties in a natural way, but we don't
69
+ # have to write a million getters and setters for every possible thing we
70
+ # want to support.
71
+ def method_missing(method_id, *args)
72
+ method_name = method_id.id2name.upcase
73
+
74
+ if method_name =~ /\w+_PARAMS/ # Its a parameter request
75
+ hash = @property_params
76
+ val = args
77
+ else # Or its a property request
78
+ hash = @properties
79
+ val = args.first unless args.empty?
80
+ end
81
+
82
+ if method_name =~ /(.*)(=)/ # Its a setter
83
+ hash[$1] = val
84
+ @@logger.debug("Setting #{$1} => #{val}")
85
+ else # Or its a getter
86
+ @@logger.debug("Getting #{method_name} => #{hash[method_name]}")
87
+ return hash[method_name]
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,16 @@
1
+ module Icalendar
2
+ # An Alarm calendar component is a grouping of component
3
+ # properties that is a reminder or alarm for an event or a
4
+ # to-do. For example, it may be used to define a reminder for a
5
+ # pending Event or an overdue Todo.
6
+ class Alarm < Component
7
+ def initialize()
8
+ super("VALARM")
9
+
10
+ end
11
+
12
+ def to_s
13
+ print_string {}
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module Icalendar
2
+ # A Event calendar component is a grouping of component
3
+ # properties, and possibly including Alarm calendar components, that
4
+ # represents a scheduled amount of time on a calendar. For example, it
5
+ # can be an activity; such as a one-hour long, department meeting from
6
+ # 8:00 AM to 9:00 AM, tomorrow. Generally, an event will take up time
7
+ # on an individual calendar.
8
+ class Event < Component
9
+ include Dtstart
10
+
11
+ attr_accessor :alarms
12
+
13
+ def initialize()
14
+ super("VEVENT")
15
+
16
+ @alarms = []
17
+ end
18
+
19
+ def to_s
20
+ print_string do |s|
21
+ @alarms.each { |alarm| s << alarm.to_s }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ module Icalendar
2
+ # A Freebusy calendar component is a grouping of
3
+ # component properties that represents either a request for, a reply to
4
+ # a request for free or busy time information or a published set of
5
+ # busy time information.
6
+ class Freebusy < Component
7
+
8
+ def initialize()
9
+ super("VFREEBUSY")
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ module Icalendar
2
+ # A Journal calendar component is a grouping of
3
+ # component properties that represent one or more descriptive text
4
+ # notes associated with a particular calendar date. The "DTSTART"
5
+ # property is used to specify the calendar date that the journal entry
6
+ # is associated with. Generally, it will have a DATE value data type,
7
+ # but it can also be used to specify a DATE-TIME value data type.
8
+ # Examples of a journal entry include a daily record of a legislative
9
+ # body or a journal entry of individual telephone contacts for the day
10
+ # or an ordered list of accomplishments for the day. The Journal
11
+ # calendar component can also be used to associate a document with a
12
+ # calendar date.
13
+ class Journal < Component
14
+
15
+ def initialize()
16
+ super("VJOURNAL")
17
+ end
18
+
19
+ def to_s
20
+ print_string { }
21
+ end
22
+
23
+ end
24
+ end
25
+