simplevpim 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0df24d09c743af64bf2d92cddeb6cddd562983a2
4
- data.tar.gz: 8bd4c70e5aedacd6123231ba34cafe33e0620935
3
+ metadata.gz: 8410d4ea911c6e28edddd2e82a69bde5b3264352
4
+ data.tar.gz: 0c5ae0d7732a08e0e676bfa507a3e5be9e7cefc0
5
5
  SHA512:
6
- metadata.gz: 15d735c9463a72ad18e245465c99f36b131f2b0d371835885ce8451f87b0ec26a7792c66578a27f8dd2ab5507eb983c51e32eb3551fe7546bb877314d72223ba
7
- data.tar.gz: c4acec171f6316d6067a48f59a132f21dbe812238ffdf3eb890ad0adcc9ac33c1c3951fd5cecdd31b0ee4e92725c2799421cfb1f6d10a4f85734623b84c14dd4
6
+ metadata.gz: 89a1aaf2c31b1d89650c673ab9433b2d400bb3fbfe9245129a750c28e47810fcede685d024c74544cdfefac288c3977938523b1b7c426c038366f6607eb13393
7
+ data.tar.gz: 3154f9e48af76784731fa4adb79492c3930ca949b50bb1f0853633ac442990df4d2fb562c8e9f308b4c22cda3907eaf9fcf1e4ab1be0f5dac571922d78e82ab2
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -2,6 +2,7 @@
2
2
 
3
3
  # file: simplevpim.rb
4
4
 
5
+ require 'hlt'
5
6
  require 'nokogiri'
6
7
  require 'vpim/vcard'
7
8
  require 'rexle-builder'
@@ -14,20 +15,25 @@ class SimpleVpim
14
15
 
15
16
  def initialize(s)
16
17
 
17
- h = SimpleConfig.new(s).to_h
18
+ @h = SimpleConfig.new(s).to_h
18
19
 
19
- if h[:name] then
20
- @to_vcard = make_vcard h
21
- @to_xml = vcard_xml h
20
+ if @h[:name] then
21
+ @to_vcard = make_vcard @h
22
+ @to_xml = vcard_xml @h
22
23
  end
23
24
 
24
25
  end
25
26
 
26
27
  alias to_vcf to_vcard
27
28
 
29
+ def to_hcard(layout=nil)
30
+ make_hcard layout, @h
31
+ end
32
+
28
33
  def to_xcard()
29
34
  make_xcard @to_xml
30
35
  end
36
+
31
37
 
32
38
  private
33
39
 
@@ -150,16 +156,122 @@ class SimpleVpim
150
156
 
151
157
  end
152
158
  end
