Skip to content

Commit

Permalink
Quotes - load and broadcast
Browse files Browse the repository at this point in the history
  • Loading branch information
oliver-kriska committed Jan 25, 2022
1 parent c24ecb2 commit 53331c1
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 9 deletions.
4 changes: 3 additions & 1 deletion lib/rubyslava_elixir/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ defmodule RubyslavaElixir.Application do
{Phoenix.PubSub, name: RubyslavaElixir.PubSub},
# Start the Endpoint (http/https)
RubyslavaElixirWeb.Endpoint,
{RubyslavaElixir.Questions, []}
{RubyslavaElixir.Questions, []},
{Finch, name: RubyslavaElixir.Finch},
{RubyslavaElixir.Quotes, []}
# Start a worker by calling: RubyslavaElixir.Worker.start_link(arg)
# {RubyslavaElixir.Worker, arg}
]
Expand Down
12 changes: 12 additions & 0 deletions lib/rubyslava_elixir/questions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,16 @@ defmodule RubyslavaElixir.Questions do
def store(%Question{} = question) do
Agent.update(__MODULE__, &(&1 ++ [question]))
end

def new(body) do
question = %Question{
id: :crypto.strong_rand_bytes(10) |> Base.encode16(),
body: body,
time: Timex.now()
}

store(question)

question
end
end
7 changes: 7 additions & 0 deletions lib/rubyslava_elixir/quote.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule RubyslavaElixir.Quote do
@moduledoc """
Definition of base struct for manipulation with quotes
"""

defstruct quote: "", author: ""
end
64 changes: 64 additions & 0 deletions lib/rubyslava_elixir/quotes.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
NimbleCSV.define(RubyslavaElixir.Quotes.Parser, separator: ";", escape: "\"")

defmodule RubyslavaElixir.Quotes do
@moduledoc """
GenServer implementation for loading and broadcasting quotes
"""

use GenServer

alias Phoenix.PubSub
alias RubyslavaElixir.Quote
alias RubyslavaElixir.Quotes.Parser

@quotes_source_url "https://raw.githubusercontent.com/akhiltak/inspirational-quotes/master/Quotes.csv"
@pub_sub_server RubyslavaElixir.PubSub

@impl true
def init(_) do
{:ok, [], {:continue, :load_quotes}}
end

def start_link(quotes) do
GenServer.start_link(__MODULE__, quotes)
end

@impl true
def handle_continue(:load_quotes, quotes) do
quotes =
Finch.build(:get, @quotes_source_url)
|> Finch.request(RubyslavaElixir.Finch)
|> case do
{:ok, %{body: body}} ->
parse_body(body)

_ ->
quotes
end

schedule_broadcast(1)
{:noreply, quotes}
end

@impl true
def handle_info(:broadcast, []), do: {:noreply, [], {:continue, :load_quotes}}

def handle_info(:broadcast, quotes) do
rand = :rand.uniform(length(quotes))
{new_quote, quotes} = List.pop_at(quotes, rand)
PubSub.broadcast!(@pub_sub_server, "quotes", {:new_quote, new_quote})
schedule_broadcast()
{:noreply, quotes}
end

defp schedule_broadcast(delay \\ :timer.seconds(30)),
do: Process.send_after(self(), :broadcast, delay)

defp parse_body(body) do
body
|> Parser.parse_string()
|> Enum.map(fn [quote_string, author, _genre] ->
%Quote{quote: :binary.copy(quote_string), author: :binary.copy(author)}
end)
end
end
14 changes: 7 additions & 7 deletions lib/rubyslava_elixir_web/live/dashboard_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule RubyslavaElixirWeb.DashboardLive.Index do
use RubyslavaElixirWeb, :live_view

alias Phoenix.PubSub
alias RubyslavaElixir.{Question, Questions}
alias RubyslavaElixir.Questions

@pub_sub_server RubyslavaElixir.PubSub

Expand All @@ -14,11 +14,13 @@ defmodule RubyslavaElixirWeb.DashboardLive.Index do
if connected?(socket) do
Process.send_after(self(), :get_questions, 1)
Phoenix.PubSub.subscribe(@pub_sub_server, "questions")
Phoenix.PubSub.subscribe(@pub_sub_server, "quotes")
end

socket =
socket
|> assign(:questions, [])
|> assign(:quote, nil)

{:ok, socket}
end
Expand All @@ -43,14 +45,12 @@ defmodule RubyslavaElixirWeb.DashboardLive.Index do
{:noreply, assign(socket, questions: questions)}
end

def handle_info({:new_quote, new_quote}, socket),
do: {:noreply, assign(socket, quote: new_quote)}

defp create_question(body) do
question = %Question{
id: :crypto.strong_rand_bytes(10) |> Base.encode16(),
body: body,
time: Timex.now()
}
question = Questions.new(body)

Questions.store(question)
PubSub.broadcast!(@pub_sub_server, "questions", {:new_question, question})
question
end
Expand Down
8 changes: 7 additions & 1 deletion lib/rubyslava_elixir_web/live/dashboard_live/index.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
</li>
</ul>
</div>
<div id="numbers">
<div id="quote">
<%= if @quote do %>
<h2><%= @quote.quote %></h2>
<h3><%= @quote.author %></h3>
<% else %>
<h2>No quote</h2>
<% end %>
</div>
</div>
2 changes: 2 additions & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ defmodule RubyslavaElixir.MixProject do
{:jason, "~> 1.2"},
{:plug_cowboy, "~> 2.5"},
{:timex, "~> 3.7"},
{:finch, "~> 0.10.2"},
{:nimble_csv, "~> 1.2"},
{:credo, "~> 1.6", only: [:dev, :test], runtime: false},
{:dialyxir, "~> 1.1", only: [:dev, :test], runtime: false}
]
Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mint": {:hex, :mint, "1.4.0", "cd7d2451b201fc8e4a8fd86257fb3878d9e3752899eb67b0c5b25b180bde1212", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "10a99e144b815cbf8522dccbc8199d15802440fc7a64d67b6853adb6fa170217"},
"nimble_csv": {:hex, :nimble_csv, "1.2.0", "4e26385d260c61eba9d4412c71cea34421f296d5353f914afe3f2e71cce97722", [:mix], [], "hexpm", "d0628117fcc2148178b034044c55359b26966c6eaa8e2ce15777be3bbc91b12a"},
"nimble_options": {:hex, :nimble_options, "0.4.0", "c89babbab52221a24b8d1ff9e7d838be70f0d871be823165c94dd3418eea728f", [:mix], [], "hexpm", "e6701c1af326a11eea9634a3b1c62b475339ace9456c1a23ec3bc9a847bca02d"},
"nimble_pool": {:hex, :nimble_pool, "0.2.4", "1db8e9f8a53d967d595e0b32a17030cdb6c0dc4a451b8ac787bf601d3f7704c3", [:mix], [], "hexpm", "367e8071e137b787764e6a9992ccb57b276dc2282535f767a07d881951ebeac6"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
Expand Down

0 comments on commit 53331c1

Please sign in to comment.