contacts_txt 0.2.11 → 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
  SHA256:
3
- metadata.gz: 355e8353cd10e38ee6e8bc865b994089e69543c4a3b5e7e78de1fdc76b363eaf
4
- data.tar.gz: 7a9e5e5df3864776b0e11574f50b26ff23243ac32d4d36fe729358841b5c5a91
3
+ metadata.gz: bf478e02d22813b059b002369a94120ffa7db0c98e7ee02f7eb5a7604f000e36
4
+ data.tar.gz: 0e220217e01429b1b35c059df1e8459100ee4003a618c8634dcafd09ca30baeb
5
5
  SHA512:
6
- metadata.gz: 51bf53d2aa3526fa69537e79444d80a05a8d958bed6f919b7268374b17b8df5c544bee3c3573b112d710114f0fe7130d0e62dcd36f35bdf9cf6912cd16bfec0e
7
- data.tar.gz: fc269d1fee4f6e48ca53f5917f4ea48c9681ba998eb96724b23cf069b6a15a548f1dfeb428071a66c97d36a1fd6e59381ab36e126ef1bde29ab78dbb8a0f40a1
6
+ metadata.gz: 71e031cd9bef37e5d93c634832d2ba450a17605cbbf5c088898a73b1678cb0c477bfce0eddfa60604c784805b3126bd8e1305ebc494e78927aea4024339e0752
7
+ data.tar.gz: 1d0686e575cd7242676541d2ad093a113c5ffd95666f56450d1139376d4d399ecd6c67e7b547f9118e02cc4f7e42620e93dd2752b550f445c43cab008d216a0c
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/contacts_txt.rb CHANGED
@@ -3,26 +3,27 @@
3
3
  # file: contacts_txt.rb
4
4
 
5
5
  require 'dynarex'
6
+ require 'rxfreadwrite'
6
7
 
7
8
 
8
9
  class ContactsTxt
9
- include RXFHelperModule
10
+ include RXFReadWriteModule
10
11
 
11
12
  attr_reader :to_s
