rwdschedule 0.99 → 1.00

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/Readme.txt +10 -0
  2. data/code/superant.com.schedule/downloadrwdschedulefiles.rb +19 -13
  3. data/code/superant.com.schedule/loadconfigurationrecord.rb +1 -2
  4. data/code/superant.com.schedule/saveconfigurationrecord.rb +4 -1
  5. data/code/superant.com.schedule/test_cases.rb +46 -0
  6. data/configuration/rwdapplicationidentity.dist +1 -1
  7. data/configuration/rwdschedule.dist +3 -2
  8. data/configuration/rwdtinker.dist +2 -2
  9. data/extras/icalendar/base.rb +17 -0
  10. data/extras/icalendar/calendar.rb +44 -0
  11. data/extras/icalendar/calendar_parser.rb +237 -0
  12. data/extras/icalendar/component.rb +91 -0
  13. data/extras/icalendar/component/alarm.rb +16 -0
  14. data/extras/icalendar/component/event.rb +25 -0
  15. data/extras/icalendar/component/freebusy.rb +12 -0
  16. data/extras/icalendar/component/journal.rb +25 -0
  17. data/extras/icalendar/component/timezone.rb +26 -0
  18. data/extras/icalendar/component/todo.rb +21 -0
  19. data/extras/icalendar/helpers.rb +103 -0
  20. data/extras/icalendar/parameter.rb +25 -0
  21. data/extras/zip/ioextras.rb +114 -0
  22. data/extras/zip/stdrubyext.rb +111 -0
  23. data/extras/zip/tempfile_bugfixed.rb +195 -0
  24. data/extras/zip/zip.rb +1377 -0
  25. data/extras/zip/zipfilesystem.rb +558 -0
  26. data/extras/zip/ziprequire.rb +61 -0
  27. data/gui/00coreguibegin/applicationguitop.rwd +1 -1
  28. data/rwd_files/HowTo_Schedule.txt +4 -0
  29. data/rwd_files/HowTo_Tinker.txt +3 -0
  30. data/schedules/200505may02a.sch +4 -0
  31. data/tests/RubyGauge.rb +179 -0
  32. data/tests/makedist.rb +1 -0
  33. metadata +24 -7
  34. data/schedules/200502february22 test event.sch +0 -5
  35. data/updates/200507july04a.sch +0 -8
data/Readme.txt CHANGED
@@ -154,6 +154,16 @@ Steven Gibson
154
154
  steven@superant.com
155
155
 
156
156
  == Changelog
157
+ Version 1.00
158
+ fixed sync download
159
+ added more unit tests
160
+
161
+ Version 0.99
162
+ updated for rwdtinker version 1.64
163
+ changed handling of application name returned
164
+ added jump seletion options
165
+ added some unit tests
166
+
157
167
  version 0.98
158
168
  updated for rwdtinker version 1.61
159
169
  add in test harness
@@ -9,24 +9,30 @@ def downloadrwdschedulefiles
9
9
  ftp.login($rwdschedule_ftplogin, $rwdschedule_ftppassword)
10
10
  ftp.chdir($rwdschedule_ftpdirectory)
11
11
  print "I'm in the directory ", ftp.pwd(), "\n"
12
- schfiles = ftp.nlst($rwdschedule_ftpdirectory)
13
- schfiles.each do |x|
14
- #adjust the filters to the files you want to see...
15
- if(!test(?d,x))
16
- if x =~ /sch/
17
- lastslash = x.rindex('/')+1
18
- newstring = x.slice!(lastslash..256)
19
- localupdatefile = File.join($rwdschedule_updatedirectory, "#{newstring}")
20
- ftp.getbinaryfile("#{newstring}" , localupdatefile )
12
+ schfiles = ftp.nlst($rwdschedule_ftpdirectory)
13
+ #puts schfiles
14
+ $stderr.print $rwdschedule_updatedirectory
15
+
16
+ schfiles.each {|x|
17
+ #adjust the filters to the files you want to see...
18
+
19
+ if x =~ /sch/
20
+ #lastslash = x.rindex('/')+1
21
+ #newstring = x.slice!(lastslash..256)
22
+ newstring = x
23
+ # $stderr.print newstring.to_s
24
+ localupdatefile = File.join($rwdschedule_updatedirectory, "#{x}")
25
+ ftp.getbinaryfile("#{x}" , localupdatefile )
21
26
  @rwdscheduleftpdisplay = @rwdscheduleftpdisplay + newstring + "\n"
22
- end
23
- end
24
27
 
25
- end
28
+ end
29
+
30
+
31
+ }
26
32
  ftp.close
27
33
 
28
34
  rescue
29
-
35
+ @rwdscheduleftpdisplay = "ftp error"
30
36
  if ftp
31
37
  ftp.close
32
38
  end
@@ -23,8 +23,7 @@
23
23
  @a_schconfigline8 = fd.readline.chomp
24
24
  @a_schconfigline9 = fd.readline.chomp
25
25
  @a_schconfigline10= fd.readline.chomp
26
- @a_schconfigline10= fd.readline.chomp
27
- @a_schconfigline11= fd.readline.chomp
26
+ @a_schconfigline11= fd.readline.chomp
28
27
  @a_schconfigline12= fd.readline.chomp
29
28
  @a_schconfigline13= fd.readline.chomp
30
29
  @a_schconfigline14= fd.readline.chomp
