class LdapDisambiguate::Name

This class allows you to use LDAP to disambiguate a text name

Public Class Methods

clear_cache() click to toggle source
# File lib/ldap_disambiguate/name.rb, line 16
def clear_cache
  @email_for_name_cache = {}
end
disambiguate(name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 8
def disambiguate(name)
  return if name.blank?
  results = ldap_attributes_for_id(name) # text includes login id
  results ||= Email.disambiguate(name) # text includes email(s)
  results ||= lookup_text_only_names(name) # straight text we need to query ldap
  results
end

Private Class Methods

clean_name(name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 90
def clean_name(name)
  name.gsub(/\([^)]*\)/, '')
      .gsub(/[^\w\s,']/, ' ')
      .strip.squeeze(' ')
end
email_for_name(text_name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 37
def email_for_name(text_name)
  return '' if text_name.blank? || word_count(text_name) < 2
  return email_for_name_cache[text_name] if email_for_name_cache.key?(text_name)

  email_for_name_cache[text_name] = translate_name_to_email(text_name)
end
email_for_name_cache() click to toggle source
# File lib/ldap_disambiguate/name.rb, line 120
def email_for_name_cache
  @email_for_name_cache ||= {}
end
lookup_name(name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 29
def lookup_name(name)
  query_result = email_for_name(name)
  query_result ||= title_after_name(name) # try again without the titles
  query_result
rescue MultipleUserError
  return nil
end
lookup_text_only_names(multi_name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 22
def lookup_text_only_names(multi_name)
  results = separate_names(multi_name).map do |name|
    lookup_name(clean_name(name))
  end
  results.reject(&:blank?)
end
multi_word?(name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 96
def multi_word?(name)
  word_count(name) > 1
end
name_parts(text_name, last_name_count) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 82
def name_parts(text_name, last_name_count)
  return if word_count(text_name) < (last_name_count + 1)

  parts = split_name_parts(text_name)
  first_name_count = parts.count - last_name_count
  { given: parts.first(first_name_count).join(' '), family: parts.last(last_name_count).join(' ') }
end
only_initial?(name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 108
def only_initial?(name)
  name.size <= 1
end
remove_titles(name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 116
def remove_titles(name)
  name.split(',')[0]
end
separate_names(multi_name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 112
def separate_names(multi_name)
  multi_name.split(/ and |;/)
end
split_name_parts(name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 104
def split_name_parts(name)
  name.split(' ')
end
title_after_name(text_name) click to toggle source

titles after the name that namae had trouble parsing

# File lib/ldap_disambiguate/name.rb, line 45
def title_after_name(text_name)
  email_for_name(remove_titles(text_name))
end
title_before_name(parsed) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 66
def title_before_name(parsed)
  return unless parsed.given && multi_word?(parsed.given)

  parts = name_parts(parsed.given, 1)
  return if only_initial?(parts[:family])

  try_name(parts[:family], parsed.family)
end
translate_name_to_email(text_name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 49
def translate_name_to_email(text_name)
  parsed = Namae::Name.parse(text_name)

  result = try_name(parsed.given, parsed.family)
  result ||= title_before_name(parsed)
  result ||= two_words_in_last_name(text_name)
  result
end
try_name(given, family) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 58
def try_name(given, family)
  return nil if family.blank?

  possible_users = LdapUser.query_ldap_by_name(given, family, ldap_attrs)
  raise(MultipleUserError, "too name results for #{given} #{family}") if possible_users.count > 1
  possible_users.first
end
two_words_in_last_name(text_name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 75
def two_words_in_last_name(text_name)
  return unless word_count(text_name) > 2

  parts = name_parts(text_name, 2)
  try_name(parts[:given], parts[:family])
end
word_count(name) click to toggle source
# File lib/ldap_disambiguate/name.rb, line 100
def word_count(name)
  name.squeeze(' ').count(' ') + 1
end