159
+
160
+ def make_hcard(raw_s, h)
161
+
162
+ raw_s ||= %q(
163
+ # hcard
164
+
165
+ img.photo
166
+ h1.fn
167
+ .email
168
+ .n
169
+
170
+ home:
171
+ .label
172
+ .adr
173
+ .tel
174
+
175
+ work:
176
+ .label
177
+ .adr
178
+ .tel
179
+ )
180
+
181
+ s = raw_s.split(/\n(?=\w+:?)/).inject('') do |r, x|
182
+
183
+ x.sub!(/^\s*#\s+.*/,'') # ignore comments
184
+
185
+ lines = x.lines
186
+ type = lines[0][/^(\w+):/,1]
187
+
188
+ if type then
189
+
190
+ lines.shift
191
+
192
+ r << lines.map do |line|
193
+
194
+ if line[/\s*\.\w+/] then
195
+ indent = line[/^ +/].to_s
196
+ "%s%sspan.type %s" % [line.sub(/^ {2}/,''), indent, type]
197
+ else
198
+ line
199
+ end
200
+
201
+ end.join("\n") + "\n"
202
+
203
+ else
204
+
205
+ r << x + "\n"
206
+ end
207
+
208
+ r
209
+
210
+ end
211
+
212
+ html_string = Hlt.new(s).to_html
213
+ html_template = <<EOF
214
+ <html>
215
+ <head>
216
+ <link rel="profile" href="http://microformats.org/profile/hcard" />
217
+ </head>
218
+ <body>
219
+ <div class='vcard'>#{html_string}</div>
220
+ </body>
221
+ </html>
222
+ EOF
223
+ doc = Rexle.new(html_template)
224
+
225
+ def doc.set(selector, val=nil)
226
+
227
+ e = self.at_css selector
228
+ return unless e
229
+ block_given? ? yield(e) : e.text = val
230
+
231
+ end
232
+
233
+ firstname, middlename, surname, fullname = extract_names(h[:name])
234
+ doc.set '.fn', fullname
235
+
236
+ #-- name ---------
237
+
238
+ e = doc.at_css '.n'
239
+ e.text = 'First Name:'
240
+ fname = Rexle::Element.new('span')
241
+ fname.attributes[:class] = 'given-name'
242
+ fname.text = firstname
243
+ e.add_element fname
244
+ e.add_element Rexle::Element.new('br')
245
+ e.add_text 'Last Name:'
246
+ lname = Rexle::Element.new('span')
247
+ lname.attributes[:class] = 'family-name'
248
+ lname.text = surname
249
+ e.add_element lname
250
+
251
+ doc.at_css('.photo').delete unless h[:photo]
252
+ doc.css('.tel').each(&:delete) unless h[:tel]
253
+ doc.css('.adr').each(&:delete) unless h[:adr]
254
+ doc.css('.label').each(&:delete) unless h[:label]
255
+
256
+ if h[:email].is_a? String then
257
+ e = doc.at_css '.email'
258
+ e.text = 'Email:'
259
+ alink = Rexle::Element.new('a')
260
+ alink.attributes[:class] = 'value'
261
+ alink.attributes[:href] = 'mailto:' + h[:email]
262
+ alink.text = h[:email]
263
+ e.add_element alink
264
+ end
265
+ [doc, h]
266
+
267
+ end
153
268
 
154
269
  def make_xcard(xml)
155
-
156
270
  lib = File.dirname(__FILE__)
157
- xsl = File.read File.join(lib,'xcard.xsl')
271
+ xsl = open(lib + '/xcard.xsl','UserAgent' => 'SimplevPim').read
158
272
  doc = Nokogiri::XML(xml)
159
-
160
273
  xslt = Nokogiri::XSLT(xsl)
161
274
  xslt.transform(doc).to_s
162
-
163
275
  end
164
276
 
165
277
  def vcard_xml(h)
@@ -0,0 +1,374 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # file: simplevpim.rb
4
+
5
+ require 'hlt'
6
+ require 'nokogiri'
7
+ require 'vpim/vcard'
8
+ require 'rexle-builder'
9
+ require 'simple-config'
10
+
11
+
12
+ class SimpleVpim
13
+
14
+ attr_reader :to_vcard, :to_xml
15
+
16
+ def initialize(s)
17
+
18
+ @h = SimpleConfig.new(s).to_h
19
+
20
+ if @h[:name] then
21
+ @to_vcard = make_vcard @h
22
+ @to_xml = vcard_xml @h
23
+ end
24
+
25
+ end
26
+
27
+ alias to_vcf to_vcard
28
+
29
+ def to_hcard(layout=nil)
30
+ make_hcard layout, @h
31
+ end
32
+
33
+ def to_xcard()
34
+ make_xcard @to_xml
35
+ end
36
+
37
+
38
+ private
39
+
40
+ def extract_names(name)
41
+
42
+ a = name.split
43
+
44
+ if a.length == 2 then
45
+
46
+ firstname, surname = a[0],nil,a[-1], name
47
+
48
+ elsif a[0][/^Mrs?|Ms|Miss|Dr/] then
49
+
50
+ prefix = a.shift
51
+
52
+ if a.length == 2 then
53
+ firstname, surname = a[0],nil,a[-1], name
54
+ else
55
+ [*a, a.join(' ')]
56
+ end
57
+
58
+ else
59
+ [*a, a.join(' ')]
60
+ end
61
+ end
62
+
63
+ def make_vcard(h)
64
+
65
+ card = Vpim::Vcard::Maker.make2 do |maker|
66
+
67
+ def maker.add(field_name, value, params={})
68
+
69
+ field = Vpim::DirectoryInfo::Field.create field_name, value, params
70
+ add_field field
71
+
72
+ end
73
+
74
+ prefix = h[:prefix]
75
+ suffix = h[:suffix]
76
+
77
+ firstname, middlename, surname, fullname = extract_names(h[:name])
78
+
79
+ maker.add_name do |name|
80
+ name.prefix = prefix if prefix
81
+ name.given = firstname
82
+ name.family = surname
83
+ name.suffix = suffix if suffix
84
+ name.fullname = fullname if fullname
85
+ end
86
+
87
+ # -- email -----------------------------
88
+
89
+ e = h[:email]
90
+
91
+ if e then
92
+
93
+ if e.is_a? String then
94
+ maker.add_email e
95
+ else
96
+ eh = h[:email][:home]
97
+ ew = h[:email][:work]
98
+ maker.add_email(ew) { |e| e.location = 'work' } if ew
99
+ maker.add_email(eh) { |e| e.location = 'home' } if eh
100
+ end
101
+ end
102
+
103
+ # -- urls ---------------------------------
104
+
105
+ h[:url] ||= h[:urls]
106
+
107
+ if h[:url] then
108
+
109
+ if h[:url].is_a? String then
110
+ maker.add_url h[:url]
111
+ else
112
+
113
+ # unfortunately vPim doesn't use a block with the add_url method
114
+ #maker.add_url (h[:url][:work]){|e| e.location = 'work'} if h[:url][:work]
115
+
116
+ h[:url][:items].each {|url| maker.add_url url }
117
+
118
+ end
119
+
120
+ end
121
+
122
+ # -- photos
123
+
124
+ maker.add_photo {|photo| photo.link = h[:photo] } if h[:photo]
125
+
126
+ # -- telephone
127
+
128
+ tel = h[:tel]
129
+
130
+ if tel then
131
+
132
+ if tel.is_a? String then
133
+
134
+ maker.add_tel tel
135
+
136
+ else
137
+ th = h[:tel][:home]
138
+ tw = h[:tel][:work]
139
+ maker.add_tel(tw) { |e| e.location = 'work' } if tw
140
+ maker.add_tel(th) { |e| e.location = 'home' } if th
141
+ end
142
+ end
143
+
144
+ # -- categories ------------
145
+ maker.add 'CATEGORIES', h[:categories].split(/\s*,\s*/) if h[:categories]
146
+
147
+ # -- source ------------
148
+ maker.add 'SOURCE', h[:source] if h[:source]
149
+
150
+ # -- Twitter ------------
151
+ maker.add 'X-TWITTER', h[:twitter] if h[:twitter]
152
+
153
+ # -- XMPP
154
+ xmpp = h[:jabber] || h[:xmpp]
155
+ maker.add 'X-JABBER', xmpp, 'TYPE' => 'im' if xmpp
156
+
157
+ end
158
+ end
159
+
160
+ def make_hcard(raw_s, h)
161
+
162
+ raw_s ||= %q(
163
+ # hcard
164
+
165
+ img.photo
166
+ h1.fn
167
+ .email
168
+ .n
169
+
170
+ home:
171
+ .label
172
+ .adr
173
+ .tel
174
+
175
+ work:
176
+ .label
177
+ .adr
178
+ .tel
179
+ )
180
+
181
+ s = raw_s.split(/\n(?=\w+:?)/).inject('') do |r, x|
182
+
183
+ x.sub!(/^\s*#\s+.*/,'') # ignore comments
184
+
185
+ lines = x.lines
186
+ type = lines[0][/^(\w+):/,1]
187
+
188
+ if type then
189
+
190
+ lines.shift
191
+
192
+ r << lines.map do |line|
193
+
194
+ if line[/\s*\.\w+/] then
195
+ indent = line[/^ +/].to_s
196
+ "%s%sspan.type %s" % [line.sub(/^ {2}/,''), indent, type]
197
+ else
198
+ line
199
+ end
200
+
201
+ end.join("\n") + "\n"
202
+
203
+ else
204
+
205
+ r << x + "\n"
206
+ end
207
+
208
+ r
209
+
210
+ end
211
+
212
+ html_string = Hlt.new(s).to_html
213
+ html_template = <<EOF
214
+ <html>
215
+ <head>
216
+ <link rel="profile" href="http://microformats.org/profile/hcard" />
217
+ </head>
218
+ <body>
219
+ <div class='vcard'>#{html_string}</div>
220
+ </body>
221
+ </html>
222
+ EOF
223
+ doc = Rexle.new(html_template)
224
+
225
+ def doc.set(selector, val=nil)
226
+
227
+ e = self.at_css selector
228
+ return unless e
229
+ block_given? ? yield(e) : e.text = val
230
+
231
+ end
232
+
233
+ firstname, middlename, surname, fullname = extract_names(h[:name])
234
+ doc.set '.fn', fullname
235
+
236
+ #-- name ---------
237
+
238
+ e = doc.at_css '.n'
239
+ e.text = 'First Name:'
240
+ fname = Rexle::Element.new('span')
241
+ fname.attributes[:class] = 'given-name'
242
+ fname.text = firstname
243
+ e.add_element fname
244
+ e.add_element Rexle::Element.new('br')
245
+ e.add_text 'Last Name:'
246
+ lname = Rexle::Element.new('span')
247
+ lname.attributes[:class] = 'family-name'
248
+ lname.text = surname
249
+ e.add_element lname
250
+
251
+ doc.at_css('.photo').delete unless h[:photo]
252
+ doc.css('.tel').each(&:delete) unless h[:tel]
253
+ doc.css('.adr').each(&:delete) unless h[:adr]
254
+ doc.css('.label').each(&:delete) unless h[:label]
255
+
256
+ if h[:email].is_a? String then
257
+ e = doc.at_css '.email'
258
+ e.text = 'Email:'
259
+ alink = Rexle::Element.new('a')
260
+ alink.attributes[:class] = 'value'
261
+ alink.attributes[:href] = 'mailto:' + h[:email]
262
+ alink.text = h[:email]
263
+ e.add_element alink
264
+ end
265
+ [doc, h]
266
+
267
+ end
268
+
269
+ def make_xcard(xml)
270
+ lib = 'http://rorbuilder.info/r/ruby/simplevpim'
271
+ xsl = open(lib + '/xcard.xsl','UserAgent' => 'SimplevPim').read
272
+ doc = Nokogiri::XML(xml)
273
+ xslt = Nokogiri::XSLT(xsl)
274
+ xslt.transform(doc).to_s
275
+ end
276
+
277
+ def vcard_xml(h)
278
+
279
+ prefix = h[:prefix]
280
+ suffix = h[:suffix]
281
+
282
+ firstname, middlename, surname, fullname = extract_names(h[:name])
283
+
284
+ xml = RexleBuilder.new
285
+
286
+ a = xml.vcard do
287
+
288
+ xml.name do
289
+
290
+ xml.prefix prefix if prefix
291
+ xml.given firstname
292
+ xml.family surname
293
+ xml.suffix suffix if suffix
294
+ xml.fullname fullname if fullname
295
+ end
296
+
297
+ # -- email -----------------------------
298
+
299
+ e = h[:email]
300
+
301
+ if e then
302
+
303
+ if e.is_a? String then
304
+
305
+ xml.email e
306
+
307
+ else
308
+ eh = h[:email][:home]
309
+ ew = h[:email][:work]
310
+ xml.email({location: 'work'}, ew) if ew
311
+ xml.email({location: 'home'}, eh) if eh
312
+ end
313
+ end
314
+
315
+ # -- urls ---------------------------------
316
+
317
+ h[:url] ||= h[:urls]
318
+
319
+ if h[:url] then
320
+
321
+ if h[:url].is_a? String then
322
+ xml.url h[:url]
323
+ else
324
+
325
+ # unfortunately vPim doesn't use a block with the add_url method
326
+ #maker.add_url (h[:url][:work]){|e| e.location = 'work'} if h[:url][:work]
327
+
328
+ h[:url][:items].each {|url| xml.url url }
329
+
330
+ end
331
+
332
+ end
333
+
334
+ # -- photos
335
+
336
+ xml.photo link: h[:photo] if h[:photo]
337
+
338
+ # -- telephone
339
+
340
+ tel = h[:tel]
341
+
342
+ if tel then
343
+
344
+ if tel.is_a? String then
345
+
346
+ xml.tel tel
347
+
348
+ else
349
+ th = h[:tel][:home]
350
+ tw = h[:tel][:work]
351
+ xml.tel({location: 'work'}, tw) if tw
352
+ xml.tel({location: 'home'}, th) if th
353
+ end
354
+ end
355
+
356
+ # -- categories ------------
357
+ xml.categories h[:categories].split(/\s*,\s*/) if h[:categories]
358
+
359
+ # -- source ------------
360
+ xml.source h[:source] if h[:source]
361
+
362
+ # -- Twitter ------------
363
+ xml.x_twitter h[:twitter] if h[:twitter]
364
+
365
+ # -- XMPP
366
+ xmpp = h[:jabber] || h[:xmpp]
367
+ xml.x_jabber({type: 'im'}, xmpp) if xmpp
368
+
369
+ end
370
+
371
+ Rexle.new(a)
372
+ end
373
+
374
+ end
@@ -0,0 +1,49 @@
1
+ <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
2
+ <xsl:output method='xml' indent='yes'/>
3
+
4
+
5
+ <xsl:template match='vcard'>
6
+ <xsl:element name='vcards'>
7
+ <xsl:attribute name='xmlns'>urn:ietf:params:xml:ns:vcard-4.0</xsl:attribute>
8
+ <xsl:element name='vcard'>
9
+
10
+ <xsl:apply-templates select='name' />
11
+ <xsl:apply-templates select='email' />
12
+ </xsl:element>
13
+ </xsl:element>
14
+
15
+ </xsl:template>
16
+
17
+ <xsl:template match='name'>
18
+ <xsl:element name='fn'>
19
+ <xsl:element name='text'><xsl:value-of select='fullname'/></xsl:element></xsl:element>
20
+ <xsl:element name='n'>
21
+ <xsl:element name="surname"><xsl:value-of select='family' /></xsl:element>
22
+ <xsl:element name="given"><xsl:value-of select='given' /></xsl:element>
23
+ <xsl:element name="additional"><xsl:value-of select='middlename' /></xsl:element>
24
+ <xsl:element name="prefix"><xsl:value-of select='prefix' /></xsl:element>
25
+ <xsl:element name="suffix"><xsl:value-of select='suffix' /></xsl:element>
26
+ </xsl:element>
27
+
28
+ </xsl:template>
29
+
30
+
31
+ <xsl:template match='email'>
32
+
33
+ <xsl:element name='email'>
34
+ <xsl:element name="parameters">
35
+ <xsl:element name='type'>
36
+ <xsl:element name='text'>
37
+ <xsl:value-of select='@location'/>
38
+ </xsl:element>
39
+ </xsl:element>
40
+ </xsl:element>
41
+ <xsl:element name='text'>
42
+ <xsl:value-of select='.' />
43
+ </xsl:element>
44
+
45
+ </xsl:element>
46
+
47
+ </xsl:template>
48
+
49
+ </xsl:stylesheet>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simplevpim
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -31,7 +31,7 @@ cert_chain:
31
31
  h7sjjIWKCtgcFF+5Gf5AtJf6C0PlDSh7mc8uoo2XSef/GV6YvwUrQbPtFakM7LDs
32
32
  a3f37q6Z/UCE6w==
33
33
  -----END CERTIFICATE-----
34
- date: 2014-11-10 00:00:00.000000000 Z
34
+ date: 2014-11-22 00:00:00.000000000 Z
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: simple-config
@@ -113,6 +113,26 @@ dependencies:
113
113
  - - ">="
114
114
  - !ruby/object:Gem::Version
115
115
  version: 1.6.2.1
116
+ - !ruby/object:Gem::Dependency
117
+ name: hlt
118
+ requirement: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '0.3'
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: 0.3.2
126
+ type: :runtime
127
+ prerelease: false
128
+ version_requirements: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '0.3'
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: 0.3.2
116
136
  description:
117
137
  email: james@r0bertson.co.uk
118
138
  executables: []
@@ -120,6 +140,8 @@ extensions: []
120
140
  extra_rdoc_files: []
121
141
  files:
122
142
  - lib/simplevpim.rb
143
+ - lib/simplevpim.rb~
144
+ - lib/xdata.xsl
123
145
  homepage: https://github.com/jrobertson/simplevpim
124
146
  licenses:
125
147
  - MIT
metadata.gz.sig CHANGED
Binary file