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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed2fa95cbd0a805204b82dc871631f368ffb5f1a1eb402efef42af42b29119b0
4
- data.tar.gz: 9ba36a30fdd823dad235de6459fe7b92ce10a4ce0388f122de899db02ced33f3
3
+ metadata.gz: 5fa609ee836533103efd9cac7c3a00e6e3b91ad3ea48c5e2bf16ff11b84d9ed5
4
+ data.tar.gz: 61d6376f1ba54350b83f635fe82e98bfe09582593fc470bbdade7b8276b55fa3
5
5
  SHA512:
6
- metadata.gz: c5f7866c924421d780db37a67c7a9ff99d35e8f0a1ed52848bd510552a275fa08f7abf888ce8ddbea88f63731932683fef616c795c491b49f07d73774467b87c
7
- data.tar.gz: '08f906f0c78dd3ab81a32984c7efaf5c4bf76788edee1e5cd0d03376a5c8b0e73430e921bba7ec10f336e11329be94f6f0ade5b77f4f031fa47e2791a7070bbe'
6
+ metadata.gz: c540c01684241f7802028026e0d7a1cc60f7fb8297ed2f4d959c16cffdac9e3a2918c039666fad9d00af81d8f87e487bb9fe83b8d37df347115aa43f50ff3305
7
+ data.tar.gz: 3bea98e5e63b9a7932bda9838ed4872cde3ec27c132bd3ee5b576f5466e56fee2d19b0b47fc3354a480f60e966588d0b2a2e2d374a38d7b5f2f9fcbd9978021d
@@ -1,6 +1,6 @@
1
1
  class Address < ApplicationRecord
2
- belongs_to :label, optional: true
3
- belongs_to :addressable, polymorphic: true
2
+ include Labelize
3
+ belongs_to :addressable, polymorphic: true, optional: true
4
4
 
5
5
  accepts_nested_attributes_for :label
6
6
 
@@ -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
@@ -1,17 +1,27 @@
1
1
  class Email < ApplicationRecord
2
- belongs_to :label, optional: true
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
@@ -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
- people = self.all.collect do |p|
18
- [p.id, [(p.fname[0] || ""), (p.minitial[0] || ""), (p.lname[0] || "")].join("").upcase]
19
- end
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
 
@@ -1,18 +1,23 @@
1
+ require "phony_rails"
2
+
1
3
  class Phone < ApplicationRecord
2
- belongs_to :label, optional: true
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 canonical[0] != "+"
12
- digits = digits_and_stuff.gsub(/[^0-9]/, "")
13
- digits = digits[1..-1] if digits[0] == '1'
14
- digits = "805" + digits if digits.length == 7
15
- canonical = "(#{digits[0..2]}) #{digits[3..5]}-#{digits[6..10]}"
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
@@ -11,7 +11,8 @@ class User < ApplicationRecord
11
11
 
12
12
  def self.lookup(item)
13
13
  person = Person.lookup(item)
14
- (person.send self.name.downcase.to_sym) if person
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
@@ -1,7 +1,7 @@
1
1
  module Openopus
2
2
  module Core
3
3
  module People
4
- VERSION = '1.1.4'
4
+ VERSION = '1.1.10'
5
5
  end
6
6
  end
7
7
  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
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: 2019-09-10 00:00:00.000000000 Z
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.0.1
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