has_vcards 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,122 @@
1
+ module Vcard::DirectoryLookup
2
+ def map_for_directory
3
+ search = {}
4
+ search[:first_name] = given_name
5
+ search[:family_name] = family_name
6
+ search[:street] = street_address
7
+ search[:zip_code] = postal_code
8
+ search[:city] = locality
9
+
10
+ search
11
+ end
12
+
13
+ def directory_lookup(ignore_fields = [])
14
+ search = map_for_directory
15
+
16
+ search.reject!{|key, value| ignore_fields.include? key}
17
+
18
+ # TODO:
19
+ # We should fetch additional pages if the result indicates there
20
+ # are more pages.
21
+ ::SwissMatch.directory_service.addresses(search, :per_page => 100)
22
+ end
23
+
24
+ def directory_found?(ignore_fields = [])
25
+ directory_lookup(ignore_fields).present?
26
+ end
27
+
28
+ def normalize(value)
29
+ normalized_value = UnicodeUtils.downcase(value.to_s)
30
+ normalized_value.gsub!(/str\./, 'strasse')
31
+ normalized_value.gsub!(/str([ $])/, 'strasse\1')
32
+
33
+ normalized_value
34
+ end
35
+
36
+ def directory_matches(ignore_lookup_fields = [])
37
+ matches = directory_lookup(ignore_lookup_fields)
38
+ matches.map do |match|
39
+ search = map_for_directory
40
+
41
+ perfect = []
42
+ search.each do |key, value|
43
+ perfect << key if normalize(match.send(key)) == normalize(value)
44
+ end
45
+
46
+ partial = []
47
+ search.each do |key, value|
48
+ partial << key if value.present? && normalize(match.send(key)).include?(normalize(value))
49
+ end
50
+ partial -= perfect
51
+
52
+ bad = search.keys - perfect - partial - ignore_lookup_fields
53
+
54
+ {:address => match, :perfect => perfect, :partial => partial, :bad => bad, :ignore => ignore_lookup_fields}
55
+ end
56
+ end
57
+
58
+ def directory_filter(match, filter = {})
59
+ # Exact filters
60
+ filter[:perfect].each do |field|
61
+ return false unless match[:perfect].include?(field)
62
+ end if filter[:perfect]
63
+ filter[:partial].each do |field|
64
+ return false unless match[:partial].include?(field)
65
+ end if filter[:partial]
66
+ filter[:bad].each do |field|
67
+ return false unless match[:bad].include?(field)
68
+ end if filter[:bad]
69
+
70
+ # "Better than" filters
71
+ filter[:partial_or_perfect].each do |field|
72
+ return false unless match[:perfect].include?(field) || match[:partial].include?(field)
73
+ end if filter[:partial_or_perfect]
74
+
75
+ return true
76
+ end
77
+
78
+ def filtered_matches(filters)
79
+ ignores = filters.delete(:ignore) || []
80
+
81
+ directory_matches(ignores).collect do |match|
82
+ match[:address] if directory_filter(match, filters)
83
+ end.compact
84
+ end
85
+
86
+ # Everything matches
87
+ def perfect_matches
88
+ filtered_matches(:perfect => [:family_name, :first_name, :street, :city])
89
+ end
90
+
91
+ def perfect_match?
92
+ perfect_matches.present?
93
+ end
94
+
95
+ # Everything is found, given or family name does is partial match
96
+ def great_matches
97
+ filtered_matches(:partial_or_perfect => [:family_name, :first_name], :perfect => [:street, :city])
98
+ end
99
+
100
+ def great_match?
101
+ great_matches.present?
102
+ end
103
+
104
+ # Everything but given name matches, family name might be partial
105
+ def family_name_matches
106
+ filtered_matches(:ignore => [:first_name], :partial_or_perfect => [:family_name], :perfect => [:street, :city])
107
+ end
108
+
109
+ def family_name_match?
110
+ family_name_matches.present?
111
+ end
112
+
113
+ # Same address different names
114
+ def address_matches
115
+ filtered_matches(:ignore => [:first_name, :family_name], :perfect => [:street, :city])
116
+ end
117
+
118
+ # Similar name in same locality
119
+ def locality_matches
120
+ filtered_matches(:ignore => [:first_name, :street], :partial_or_perfect => [:family_name], :perfect => [:city])
121
+ end
122
+ end
data/app/models/vcard.rb CHANGED
@@ -118,4 +118,7 @@ class Vcard < ActiveRecord::Base
118
118
  end
119
119
  return result
120
120
  end
121
+
122
+ # SwissMatch
123
+ include Vcard::DirectoryLookup
121
124
  end
@@ -66,3 +66,13 @@ de:
66
66
  region: Region
67
67
  postal_code: PLZ
68
68
  country_name: Land
69
+
70
+ # DirectoryLookup
71
+ directory_lookup:
72
+ title: Treffer in Telefonbuch
73
+ match_type:
74
+ perfect: Genauer Treffer
75
+ great: Ungenauer Name
76
+ family_name: Anderer Vorname
77
+ address: An dieser Adresse
78
+ locality: In diesem Ort
@@ -1,3 +1,3 @@
1
1
  module HasVcards
2
- VERSION = '0.15.0'
2
+ VERSION = '0.16.0'
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: has_vcards
3
3
  version: !ruby/object:Gem::Version
4
- hash: 35
4
+ hash: 95
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 15
8
+ - 16
9
9
  - 0
10
- version: 0.15.0
10
+ version: 0.16.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Simon H\xC3\xBCrlimann (CyT)"
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-07-04 00:00:00 +02:00
18
+ date: 2012-07-19 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -62,6 +62,7 @@ files:
62
62
  - app/models/address.rb
63
63
  - app/models/phone_number.rb
64
64
  - app/models/vcard.rb
65
+ - app/models/vcard/directory_lookup.rb
65
66
  - app/views/phone_numbers/_form.html.haml
66
67
  - app/views/phone_numbers/_list.html.haml
67
68
  - app/views/phone_numbers/_nested_form.html.haml