vcard 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/vcard.rb +26 -47
- data/lib/vcard/bnf.rb +5 -2
- data/lib/vcard/version.rb +1 -1
- data/test/test_helper.rb +6 -6
- metadata +2 -8
data/lib/vcard.rb
CHANGED
@@ -30,9 +30,9 @@ module Vcard
|
|
30
30
|
line.chomp!
|
31
31
|
# If it's a continuation line, add it to the last.
|
32
32
|
# If it's an empty line, drop it from the input.
|
33
|
-
if
|
33
|
+
if line =~ /^[ \t]/
|
34
34
|
unfolded[-1] << line[1, line.size-1]
|
35
|
-
elsif
|
35
|
+
elsif line =~ /^$/
|
36
36
|
else
|
37
37
|
unfolded << line
|
38
38
|
end
|
@@ -49,14 +49,13 @@ module Vcard
|
|
49
49
|
item.chomp!(sep)
|
50
50
|
list << yield(item)
|
51
51
|
end
|
52
|
+
|
52
53
|
list
|
53
54
|
end
|
54
55
|
|
55
56
|
# Convert a RFC 2425 date into an array of [year, month, day].
|
56
57
|
def self.decode_date(v) # :nodoc:
|
57
|
-
|
58
|
-
raise ::Vcard::InvalidEncodingError, "date not valid (#{v})"
|
59
|
-
end
|
58
|
+
raise ::Vcard::InvalidEncodingError, "date not valid (#{v})" unless v =~ Bnf::DATE
|
60
59
|
[$1.to_i, $2.to_i, $3.to_i]
|
61
60
|
end
|
62
61
|
|
@@ -70,31 +69,29 @@ module Vcard
|
|
70
69
|
|
71
70
|
# Encode a Date object as "yyyymmdd".
|
72
71
|
def self.encode_date(d) # :nodoc:
|
73
|
-
"%0.4d%0.2d%0.2d" % [
|
72
|
+
"%0.4d%0.2d%0.2d" % [d.year, d.mon, d.day]
|
74
73
|
end
|
75
74
|
|
76
75
|
# Encode a Date object as "yyyymmdd".
|
77
76
|
def self.encode_time(d) # :nodoc:
|
78
|
-
"%0.4d%0.2d%0.2d" % [
|
77
|
+
"%0.4d%0.2d%0.2d" % [d.year, d.mon, d.day]
|
79
78
|
end
|
80
79
|
|
81
80
|
# Encode a Time or DateTime object as "yyyymmddThhmmss"
|
82
81
|
def self.encode_date_time(d) # :nodoc:
|
83
|
-
"%0.4d%0.2d%0.2dT%0.2d%0.2d%0.2d" % [
|
82
|
+
"%0.4d%0.2d%0.2dT%0.2d%0.2d%0.2d" % [d.year, d.mon, d.day, d.hour, d.min, d.sec]
|
84
83
|
end
|
85
84
|
|
86
85
|
# Convert a RFC 2425 time into an array of [hour,min,sec,secfrac,timezone]
|
87
86
|
def self.decode_time(v) # :nodoc:
|
88
|
-
|
89
|
-
raise ::Vcard::InvalidEncodingError, "time '#{v}' not valid"
|
90
|
-
end
|
87
|
+
raise ::Vcard::InvalidEncodingError, "time '#{v}' not valid" unless match = Bnf::TIME.match(v)
|
91
88
|
hour, min, sec, secfrac, tz = match.to_a[1..5]
|
92
89
|
|
93
90
|
[hour.to_i, min.to_i, sec.to_i, secfrac ? secfrac.to_f : 0, tz]
|
94
91
|
end
|
95
92
|
|
96
93
|
def self.array_datetime_to_time(dtarray) #:nodoc:
|
97
|
-
# We get [
|
94
|
+
# We get [year, month, day, hour, min, sec, usec, tz]
|
98
95
|
tz = (dtarray.pop == "Z") ? :gm : :local
|
99
96
|
Time.send(tz, *dtarray)
|
100
97
|
rescue ArgumentError => e
|
@@ -108,9 +105,7 @@ module Vcard
|
|
108
105
|
|
109
106
|
# Convert a RFC 2425 date-time into an array of [year,mon,day,hour,min,sec,secfrac,timezone]
|
110
107
|
def self.decode_date_time(v) # :nodoc:
|
111
|
-
|
112
|
-
raise ::Vcard::InvalidEncodingError, "date-time '#{v}' not valid"
|
113
|
-
end
|
108
|
+
raise ::Vcard::InvalidEncodingError, "date-time '#{v}' not valid" unless match = Bnf::DATE_TIME.match(v)
|
114
109
|
year, month, day, hour, min, sec, secfrac, tz = match.to_a[1..8]
|
115
110
|
|
116
111
|
[
|
@@ -135,9 +130,7 @@ module Vcard
|
|
135
130
|
|
136
131
|
# Convert an RFC2425 INTEGER value into an Integer
|
137
132
|
def self.decode_integer(v) # :nodoc:
|
138
|
-
|
139
|
-
raise ::Vcard::InvalidEncodingError, "integer not valid (#{v})"
|
140
|
-
end
|
133
|
+
raise ::Vcard::InvalidEncodingError, "integer not valid (#{v})" unless v =~ Bnf::INTEGER
|
141
134
|
v.to_i
|
142
135
|
end
|
143
136
|
|
@@ -148,9 +141,7 @@ module Vcard
|
|
148
141
|
def self.decode_date_list(v) # :nodoc:
|
149
142
|
decode_list(v) do |date|
|
150
143
|
date.strip!
|
151
|
-
if date.length > 0
|
152
|
-
decode_date(date)
|
153
|
-
end
|
144
|
+
decode_date(date) if date.length > 0
|
154
145
|
end.compact
|
155
146
|
end
|
156
147
|
|
@@ -158,9 +149,7 @@ module Vcard
|
|
158
149
|
def self.decode_time_list(v) # :nodoc:
|
159
150
|
decode_list(v) do |time|
|
160
151
|
time.strip!
|
161
|
-
if time.length > 0
|
162
|
-
decode_time(time)
|
163
|
-
end
|
152
|
+
decode_time(time) if time.length > 0
|
164
153
|
end.compact
|
165
154
|
end
|
166
155
|
|
@@ -168,9 +157,7 @@ module Vcard
|
|
168
157
|
def self.decode_date_time_list(v) # :nodoc:
|
169
158
|
decode_list(v) do |datetime|
|
170
159
|
datetime.strip!
|
171
|
-
if datetime.length > 0
|
172
|
-
decode_date_time(datetime)
|
173
|
-
end
|
160
|
+
decode_date_time(datetime) if datetime.length > 0
|
174
161
|
end.compact
|
175
162
|
end
|
176
163
|
|
@@ -197,27 +184,21 @@ module Vcard
|
|
197
184
|
end
|
198
185
|
|
199
186
|
def self.encode_text(v) #:nodoc:
|
200
|
-
v.to_str.gsub(/([\\,;\n])/) { $1 == "\n" ? "\\n" : "
|
187
|
+
v.to_str.gsub(/([\\,;\n])/) { $1 == "\n" ? "\\n" : "\\#{$1}" }
|
201
188
|
end
|
202
189
|
|
203
190
|
# v is an Array of String, or just a single String
|
204
191
|
def self.encode_text_list(v, sep = ",") #:nodoc:
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
encode_text(v)
|
209
|
-
end
|
192
|
+
v.to_ary.map { |t| encode_text(t) }.join(sep)
|
193
|
+
rescue
|
194
|
+
encode_text(v)
|
210
195
|
end
|
211
196
|
|
212
197
|
# Convert a +sep+-seperated list of TEXT values into an array of values.
|
213
198
|
def self.decode_text_list(value, sep = ",") # :nodoc:
|
214
199
|
# Need to do in two stages, as best I can find.
|
215
|
-
list = value.scan(/([^#{sep}\\]*(?:\\.[^#{sep}\\]*)*)#{sep}/).map
|
216
|
-
|
217
|
-
end
|
218
|
-
if value.match(/([^#{sep}\\]*(?:\\.[^#{sep}\\]*)*)$/)
|
219
|
-
list << $1
|
220
|
-
end
|
200
|
+
list = value.scan(/([^#{sep}\\]*(?:\\.[^#{sep}\\]*)*)#{sep}/).map { |v| decode_text(v.first) }
|
201
|
+
list << $1 if value.match(/([^#{sep}\\]*(?:\\.[^#{sep}\\]*)*)$/)
|
221
202
|
list
|
222
203
|
end
|
223
204
|
|
@@ -236,7 +217,7 @@ module Vcard
|
|
236
217
|
if value =~ Bnf::ALL_SAFECHARS
|
237
218
|
value
|
238
219
|
elsif value =~ Bnf::ALL_QSAFECHARS
|
239
|
-
|
220
|
+
%Q{"#{value}"}
|
240
221
|
else
|
241
222
|
raise ::Vcard::Unencodable, "param-value #{value.inspect}"
|
242
223
|
end
|
@@ -245,7 +226,7 @@ module Vcard
|
|
245
226
|
# Unfold the lines in +card+, then return an array of one Field object per
|
246
227
|
# line.
|
247
228
|
def self.decode(card) #:nodoc:
|
248
|
-
unfold(card).
|
229
|
+
unfold(card).map { |line| DirectoryInfo::Field.decode(line) }
|
249
230
|
end
|
250
231
|
|
251
232
|
|
@@ -259,15 +240,14 @@ module Vcard
|
|
259
240
|
dst = []
|
260
241
|
# stack used to track our nesting level, as we see begin/end we start a
|
261
242
|
# new/finish the current entity, and push/pop that entity from the stack
|
262
|
-
current = [
|
243
|
+
current = [dst]
|
263
244
|
|
264
245
|
for f in src
|
265
246
|
if f.name? "BEGIN"
|
266
|
-
e = [
|
247
|
+
e = [f]
|
267
248
|
|
268
249
|
current.last.push(e)
|
269
250
|
current.push(e)
|
270
|
-
|
271
251
|
elsif f.name? "END"
|
272
252
|
current.last.push(f)
|
273
253
|
|
@@ -276,7 +256,6 @@ module Vcard
|
|
276
256
|
end
|
277
257
|
|
278
258
|
current.pop
|
279
|
-
|
280
259
|
else
|
281
260
|
current.last.push(f)
|
282
261
|
end
|
@@ -296,8 +275,8 @@ module Vcard
|
|
296
275
|
inner = []
|
297
276
|
fields.each do |line|
|
298
277
|
case line
|
299
|
-
when Array
|
300
|
-
else
|
278
|
+
when Array then inner << line
|
279
|
+
else outer << line
|
301
280
|
end
|
302
281
|
end
|
303
282
|
return outer, inner
|
data/lib/vcard/bnf.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: ascii
|
1
2
|
# Copyright (C) 2008 Sam Roberts
|
2
3
|
|
3
4
|
# This library is free software; you can redistribute it and/or modify
|
@@ -59,12 +60,14 @@ module Vcard
|
|
59
60
|
|
60
61
|
# QSAFE-CHAR = WSP / %x21 / %x23-7E / NON-US-ASCII
|
61
62
|
# ; Any character except CTLs and DQUOTE
|
62
|
-
|
63
|
+
# set ascii encoding so that multibyte chars can be properly escaped
|
64
|
+
QSAFECHAR = Regexp.new("[ \t\x21\x23-\x7e\x80-\xff]")
|
63
65
|
ALL_QSAFECHARS = /\A#{QSAFECHAR}*\z/
|
64
66
|
|
65
67
|
# SAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E / NON-US-ASCII
|
66
68
|
# ; Any character except CTLs, DQUOTE, ";", ":", ","
|
67
|
-
|
69
|
+
# escape character classes then create new Regexp
|
70
|
+
SAFECHAR = Regexp.new(Regexp.escape("[ \t\x21\x23-\x2b\x2d-\x39\x3c-\x7e\x80-\xff]"))
|
68
71
|
ALL_SAFECHARS = /\A#{SAFECHAR}*\z/
|
69
72
|
end
|
70
73
|
end
|
data/lib/vcard/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -7,25 +7,25 @@ class Test::Unit::TestCase
|
|
7
7
|
# Test equivalence where whitespace is compressed.
|
8
8
|
|
9
9
|
def assert_equal_nospace(expected, got)
|
10
|
-
expected = expected.gsub(/\s+/,
|
11
|
-
got = expected.gsub(/\s+/,
|
10
|
+
expected = expected.gsub(/\s+/, "")
|
11
|
+
got = expected.gsub(/\s+/, "")
|
12
12
|
assert_equal(expected, got)
|
13
13
|
end
|
14
14
|
|
15
15
|
def utf_name_test(c)
|
16
16
|
card = Vcard::Vcard.decode(c).first
|
17
17
|
assert_equal("name", card.name.family)
|
18
|
-
rescue
|
19
|
-
|
18
|
+
rescue => exception
|
19
|
+
exception.message << " #{c.inspect}"
|
20
20
|
raise
|
21
21
|
end
|
22
22
|
|
23
23
|
def be(s)
|
24
|
-
s.unpack(
|
24
|
+
s.unpack("U*").pack("n*")
|
25
25
|
end
|
26
26
|
|
27
27
|
def le(s)
|
28
|
-
s.unpack(
|
28
|
+
s.unpack("U*").pack("v*")
|
29
29
|
end
|
30
30
|
|
31
31
|
def vcard(name)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vcard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-14 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Vcard extracted from Vpim
|
15
15
|
email:
|
@@ -76,18 +76,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
76
|
- - ! '>='
|
77
77
|
- !ruby/object:Gem::Version
|
78
78
|
version: '0'
|
79
|
-
segments:
|
80
|
-
- 0
|
81
|
-
hash: 376442794917458825
|
82
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
80
|
none: false
|
84
81
|
requirements:
|
85
82
|
- - ! '>='
|
86
83
|
- !ruby/object:Gem::Version
|
87
84
|
version: '0'
|
88
|
-
segments:
|
89
|
-
- 0
|
90
|
-
hash: 376442794917458825
|
91
85
|
requirements: []
|
92
86
|
rubyforge_project:
|
93
87
|
rubygems_version: 1.8.24
|