rwdaddresses 1.01 → 1.02

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/Readme.txt +5 -0
  2. data/code/01rwdcore/01rwdcore.rb +15 -13
  3. data/code/01rwdcore/openhelpwindow.rb +26 -26
  4. data/code/01rwdcore/returntomain.rb +8 -8
  5. data/code/01rwdcore/rwdtinkerversion.rb +12 -13
  6. data/code/01rwdcore/rwdwindowreturn.rb +3 -5
  7. data/code/01rwdcore/test_cases.rb +115 -0
  8. data/code/01rwdcore/test_harness.rb +12 -0
  9. data/code/01rwdcore/uploadreturns.rb +60 -59
  10. data/code/superant.com.rwdaddresses/attachtmpcontactphoto.rb +23 -23
  11. data/code/superant.com.rwdaddresses/clearscreendisplay.rb +14 -15
  12. data/code/superant.com.rwdaddresses/createnewnamerecord.rb +19 -18
  13. data/code/superant.com.rwdaddresses/deletecontactrecord.rb +22 -21
  14. data/code/superant.com.rwdaddresses/deleterwdaddressesupdatefiles.rb +15 -16
  15. data/code/superant.com.rwdaddresses/downloadrwdaddressfiles.rb +34 -32
  16. data/code/superant.com.rwdaddresses/listnamerecord.rb +14 -14
  17. data/code/superant.com.rwdaddresses/listvcardrecord.rb +15 -0
  18. data/code/superant.com.rwdaddresses/loadconfigurationrecord.rb +45 -44
  19. data/code/superant.com.rwdaddresses/loadconfigurationvariables.rb +14 -13
  20. data/code/superant.com.rwdaddresses/loadnamerecord.rb +29 -29
  21. data/code/superant.com.rwdaddresses/openhelpwindowrwdaddresses.rb +25 -25
  22. data/code/superant.com.rwdaddresses/renamecontact.rb +14 -15
  23. data/code/superant.com.rwdaddresses/returntomain.rb +8 -8
  24. data/code/superant.com.rwdaddresses/runaddresseswindow.rb +8 -8
  25. data/code/superant.com.rwdaddresses/runrwdaddressesmenu1.rb +31 -31
  26. data/code/superant.com.rwdaddresses/runrwdaddresssyncbackwindow.rb +8 -8
  27. data/code/superant.com.rwdaddresses/rwdaddressesbackwindow.rb +8 -8
  28. data/code/superant.com.rwdaddresses/rwdaddresseshelpabout.rb +10 -11
  29. data/code/superant.com.rwdaddresses/saveconfigurationrecord.rb +20 -20
  30. data/code/superant.com.rwdaddresses/savevcardrecord.rb +76 -0
  31. data/code/superant.com.rwdaddresses/syncrwdaddress.rb +24 -26
  32. data/code/superant.com.rwdaddresses/uploadrwdaddressfiles.rb +28 -28
  33. data/code/superant.com.rwdaddresses/viewaddressconfiguration.rb +21 -21
  34. data/code/superant.com.rwdaddresses/viewnamedata.rb +27 -26
  35. data/code/superant.com.rwdaddresses/viewphoto.rb +4 -4
  36. data/code/superant.com.rwdaddresses/viewrwdaddressesconfiguration.rb +23 -21
  37. data/code/superant.com.rwdaddresses/viewtmpcontactphoto.rb +6 -6
  38. data/code/superant.com.rwdaddresses/viewvcarddata.rb +22 -0
  39. data/code/superant.com.rwdtinkerbackwindow/controlclient.rb +89 -92
  40. data/code/superant.com.rwdtinkerbackwindow/diagnostictab.rb +15 -20
  41. data/code/superant.com.rwdtinkerbackwindow/installapplet.rb +19 -18
  42. data/code/superant.com.rwdtinkerbackwindow/installgemapplet.rb +20 -19
  43. data/code/superant.com.rwdtinkerbackwindow/installremotegem.rb +19 -18
  44. data/code/superant.com.rwdtinkerbackwindow/listgemdirs.rb +7 -7
  45. data/code/superant.com.rwdtinkerbackwindow/listgemzips.rb +48 -49
  46. data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +8 -7
  47. data/code/superant.com.rwdtinkerbackwindow/listzips.rb +22 -26
  48. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +32 -31
  49. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationvariables.rb +14 -13
  50. data/code/superant.com.rwdtinkerbackwindow/network.rb +82 -82
  51. data/code/superant.com.rwdtinkerbackwindow/openappletname.rb +18 -17
  52. data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +37 -37
  53. data/code/superant.com.rwdtinkerbackwindow/remotegemlist.rb +20 -20
  54. data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +33 -32
  55. data/code/superant.com.rwdtinkerbackwindow/runrwdtinkerbackwindow.rb +8 -9
  56. data/code/superant.com.rwdtinkerbackwindow/rwdtinkerwin2version.rb +10 -11
  57. data/code/superant.com.rwdtinkerbackwindow/saveconfigurationrecord.rb +19 -18
  58. data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +21 -20
  59. data/code/superant.com.rwdtinkerbackwindow/viewgemappletcontents.rb +23 -20
  60. data/configuration/language.dist +1 -1
  61. data/configuration/rwdaddresses.dist +2 -2
  62. data/configuration/rwdtinker.dist +2 -2
  63. data/configuration/tinkerwin2variables.dist +1 -1
  64. data/extras/vpim/date.rb +198 -0
  65. data/extras/vpim/dirinfo.rb +229 -0
  66. data/extras/vpim/enumerator.rb +29 -0
  67. data/extras/vpim/field.rb +497 -0
  68. data/extras/vpim/maker/vcard.rb +312 -0
  69. data/extras/vpim/rfc2425.rb +244 -0
  70. data/extras/vpim/rrule.rb +482 -0
  71. data/extras/vpim/time.rb +42 -0
  72. data/extras/vpim/vcard.rb +151 -0
  73. data/extras/vpim/vpim.rb +94 -0
  74. data/gui/frontwindow0/superant.com.rwdaddresses/16editrecord.rwd +5 -0
  75. data/gui/frontwindow0/superant.com.rwdaddresses/17viewvcardrecord.rwd +32 -0
  76. data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/3copyright.rwd +1 -1
  77. data/gui/tinkerbackwindows/superant.com.rwdaddressessyncbackwindow/70rwddiagnostics.rwd +1 -11
  78. data/init.rb +231 -228
  79. data/names/Angelina Jolie.vcf +8 -0
  80. data/rwd_files/HowTo_Addresses.txt +5 -0
  81. data/rwd_files/HowTo_Tinker.txt +14 -0
  82. data/rwdconfig.dist +6 -2
  83. data/tests/makedist.rb +36 -7
  84. metadata +23 -21
  85. data/extras/cmdline_parse +0 -47
  86. data/extras/config_file +0 -69
  87. data/extras/errorMsg +0 -19
  88. data/extras/makePlaylist +0 -34
  89. data/extras/mp3controld +0 -289
  90. data/extras/playlist +0 -186
  91. data/extras/plugins/Network +0 -237
  92. data/extras/showHelp +0 -18
  93. data/gui/frontwindowselections/superant.com.rwdaddressesselectiontab/rwdaddressessyncselectiontab.rwd +0 -12
  94. data/gui/helpaboutinstalled/superant.com.rwdwin2helpabout/1appname.rwd +0 -4
  95. data/gui/helpaboutinstalled/superant.com.rwdwin2helpabout/3copyright.rwd +0 -3
  96. data/gui/helpaboutinstalled/superant.com.rwdwin2helpabout/5version.rwd +0 -10
  97. data/installed/rwdaddressesdata2.inf +0 -8
  98. data/rwd_files/tinker.png +0 -0
