openopus-core-people 1.1.4 → 1.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/address.rb +2 -2
- data/app/models/concerns/labelize.rb +26 -0
- data/app/models/email.rb +13 -3
- data/app/models/person.rb +37 -10
- data/app/models/phone.rb +28 -9
- data/app/models/user.rb +2 -2
- data/lib/openopus/core/people/engine.rb +1 -1
- data/lib/openopus/core/people/version.rb +1 -1
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fa609ee836533103efd9cac7c3a00e6e3b91ad3ea48c5e2bf16ff11b84d9ed5
|
4
|
+
data.tar.gz: 61d6376f1ba54350b83f635fe82e98bfe09582593fc470bbdade7b8276b55fa3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c540c01684241f7802028026e0d7a1cc60f7fb8297ed2f4d959c16cffdac9e3a2918c039666fad9d00af81d8f87e487bb9fe83b8d37df347115aa43f50ff3305
|
7
|
+
data.tar.gz: 3bea98e5e63b9a7932bda9838ed4872cde3ec27c132bd3ee5b576f5466e56fee2d19b0b47fc3354a480f60e966588d0b2a2e2d374a38d7b5f2f9fcbd9978021d
|
data/app/models/address.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# labelize.rb: -*- Ruby -*- DESCRIPTIVE TEXT.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2019 Brian J. Fox Opus Logica, Inc.
|
4
|
+
# Author: Brian J. Fox (bfox@opuslogica.com)
|
5
|
+
# Birthdate: Wed Sep 11 09:37:52 2019.
|
6
|
+
module Labelize
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
included do
|
9
|
+
belongs_to :label, optional: true
|
10
|
+
|
11
|
+
def label
|
12
|
+
db_label = super
|
13
|
+
if not db_label
|
14
|
+
self.label = "Work"
|
15
|
+
db_label = super
|
16
|
+
end
|
17
|
+
|
18
|
+
db_label.value
|
19
|
+
end
|
20
|
+
|
21
|
+
def label=(name)
|
22
|
+
super(Label.get(name))
|
23
|
+
self.label
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/app/models/email.rb
CHANGED
@@ -1,17 +1,27 @@
|
|
1
1
|
class Email < ApplicationRecord
|
2
|
-
|
3
|
-
belongs_to :emailable, polymorphic: true
|
2
|
+
include Labelize
|
3
|
+
belongs_to :emailable, polymorphic: true, optional: true
|
4
4
|
accepts_nested_attributes_for :label
|
5
5
|
before_create :default_label
|
6
|
+
before_save :canonicalize
|
7
|
+
|
8
|
+
VALID_EMAIL_FORMAT_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
9
|
+
|
10
|
+
validates_format_of :address, with: VALID_EMAIL_FORMAT_REGEX, :on => :create
|
6
11
|
|
7
12
|
def self.canonicalize(addr)
|
8
|
-
addr.strip.downcase if not addr.blank?
|
13
|
+
candidate = addr.strip.downcase if not addr.blank?
|
14
|
+
candidate ||= addr
|
9
15
|
end
|
10
16
|
|
11
17
|
def canonicalize
|
12
18
|
self.address = self.class.canonicalize(self.address)
|
13
19
|
end
|
14
20
|
|
21
|
+
def self.valid_format?(addr)
|
22
|
+
return (addr =~ VALID_EMAIL_FORMAT_REGEX) != nil
|
23
|
+
end
|
24
|
+
|
15
25
|
def default_label
|
16
26
|
self.label = Label.get("Work")
|
17
27
|
end
|
data/app/models/person.rb
CHANGED
@@ -11,12 +11,25 @@ class Person < ApplicationRecord
|
|
11
11
|
accepts_nested_attributes_for :emails
|
12
12
|
|
13
13
|
def self.lookup(name)
|
14
|
+
return nil if not name
|
14
15
|
person = self.find_by(self.name_components(name))
|
15
16
|
person ||= self.includes(:nicknames).joins(:nicknames).find_by("nicknames.nickname" => name)
|
17
|
+
|
18
|
+
# Maybe we're looking up by phone number?
|
16
19
|
if not person
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
phone = Phone.where(number: Phone.canonicalize(name)).first rescue nil
|
21
|
+
person = phone.phoneable if phone
|
22
|
+
end
|
23
|
+
|
24
|
+
if not person
|
25
|
+
email = Email.where(emailable_type: name.to_s, address: Email.canonicalize(name.downcase)).first
|
26
|
+
person = email.emailable if email
|
27
|
+
end
|
28
|
+
|
29
|
+
if not person
|
30
|
+
# Try hard to find a person by their initials, even if there wasn't a nickname for them.
|
31
|
+
people = self.all.collect {|p| [p.id, p.initials]}
|
32
|
+
|
20
33
|
people.each do |parry|
|
21
34
|
if parry[1] == name.upcase
|
22
35
|
person = self.find(parry[0])
|
@@ -25,11 +38,6 @@ class Person < ApplicationRecord
|
|
25
38
|
end
|
26
39
|
end
|
27
40
|
|
28
|
-
if not person
|
29
|
-
addr = Email.where(emailable_type: self.name.to_s, address: Email.canonicalize(name.downcase)).first
|
30
|
-
person = addr.person.first if addr
|
31
|
-
end
|
32
|
-
|
33
41
|
person
|
34
42
|
end
|
35
43
|
|
@@ -82,7 +90,7 @@ class Person < ApplicationRecord
|
|
82
90
|
result = possibles.include?(text.gsub(/[.]*/, "").downcase) if text.present?
|
83
91
|
end
|
84
92
|
|
85
|
-
def self.name_components(name)
|
93
|
+
def self.name_components(name, transformer=nil)
|
86
94
|
res = {}
|
87
95
|
component = ""
|
88
96
|
components = name.gsub(/,/, " ").gsub(/ /, " ").split(" ") rescue [name]
|
@@ -92,32 +100,51 @@ class Person < ApplicationRecord
|
|
92
100
|
# What kind of thing is this?
|
93
101
|
if is_name_prefix?(component)
|
94
102
|
res[:prefix] = component
|
103
|
+
res[:prefix] = res[:prefix].send(transformer) if res[:prefix] && transformer
|
95
104
|
res[:fname] = components.shift
|
96
105
|
else
|
97
106
|
res[:fname] = component
|
98
107
|
end
|
99
108
|
|
109
|
+
res[:fname] = res[:fname].send(transformer) if res[:fname] && transformer
|
110
|
+
|
100
111
|
# Next up, middle initial or last name.
|
101
112
|
# If only one word remains, that's the last name
|
102
113
|
if components.length == 1
|
103
114
|
res[:lname] = components.shift
|
115
|
+
res[:lname] = res[:lname].send(transformer) if res[:lname] && transformer
|
104
116
|
elsif components.length > 0
|
105
117
|
# At least 2 words remain. We might have middle names, prefixes, suffixes, etc.
|
106
118
|
components.reverse!
|
107
119
|
component = components.shift
|
120
|
+
|
108
121
|
if is_name_suffix?(component)
|
109
122
|
res[:suffix] = component
|
123
|
+
res[:suffix] = res[:suffix].send(transformer) if res[:suffix] && transformer
|
110
124
|
res[:lname] = components.shift
|
111
125
|
else
|
112
126
|
res[:lname] = component
|
113
127
|
end
|
128
|
+
|
129
|
+
res[:lname] = res[:lname].send(transformer) if res[:lname] && transformer
|
130
|
+
|
114
131
|
res[:minitial] = components.shift
|
132
|
+
res[:minitial] = res[:minitial].send(transformer) if res[:minitial] && transformer
|
133
|
+
|
115
134
|
end
|
116
135
|
|
117
136
|
res[:minitial] = res[:minitial].gsub(/[.]/, "") if res[:minitial].present?
|
118
137
|
res
|
119
138
|
end
|
120
|
-
|
139
|
+
|
140
|
+
def initials
|
141
|
+
res = ""
|
142
|
+
res += fname[0] if fname
|
143
|
+
res += minitial[0] if minitial
|
144
|
+
res += lname[0] if lname
|
145
|
+
res.upcase
|
146
|
+
end
|
147
|
+
|
121
148
|
def name
|
122
149
|
components = []
|
123
150
|
|
data/app/models/phone.rb
CHANGED
@@ -1,18 +1,23 @@
|
|
1
|
+
require "phony_rails"
|
2
|
+
|
1
3
|
class Phone < ApplicationRecord
|
2
|
-
|
3
|
-
belongs_to :phoneable, polymorphic: true
|
4
|
+
include Labelize
|
5
|
+
belongs_to :phoneable, polymorphic: true, optional: true
|
4
6
|
before_validation :canonicalize
|
5
7
|
|
6
8
|
def self.canonicalize(digits_and_stuff)
|
7
|
-
canonical = digits_and_stuff
|
8
|
-
canonical.gsub!(" ", "") #remove extra spaces
|
9
|
+
canonical = digits_and_stuff.gsub(" ", "")
|
9
10
|
if canonical
|
10
11
|
canonical = canonical[2..100].strip if canonical.starts_with?("+1")
|
11
|
-
if
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
if self.const_defined?("PhonyRails")
|
13
|
+
canonical = PhonyRails.normalize_number(digits_and_stuff, default_country_code: "US").phony_formatted(format: :international)
|
14
|
+
else
|
15
|
+
if canonical[0] != "+"
|
16
|
+
digits = digits_and_stuff.gsub(/[^0-9]/, "")
|
17
|
+
digits = digits[1..-1] if digits[0] == '1'
|
18
|
+
digits = "805" + digits if digits.length == 7
|
19
|
+
canonical = "(#{digits[0..2]}) #{digits[3..5]}-#{digits[6..10]}"
|
20
|
+
end
|
16
21
|
end
|
17
22
|
end
|
18
23
|
canonical
|
@@ -23,4 +28,18 @@ class Phone < ApplicationRecord
|
|
23
28
|
self.number = self.class.canonicalize(self.number) if self.number
|
24
29
|
end
|
25
30
|
|
31
|
+
def label
|
32
|
+
db_label = super
|
33
|
+
if not db_label
|
34
|
+
self.label = "Work"
|
35
|
+
db_label = super
|
36
|
+
end
|
37
|
+
|
38
|
+
db_label.value
|
39
|
+
end
|
40
|
+
|
41
|
+
def label=(name)
|
42
|
+
super(Label.get(name))
|
43
|
+
self.label
|
44
|
+
end
|
26
45
|
end
|
data/app/models/user.rb
CHANGED
@@ -11,7 +11,8 @@ class User < ApplicationRecord
|
|
11
11
|
|
12
12
|
def self.lookup(item)
|
13
13
|
person = Person.lookup(item)
|
14
|
-
|
14
|
+
this_class = self.name.downcase.to_sym
|
15
|
+
(person.send this_class) if person and person.respond_to?(this_class)
|
15
16
|
end
|
16
17
|
|
17
18
|
def organization=(org)
|
@@ -28,5 +29,4 @@ class User < ApplicationRecord
|
|
28
29
|
end
|
29
30
|
super(attr)
|
30
31
|
end
|
31
|
-
|
32
32
|
end
|
@@ -5,7 +5,7 @@ module Openopus
|
|
5
5
|
initializer :append_migrations do |app|
|
6
6
|
unless app.root.to_s.match(root.to_s)
|
7
7
|
config.paths["db/migrate"].expanded.each do |expanded_path|
|
8
|
-
app.config.paths["db/migrate"] << expanded_path
|
8
|
+
# app.config.paths["db/migrate"] << expanded_path
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openopus-core-people
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian J. Fox
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 5.2.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 5.2.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 3.1.13
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: phony_rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.14'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.14'
|
41
55
|
description: A person can have many email addresses, but this is not usually represented
|
42
56
|
in applications. openopus/core/people creates the database structure, relations,
|
43
57
|
and convenience functions for your application so you don't have to. Just connect
|
@@ -53,6 +67,7 @@ files:
|
|
53
67
|
- Rakefile
|
54
68
|
- app/assets/config/openopus_core_people_manifest.js
|
55
69
|
- app/models/address.rb
|
70
|
+
- app/models/concerns/labelize.rb
|
56
71
|
- app/models/email.rb
|
57
72
|
- app/models/label.rb
|
58
73
|
- app/models/nickname.rb
|
@@ -95,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
110
|
- !ruby/object:Gem::Version
|
96
111
|
version: '0'
|
97
112
|
requirements: []
|
98
|
-
rubygems_version: 3.
|
113
|
+
rubygems_version: 3.1.2
|
99
114
|
signing_key:
|
100
115
|
specification_version: 4
|
101
116
|
summary: Model the real world of people in your application, making user interaction
|