From 02cd93596c7de6716a83a7623d5917f53c273911 Mon Sep 17 00:00:00 2001 From: Pedro Vieira Date: Mon, 23 Oct 2017 11:14:16 -0200 Subject: [PATCH 1/2] support_to_api_v2 --- README.md | 38 ++++++++--- lib/excountries/api.ex | 26 +++++++- lib/excountries/country.ex | 29 ++++++++- lib/excountries/radar.ex | 58 ++++++++++------- mix.exs | 14 +---- mix.lock | 10 +-- test/excountries/radar_test.exs | 108 +++++++++----------------------- 7 files changed, 150 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index db25ad2..31da90b 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ First, add Excountries to your `mix.exs` dependencies: ```elixir def deps do - [{:excountries, "~> 0.0.1"}] + [{:excountries, "~> 0.0.4"}] end ``` -and run `$ mix deps.get`. +and run `$ mix deps.get`. ## Usage @@ -74,7 +74,7 @@ Searches for the country by it's calling code: Excountries.Radar.by_calling_code("01") ``` -### Region +### Region Searches for the country by it's region: @@ -82,7 +82,7 @@ Searches for the country by it's region: Excountries.Radar.by_region("Oceania") ``` -### Subregion +### Subregion Searches for the country by it's subregion: @@ -98,25 +98,47 @@ Searches for the country by it's country code: Excountries.Radar.by_country_code("MKD") ``` +### Regional bloc + +Searches for the country by it's regional bloc: + +```elixir + Excountries.Radar.by_regional_bloc("eu") +``` + ## ```Country``` ```%Excountries.Country``` is a struct containing multiple properties: - name + - topLevelDomain + - alpha2Code + - alpha3Code + - callingCodes - capital - - relevance + - altSpellings - region - subregion - population - - latitude - - longitude + - latlng - demonym - area + - gini - timezones + - borders - nativeName - - topLevelDomain + - numericCode - currencies - languages + - translations + - flag + - regionalBlocs + - cioc + +## News + +- **2017/10/23** + - Added support to API v2 (Thanks to Pedro Vieira) ## Contributing diff --git a/lib/excountries/api.ex b/lib/excountries/api.ex index 03b1b02..9809d47 100644 --- a/lib/excountries/api.ex +++ b/lib/excountries/api.ex @@ -1,8 +1,28 @@ defmodule Excountries.API do - @url "https://restcountries.eu/rest/v1" + @url "https://restcountries.eu/rest/v2" - def call path do - %{ body: body, headers: _headers, status_code: status_code } = HTTPoison.get! "#{@url}#{path}" + def call(path, fields) do + %{ body: body, headers: _headers, status_code: status_code } = + case fields == nil do + true -> + HTTPoison.get!("#{@url}#{path}") + false -> + HTTPoison.get!("#{@url}#{path}", [], [params: [{"fields", fields}]]) + end + case status_code do + 200 -> body + _ -> throw "Not found." + end + end + + def call_fulltext(path, fields) do + %{ body: body, headers: _headers, status_code: status_code } = + case fields == nil do + true -> + HTTPoison.get!("#{@url}#{path}", [], [params: [{"fullText", true}]]) + false -> + HTTPoison.get!("#{@url}#{path}", [], [params: [{"fullText", true}, {"fields", fields}]]) + end case status_code do 200 -> body _ -> throw "Not found." diff --git a/lib/excountries/country.ex b/lib/excountries/country.ex index f096041..4a0eee4 100644 --- a/lib/excountries/country.ex +++ b/lib/excountries/country.ex @@ -1,7 +1,30 @@ defmodule Excountries.Country do @derive [Poison.Encoder] - defstruct [:name, :capital, :relevance, :region, :subregion, :population, - :latitude, :longitude, :demonym, :area, :timezones, :nativeName, :topLevelDomain, - :currencies, :languages] + defstruct [ + :name, + :topLevelDomain, + :alpha2Code, + :alpha3Code, + :callingCodes, + :capital, + :altSpellings, + :region, + :subregion, + :population, + :latlng, + :demonym, + :area, + :gini, + :timezones, + :borders, + :nativeName, + :numericCode, + :currencies, + :languages, + :translations, + :flag, + :regionalBlocs, + :cioc + ] end diff --git a/lib/excountries/radar.ex b/lib/excountries/radar.ex index 76740f7..d6767d4 100644 --- a/lib/excountries/radar.ex +++ b/lib/excountries/radar.ex @@ -14,8 +14,11 @@ defmodule Excountries.Radar do * by_country_code * by_region * by_subregion + * by_regional_bloc """ + alias Excountries.API + @doc """ Returns all of the countries in a list. @@ -23,8 +26,8 @@ defmodule Excountries.Radar do Excountries.Radar.all() ``` """ - def all(client \\ Excountries.API) do - client.call("/all") |> Poison.decode!(as: [Excountries.Country]) + def all(fields \\ nil) do + API.call("/all", fields) |> Poison.decode!(as: [Excountries.Country]) end @doc """ @@ -34,11 +37,11 @@ defmodule Excountries.Radar do Excountries.Radar.by_full_name("United States Of America") ``` """ - def by_full_name(name, client \\ Excountries.API) do + def by_full_name(name, fields \\ nil) do name = String.downcase name - client.call("/name/#{name}?fullText=true") |> Poison.decode!(as: [Excountries.Country]) |> List.first + API.call_fulltext("/name/#{name}", fields) |> Poison.decode!(as: [Excountries.Country]) |> List.first end - + @doc """ Searches for a country by a substring of it's name or abbreviation: @@ -46,9 +49,9 @@ defmodule Excountries.Radar do Excountries.Radar.by_name("USA") ``` """ - def by_name(name, client \\ Excountries.API) do + def by_name(name, fields \\ nil) do name = String.downcase name - client.call("/name/#{name}") |> Poison.decode!(as: [Excountries.Country]) + API.call("/name/#{name}", fields) |> Poison.decode!(as: [Excountries.Country]) end @doc """ @@ -58,9 +61,9 @@ defmodule Excountries.Radar do Excountries.Radar.by_language("en") ``` """ - def by_language(lang, client \\ Excountries.API) do - Excountries.LanguageValidator.validate!(lang) - client.call("/lang/#{lang}") |> Poison.decode!(as: [Excountries.Country]) + def by_language(lang, fields \\ nil) do + Excountries.LanguageValidator.validate!(lang) + API.call("/lang/#{lang}", fields) |> Poison.decode!(as: [Excountries.Country]) end @doc """ @@ -70,8 +73,8 @@ defmodule Excountries.Radar do Excountries.Radar.by_currency("USD") ``` """ - def by_currency(currency, client \\ Excountries.API) do - client.call("/currency/#{currency}") |> Poison.decode!(as: [Excountries.Country]) + def by_currency(currency, fields \\ nil) do + API.call("/currency/#{currency}", fields) |> Poison.decode!(as: [Excountries.Country]) end @doc """ @@ -81,8 +84,8 @@ defmodule Excountries.Radar do Excountries.Radar.by_capital("USD") ``` """ - def by_capital(capital, client \\ Excountries.API) do - client.call("/capital/#{capital}") |> Poison.decode!(as: [Excountries.Country]) |> List.first + def by_capital(capital, fields \\ nil) do + API.call("/capital/#{capital}", fields) |> Poison.decode!(as: [Excountries.Country]) |> List.first end @doc """ @@ -92,8 +95,8 @@ defmodule Excountries.Radar do Excountries.Radar.by_calling_code("01") ``` """ - def by_calling_code(code, client \\ Excountries.API) do - client.call("/calling_code/#{code}") |> Poison.decode!(as: [Excountries.Country]) + def by_calling_code(code, fields \\ nil) do + API.call("/calling_code/#{code}", fields) |> Poison.decode!(as: [Excountries.Country]) end @doc """ @@ -103,8 +106,8 @@ defmodule Excountries.Radar do Excountries.Radar.by_region("Oceania") ``` """ - def by_region(region, client \\ Excountries.API) do - client.call("/region/#{region}") |> Poison.decode!(as: [Excountries.Country]) + def by_region(region, fields \\ nil) do + API.call("/region/#{region}", fields) |> Poison.decode!(as: [Excountries.Country]) end @doc """ @@ -114,8 +117,8 @@ defmodule Excountries.Radar do Excountries.Radar.by_subregion("Polynesia") ``` """ - def by_subregion(subregion, client \\ Excountries.API) do - client.call("/subregion/#{subregion}") |> Poison.decode!(as: [Excountries.Country]) + def by_subregion(subregion, fields \\ nil) do + API.call("/subregion/#{subregion}", fields) |> Poison.decode!(as: [Excountries.Country]) end @doc """ @@ -125,7 +128,18 @@ defmodule Excountries.Radar do Excountries.Radar.by_country_code("MKD") ``` """ - def by_country_code(code, client \\ Excountries.API) do - client.call("/alpha/#{code}") |> Poison.decode!(as: [Excountries.Country]) + def by_country_code(code, fields \\ nil) do + API.call("/alpha/#{code}", fields) |> Poison.decode!(as: [Excountries.Country]) + end + + @doc """ + Searches for the country by it's regional bloc: + + ``` + Excountries.Radar.by_regional_bloc("eu") + ``` + """ + def by_regional_bloc(regionalbloc, fields \\ nil) do + API.call("/regionalbloc/#{regionalbloc}", fields) |> Poison.decode!(as: [Excountries.Country]) end end diff --git a/mix.exs b/mix.exs index 108c288..aa561d1 100644 --- a/mix.exs +++ b/mix.exs @@ -3,7 +3,7 @@ defmodule Excountries.Mixfile do def project do [app: :excountries, - version: "0.0.3", + version: "0.0.4", elixir: "~> 1.0", build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod, @@ -12,22 +12,10 @@ defmodule Excountries.Mixfile do deps: deps] end - # Configuration for the OTP application - # - # Type `mix help compile.app` for more information def application do [applications: [:logger, :httpoison]] end - # Dependencies can be Hex packages: - # - # {:mydep, "~> 0.3.0"} - # - # Or git/path repositories: - # - # {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"} - # - # Type `mix help deps` for more examples and options defp deps do [ {:httpoison, "~> 0.7.2"}, diff --git a/mix.lock b/mix.lock index f4b1089..e3b05ba 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ -%{"hackney": {:hex, :hackney, "1.3.2"}, - "httpoison": {:hex, :httpoison, "0.7.4"}, - "idna": {:hex, :idna, "1.0.2"}, - "poison": {:hex, :poison, "1.5.0"}, - "ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.5"}} +%{"hackney": {:hex, :hackney, "1.3.2", "43bd07ab88753f5e136e38fddd2a09124bee25733b03361eeb459d0173fc17ab", [], [{:idna, "~> 1.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:ssl_verify_hostname, "~> 1.0.5", [hex: :ssl_verify_hostname, repo: "hexpm", optional: false]}], "hexpm"}, + "httpoison": {:hex, :httpoison, "0.7.4", "053fa5420c9a2f7792ab49c9963ce67ede8b81dd9a1d0a7123cce54028deeb05", [], [{:hackney, "~> 1.3.1", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "1.0.2", "397e3d001c002319da75759b0a81156bf11849c71d565162436d50020cb7265e", [], [], "hexpm"}, + "poison": {:hex, :poison, "1.5.0", "f2f4f460623a6f154683abae34352525e1d918380267cdbd949a07ba57503248", [], [], "hexpm"}, + "ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.5", "2e73e068cd6393526f9fa6d399353d7c9477d6886ba005f323b592d389fb47be", [], [], "hexpm"}} diff --git a/test/excountries/radar_test.exs b/test/excountries/radar_test.exs index efb6a0f..3685a81 100644 --- a/test/excountries/radar_test.exs +++ b/test/excountries/radar_test.exs @@ -1,99 +1,49 @@ defmodule Excountries.RadarTest do use ExUnit.Case - defmodule ClientMock do - def call(_path) do - ~s( - [ - { - "name": "Republic of Macedonia", - "capital": "Skopje", - "altSpellings": [ - "MK", - "Republic of Macedonia", - "Република Македонија" - ], - "relevance": "0", - "region": "Europe", - "subregion": "Southern Europe", - "translations": { - "de": "Mazedonien", - "es": "Macedonia", - "fr": "Macédoine", - "ja": "マケドニア旧ユーゴスラビア共和国", - "it": "Macedonia" - }, - "population": 2058539, - "latlng": [ - 41.83333333, - 22 - ], - "demonym": "Macedonian", - "area": 25713, - "gini": 43.2, - "timezones": [ - "UTC+01:00" - ], - "borders": [ - "ALB", - "BGR", - "GRC", - "KOS", - "SRB" - ], - "nativeName": "Македонија", - "callingCodes": [ - "389" - ], - "topLevelDomain": [ - ".mk" - ], - "alpha2Code": "MK", - "alpha3Code": "MKD", - "currencies": [ - "MKD" - ], - "languages": [ - "mk" - ] - } - ] - ) - end - end - test ".all returns a list of Country structs" do - countries = Excountries.Radar.all(ClientMock) - country = List.first countries - assert country.name, "Republic Of Macedonia" - assert country.capital, "Skopje" - assert country.region, "Europe" - assert country.relevance, "0" + countries = + Excountries.Radar.all("alpha2Code;capital") + |> Enum.filter(fn x -> x.alpha2Code == "MK" end) + |> List.first() + assert countries.capital, "Skopje" end test ".by_full_name returns the matching Country" do - country = Excountries.Radar.by_full_name("Republic Of Macedonia", ClientMock) - assert country.name, "Republic Of Macedonia" - assert country.capital, "Skopje" + country = Excountries.Radar.by_full_name("Spain") + assert country.capital, "Madrid" end test ".by_language returns the countries where the language is spoken" do - countries = Excountries.Radar.by_language("mk", ClientMock) + countries = Excountries.Radar.by_language("mk") country = List.first countries - assert country.name, "Republic Of Macedonia" - assert List.first(country.languages), "mk" + assert country.name, "Macedonia (the former Yugoslav Republic of)" end test ".by_currency returns the countries where the currency is used" do - countries = Excountries.Radar.by_currency("MKD", ClientMock) + countries = Excountries.Radar.by_currency("MKD") country = List.first countries - assert country.name, "Republic Of Macedonia" - assert List.first(country.currencies), "MKD" + assert country.name, "Macedonia (the former Yugoslav Republic of)" end test ".by_capital returns the country whose capital matches the name" do - country = Excountries.Radar.by_capital("Skopje", ClientMock) - assert country.name, "Republic Of Macedonia" - assert country.capital, "Skopje" + country = Excountries.Radar.by_capital("Skopje") + assert country.name, "Macedonia (the former Yugoslav Republic of)" + end + + test ".by_regional_bloc returns the country whose regional bloc matches the name" do + country = + Excountries.Radar.by_regional_bloc("eu") + |> Enum.filter(fn x -> x.alpha2Code == "ES" end) + |> List.first() + assert country.name, "Spain" + end + + test "with filter returns the country fields whose regional bloc matches the name" do + country = + Excountries.Radar.by_regional_bloc("eu", "name;alpha2Code;capital") + |> Enum.filter(fn x -> x.alpha2Code == "ES" end) + |> List.first() + assert country.name, "Spain" end end From 4dd8b7863fb70db4ea823da4db7773dadcd0a868 Mon Sep 17 00:00:00 2001 From: Pedro Vieira Date: Mon, 23 Oct 2017 17:56:11 -0200 Subject: [PATCH 2/2] elixir 1.5 & mix / deps update --- mix.exs | 12 ++++++------ mix.lock | 14 +++++++++----- test/excountries/radar_test.exs | 20 ++++++++++---------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/mix.exs b/mix.exs index aa561d1..b5f41f2 100644 --- a/mix.exs +++ b/mix.exs @@ -4,12 +4,12 @@ defmodule Excountries.Mixfile do def project do [app: :excountries, version: "0.0.4", - elixir: "~> 1.0", + elixir: "~> 1.5", build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod, - description: description, - package: package, - deps: deps] + description: description(), + package: package(), + deps: deps()] end def application do @@ -18,8 +18,8 @@ defmodule Excountries.Mixfile do defp deps do [ - {:httpoison, "~> 0.7.2"}, - {:poison, "~> 1.5"} + {:httpoison, "~> 0.13.0"}, + {:poison, "~> 3.1"} ] end diff --git a/mix.lock b/mix.lock index e3b05ba..1a0628b 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,9 @@ -%{"hackney": {:hex, :hackney, "1.3.2", "43bd07ab88753f5e136e38fddd2a09124bee25733b03361eeb459d0173fc17ab", [], [{:idna, "~> 1.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:ssl_verify_hostname, "~> 1.0.5", [hex: :ssl_verify_hostname, repo: "hexpm", optional: false]}], "hexpm"}, - "httpoison": {:hex, :httpoison, "0.7.4", "053fa5420c9a2f7792ab49c9963ce67ede8b81dd9a1d0a7123cce54028deeb05", [], [{:hackney, "~> 1.3.1", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, - "idna": {:hex, :idna, "1.0.2", "397e3d001c002319da75759b0a81156bf11849c71d565162436d50020cb7265e", [], [], "hexpm"}, - "poison": {:hex, :poison, "1.5.0", "f2f4f460623a6f154683abae34352525e1d918380267cdbd949a07ba57503248", [], [], "hexpm"}, - "ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.5", "2e73e068cd6393526f9fa6d399353d7c9477d6886ba005f323b592d389fb47be", [], [], "hexpm"}} +%{"certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.10.1", "c38d0ca52ea80254936a32c45bb7eb414e7a96a521b4ce76d00a69753b157f21", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "httpoison": {:hex, :httpoison, "0.13.0", "bfaf44d9f133a6599886720f3937a7699466d23bb0cd7a88b6ba011f53c6f562", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], [], "hexpm"}, + "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [], [], "hexpm"}} diff --git a/test/excountries/radar_test.exs b/test/excountries/radar_test.exs index 3685a81..ab94580 100644 --- a/test/excountries/radar_test.exs +++ b/test/excountries/radar_test.exs @@ -4,46 +4,46 @@ defmodule Excountries.RadarTest do test ".all returns a list of Country structs" do countries = Excountries.Radar.all("alpha2Code;capital") - |> Enum.filter(fn x -> x.alpha2Code == "MK" end) + |> Enum.filter(fn x -> x["alpha2Code"] == "MK" end) |> List.first() - assert countries.capital, "Skopje" + assert countries["capital"], "Skopje" end test ".by_full_name returns the matching Country" do country = Excountries.Radar.by_full_name("Spain") - assert country.capital, "Madrid" + assert country["capital"], "Madrid" end test ".by_language returns the countries where the language is spoken" do countries = Excountries.Radar.by_language("mk") country = List.first countries - assert country.name, "Macedonia (the former Yugoslav Republic of)" + assert country["name"], "Macedonia (the former Yugoslav Republic of)" end test ".by_currency returns the countries where the currency is used" do countries = Excountries.Radar.by_currency("MKD") country = List.first countries - assert country.name, "Macedonia (the former Yugoslav Republic of)" + assert country["name"], "Macedonia (the former Yugoslav Republic of)" end test ".by_capital returns the country whose capital matches the name" do country = Excountries.Radar.by_capital("Skopje") - assert country.name, "Macedonia (the former Yugoslav Republic of)" + assert country["name"], "Macedonia (the former Yugoslav Republic of)" end test ".by_regional_bloc returns the country whose regional bloc matches the name" do country = Excountries.Radar.by_regional_bloc("eu") - |> Enum.filter(fn x -> x.alpha2Code == "ES" end) + |> Enum.filter(fn x -> x["alpha2Code"] == "ES" end) |> List.first() - assert country.name, "Spain" + assert country["name"], "Spain" end test "with filter returns the country fields whose regional bloc matches the name" do country = Excountries.Radar.by_regional_bloc("eu", "name;alpha2Code;capital") - |> Enum.filter(fn x -> x.alpha2Code == "ES" end) + |> Enum.filter(fn x -> x["alpha2Code"] == "ES" end) |> List.first() - assert country.name, "Spain" + assert country["name"], "Spain" end end