@@ -0,0 +1,497 @@
1
+ =begin
2
+ $Id: field.rb,v 1.11 2005/01/07 03:32:16 sam Exp $
3
+
4
+ Copyright (C) 2005 Sam Roberts
5
+
6
+ This library is free software; you can redistribute it and/or modify it
7
+ under the same terms as the ruby language itself, see the file COPYING for
8
+ details.
9
+ =end
10
+
11
+ require 'extras/vpim/rfc2425'
12
+ require 'extras/vpim/vpim'
13
+ require 'date'
14
+
15
+ module Vpim
16
+
17
+ class DirectoryInfo
18
+
19
+ # A field in a directory info object.
20
+ class Field
21
+ private_class_method :new
22
+
23
+ # Encode a field.
24
+ def Field.encode0(group, name, params={}, value='') # :nodoc:
25
+ line = ""
26
+
27
+ # A reminder of the line format:
28
+ # [<group>.]<name>;<pname>=<pvalue>,<pvalue>:<value>
29
+
30
+ if group
31
+ line << group << '.'
32
+ end
33
+
34
+ line << name
35
+
36
+ params.each do |pname, pvalues|
37
+
38
+ unless pvalues.respond_to? :to_ary
39
+ pvalues = [ pvalues ]
40
+ end
41
+
42
+ line << ';' << pname << '='
43
+
44
+ sep = "" # set to ',' after one pvalue has been appended
45
+
46
+ pvalues.each do |pvalue|
47
+ # check if we need to do any encoding
48
+ if pname.downcase == 'encoding' && pvalue == :b64
49
+ pvalue = 'b' # the RFC definition of the base64 param value
50
+ value = [ value.to_str ].pack('m').gsub("\n", '')
51
+ end
52
+
53
+ line << sep << pvalue
54
+ sep =",";
55
+ end
56
+ end
57
+
58
+ line << ':'
59
+
60
+ # Should I set the 'VALUE' param?
61
+ case value
62
+ when Date
63
+ line << Vpim.encode_date(value)
64
+
65
+ when Time #, DateTime
66
+ line << Vpim.encode_date_time(value)
67
+
68
+ when Array
69
+ line << value.join(';')
70
+
71
+ else
72
+ line << value
73
+ end
74
+ line
75
+ end
76
+
77
+ # Decode a field.
78
+ def Field.decode0(atline) # :nodoc:
79
+ unless atline =~ %r{#{Bnf::LINE}}i
80
+ raise Vpim::InvalidEncodingError, atline
81
+ end
82
+
83
+ atgroup = $1
84
+ atname = $2
85
+ paramslist = $3
86
+ atvalue = $4
87
+
88
+ if atgroup.length > 0
89
+ atgroup.chomp!('.')
90
+ else
91
+ atgroup = nil
92
+ end
93
+
94
+ atparams = {}
95
+
96
+ # Collect the params, if any.
97
+ if paramslist.size > 1
98
+
99
+ #p paramslist
100
+
101
+ # v3.0 and v2.1 params
102
+ paramslist.scan( %r{#{Bnf::PARAM}}i ) do
103
+
104
+ # param names are case-insensitive, and multi-valued
105
+ name = $1.downcase
106
+ params = $3
107
+
108
+ # puts "#2 is #{$2.inspect}"
109
+
110
+ # v2.1 params have no '=' sign, figure out what kind of param it
111
+ # is (either its a known encoding, or we treat it as a 'type'
112
+ # param).
113
+
114
+ if $2 == ""
115
+ params = $1
116
+ case $1
117
+ when /quoted-printable/i
118
+ name = 'encoding'
119
+
120
+ when /base64/i
121
+ name = 'encoding'
122
+
123
+ else
124
+ name = 'type'
125
+ end
126
+ end
127
+
128
+ unless atparams.key? name
129
+ atparams[name] = []
130
+ end
131
+
132
+ params.scan( %r{(#{Bnf::PVALUE})} ) do
133
+ if $1.size > 0
134
+ atparams[name] << $1.downcase
135
+ end
136
+ end
137
+
138
+ #p atparams['type']
139
+ end
140
+ end
141
+
142
+ [ atgroup, atname, atparams, atvalue ]
143
+ end
144
+
145
+ def initialize(line) # :nodoc:
146
+ @line = line.to_str
147
+ @group, @name, @params, @value = Field.decode0(@line)
148
+ self
149
+ end
150
+
151
+ # Create a field by decoding +line+, a String which must already be
152
+ # unfolded. Decoded fields are frozen, but see #copy().
153
+ def Field.decode(line)
154
+ new(line).freeze
155
+ end
156
+
157
+ # Create a field with name +name+ (a String), value +value+ (see below),
158
+ # and optional parameters, +params+. +params+ is a hash of the parameter
159
+ # name (a String) to either a single string or symbol, or an array of
160
+ # strings and symbols (parameters can be multi-valued).
161
+ #
162
+ # If 'encoding' => :b64 is specified as a parameter, the value will be
163
+ # base-64 encoded. If it's already base-64 encoded, then use String
164
+ # values ('encoding' => 'b'), and no further encoding will be done by
165
+ # this routine.
166
+ #
167
+ # Currently handled value types are:
168
+ # - Time, encoded as a date-time value
169
+ # - Date, encoded as a date value
170
+ # - String, encoded directly
171
+ # - Array of String, concatentated with ';' between them.
172
+ #
173
+ # TODO - need a way to encode String values as TEXT, at least optionally,
174
+ # so as to escape special chars, etc.
175
+ def Field.create(name, value="", params={})
176
+ line = Field.encode0(nil, name, params, value)
177
+
178
+ begin
179
+ new(line)
180
+ rescue Vpim::InvalidEncodingError => e
181
+ raise ArgumentError, e.to_s
182
+ end
183
+ end
184
+
185
+ # Create a copy of Field. If the original Field was frozen, this one
186
+ # won't be.
187
+ def copy
188
+ Marshal.load(Marshal.dump(self))
189
+ end
190
+
191
+ # The String encoding of the Field. The String will be wrapped to a
192
+ # maximum line width of +width+, where +0+ means no wrapping, and nil is
193
+ # to accept the default wrapping (75, recommended by RFC2425).
194
+ #
195
+ # Note: Apple's Address Book 3.0.3 neither understands to unwrap lines
196
+ # when it imports vCards (it treats them as raw new-line characters), nor
197
+ # wraps long lines on export. On import, this is mostly a cosmetic
198
+ # problem, but wrapping can be disabled by setting width to +0+, if
199
+ # desired. On export, its a more serious bug, since Address Book wil
200
+ # encode the entire Note: section as a single, very long, line.
201
+ def encode(width=nil)
202
+ width = 75 unless width
203
+ l = @line
204
+ # Wrap to width, unless width is zero.
205
+ if width > 0
206
+ l = l.gsub(/.{#{width},#{width}}/) { |m| m + "\n " }
207
+ end
208
+ # Make sure it's terminated with no more than a single NL.
209
+ l.gsub(/\s*\z/, '') + "\n"
210
+ end
211
+
212
+ alias to_s encode
213
+
214
+ # The name.
215
+ def name
216
+ @name
217
+ end
218
+
219
+ # The group, if present, or nil if not present.
220
+ def group
221
+ @group
222
+ end
223
+
224
+ # An Array of all the param names.
225
+ def params
226
+ @params.keys
227
+ end
228
+
229
+ # The Array of all values of the param +name+, or nil if there is no
230
+ # such param.
231
+ #
232
+ # TODO - this doesn't return [] if the param isn't found, because then
233
+ # you can't distinguish between a param with no values, and a param that
234
+ # isn't defined. But maybe it isn't useful? You can always do
235
+ # params.include?(a_name) if you want to know if it exists. Maybe this
236
+ # should take a block specifying the default value, even?
237
+ def param(name)
238
+ v = @params[name.downcase]
239
+ if v
240
+ v = v.collect do |p|
241
+ p.downcase.freeze
242
+ end
243
+ v.freeze
244
+ end
245
+ v
246
+ end
247
+
248
+ alias [] param
249
+
250
+ # Yield once for each param, +name+ is the parameter name, +value+ is an
251
+ # array of the parameter values.
252
+ def each_param(&block) #:yield: name, value
253
+ if @params
254
+ @params.each(&block)
255
+ end
256
+ end
257
+
258
+ # The decoded value.
259
+ #
260
+ # The encoding specified by the #encoding, if any, is stripped.
261
+ #
262
+ # Note: Both the RFC 2425 encoding param ("b", meaning base-64) and the
263
+ # vCard 2.1 encoding params ("base64", "quoted-printable", "8bit", and
264
+ # "7bit") are supported.
265
+ def value
266
+ case encoding
267
+ when nil, '8bit', '7bit' then @value
268
+
269
+ # Hack - if the base64 lines started with 2 SPC chars, which is invalid,
270
+ # there will be extra spaces in @value. Since no SPC chars show up in
271
+ # b64 encodings, they can be safely stripped out before unpacking.
272
+ when 'b', 'base64' then @value.gsub(' ', '').unpack('m*').first
273
+
274
+ when 'quoted-printable' then @value.unpack('M*').first
275
+
276
+ else raise Vpim::InvalidEncodingError, "unrecognized encoding (#{encoding})"
277
+ end
278
+ end
279
+
280
+ # Is the #name of this Field +name+? Names are case insensitive.
281
+ def name?(name)
282
+ name.to_s.downcase == @name.downcase
283
+ end
284
+
285
+ # Is the #group of this field +group+? Group names are case insensitive.
286
+ # A +group+ of nil matches if the field has no group.
287
+ def group?(group)
288
+ g1 = @group ? @group.downcase : nil
289
+ g2 = group ? group.downcase : nil
290
+ g1 == g2
291
+ end
292
+
293
+ # Is the value of this field of type +kind+? RFC2425 allows the type of
294
+ # a fields value to be encoded in the VALUE parameter. Don't rely on its
295
+ # presence, they aren't required, and usually aren't bothered with. In
296
+ # cases where the kind of value might vary (an iCalendar DTSTART can be
297
+ # either a date or a date-time, for example), you are more likely to see
298
+ # the kind of value specified explicitly.
299
+ #
300
+ # The value types defined by RFC 2425 are:
301
+ # - uri:
302
+ # - text:
303
+ # - date: a list of 1 or more dates
304
+ # - time: a list of 1 or more times
305
+ # - date-time: a list of 1 or more date-times
306
+ # - integer:
307
+ # - boolean:
308
+ # - float:
309
+ def kind?(kind)
310
+ kind.downcase == self.kind
311
+ end
312
+
313
+ # Is one of the values of the TYPE parameter of this field +type+? The
314
+ # type parameter values are case insensitive. False if there is no TYPE
315
+ # parameter.
316
+ #
317
+ # TYPE parameters are used for general categories, such as
318
+ # distinguishing between an email address used at home or at work.
319
+ def type?(type)
320
+ types = param('type')
321
+
322
+ if types
323
+ types = types.include?(type.to_str.downcase)
324
+ end
325
+ end
326
+
327
+ # Is this field marked as preferred? A vCard field is preferred if
328
+ # #type?('pref'). This method is not necessarily meaningful for
329
+ # non-vCard profiles.
330
+ def pref?
331
+ type?('pref')
332
+ end
333
+
334
+ # Is the value of this field +value+? The check is case insensitive.
335
+ def value?(value)
336
+ @value && @value.downcase == value.downcase
337
+ end
338
+
339
+ # The value of the ENCODING parameter, if present, or nil if not
340
+ # present.
341
+ def encoding
342
+ e = param("encoding")
343
+
344
+ if e
345
+ if e.length > 1
346
+ raise Vpim::InvalidEncodingError, "multi-valued param 'encoding' (#{e})"
347
+ end
348
+ e = e.first
349
+ end
350
+ e
351
+ end
352
+
353
+ # The type of the value, as specified by the VALUE parameter, nil if
354
+ # unspecified.
355
+ def kind
356
+ v = param('value')
357
+ if v
358
+ if v.size > 1
359
+ raise InvalidEncodingError, "multi-valued param 'value' (#{values})"
360
+ end
361
+ v = v.first
362
+ end
363
+ v
364
+ end
365
+
366
+ # The value as an array of Time objects (all times and dates in
367
+ # RFC2425 are lists, even where it might not make sense, such as a
368
+ # birthday). The time will be UTC if marked as so (with a timezone of
369
+ # "Z"), and in localtime otherwise.
370
+ #
371
+ # TODO: support timezone offsets
372
+ #
373
+ # TODO - if year is before 1970, this won't work... but some people
374
+ # are generating calendars saying Canada Day started in 1753!
375
+ # That's just wrong! So, what to do? I add a message
376
+ # saying what the year is that breaks, so they at least know that
377
+ # its ridiculous! I think I need my own DateTime variant.
378
+ def to_time
379
+ begin
380
+ Vpim.decode_date_time_list(value).collect do |d|
381
+ # We get [ year, month, day, hour, min, sec, usec, tz ]
382
+ begin
383
+ if(d.pop == "Z")
384
+ Time.gm(*d)
385
+ else
386
+ Time.local(*d)
387
+ end
388
+ rescue ArgumentError => e
389
+ raise Vpim::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}"
390
+ end
391
+ end
392
+ rescue Vpim::InvalidEncodingError
393
+ Vpim.decode_date_list(value).collect do |d|
394
+ # We get [ year, month, day ]
395
+ begin
396
+ Time.gm(*d)
397
+ rescue ArgumentError => e
398
+ raise Vpim::InvalidEncodingError, "Time.gm(#{d.join(', ')}) failed with #{e.message}"
399
+ end
400
+ end
401
+ end
402
+ end
403
+
404
+ # The value as an array of Date objects (all times and dates in
405
+ # RFC2425 are lists, even where it might not make sense, such as a
406
+ # birthday).
407
+ #
408
+ # The field value may be a list of either DATE or DATE-TIME values,
409
+ # decoding is tried first as a DATE-TIME, then as a DATE, if neither
410
+ # works an InvalidEncodingError will be raised.
411
+ def to_date
412
+ begin
413
+ Vpim.decode_date_time_list(value).collect do |d|
414
+ # We get [ year, month, day, hour, min, sec, usec, tz ]
415
+ Date.new(d[0], d[1], d[2])
416
+ end
417
+ rescue Vpim::InvalidEncodingError
418
+ Vpim.decode_date_list(value).collect do |d|
419
+ # We get [ year, month, day ]
420
+ Date.new(*d)
421
+ end
422
+ end
423
+ end
424
+
425
+ # The value as text. Text can have escaped newlines, commas, and escape
426
+ # characters, this method will strip them, if present.
427
+ #
428
+ # In theory, #value could also do this, but it would need to know that
429
+ # the value is of type 'text', and often for text values the 'type'
430
+ # parameter is not present, so knowledge of the expected type of the
431
+ # field is required from the decoder.
432
+ def to_text
433
+ Vpim.decode_text(value)
434
+ end
435
+
436
+ # The undecoded value, see +value+.
437
+ def value_raw
438
+ @value
439
+ end
440
+
441
+ def inspect # :nodoc:
442
+ @line
443
+ end
444
+
445
+ # TODO def pretty_print() ...
446
+
447
+ # Set the group of this field to +group+.
448
+ def group=(group)
449
+ mutate(group, @name, @params, @value)
450
+ group
451
+ end
452
+
453
+ # Set the value of this field to +value+. Valid values are as in
454
+ # Field.create().
455
+ def value=(value)
456
+ mutate(@group, @name, @params, value)
457
+ value
458
+ end
459
+
460
+ # Convert +value+ to text, then assign.
461
+ #
462
+ # TODO - unimplemented
463
+ def text=(text)
464
+ end
465
+
466
+ # Set a the param +param+'s value to +pvalue+. Valid values are as in
467
+ # Field.create().
468
+ def []=(param,pvalue)
469
+ unless pvalue.respond_to?(:to_ary)
470
+ pvalue = [ pvalue ]
471
+ end
472
+
473
+ h = @params.dup
474
+
475
+ h[param.downcase] = pvalue
476
+
477
+ mutate(@group, @name, h, @value)
478
+ pvalue
479
+ end
480
+
481
+ def mutate(g, n, p, v) #:nodoc:
482
+ line = Field.encode0(g, n, p, v)
483
+
484
+ begin
485
+ @group, @name, @params, @value = Field.decode0(line)
486
+ @line = line
487
+ rescue Vpim::InvalidEncodingError => e
488
+ raise ArgumentError, e.to_s
489
+ end
490
+ self
491
+ end
492
+
493
+ private :mutate
494
+ end
495
+ end
496
+ end
497
+