Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved design #110

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions backend/api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ FROM node:14-alpine AS REACT_BUILD

WORKDIR /app
COPY interface/package.json .

# This is a workaround for a known issue with the react app
ENV SKIP_PREFLIGHT_CHECK=true

RUN npm install
COPY interface/ .

Expand Down
6 changes: 6 additions & 0 deletions backend/api/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ config :toia, Toia.Guardian,
issuer: "toia",
secret_key: System.get_env("GUARDIAN_SECRET_KEY")

config :waffle,
storage: Waffle.Storage.Google.CloudStorage,
bucket: "toia-phoenix",
storage_dir: "/",
token_fetcher: Toia.WaffleTokenFetcher

# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs"
48 changes: 48 additions & 0 deletions backend/api/lib/toia/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ defmodule Toia.Application do
# See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
require HTTPoison
alias Jason, as: JSON

use Application
alias EmailHandlers
Expand All @@ -17,6 +19,8 @@ defmodule Toia.Application do
{Phoenix.PubSub, name: Toia.PubSub},
# Start Finch
{Finch, name: Toia.Finch},
# Goth for OAuth with Google
{Goth, name: Toia.Goth},
# Start the Endpoint (http/https)
ToiaWeb.Endpoint
# Start a worker by calling: Toia.Worker.start_link(arg)
Expand All @@ -30,6 +34,7 @@ defmodule Toia.Application do
[:swoosh, :deliver_many, :exception],
], &EmailHandlers.handle_event/4, nil)

set_gcloud_cors_on_startup()
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Toia.Supervisor]
Expand All @@ -43,4 +48,47 @@ defmodule Toia.Application do
ToiaWeb.Endpoint.config_change(changed, removed)
:ok
end

def set_gcloud_cors_config(bucket_name) do
# Define your CORS configuration directly in code
cors_config = %{
cors: [
%{
origin: [System.get_env("API_URL")],
method: ["GET"],
responseHeader: ["Content-Type"],
maxAgeSeconds: 3600
}
]
}

# Encode the configuration to a JSON string
body = JSON.encode!(cors_config)

# Construct the URL
url = "https://storage.googleapis.com/storage/v1/b/#{bucket_name}?fields=cors"

# Get the access token using Goth
{:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/devstorage.full_control")

# Set headers
headers = [
{"Authorization", "Bearer #{token.token}"},
{"Content-Type", "application/json"}
]

# Make the PATCH request
HTTPoison.patch(url, body, headers)
end

defp set_gcloud_cors_on_startup do
bucket_name = "toia-phoenix"

case set_gcloud_cors_config(bucket_name) do
{:ok, response} ->
IO.puts("CORS configuration set successfully: #{inspect(response)}")
{:error, reason} ->
IO.puts("Failed to set CORS configuration: #{inspect(reason)}")
end
end
end
47 changes: 39 additions & 8 deletions backend/api/lib/toia/streams.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ defmodule Toia.Streams do
alias Toia.Videos
alias Toia.VideosQuestionsStreams.VideoQuestionStream
alias Toia.ToiaUsers
alias Toia.StreamPhoto

alias ServiceHandlers.DialogueManager
alias ServiceHandlers.SmartSuggester

Expand Down Expand Up @@ -117,9 +119,26 @@ defmodule Toia.Streams do
destDir = "Accounts/#{user.first_name}_#{user.id}/StreamPic/"
destFilename = "#{attrs["name"]}_#{stream.id_stream}.jpg"

case Videos.copyAndDelete(filePath, destDir, destFilename) do
:ok -> {:ok, stream}
{:error, reason} -> {:error, reason}
scope = %{
first_name: user.first_name,
toia_id: user.id,
file_name: destFilename,
stream_id: stream.id_stream,
stream_name: attrs["name"]
}

case System.get_env("ENVIRONMENT") do
"production" ->
case StreamPhoto.store({filePath, scope}) do
{:ok, _} -> {:ok, stream}
{:error, reason} -> {:error, reason}
end
"development" ->
case Videos.copyAndDelete(filePath, destDir, destFilename) do
:ok -> {:ok, stream}
{:error, reason} -> {:error, reason}
end
_ -> raise "Unknown environment"
end
end
end
Expand Down Expand Up @@ -232,7 +251,7 @@ defmodule Toia.Streams do

query =
from([_q, vqs, v] in query,
select: %{id_video: vqs.id_video, answer: v.answer, duration_seconds: v.duration_seconds}
select: %{"id_video" => vqs.id_video, "answer" => v.answer, "duration_seconds" => v.duration_seconds}
)

all_videos = Repo.all(query)
Expand Down Expand Up @@ -260,7 +279,7 @@ defmodule Toia.Streams do

query =
from([_q, vqs, v] in query,
select: %{id_video: vqs.id_video, answer: v.answer, duration_seconds: v.duration_seconds}
select: %{"id_video" => vqs.id_video, "answer" => v.answer, "duration_seconds" => v.duration_seconds}
)

all_videos = Repo.all(query)
Expand Down Expand Up @@ -313,7 +332,7 @@ defmodule Toia.Streams do
# A match was found
{:ok, x} ->
{:ok,
Map.put(x, :url, Videos.getPlaybackUrl(streamUser.first_name, streamUser.id, x.id_video))}
Map.put(x, :url, Videos.getPlaybackUrl(streamUser.first_name, streamUser.id, Map.get(x, "id_video")))}
end
end

