Current section
Files
Jump to
Current section
Files
lib/smee_orgs/ror.ex
defmodule SmeeOrgs.ROR do
@moduledoc false
require Logger
alias SmeeOrgs.Normalize
alias SmeeOrgs.Organization
alias SmeeOrgs.Utils
@spec get(org :: Organization.t()) :: ROR.Organization.t() | nil
def get(%{ror: nil} = org) do
try do
Organization.aggregated_text(org)
|> String.slice(0..127)
|> String.replace_trailing("LLC", "") # Too many Lakeland Colleges! Bug in ROR?
|> ROR.chosen_organization!() ## Bug in ROR package, need to fix then rewrite this.
rescue
oops ->
Logger.error("Could not get ROR record for #{org.noid} so returning nil, error was: #{Exception.message(oops)}")
nil
end
end
def get(org) do
try do
ROR.get!(org.ror)
rescue
oops ->
Logger.error(
"Could not retrieve ROR record #{org.ror} so searching instead. Error was: #{Exception.message(oops)}"
)
get(%{org | ror: nil})
end
end
@spec overlay(org :: Organization.t()) :: Organization.t()
def overlay(org) do
org
|> get()
|> apply_ror_overlay(org)
end
#####################
@spec apply_ror_overlay(ror :: ROR.Organization.t() | nil, org :: Organization.t()) :: Organization.t()
defp apply_ror_overlay(nil, org) do
org
end
defp apply_ror_overlay(ror, org) do
website = website(ror)
base_domain = if website, do: Normalize.base_domain(website), else: org.base_domain
overlay = %{
ror: ror.id,
base_domain: base_domain,
domains: Utils.add_to_unique_list(org.domains, ror.domains),
displaynames: Utils.merge_lang_maps(org.displaynames, Normalize.lang_map(names(ror))),
country: country(ror),
location: location(ror),
wikipedia: wikipedia(ror),
type: type(ror),
tags: Utils.add_to_unique_list(org.tags, [:ror])
}
struct!(org, overlay)
end
@spec location(ror :: ROR.Organization.t()) :: binary() | nil
defp location(%{locations: [%{name: name}]}) do
name
end
defp location(_) do
nil
end
@spec country(ror :: ROR.Organization.t()) :: binary() | nil
defp country(%{locations: [%{country_code: country}]}) do
country
end
defp country(_) do
nil
end
@spec type(ror :: ROR.Organization.t()) :: atom()
defp type(%{types: types}) do
types = List.delete(types, "funder")
cond do
:education in types -> :education
:archive in types -> :archive
:company in types -> :company
:government in types -> :government
:nonprofit in types -> :nonprofit
:facility in types -> :facility
:healthcare in types -> :healthcare
:other in types -> :other
true -> :unknown
end
end
@spec names(ror :: ROR.Organization.t()) :: map()
defp names(ror) do
Map.get(ror, :names, [])
|> Enum.filter(fn name -> :label in name.types end)
|> Enum.map(fn name -> {name.lang, name.value} end)
|> Map.new()
end
@spec wikipedia(ror :: ROR.Organization.t()) :: binary() | nil
defp wikipedia(ror) do
Map.get(ror, :links, [])
|> Enum.find(%{value: nil}, fn link -> link.type == :wikipedia end)
|> Map.get(:value)
end
@spec website(ror :: ROR.Organization.t()) :: binary() | nil
defp website(ror) do
Map.get(ror, :links, [])
|> Enum.find(%{value: nil}, fn link -> link.type == :website end)
|> Map.get(:value)
end
end