@@ -3,7 +3,10 @@
3
3
  require 'fileutils'
4
4
 
5
5
  newname = "rwdschedule.cnf" # grab the filename to create
6
- newdata =@a_schconfigline1.to_s + "\n" + @a_schconfigline2.to_s + "\n" + @a_schconfigline3.to_s + "\n" + @a_schconfigline4.to_s + "\n" + @a_schconfigline5.to_s + "\n" + @a_schconfigline6.to_s + "\n" + @a_schconfigline7.to_s + "\n" + @a_schconfigline8.to_s + "\n" + @a_schconfigline9.to_s + "\n"
6
+ newdata =@a_schconfigline1.to_s + "\n" + @a_schconfigline2.to_s + "\n" + @a_schconfigline3.to_s + "\n" + @a_schconfigline4.to_s + "\n" + @a_schconfigline5.to_s + "\n" +
7
+ @a_schconfigline6.to_s + "\n" + @a_schconfigline7.to_s + "\n" + @a_schconfigline8.to_s + "\n" + @a_schconfigline9.to_s + "\n"+
8
+ @a_schconfigline10.to_s + "\n" + @a_schconfigline11.to_s + "\n"+ @a_schconfigline12.to_s +
9
+ "\n" + @a_schconfigline13.to_s + "\n"+ @a_schconfigline14.to_s + "\n"+ @a_schconfigline15.to_s + "\n"
7
10
 
8
11
  begin # exception trapped block
9
12
  fileName = File.join( ConfigurationDir, newname )
@@ -0,0 +1,46 @@
1
+ # test harness
2
+
3
+
4
+ require 'test/unit/testcase'
5
+ require 'test/unit/assertions'
6
+ include Test::Unit::Assertions
7
+ include Test::Unit
8
+ def rwdschedule_all_tests
9
+ print "in rwdschedule all tests\n"
10
+ $testrwdscheduletestcase = TestSuite.new
11
+ test_runrwdschedule
12
+ end
13
+
14
+ def test_runrwdschedule
15
+
16
+
17
+ begin
18
+ testasserts = 0
19
+ print "Starting rwdtorrent tests!\n"
20
+ runselectiontab
21
+ assert_equal("selectiontab",@rwd_tab) ; testasserts += 1
22
+ runrwdschedulemenu10
23
+ assert_equal("viewrwdscheduleconfiguration",@rwd_tab) ; testasserts += 1
24
+ loadrwdscheduleconfiguration
25
+ assert_equal("rwdschedule.cnf",@a_schconfigurationfilename) ; testasserts += 1
26
+
27
+ $stderr.print "tests completed succesfully!\n"
28
+ $stderr.print testasserts, " asserts performed\n"
29
+
30
+ rescue NotImplementedError, Exception
31
+ $stderr.print $!
32
+
33
+ end
34
+
35
+ end
36
+
37
+
38
+
39
+ def teststobedown
40
+ runtinkerhelpabout
41
+ assert_equal("rwdtinkerhelpwindow",@rwd_tab) ; testasserts += 1
42
+ end
43
+
44
+
45
+
46
+
@@ -1,3 +1,3 @@
1
1
  ##VERSION:1.63
2
- $rwdapplicationidentity = "rwdschedule calendar application"
2
+ $rwdapplicationidentity = "rwdtinker main application"
3
3
 
@@ -1,4 +1,4 @@
1
- ##VERSION:0.99
1
+ ##VERSION:1.00
2
2
  ##NAME:$rwdschedule_directory:0
3
3
  $rwdschedule_directory = "schedules"
4
4
  ##NAME:$rwdschedule_ftpsite:0
@@ -11,5 +11,6 @@ $rwdschedule_ftppassword = "mypassword"
11
11
  $rwdschedule_ftpdirectory = "/incoming/rwdschedules/"
12
12
  ##NAME:$rwdschedule_updatedirectory:0
13
13
  $rwdschedule_updatedirectory = "updates"
14
- RwdScheduleVersion = "0.99"
14
+ $testharnessarray += ["rwdschedule_all_tests"]
15
+ RwdScheduleVersion = "1.00"
15
16
 
@@ -1,4 +1,4 @@
1
- ##VERSION:1.63
1
+ ##VERSION:1.64
2
2
  ConfigurationDir = "configuration" # for use in program - init.rb has this value without using this constant
3
3
  CodeName = "rwdtinker"
4
4
  CodeNameFile = CodeName + ".rb"
@@ -12,4 +12,4 @@ LangDir = "lang"
12
12
  $rwdcontrolports =["13713","13714","13715","13716","13717","13718"]
13
13
  $port = 7705
14
14
  $rwdjumplink = ["helpscreen","tinkerbackwindow","returntomain","opendocuments","editconfiguration"]
15
- RwdTinkerVersion = "1.63"
15
+ RwdTinkerVersion = "1.64"
@@ -0,0 +1,17 @@
1
+ require 'logger'
2
+
3
+ module Icalendar #:nodoc:
4
+ class IcalendarError < StandardError #:nodoc:
5
+ end
6
+
7
+ class InvalidComponentClass < IcalendarError
8
+ end
9
+
10
+ class InvalidPropertyValue < IcalendarError
11
+ end
12
+
13
+ class Base
14
+ @@logger = Logger.new(STDOUT)
15
+ @@logger.level = Logger::INFO
16
+ end
17
+ end
@@ -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