Skip to content

Commit

Permalink
Merge pull request #155 from poacpm/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
Ken Matsui authored Oct 1, 2018
2 parents 308f8be + 95fc5cd commit 554abc4
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 125 deletions.
93 changes: 93 additions & 0 deletions lib/poacpm/util/firestore.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
defmodule Poacpm.Util.Firestore do
alias GoogleApi.Firestore.V1beta1.Api.Projects, as: Api


@project_id "poac-pm"
@database_id "(default)"


defp create_connection() do
{:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/cloud-platform")
GoogleApi.Firestore.V1beta1.Connection.new(token.token)
end

def get_docs_list(collection_id) do
{:ok, object} = Api.firestore_projects_databases_documents_list(
create_connection(),
"projects/#{@project_id}/databases/#{@database_id}/documents",
collection_id
)
object.documents
end

def create_doc(body) do
# Write package info to firestore
data = %{
:createTime => nil,
:fields => body |> typing,
:name => nil,
:updateTime => nil
}
{:ok, _object} = Api.firestore_projects_databases_documents_create_document(
create_connection(),
"projects/#{@project_id}/databases/#{@database_id}/documents",
"packages",
[body: data]
)
end


defp _typing(value) do
case value do
x when is_list(x) ->
%{arrayValue:
%{values:
Enum.map(x, fn y ->
_typing(y)
end)
}
}
x when is_map(x) ->
%{mapValue:
%{fields:
Enum.map(x, fn {k, v} ->
{k, _typing(v)}
end)
|> Enum.into(%{})
}
}
x when is_binary(x) ->
%{stringValue: x}
x when is_integer(x) ->
%{integerValue: x}
x when is_float(x) ->
%{doubleValue: x}
x when is_boolean(x) ->
%{booleanValue: x}
_ ->
%{nullValue: nil}
end
end
@doc """
%GoogleApi.Firestore.V1beta1.Model.Value{
arrayValue: nil,
booleanValue: nil,
bytesValue: nil,
doubleValue: nil,
geoPointValue: nil,
integerValue: nil,
mapValue: nil,
nullValue: nil,
referenceValue: nil,
stringValue: nil,
timestampValue: nil
}
"""
def typing(map) do
map
|> Enum.map(fn {k, v} ->
{k, _typing(v)}
end)
|> Enum.into(%{})
end
end
20 changes: 20 additions & 0 deletions lib/poacpm/util/gcs.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule Poacpm.Util.GCS do
alias GoogleApi.Storage.V1.Api.Objects, as: Api

@bucket_name "re.poac.pm"

defp create_connection() do
{:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/cloud-platform")
GoogleApi.Storage.V1.Connection.new(token.token)
end

def upload_file(filename, filepath) do
{:ok, _object} = Api.storage_objects_insert_simple(
create_connection(),
@bucket_name,
"multipart",
%{name: filename},
filepath
)
end
end
146 changes: 25 additions & 121 deletions lib/poacpm_web/controllers/api/v1/packages_controller.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
defmodule PoacpmWeb.Api.V1.PackagesController do
use PoacpmWeb, :controller
alias PoacpmWeb.Api.ErrorView
alias Poacpm.Util.Firestore
alias Poacpm.Util.GCS
import Phoenix.Controller, only: [
put_new_layout: 2,
put_new_view: 2,
Expand All @@ -9,102 +11,43 @@ defmodule PoacpmWeb.Api.V1.PackagesController do
]


@spec search(Plug.Conn.t(), map) :: Plug.Conn.t()
def search(conn, %{"q" => word}) do
# response =
# word
# |> ElasticSearch.suggest()
# |> suggest_to_list()

# json(conn, %{"packages" => response})
json(conn, %{"packages" => word})
# Check if package already exists
defp _exists(name, version) do
Firestore.get_docs_list("packages")
|> Enum.find_value(false, fn x ->
(name == x.fields["name"].stringValue) and
(version == x.fields["version"].stringValue)
end)
end
def search(conn, _), do: json(conn, ErrorView.render("404.json"))


def exists(conn, %{"name" => name, "version" => version}) do
get_docs_list_from_firestore("packages")
exst = get_docs_list_from_firestore("packages")
|> Enum.find_value(false, fn x ->
(name == x.fields["name"].stringValue) and
(version == x.fields["version"].stringValue)
end)
if exst do
text(conn, "true")
else
text(conn, "false")
end
res = (if _exists(name, version), do: "true", else: "false")
text(conn, res)
end
def exists(conn, _), do: json(conn, ErrorView.render("404.json"))


defp get_docs_list_from_firestore(collection_id) do
{:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/cloud-platform")
conn = GoogleApi.Firestore.V1beta1.Connection.new(token.token)

{:ok, object} = GoogleApi.Firestore.V1beta1.Api.Projects.firestore_projects_databases_documents_list(
conn,
"projects/poac-pm/databases/(default)/documents",
collection_id
)
object.documents
end

defp get_token_name(x) do
# "projects/{}/databases/{}/documents/tokens/ABCDEFG"
x.name
|> String.split("/")
|> List.last() # ABCDEFG
end

# Exists token and it owned by owners
defp _validate(token, owners) do
get_docs_list_from_firestore("tokens")
Firestore.get_docs_list("tokens")
|> Enum.find_value(false, fn x ->
(get_token_name(x) == token) and
Enum.member?(owners, x.fields["owner"].stringValue)
end)
end

def validate(conn, %{"token" => token, "owners" => owners}) do
if _validate(token, owners) do
text(conn, "ok")
else
text(conn, "err")
end
res = (if _validate(token, owners), do: "ok", else: "err")
text(conn, res)
end


@doc """
%GoogleApi.Firestore.V1beta1.Model.Value{
arrayValue: nil,
booleanValue: nil,
bytesValue: nil,
doubleValue: nil,
geoPointValue: nil,
integerValue: nil,
mapValue: nil,
nullValue: nil,
referenceValue: nil,
stringValue: nil,
timestampValue: nil
}
"""
defp _typing(value) do
case value do
x when is_list(x) -> %{arrayValue: %{values: Enum.map(x, fn y -> _typing(y) end)}}
x when is_map(x) -> %{mapValue: %{fields: Enum.map(x, fn {k, v} -> {k, _typing(v)} end) |> Enum.into(%{})}}
x when is_binary(x) -> %{stringValue: x}
x when is_integer(x) -> %{integerValue: x}
x when is_float(x) -> %{doubleValue: x}
x when is_boolean(x) -> %{booleanValue: x}
_ -> %{nullValue: nil}
end
end
defp typing(map) do
map
|> Enum.map(fn {k, v} -> {k, _typing(v)} end)
|> Enum.into(%{})
end

def upload(conn, %{"user" => user_params}) do
# Note: This file is temporary, and Plug will remove it
# from the directory as the request completes.
Expand All @@ -119,58 +62,19 @@ defmodule PoacpmWeb.Api.V1.PackagesController do
|> Poison.decode!()
|> Map.get("token")

# Exists token and it owned by owners
validation = get_docs_list_from_firestore("tokens")
|> Enum.find_value(false, fn x ->
(get_token_name(x) == token) and
Enum.member?(setting["owners"], x.fields["owner"].stringValue)
end)

# Check if package already exists
owners = setting["owners"]
name = setting["name"]
version = setting["version"]
# TODO: もし,存在していても,ownerが一致していれば,上書きができる(next version)
exists = get_docs_list_from_firestore("packages")
|> Enum.find_value(false, fn x ->
setting["name"] == x.fields["name"].stringValue and
setting["version"] == x.fields["version"].stringValue
end)

if validation and !exists do
# Write package info to firestore
data = %{
:createTime => nil,
:fields => setting |> typing,
:name => nil,
:updateTime => nil
}

{:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/cloud-platform")
conn_goth = GoogleApi.Firestore.V1beta1.Connection.new(token.token)
{:ok, _object} = GoogleApi.Firestore.V1beta1.Api.Projects.firestore_projects_databases_documents_create_document(
conn_goth,
"projects/poac-pm/databases/(default)/documents",
"packages",
[body: data]
)
if _validate(token, owners) and !_exists(name, version) do
Firestore.create_doc(setting)
# Upload to google cloud storage
upload_to_gcs(user_params["data"])
json(conn, %{"status" => "ok"})
file = user_params["data"]
GCS.upload_file(file.filename, file.path)
text(conn, "ok")
else
json(conn, %{"status" => "err"})
text(conn, "err")
end
end

defp upload_to_gcs(file) do
# Authenticate
{:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/cloud-platform")
conn = GoogleApi.Storage.V1.Connection.new(token.token)

# Make the API request
{:ok, _object} = GoogleApi.Storage.V1.Api.Objects.storage_objects_insert_simple(
conn,
"re.poac.pm",
"multipart",
%{name: file.filename},
file.path
)
end
end
4 changes: 0 additions & 4 deletions lib/poacpm_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,13 @@ defmodule PoacpmWeb.Router do

pipeline :api do
plug(:accepts, ["json"])
plug(:fetch_session)
# plug(:assign_current_user)
# plug(:assign_access_token)
end


scope "/api", PoacpmWeb.Api do
pipe_through(:api)

scope "/v1", V1 do
get("/packages/search", PackagesController, :search)
get("/packages/exists", PackagesController, :exists)
post("/packages/upload", PackagesController, :upload)
post("/packages/validate", PackagesController, :validate)
Expand Down

0 comments on commit 554abc4

Please sign in to comment.