99 lines
2.7 KiB
Elixir
99 lines
2.7 KiB
Elixir
defmodule Diffuser.Generator.PromptRequestGenserver do
|
|
use GenServer
|
|
alias Diffuser.Generator
|
|
alias Diffuser.Generator.PromptRequest
|
|
alias DiffuserWeb.Endpoint
|
|
alias Diffuser.PythonHelper, as: Helper
|
|
|
|
@path 'lib/diffuser/python'
|
|
|
|
def new(%{prompt_request: %PromptRequest{} = prompt_request}) do
|
|
GenServer.start_link(
|
|
__MODULE__,
|
|
%{prompt_request: prompt_request},
|
|
name: name_for(prompt_request)
|
|
)
|
|
end
|
|
|
|
def name_for(%PromptRequest{id: prompt_request_id}),
|
|
do: {:global, "prompt_request:#{prompt_request_id}"}
|
|
|
|
def init(%{prompt_request: %PromptRequest{} = prompt_request}) do
|
|
send(self(), :start_prompt)
|
|
|
|
{:ok,
|
|
%{
|
|
prompt_request: prompt_request
|
|
}}
|
|
end
|
|
|
|
def handle_info(:start_prompt, %{prompt_request: prompt_request} = state) do
|
|
with {:ok, %{prompt: prompt} = active_prompt} <-
|
|
update_and_broadcast_progress(prompt_request, "in_progress"),
|
|
:ok <- call_python(:test_script, :test_func, prompt),
|
|
%PromptRequest{} = prompt_request_with_results <- write_and_save_images(active_prompt),
|
|
{:ok, completed_prompt} <-
|
|
update_and_broadcast_progress(prompt_request_with_results, "finished") do
|
|
IO.inspect(completed_prompt)
|
|
{:noreply, state}
|
|
else
|
|
nil ->
|
|
raise("prompt not found")
|
|
|
|
{:error, message} ->
|
|
raise(message)
|
|
end
|
|
end
|
|
|
|
defp update_and_broadcast_progress(%PromptRequest{id: id} = prompt_request, new_status) do
|
|
{:ok, new_prompt} = Generator.update_prompt_request(prompt_request, %{status: new_status})
|
|
:ok = Endpoint.broadcast("request:#{id}", "request", %{prompt_request: new_prompt})
|
|
|
|
{:ok, new_prompt}
|
|
end
|
|
|
|
defp call_python(_module, _func, prompt) do
|
|
Port.open(
|
|
{:spawn, "python #{@path}/stable_diffusion.py --prompt #{prompt}"},
|
|
[:binary, {:packet, 4}]
|
|
)
|
|
|
|
# TODO: We will want to flush, and get the image data from the script
|
|
# then write it to PromptResult
|
|
|
|
# pid = Helper.py_instance(Path.absname(@path))
|
|
# :python.call(pid, module, func, args)
|
|
|
|
# pid
|
|
# |> :python.stop()
|
|
|
|
:ok
|
|
end
|
|
|
|
defp write_and_save_images(%PromptRequest{id: id, prompt: prompt}) do
|
|
height = :rand.uniform(512)
|
|
width = :rand.uniform(512)
|
|
IO.inspect(height)
|
|
|
|
{:ok, resp} =
|
|
:httpc.request(
|
|
:get,
|
|
{'http://placekitten.com/#{height}/#{width}', []},
|
|
[],
|
|
body_format: :binary
|
|
)
|
|
|
|
{{_, 200, 'OK'}, _headers, body} = resp
|
|
|
|
Generator.create_prompt_request_results(id, [
|
|
%{
|
|
file_name: "#{prompt}.jpg",
|
|
filename: "#{prompt}.jpg",
|
|
binary: body
|
|
}
|
|
])
|
|
|
|
Generator.get_prompt_request!(id)
|
|
end
|
|
end
|