Expand All @@ -339,7 +358,7 @@ defmodule Toia.Streams do
Map.put(
x,
:url,
Videos.getPlaybackUrl(streamUser.first_name, streamUser.id, x.id_video)
Videos.getPlaybackUrl(streamUser.first_name, streamUser.id, Map.get(x, "id_video"))
)}
end
else
Expand Down Expand Up @@ -428,6 +447,18 @@ defmodule Toia.Streams do
user_id = stream.toia_id
user = ToiaUsers.get_toia_user!(user_id)

"#{System.get_env("API_URL")}/media/#{user.first_name}_#{user.id}/StreamPic/#{stream.name}_#{stream.id_stream}.jpg"
scope = %{
first_name: user.first_name,
toia_id: user.id,
file_name: "#{stream.name}_#{stream.id_stream}.jpg",
stream_id: stream.id_stream,
stream_name: stream.name
}

case System.get_env("ENVIRONMENT") do
"production" -> StreamPhoto.url({scope.file_name, scope}, signed: true)
"development" -> "#{System.get_env("API_URL")}/media/#{user.first_name}_#{user.id}/StreamPic/#{stream.name}_#{stream.id_stream}.jpg"
_ -> ""
end
end
end
98 changes: 68 additions & 30 deletions backend/api/lib/toia/toia_users.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule Toia.ToiaUsers do
alias Toia.Questions.Question
alias Toia.VideosQuestionsStreams.VideoQuestionStream
alias Toia.Videos.Video
alias Toia.StreamPhoto

@doc """
Returns the list of toia_user.
Expand Down Expand Up @@ -55,44 +56,27 @@ defmodule Toia.ToiaUsers do

"""
# `Accounts/${fields.firstName[0]}_${entry.insertId}/StreamPic/All_${stream_entry.insertId}.jpg`;
def create_toia_user_with_stream(
%{"profile_pic" => %Plug.Upload{path: path}} = toia_user_params
) do
def create_toia_user_with_stream(%{"profile_pic" => %Plug.Upload{path: path}} = toia_user_params) do
toia_user_params = Map.delete(toia_user_params, "profile_pic")

case create_toia_user_with_stream(toia_user_params) do
{:ok, toia_user, stream} ->
destDir = "Accounts/#{toia_user.first_name}_#{toia_user.id}/StreamPic/"
destFilename = "All_#{stream.id_stream}.jpg"

case File.mkdir_p(destDir) do
:ok ->
case File.cp(path, destDir <> destFilename) do
:ok ->
case File.rm(path) do
:ok ->
{:ok, toia_user, stream}

{:error, reason} ->
IO.puts("Error deleting file")
{:error_pic, reason}
end

{:error, reason} ->
IO.puts("Error copying file")
{:error_pic, reason}
end

{:error, reason} ->
IO.puts("Error creating directory")
{:error_pic, reason}
environ = System.get_env("ENVIRONMENT", "development")

case environ do
"production" ->
upload_to_google_cloud(path, toia_user, stream)
"development" ->
upload_locally(path, toia_user, stream)
_ ->
{:error, "Invalid environment when uploading file"}
end

{:error, changeset} ->
{:error, changeset}
end
end

