Add face importing from github.
This commit is contained in:
parent
d38a867de1
commit
7ec94ec686
9 changed files with 111 additions and 13 deletions
|
@ -3,10 +3,8 @@ defmodule Faces.Gallery do
|
||||||
The Gallery context.
|
The Gallery context.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import Ecto.Query, warn: false
|
|
||||||
alias Faces.Repo
|
alias Faces.Repo
|
||||||
|
alias Faces.Gallery.{Person, Importer}
|
||||||
alias Faces.Gallery.Person
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns the list of people.
|
Returns the list of people.
|
||||||
|
@ -20,4 +18,6 @@ defmodule Faces.Gallery do
|
||||||
def list_people do
|
def list_people do
|
||||||
Repo.all(Person)
|
Repo.all(Person)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def import_user(username), do: Importer.import(username)
|
||||||
end
|
end
|
||||||
|
|
49
lib/faces/gallery/github_user_data.ex
Normal file
49
lib/faces/gallery/github_user_data.ex
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
defmodule Faces.Gallery.GithubUserData do
|
||||||
|
alias Tentacat.{Client, Users}
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Retrieves a user's information from GitHub.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> GitHubUserData.get("jamesotron")
|
||||||
|
{:ok, %{
|
||||||
|
"avatar_url" => "https://avatars2.githubusercontent.com/u/59449?v=4",
|
||||||
|
"location" => "Wellington, New Zealand",
|
||||||
|
"name" => "James Harton",
|
||||||
|
"username" => "jamesotron"
|
||||||
|
}}
|
||||||
|
|
||||||
|
iex> GitHubUserData.get("thisUserReallyDoesntExist")
|
||||||
|
{:error, "404 while retrieving thisUserReallyDoesntExist from Github: Not Found"}
|
||||||
|
"""
|
||||||
|
def get(username) do
|
||||||
|
with {200, user_data, _} <- get_user_from_github(username),
|
||||||
|
{:ok, user_data} <- just_the_facts(user_data),
|
||||||
|
{:ok, user_data} <- add_username(username, user_data) do
|
||||||
|
{:ok, user_data}
|
||||||
|
else
|
||||||
|
{:error, reason} ->
|
||||||
|
{:error, reason}
|
||||||
|
|
||||||
|
{i, %{"message" => message}, _} when is_integer(i) ->
|
||||||
|
{:error, "#{i} while retrieving #{username} from Github: #{message}"}
|
||||||
|
|
||||||
|
{i, _, _} when is_integer(i) ->
|
||||||
|
{:error, "#{i} while retrieving #{username} from Github"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp get_user_from_github(username) do
|
||||||
|
username
|
||||||
|
|> Users.find(Client.new())
|
||||||
|
end
|
||||||
|
|
||||||
|
defp just_the_facts(user_data) do
|
||||||
|
{:ok, Map.take(user_data, ["avatar_url", "name", "location"])}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp add_username(username, user_data) do
|
||||||
|
{:ok, Map.put(user_data, "username", username)}
|
||||||
|
end
|
||||||
|
end
|
23
lib/faces/gallery/importer.ex
Normal file
23
lib/faces/gallery/importer.ex
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
defmodule Faces.Gallery.Importer do
|
||||||
|
alias Faces.Gallery.{Person, GithubUserData}
|
||||||
|
alias Faces.Repo
|
||||||
|
|
||||||
|
def import(username) do
|
||||||
|
with {:ok, user_data} <- GithubUserData.get(username),
|
||||||
|
{:ok, changeset} <- generate_changeset(user_data),
|
||||||
|
{:ok, person} <- upsert(changeset) do
|
||||||
|
{:ok, person}
|
||||||
|
else
|
||||||
|
{:error, reason} -> {:error, reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp generate_changeset(user_data) do
|
||||||
|
{:ok, Person.changeset(%Person{}, user_data)}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp upsert(changeset) do
|
||||||
|
changeset
|
||||||
|
|> Repo.insert(on_conflict: :replace_all, conflict_target: [:username])
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,11 +2,11 @@ defmodule Faces.Gallery.Person do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
|
||||||
schema "people" do
|
schema "people" do
|
||||||
field :avatar_url, :string
|
field(:username, :string)
|
||||||
field :location, :string
|
field(:avatar_url, :string)
|
||||||
field :name, :string
|
field(:location, :string)
|
||||||
|
field(:name, :string)
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
@ -14,7 +14,7 @@ defmodule Faces.Gallery.Person do
|
||||||
@doc false
|
@doc false
|
||||||
def changeset(person, attrs) do
|
def changeset(person, attrs) do
|
||||||
person
|
person
|
||||||
|> cast(attrs, [:name, :location, :avatar_url])
|
|> cast(attrs, [:username, :name, :location, :avatar_url])
|
||||||
|> validate_required([:name, :location, :avatar_url])
|
|> validate_required([:username, :name, :avatar_url])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
3
mix.exs
3
mix.exs
|
@ -40,7 +40,8 @@ defmodule Faces.Mixfile do
|
||||||
{:phoenix_html, "~> 2.10"},
|
{:phoenix_html, "~> 2.10"},
|
||||||
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
||||||
{:gettext, "~> 0.11"},
|
{:gettext, "~> 0.11"},
|
||||||
{:cowboy, "~> 1.0"}
|
{:cowboy, "~> 1.0"},
|
||||||
|
{:tentacat, "~> 0.9.0"}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
12
mix.lock
12
mix.lock
|
@ -1,13 +1,22 @@
|
||||||
%{
|
%{
|
||||||
|
"certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
|
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
|
||||||
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
|
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"},
|
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"},
|
||||||
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
|
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
|
||||||
"ecto": {:hex, :ecto, "2.2.9", "031d55df9bb430cb118e6f3026a87408d9ce9638737bda3871e5d727a3594aae", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
"ecto": {:hex, :ecto, "2.2.9", "031d55df9bb430cb118e6f3026a87408d9ce9638737bda3871e5d727a3594aae", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
|
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"file_system": {:hex, :file_system, "0.2.4", "f0bdda195c0e46e987333e986452ec523aed21d784189144f647c43eaf307064", [:mix], [], "hexpm"},
|
"file_system": {:hex, :file_system, "0.2.4", "f0bdda195c0e46e987333e986452ec523aed21d784189144f647c43eaf307064", [:mix], [], "hexpm"},
|
||||||
"gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm"},
|
"gettext": {:hex, :gettext, "0.15.0", "40a2b8ce33a80ced7727e36768499fc9286881c43ebafccae6bab731e2b2b8ce", [:mix], [], "hexpm"},
|
||||||
|
"hackney": {:hex, :hackney, "1.12.1", "8bf2d0e11e722e533903fe126e14d6e7e94d9b7983ced595b75f532e04b7fdc7", [:rebar3], [{:certifi, "2.3.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.1", [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.1", "cbc3b2fa1645113267cc59c760bafa64b2ea0334635ef06dbac8801e42f7279c", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"},
|
||||||
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
||||||
"mime": {:hex, :mime, "1.2.0", "78adaa84832b3680de06f88f0997e3ead3b451a440d183d688085be2d709b534", [:mix], [], "hexpm"},
|
"mime": {:hex, :mime, "1.2.0", "78adaa84832b3680de06f88f0997e3ead3b451a440d183d688085be2d709b534", [:mix], [], "hexpm"},
|
||||||
|
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
|
||||||
|
"parse_trans": {:hex, :parse_trans, "3.2.0", "2adfa4daf80c14dc36f522cf190eb5c4ee3e28008fc6394397c16f62a26258c2", [:rebar3], [], "hexpm"},
|
||||||
"phoenix": {:hex, :phoenix, "1.3.2", "2a00d751f51670ea6bc3f2ba4e6eb27ecb8a2c71e7978d9cd3e5de5ccf7378bd", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
"phoenix": {:hex, :phoenix, "1.3.2", "2a00d751f51670ea6bc3f2ba4e6eb27ecb8a2c71e7978d9cd3e5de5ccf7378bd", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"phoenix_ecto": {:hex, :phoenix_ecto, "3.3.0", "702f6e164512853d29f9d20763493f2b3bcfcb44f118af2bc37bb95d0801b480", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
"phoenix_ecto": {:hex, :phoenix_ecto, "3.3.0", "702f6e164512853d29f9d20763493f2b3bcfcb44f118af2bc37bb95d0801b480", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"phoenix_html": {:hex, :phoenix_html, "2.11.1", "77b6f7fbd252168c6ec4f573de648d37cc5258cda13266ef001fbf99267eb6f3", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
"phoenix_html": {:hex, :phoenix_html, "2.11.1", "77b6f7fbd252168c6ec4f573de648d37cc5258cda13266ef001fbf99267eb6f3", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
@ -18,4 +27,7 @@
|
||||||
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
|
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
|
||||||
"postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
|
"postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
|
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
|
||||||
|
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"},
|
||||||
|
"tentacat": {:hex, :tentacat, "0.9.0", "c773d6d3def1a37296330c2787549c0f0f507f45b3a580d32d7d8aa3fdd56d3f", [:mix], [{:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.8", [hex: :httpoison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,14 @@ defmodule Faces.Repo.Migrations.CreatePeople do
|
||||||
|
|
||||||
def change do
|
def change do
|
||||||
create table(:people) do
|
create table(:people) do
|
||||||
add :name, :string
|
add(:username, :string)
|
||||||
add :location, :string
|
add(:name, :string)
|
||||||
add :avatar_url, :string
|
add(:location, :string)
|
||||||
|
add(:avatar_url, :string)
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create(index(:people, [:username], unique: true))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,3 +9,9 @@
|
||||||
#
|
#
|
||||||
# We recommend using the bang functions (`insert!`, `update!`
|
# We recommend using the bang functions (`insert!`, `update!`
|
||||||
# and so on) as they will fail if something goes wrong.
|
# and so on) as they will fail if something goes wrong.
|
||||||
|
|
||||||
|
alias Faces.Gallery
|
||||||
|
|
||||||
|
Gallery.import_user("jamesotron")
|
||||||
|
Gallery.import_user("terrcin")
|
||||||
|
Gallery.import_user("edgurgel")
|
||||||
|
|
5
test/faces/gallery/github_user_data_test.exs
Normal file
5
test/faces/gallery/github_user_data_test.exs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
defmodule FacesGalleryGithubUserDataTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
alias Faces.Gallery.GithubUserData
|
||||||
|
doctest Faces.Gallery.GithubUserData
|
||||||
|
end
|
Reference in a new issue