12
-
13
- def initialize(src=nil, fields: %w(role organisation mobile
14
- sms email dob tags address notes note mobile2 ),
13
+
14
+ def initialize(src=nil, fields: %w(role organisation mobile
15
+ sms email dob tags address notes note mobile2 ),
15
16
  username: nil, password: nil, debug: false)
16
-
17
+
17
18
  @debug = debug
18
19
  @fields = %w(fullname firstname lastname tel) | fields
19
20
 
20
21
  txt, type = if src then
21
- RXFHelper.read(src, username: username, password: password)
22
+ RXFReader.read(src, username: username, password: password)
22
23
  else
23
24
  ['', :unknown]
24
25
  end
25
-
26
+
26
27
  case type
27
28
  when :file
28
29
  @path, @filename = File.dirname(src), File.basename(src)
@@ -33,94 +34,165 @@ class ContactsTxt
33
34
  when :unknown
34
35
  @path, @filename = '.', 'contacts.txt'
35
36
  end
36
-
37
+
37
38
  @dx = txt.lines.length > 1 ? import_to_dx(txt) : new_dx()
38
39
 
39
40
  end
40
-
41
+
42
+ def all()
43
+ @dx.all
44
+ end
45
+
41
46
  def dx()
42
47
  @dx
43
48
  end
44
-
49
+
45
50
  def find_by_id(id)
46
-
51
+
47
52
  @dx.find_by_id id
48
-
53
+
49
54
  end
50
-
55
+
51
56
  def find_by_mobile(raw_number, countrycode='44')
52
57
 
53
58
  number = Regexp.new raw_number.sub(/^(?:0|#{countrycode})/,'').gsub(/[ -]*/,'')
54
-
55
- @dx.all.find {|x| x.mobile.gsub(/[ -]*/,'') =~ number }
56
59
 
57
- end
58
-
59
- def find_by_name(raw_name)
60
+ @dx.all.find {|x| x.mobile.gsub(/[ -]*/,'') =~ number }
61
+
62
+ end
63
+
64
+ def find_by_name(s)
65
+
66
+ # Appending a hashtag to the name can help with finding the specific record
67
+ # e.g. 'Peter#plumber' or 'Peter #plumber'
68
+
69
+ raw_name, tag = s.split('#',2).map(&:strip)
60
70
 
61
71
  name = Regexp.new "\b#{raw_name}\b|#{raw_name}", Regexp::IGNORECASE
62
72
  puts 'name: ' + name.inspect if @debug
63
-
64
- @dx.all.select do |x|
73
+
74
+ a = @dx.all.select do |x|
65
75
  x.fullname =~ name or x.firstname =~ name or x.lastname =~ name
66
76
  end
67
77
 
68
- end
69
-
78
+ if tag then
79
+ a.find {|x| x.tags.split.map(&:downcase).include? tag.downcase }
80
+ else
81
+ a
82
+ end
83
+
84
+ end
85
+
70
86
  def find_by_sms(raw_number, countrycode='44')
71
87
 
72
88
  number = Regexp.new raw_number\
73
89
  .sub(/^(?:0|#{countrycode})/,'').gsub(/[ -]*/,'')
74
-
90
+
75
91
  @dx.all.find {|x| x.sms.gsub(/[ -]*/,'') =~ number \
76
- or x.mobile.gsub(/[ -]*/,'') =~ number }
92
+ or x.mobile.gsub(/[ -]*/,'') =~ number }
77
93
 
78
- end
79
-
80
- # find using the tel, mobile, or mobile2 fields
94
+ end
95
+
96
+ # find using the tel, mobile, or mobile2 fields
81
97
  #
82
98
  def find_by_telno(raw_number)
83
99
 
84
100
  number = Regexp.new raw_number.gsub(/[ -]*/,'')
85
-
101
+
86
102
  @dx.all.find do |x|
87
-
103
+
88
104
  numbers = %i(tel mobile mobile2).map do |y|
89
105
  x.method(y).call.gsub(/[ -]*/,'') if x.respond_to? y
90
106
  end
91
-
107
+
92
108
  puts 'numbers: ' + numbers.inspect if @debug
93
109
  numbers.grep(number).any?
94
110
  end
95
111
 
96
- end
112
+ end
97
113
 
98
114
  # returns a Dynarex object
99
- #
115
+ #
100
116
  def email_list()
101
117
  @dx.filter {|x| x.email.length > 0}
102
118
  end
103
-
119
+
104
120
  def list_names()
105
-
121
+
106
122
  @dx.all.inject([]) do |r, x|
107
123
  x.fullname.length >= 1 ? r << x.fullname : r
108
124
  end
109
125
 
110
126
  end
111
-
127
+
112
128
  def mobile_list()
113
129
  @dx.filter {|x| x.mobile.length > 0}
114
- end
130
+ end
131
+
132
+ def multi_tel_index()
133
+
134
+ a = @dx.all.map do |x|
135
+
136
+ tel = %i(tel mobile mobile2).detect do |name|
137
+ !x.method(name).call.empty?
138
+ end
139
+ next unless tel
140
+ "%s %s" % [x.fullname, x.method(tel).call]
141
+ end.compact
142
+
143
+
144
+ # group by first name
145
+ r = a.group_by {|x| x[0]}
146
+
147
+ a2 = a.clone
148
+
149
+ # group by last name
150
+ r2 = a.group_by {|x| x.split(/ /,2).last[0]}
151
+ c = r2.merge(r)
152
+
153
+ c.each do |k, v|
154
+
155
+ puts "k: %s v: %s" % [k, v]
156
+ v.concat(r2[k]) if r2[k]
157
+
158
+ end
159
+
160
+ h = c.sort.each {|k,v| v.uniq!}.to_h
161
+
162
+ out = []
163
+
164
+ h.each do |k,v|
165
+
166
+ out << ' ' + (' ' * 30) + k
167
+
168
+ v.each do |x|
169
+
170
+ name, phone = x.split(/(?=\d)/,2)
171
+ out << "\n" + (name.length >= 29 ? name[0..26] + '...' : name)
172
+ tel = (' ' + ' ' * (26 - phone.length)) + 't: ' + phone
173
+ out << tel + "\n"
174
+ out << ('-' * 30)
175
+
176
+ end
177
+
178
+ end
179
+
180
+ puts out.join("\n")
181
+
182
+ end
115
183
 
116
184
  def save(filename=@filename)
117
-
185
+
118
186
  s = dx_to_s(@dx)
119
187
  FileX.write File.join(@path, filename), s
120
188
  @dx.save File.join(@path, filename.sub(/\.txt$/,'.xml'))
121
-
189
+
190
+ end
191
+
192
+ def to_dx()
193
+ @dx
122
194
  end
123
-
195
+
124
196
  def to_s()
125
197
  dx_to_s @dx
126
198
  end
@@ -128,9 +200,9 @@ class ContactsTxt
128
200
  private
129
201
 
130
202
  def dx_to_s(dx)
131
-
203
+
132
204
  rows = dx.all.map do |row|
133
-
205
+
134
206
  h = row.to_h
135
207
 
136
208
  fullname = h.delete :fullname
@@ -140,11 +212,11 @@ class ContactsTxt
140
212
 
141
213
  ([fullname] + a.map {|x| x.join(': ') }).join("\n")
142
214
  end
143
-
215
+
144
216
  "<?contacts fields='%s'?>\n\n%s" % [@fields, rows.join("\n\n")]
145
-
217
+
146
218
  end
147
-
219
+
148
220
  def import_to_dx(raw_s)
149
221
 
150
222
  s = if raw_s =~ /<?contacts / then
@@ -156,35 +228,97 @@ class ContactsTxt
156
228
  found = s2[/(?<=#{keyword}=['"])[^'"]+/]
157
229
  found ? r.merge(keyword.to_sym => found) : r
158
230
  end
159
-
231
+
160
232
  h = {
161
- fields: @fields.join(', '),
162
- }.merge attributes
233
+ fields: @fields.join(', '),
234
+ }.merge attributes
163
235
 
164
- @fields = h[:fields].split(/ *, */)
236
+ @fields = h[:fields].split(/ *, */)
165
237
 
166
238
  if h[:root] then
167
- "\n\n" + h[:root] + "\n" +
239
+ "\n\n" + h[:root] + "\n" +
168
240
  raw_contacts.strip.lines.map {|line| ' ' + line}.join
169
241
  else
170
242
  raw_contacts
171
243
  end
172
-
244
+
173
245
  else
174
-
246
+
175
247
  raw_s.lstrip.lines[2..-1].join.strip
176
248
 
177
249
  end
178
250
 
179
251
  new_dx().import "--+\n" + s.split(/\s+(?=^[\w\s\(\)]+$)/)\
180
- .map {|x| 'fullname: ' + x }.join("\n")
181
-
252
+ .map {|x| 'fullname: ' + x }.join("\n")
253
+
182
254
  end
183
-
255
+
184
256
  def new_dx()
185
-
257
+
186
258
  Dynarex.new "contacts/contact(#{@fields.join ', '})"
187
-
259
+
260
+ end
261
+
262
+ end
263
+
264
+ class ContactsTxtAgent < ContactsTxt
265
+
266
+ def find_mobile_by_name(s)
267
+
268
+ result = find_by_name(s)
269
+
270
+ r = validate(result)
271
+
272
+ numbers = [r.sms.empty? ? r.mobile : r.sms, r.mobile].uniq\
273
+ .map {|x| x.sub(/\([^\)]+\)/,'').strip}
274
+
275
+ h = {}
276
+ h[:msg] = if numbers.length > 1 then
277
+ "The SMS number for %s is %s and the mobile number is %s" % \
278
+ [r.fullname, *numbers]
279
+ elsif numbers.first.length > 0 then
280
+ "The mobile number for %s is %s" % [r.fullname, numbers.first]
281
+ elsif r.tel.length > 0 then
282
+ "I don't have a mobile number, but the landline telephone " + \
283
+ "number for %s is %s" % [r.fullname, r.tel]
284
+ else
285
+ "I don't have a telephone number for " + r.fullname
286
+ end
287
+
288
+ h[:tags] = r.tags.to_s
289
+ h
290
+ end
291
+
292
+ def find_tel_by_name(s)
293
+
294
+ result = find_by_name(s)
295
+ r = validate(result)
296
+
297
+ h = {}
298
+
299
+ if r.tel.empty? then
300
+ return find_mobile_by_name(s)
301
+ else
302
+ h[:msg] = "The telephone number for %s is %s" % [r.fullname, r.tel]
303
+ end
304
+
305
+ h[:tags] = r.tags.to_s
306
+ h
307
+ end
308
+
309
+ private
310
+
311
+ def validate(result)
312
+
313
+ case result.class.to_s
314
+ when 'RecordX'
315
+ result
316
+ when 'Array'
317
+ result.first
318
+ when 'NilClass'
319
+ return "I couldn't find that name."
320
+ end
321
+
188
322
  end
189
323
 
190
324
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contacts_txt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.11
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -10,27 +10,32 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIDXjCCAkagAwIBAgIBATANBgkqhkiG9w0BAQUFADAsMSowKAYDVQQDDCFnZW1t
14
- YXN0ZXIvREM9amFtZXNyb2JlcnRzb24vREM9ZXUwHhcNMTgwODAxMjEwNzA0WhcN
15
- MTkwODAxMjEwNzA0WjAsMSowKAYDVQQDDCFnZW1tYXN0ZXIvREM9amFtZXNyb2Jl
16
- cnRzb24vREM9ZXUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC9696
17
- mu8TEN1NeSExgfozGbuajnFfKg3O4ipvtmz5qaM2BmYgxtsq/Y3JvcOmBmjXWJlL
18
- pH7PoEWZvonazT/HqYdKu9yihQ3tN5Ke/A9XvJwcz6Ug94LO0N8KgByLEBxRmSP1
19
- BYL8EpWJnhlNAffEdirPBcCLHvDl2S6RbDXyUWa03+qw6zK+Iuu9mcWoQdSxBrwU
20
- jD18mgNpVipsL1NT/dV2uz5LIESdYVA6kxvSwL2aGZ8O9c7XI8hl/9DNntRXB6BI
21
- qJ5PuYUBZVy3kOI4Ks4ra/QgaRcAGeH8f7Vl2A9SdLIYjP45CQyanHy6M8cmuwm1
22
- nSRHWQx/q3I8DhRdAgMBAAGjgYowgYcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
23
- HQYDVR0OBBYEFBgkPuVzdzsTk+wKFFCEXg7Lb9ZyMCYGA1UdEQQfMB2BG2dlbW1h
24
- c3RlckBqYW1lc3JvYmVydHNvbi5ldTAmBgNVHRIEHzAdgRtnZW1tYXN0ZXJAamFt
25
- ZXNyb2JlcnRzb24uZXUwDQYJKoZIhvcNAQEFBQADggEBAGoMpMeiWATe9UNHf317
26
- WRymCKIukfzFSTjwg/yc67F/qk5P23BdYywy7TA/l8M3L52+Cav3ZjiyquvkLDTX
27
- xNXGFArD5J5Wu/GN6I5vSLYwzC0G/iN4ZOffa3lpdxtqU0BWk1PgrMKSBYM22wCD
28
- Q1V22nUmZshq07vu1naaJvnmQe5SrXdNAwNue9xXHpAXRStGq3OgEtWl7k8MCPpr
29
- G//X20IZZXsvN64DFHpFyhz7JZTiTuyH+GkH/3BpwwTrz5Fv1f4nPpYg2Jxka1B5
30
- Ms9N9IXVzqxWl6qaGY7lENrLhETsyyvXsYq+Djcg8A9Fvn3Fk3do1ooh9ePNno3a
31
- 1G4=
13
+ MIIEXjCCAsagAwIBAgIBATANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDDCFnZW1t
14
+ YXN0ZXIvREM9amFtZXNyb2JlcnRzb24vREM9ZXUwHhcNMjIwMjIzMTk0ODIwWhcN
15
+ MjMwMjIzMTk0ODIwWjAsMSowKAYDVQQDDCFnZW1tYXN0ZXIvREM9amFtZXNyb2Jl
16
+ cnRzb24vREM9ZXUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDlecEA
17
+ 1V+ZCFfCwQwbOZ9S2Tn+ggDp85hVOoHZyfA+E6MMOShj1CE22RDfbyrAal+Z01C5
18
+ dol4wfM2s3x3QGwU/BhwoBs1el3beCkqEf86/bAfBMZ7TsxP8NcxeaQYxd4XUW52
19
+ f0UTA6EgM65L4F+K6vBWD76vjHwO6Z+hF9BrVVvifuT1jNykZ/PoDncs4nZaQKFP
20
+ yCtrrfjq9WOVG+ueHSm1+7rWqxBO2jH95Nlyfe2t2Q27gOz4hpcU6tyCGEb5Liz/
21
+ za+SUVNKbv8kxVBoQYYDMyHgZeS5YN1qlkxXSjSrUAIpp4eUHxaKMo6lTcXPXRPA
22
+ CezHTFC1cn276L80YXTj0Gw2Jp9On2AJXifKZ11nlOs+gBSS32r8UiqptAGe97Py
23
+ PotM+fYUjH7yunVnvsPIN+EC08vAhXCrMfFnvCuuyeSv8KKUFxmIeZE1Fn29MooE
24
+ Qd6QI6SJGWQ918Vj1NE4Lo/EKtgl5opL4cVPRzrH7yH82oyQiI/7NiemwrMCAwEA
25
+ AaOBijCBhzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUaABOt2ER
26
+ TZ9I1b5uj7HkRf+YVr4wJgYDVR0RBB8wHYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0
27
+ c29uLmV1MCYGA1UdEgQfMB2BG2dlbW1hc3RlckBqYW1lc3JvYmVydHNvbi5ldTAN
28
+ BgkqhkiG9w0BAQsFAAOCAYEABS1c63h+vQL2hjWs7BvQM6vFxp1T4RDvviUqLUBt
29
+ YAg1/vWquUZ0PVi+Hf9gAaSumDjBb7qbbkn3Y2j/aV7wpG/yFtBoknIqihp7oH7/
30
+ wqGlntx9baORy7chaaBRA4CB4gGUFQ0wYHCBrHmj9zvfFWXnnRoFa06JIHm2DmOB
31
+ 41DwQiiLflNj4iYbLzNQSI5X0iRu3H8zcAp45HJNF2LBrY32b8U+4Uf1w9QOJ4Io
32
+ bXdjMDxNnHEj2+V2yaq4J8v0o/xEE0Qv2TEeXyiv2fvIRz5VsS3ayYv+rHVmxGuo
33
+ VuXOnyLlTUjeB0IakaSYdBFWW3uno+fds/mIBL9VtmZzPJ4UhirVs0t4GvftJ2oT
34
+ weBCjBPmFwYPtn66vFgOaUHK421yIA2FC+AQO/pOOSgngHz0pm08NMpcTeTaufKu
35
+ x9gWyaB0gatLOaqUuwj8jCICpzNLo20JZQyEav2hZDxdB1EQjxq9jZrMaxwW3lF/
36
+ zHoZFKaw47O+Nd14HCqMVZUt
32
37
  -----END CERTIFICATE-----
33
- date: 2019-02-13 00:00:00.000000000 Z
38
+ date: 2022-02-23 00:00:00.000000000 Z
34
39
  dependencies:
35
40
  - !ruby/object:Gem::Dependency
36
41
  name: dynarex
@@ -38,22 +43,22 @@ dependencies:
38
43
  requirements:
39
44
  - - "~>"
40
45
  - !ruby/object:Gem::Version
41
- version: '1.8'
46
+ version: '1.9'
42
47
  - - ">="
43
48
  - !ruby/object:Gem::Version
44
- version: 1.8.15
49
+ version: 1.9.6
45
50
  type: :runtime
46
51
  prerelease: false
47
52
  version_requirements: !ruby/object:Gem::Requirement
48
53
  requirements:
49
54
  - - "~>"
50
55
  - !ruby/object:Gem::Version
51
- version: '1.8'
56
+ version: '1.9'
52
57
  - - ">="
53
58
  - !ruby/object:Gem::Version
54
- version: 1.8.15
59
+ version: 1.9.6
55
60
  description:
56
- email: james@jamesrobertson.eu
61
+ email: digital.robertson@gmail.com
57
62
  executables: []
58
63
  extensions: []
59
64
  extra_rdoc_files: []
@@ -78,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
83
  - !ruby/object:Gem::Version
79
84
  version: '0'
80
85
  requirements: []
81
- rubygems_version: 3.0.2
86
+ rubygems_version: 3.2.22
82
87
  signing_key:
83
88
  specification_version: 4
84
89
  summary: Reads a contacts.txt file
metadata.gz.sig CHANGED
Binary file