def create_toia_user_with_stream(attrs) do
case create_toia_user(attrs) do
{:ok, %ToiaUser{} = toia_user} ->
Expand All @@ -117,6 +101,60 @@ defmodule Toia.ToiaUsers do
end
end

defp upload_locally(path, toia_user, stream) do
dest_dir = "Accounts/#{toia_user.first_name}_#{toia_user.id}/StreamPic/"
dest_filename = "All_#{stream.id_stream}.jpg"

case File.mkdir_p(dest_dir) do
:ok ->
case File.cp(path, dest_dir <> dest_filename) do
:ok ->
case File.rm(path) do
:ok ->
{:ok, toia_user, stream}

{:error, reason} ->
IO.puts("Error deleting file")
{:error_pic, reason}
end

{:error, reason} ->
IO.puts("Error copying file")
{:error_pic, reason}
end

{:error, reason} ->
IO.puts("Error creating directory")
{:error_pic, reason}
end
end

defp upload_to_google_cloud(path, toia_user, stream) do
scope = %{
first_name: toia_user.first_name,
toia_id: toia_user.id,
file_name: "All_#{stream.id_stream}.jpg",
stream_id: stream.id_stream,
stream_name: stream.name
}
case StreamPhoto.store({path, scope}) do
{:ok, _} ->
case File.rm(path) do
:ok ->
{:ok, toia_user, stream}

{:error, reason} ->
IO.puts("Error deleting file")
{:error_pic, reason}
end

{:error, reason} ->
IO.puts("Error uploading file")
IO.inspect(reason)
{:error_pic, reason}
end
end

def create_toia_user(attrs \\ %{}) do
%{"password" => password} = attrs
hash = Bcrypt.hash_pwd_salt(password)
Expand Down
38 changes: 35 additions & 3 deletions backend/api/lib/toia/videos.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ defmodule Toia.Videos do
alias Toia.Questions.Question
alias Toia.Questions
alias Toia.ToiaUsers
alias Toia.VideoFiles

alias ServiceHandlers.QuestionSuggester
alias ServiceHandlers.GenerateEmbeddings
Expand Down Expand Up @@ -149,7 +150,14 @@ defmodule Toia.Videos do
Returns the playback url. Legacy: `/${entries[0].first_name}_${entries[0].id}/Videos/${req.body.params.playbackVideoID}`
"""
def getPlaybackUrl(first_name, toia_id, video_id) do
"#{System.get_env("API_URL")}/media/#{first_name}_#{toia_id}/Videos/#{video_id}"
case System.get_env("ENVIRONMENT") do
"development" ->
"#{System.get_env("API_URL")}/media/#{first_name}_#{toia_id}/Videos/#{video_id}"
"production" ->
VideoFiles.url({video_id, %{first_name: first_name, toia_id: toia_id, id_video: video_id}}, signed: true)
_ -> raise "Unknown environment"
end

end

@doc """
Expand Down Expand Up @@ -249,7 +257,13 @@ defmodule Toia.Videos do
Returns the video path given a video id
"""
def getVideoPath(first_name, user_id, id_video) do
"Accounts/#{first_name}_#{user_id}/Videos/#{id_video}"
case System.get_env("ENVIRONMENT") do
"development" ->
"Accounts/#{first_name}_#{user_id}/Videos/#{id_video}"
"production" ->
VideoFiles.url({id_video, %{first_name: first_name, toia_id: user_id, id_video: id_video}})
_ -> raise "Unknown environment"
end
end

def getDestPath(first_name, user_id) do
Expand Down Expand Up @@ -281,7 +295,25 @@ defmodule Toia.Videos do
Save the video file
"""
def saveVideoFile(first_name, user_id, id_video, upload_path) do
copyAndDelete(upload_path, getDestPath(first_name, user_id), id_video)
case System.get_env("ENVIRONMENT") do
"development" ->
copyAndDelete(upload_path, getDestPath(first_name, user_id), id_video)
"production" ->
scope = %{
first_name: first_name,
toia_id: user_id,
id_video: id_video
}
case VideoFiles.store({upload_path, scope}) do
{:ok, _} ->
File.rm(upload_path)

{:error, reason} ->
IO.puts("Error uploading file")
{:error, reason}
end
_ -> raise "Unknown environment"
end
end

@doc """
Expand Down
Loading