-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
93bb62e
commit c279785
Showing
14 changed files
with
283 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
defmodule Plausible.Geo do | ||
@moduledoc "Geolocation functions" | ||
@adapter Application.compile_env!(:plausible, [__MODULE__, :adapter]) | ||
|
||
@doc """ | ||
Looks up geo info about an ip address. | ||
Example: | ||
iex> lookup("8.7.6.5") | ||
%{ | ||
"city" => %{ | ||
"geoname_id" => 5349755, | ||
"names" => %{ | ||
"de" => "Fontana", | ||
"en" => "Fontana", | ||
"ja" => "フォンタナ", | ||
"ru" => "Фонтана" | ||
} | ||
}, | ||
"continent" => %{ | ||
"code" => "NA", | ||
"geoname_id" => 6255149, | ||
"names" => %{ | ||
"de" => "Nordamerika", | ||
"en" => "North America", | ||
"es" => "Norteamérica", | ||
"fr" => "Amérique du Nord", | ||
"ja" => "北アメリカ", | ||
"pt-BR" => "América do Norte", | ||
"ru" => "Северная Америка", | ||
"zh-CN" => "北美洲" | ||
} | ||
}, | ||
"country" => %{ | ||
"geoname_id" => 6252001, | ||
"iso_code" => "US", | ||
"names" => %{ | ||
"de" => "Vereinigte Staaten", | ||
"en" => "United States", | ||
"es" => "Estados Unidos", | ||
"fr" => "États Unis", | ||
"ja" => "アメリカ", | ||
"pt-BR" => "EUA", | ||
"ru" => "США", | ||
"zh-CN" => "美国" | ||
} | ||
}, | ||
"location" => %{ | ||
"accuracy_radius" => 50, | ||
"latitude" => 34.1211, | ||
"longitude" => -117.4362, | ||
"metro_code" => 803, | ||
"time_zone" => "America/Los_Angeles" | ||
}, | ||
"postal" => %{"code" => "92336"}, | ||
"registered_country" => %{ | ||
"geoname_id" => 6252001, | ||
"iso_code" => "US", | ||
"names" => %{ | ||
"de" => "Vereinigte Staaten", | ||
"en" => "United States", | ||
"es" => "Estados Unidos", | ||
"fr" => "États Unis", | ||
"ja" => "アメリカ", | ||
"pt-BR" => "EUA", | ||
"ru" => "США", | ||
"zh-CN" => "美国" | ||
} | ||
}, | ||
"subdivisions" => [ | ||
%{ | ||
"geoname_id" => 5332921, | ||
"iso_code" => "CA", | ||
"names" => %{ | ||
"de" => "Kalifornien", | ||
"en" => "California", | ||
"es" => "California", | ||
"fr" => "Californie", | ||
"ja" => "カリフォルニア州", | ||
"pt-BR" => "Califórnia", | ||
"ru" => "Калифорния", | ||
"zh-CN" => "加州" | ||
} | ||
} | ||
] | ||
} | ||
""" | ||
def lookup(ip_address) do | ||
@adapter.lookup(ip_address) | ||
end | ||
|
||
@doc """ | ||
Starts the geodatabase loading process. Two options are supported, local file and maxmind key. | ||
Loading a local file: | ||
iex> load_db(path: "/etc/plausible/dbip-city.mmdb") | ||
:ok | ||
Loading a maxmind db: | ||
# this license key is no longer active | ||
iex> load_db(license_key: "LNpsJCCKPis6XvBP", edition: "GeoLite2-City", async: true) | ||
:ok | ||
""" | ||
def load_db(opts \\ []) do | ||
@adapter.load_db(opts) | ||
end | ||
|
||
@doc """ | ||
Returns geodatabase type. Used for deciding whether to show the DBIP disclaimer. | ||
Example: | ||
# in the case of a dbip db | ||
iex> database_type() | ||
"DBIP-City-Lite" | ||
# in the case of a maxmind db | ||
iex> database_type() | ||
"GeoLite2-City" | ||
""" | ||
def database_type do | ||
@adapter.database_type() | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
defmodule Plausible.Geo.Adapter do | ||
@moduledoc "Behaviour to be implemented by geolocation adapters" | ||
|
||
@type entry :: map | ||
@type opts :: Keyword.t() | ||
@type ip_address :: :inet.ip_address() | String.t() | ||
|
||
@callback load_db(opts) :: :ok | ||
@callback database_type :: String.t() | nil | ||
@callback lookup(ip_address) :: entry | nil | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
defmodule Plausible.Geo.Locus do | ||
@moduledoc false | ||
@behaviour Plausible.Geo.Adapter | ||
@db :geolocation | ||
|
||
@impl true | ||
def load_db(opts) do | ||
cond do | ||
license_key = opts[:license_key] -> | ||
edition = opts[:edition] || "GeoLite2-City" | ||
:ok = :locus.start_loader(@db, {:maxmind, edition}, license_key: license_key) | ||
|
||
path = opts[:path] -> | ||
:ok = :locus.start_loader(@db, path) | ||
|
||
true -> | ||
raise "failed to load geolocation db: need :path or :license_key to be provided" | ||
end | ||
|
||
unless opts[:async] do | ||
{:ok, _version} = :locus.await_loader(@db) | ||
end | ||
|
||
:ok | ||
end | ||
|
||
@impl true | ||
def database_type do | ||
case :locus.get_info(@db, :metadata) do | ||
{:ok, %{database_type: type}} -> type | ||
_other -> nil | ||
end | ||
end | ||
|
||
@impl true | ||
def lookup(ip_address) do | ||
case :locus.lookup(@db, ip_address) do | ||
{:ok, entry} -> | ||
entry | ||
|
||
:not_found -> | ||
nil | ||
|
||
{:error, reason} -> | ||
raise "failed to lookup ip address #{inspect(ip_address)}: " <> inspect(reason) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.