From 968c2634b756a10a7e6fe39bcf92a9a7cc1e40a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro?= Date: Fri, 7 Jun 2024 01:42:45 +0200 Subject: [PATCH] add metadata to summoner spell --- .../summoner_spell/summoner_spell_metadata.ex | 22 ++++++++++++ .../summoner_spell/summoner_spell_repo.ex | 8 +++++ .../summoner_spell/summoner_spell_schema.ex | 3 +- .../champion_picked_summoner_spell/repo.ex | 33 ++++++++++++----- ...20240606222334_summoner_spell_metadata.exs | 9 +++++ ...06222701_summoner_spell_metadata_index.exs | 11 ++++++ .../champion_components/summoner_spells.ex | 36 +++++++++++++++++++ .../live/champion_live/champion.ex | 2 +- .../live/champion_live/mapper.ex | 4 +-- .../live/champion_live/show.ex | 20 ++++++++++- .../live/champion_live/show.html.heex | 6 +++- .../live/role_live/show.html.heex | 2 -- config/prod.exs | 2 +- config/runtime.exs | 2 +- mix.lock | 2 +- 15 files changed, 143 insertions(+), 19 deletions(-) create mode 100644 apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_metadata.ex create mode 100644 apps/lol_analytics/priv/repo/migrations/20240606222334_summoner_spell_metadata.exs create mode 100644 apps/lol_analytics/priv/repo/migrations/20240606222701_summoner_spell_metadata_index.exs create mode 100644 apps/lol_analytics_web/lib/lol_analytics_web/components/champion_components/summoner_spells.ex diff --git a/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_metadata.ex b/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_metadata.ex new file mode 100644 index 0000000..9426d5b --- /dev/null +++ b/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_metadata.ex @@ -0,0 +1,22 @@ +defmodule LolAnalytics.Dimensions.SummonerSpell.SummonerSpellMetadata do + alias LolAnalytics.Dimensions.SummonerSpell.SummonerSpellRepo + @spells_url "https://ddragon.leagueoflegends.com/cdn/14.11.1/data/en_US/summoner.json" + + def update_metadata() do + get_spells() + |> Enum.each(&save_metadata/1) + end + + defp get_spells() do + case HTTPoison.get(@spells_url) do + {:ok, resp} -> + Poison.decode!(resp.body)["data"] + end + end + + defp save_metadata({name, metadata}) do + %{"key" => spell_id} = metadata + + SummonerSpellRepo.update(spell_id, %{metadata: metadata}) + end +end diff --git a/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_repo.ex b/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_repo.ex index 14b5dec..c3bd44f 100644 --- a/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_repo.ex +++ b/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_repo.ex @@ -4,6 +4,7 @@ defmodule LolAnalytics.Dimensions.SummonerSpell.SummonerSpellRepo do alias LolAnalytics.Dimensions.SummonerSpell.SummonerSpellSchema alias LoLAnalytics.Repo + @spec get_or_create(String.t()) :: any() def get_or_create(spell_id) do query = from s in SummonerSpellSchema, where: s.spell_id == ^spell_id spell = Repo.one(query) @@ -23,6 +24,13 @@ defmodule LolAnalytics.Dimensions.SummonerSpell.SummonerSpellRepo do end end + @spec update(spell_id :: String.t(), attrs :: map()) :: any() + def update(spell_id, attrs) do + get_or_create(spell_id) + |> SummonerSpellSchema.changeset(attrs) + |> Repo.update() + end + def list_spells() do Repo.all(SummonerSpellSchema) end diff --git a/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_schema.ex b/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_schema.ex index 9a678da..385ba4f 100644 --- a/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_schema.ex +++ b/apps/lol_analytics/lib/lol_analytics/dimensions/summoner_spell/summoner_spell_schema.ex @@ -4,12 +4,13 @@ defmodule LolAnalytics.Dimensions.SummonerSpell.SummonerSpellSchema do schema "dim_summoner_spell" do field :spell_id, :integer + field :metadata, :map timestamps() end def changeset(summoner_spell = %__MODULE__{}, attrs) do summoner_spell - |> cast(attrs, [:spell_id]) + |> cast(attrs, [:spell_id, :metadata]) |> validate_required([:spell_id]) end end diff --git a/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/repo.ex b/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/repo.ex index f2607cc..80a21de 100644 --- a/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/repo.ex +++ b/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/repo.ex @@ -1,6 +1,7 @@ defmodule LolAnalytics.Facts.ChampionPickedSummonerSpell.Repo do import Ecto.Query + alias LolAnalytics.Dimensions.SummonerSpell.SummonerSpellSchema alias LolAnalytics.Dimensions.SummonerSpell.SummonerSpellRepo alias LolAnalytics.Dimensions.Champion.ChampionSchema @@ -13,11 +14,11 @@ defmodule LolAnalytics.Facts.ChampionPickedSummonerSpell.Repo do alias LoLAnalytics.Repo @type insert_attrs :: %{ - match_id: String.t(), - champion_id: String.t(), - puuid: String.t(), - summoner_spell_id: :integer - } + match_id: String.t(), + champion_id: String.t(), + puuid: String.t(), + summoner_spell_id: :integer + } @spec insert(insert_attrs()) :: any() def insert(attrs) do @@ -33,11 +34,17 @@ defmodule LolAnalytics.Facts.ChampionPickedSummonerSpell.Repo do |> IO.inspect() end + @spec get_champion_spells_by_win_rate(String.t()) :: list() + def get_champion_spells_by_win_rate(championId) do + end + def get_champion_picked_summoners() do query = from f in Schema, join: c in ChampionSchema, on: c.champion_id == f.champion_id, + join: s in SummonerSpellSchema, + on: s.spell_id == f.summoner_spell_id, select: %{ wins: fragment("count(CASE WHEN ? THEN 1 END)", f.is_win), win_rate: @@ -48,13 +55,23 @@ defmodule LolAnalytics.Facts.ChampionPickedSummonerSpell.Repo do f.is_win ), id: f.champion_id, - spell_id: f.spell_id, - name: c.name, + spell_id: f.summoner_spell_id, + metadata: s.metadata, + champion_name: c.name, + champion_id: c.champion_id, image: c.image, team_position: f.team_position, total_games: count("*") }, - group_by: [f.champion_id, f.spell_id, c.image, c.name, f.team_position] + group_by: [ + f.champion_id, + f.summoner_spell_id, + s.metadata, + c.image, + c.name, + c.champion_id, + f.team_position + ] Repo.all(query) end diff --git a/apps/lol_analytics/priv/repo/migrations/20240606222334_summoner_spell_metadata.exs b/apps/lol_analytics/priv/repo/migrations/20240606222334_summoner_spell_metadata.exs new file mode 100644 index 0000000..6e739ea --- /dev/null +++ b/apps/lol_analytics/priv/repo/migrations/20240606222334_summoner_spell_metadata.exs @@ -0,0 +1,9 @@ +defmodule LoLAnalytics.Repo.Migrations.SummonerSpellMetadata do + use Ecto.Migration + + def change do + alter table("dim_summoner_spell") do + add :metadata, :map + end + end +end diff --git a/apps/lol_analytics/priv/repo/migrations/20240606222701_summoner_spell_metadata_index.exs b/apps/lol_analytics/priv/repo/migrations/20240606222701_summoner_spell_metadata_index.exs new file mode 100644 index 0000000..8ae1b5d --- /dev/null +++ b/apps/lol_analytics/priv/repo/migrations/20240606222701_summoner_spell_metadata_index.exs @@ -0,0 +1,11 @@ +defmodule LoLAnalytics.Repo.Migrations.SummonerSpellMetadataIndex do + use Ecto.Migration + + def up do + execute("CREATE INDEX dim_summoner_spell_metadata ON dim_summoner_spell USING GIN(metadata)") + end + + def down do + execute("DROP INDEX dim_summoner_spell_metadata") + end +end diff --git a/apps/lol_analytics_web/lib/lol_analytics_web/components/champion_components/summoner_spells.ex b/apps/lol_analytics_web/lib/lol_analytics_web/components/champion_components/summoner_spells.ex new file mode 100644 index 0000000..23e098f --- /dev/null +++ b/apps/lol_analytics_web/lib/lol_analytics_web/components/champion_components/summoner_spells.ex @@ -0,0 +1,36 @@ +defmodule LolAnalyticsWeb.ChampionComponents.SummonerSpells.SummonerSpell do + defstruct [:id, :win_rate, :total_games] + + @type t :: %{ + id: integer(), + win_rate: float(), + total_games: integer() + } +end + +defmodule LolAnalyticsWeb.ChampionComponents.SummonerSpells.Props do + alias LolAnalyticsWeb.ChampionComponents.SummonerSpells.SummonerSpell + + defstruct spell1: %SummonerSpell{}, + spell2: %SummonerSpell{} + + @type t :: %{ + spell1: SummonerSpell.t(), + spell2: SummonerSpell.t() + } +end + +defmodule LolAnalyticsWeb.ChampionComponents.SummonerSpells do + alias LolAnalyticsWeb.ChampionComponents.SummonerSpells.Props + use Phoenix.Component + + attr :spells, Props, default: %Props{} + + def summoner_spells(assigns) do + ~H""" +
+ Spells +
+ """ + end +end diff --git a/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/champion.ex b/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/champion.ex index 0da455d..8945a76 100644 --- a/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/champion.ex +++ b/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/champion.ex @@ -1,3 +1,3 @@ -defmodule LolAnalyticsWeb.ChampionLive.Champion do +defmodule LolAnalyticsWeb.ChampionLive.ChampionSummary do defstruct [:id, :win_rate, :image, :name, :team_position, :wins, :total_games] end diff --git a/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/mapper.ex b/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/mapper.ex index 22447db..a471514 100644 --- a/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/mapper.ex +++ b/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/mapper.ex @@ -1,11 +1,11 @@ defmodule LolAnalyticsWeb.ChampionLive.Mapper do - alias LolAnalyticsWeb.ChampionLive.Champion + alias LolAnalyticsWeb.ChampionLive.ChampionSummary def map_champs(champs) do champs |> Enum.map(fn champ -> %{ - Kernel.struct!(%Champion{}, champ) + Kernel.struct!(%ChampionSummary{}, champ) | win_rate: :erlang.float_to_binary(champ.win_rate, decimals: 2) } end) diff --git a/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/show.ex b/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/show.ex index 0640f45..540eb0b 100644 --- a/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/show.ex +++ b/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/show.ex @@ -1,6 +1,8 @@ defmodule LoLAnalyticsWeb.ChampionLive.Show do use LoLAnalyticsWeb, :live_view + import LolAnalyticsWeb.ChampionComponents.SummonerSpells + @impl true def mount(_params, _session, socket) do {:ok, socket} @@ -11,7 +13,23 @@ defmodule LoLAnalyticsWeb.ChampionLive.Show do {:noreply, socket |> assign(:page_title, page_title(socket.assigns.live_action)) - |> assign(:champion, %{id: id})} + |> assign(:champion, %{id: id}) + |> assign(:summoner_spells, %{summoner_spells: load_summoner_spells()})} + end + + defp load_summoner_spells() do + %LolAnalyticsWeb.ChampionComponents.SummonerSpells.Props{ + spell1: %LolAnalyticsWeb.ChampionComponents.SummonerSpells.SummonerSpell{ + id: 1, + win_rate: 51.7, + total_games: 400 + }, + spell2: %LolAnalyticsWeb.ChampionComponents.SummonerSpells.SummonerSpell{ + id: 2, + win_rate: 51.7, + total_games: 500 + } + } end defp page_title(:show), do: "Show Champion" diff --git a/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/show.html.heex b/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/show.html.heex index cdc1890..28bb59f 100644 --- a/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/show.html.heex +++ b/apps/lol_analytics_web/lib/lol_analytics_web/live/champion_live/show.html.heex @@ -4,4 +4,8 @@ <:actions> -<.back navigate={~p"/champions"}>Back to champions +<.summoner_spells spells={@summoner_spells} /> + +<.back navigate={~p"/champions"}> + Back to champions + diff --git a/apps/lol_analytics_web/lib/lol_analytics_web/live/role_live/show.html.heex b/apps/lol_analytics_web/lib/lol_analytics_web/live/role_live/show.html.heex index 6305ac3..2642cfb 100644 --- a/apps/lol_analytics_web/lib/lol_analytics_web/live/role_live/show.html.heex +++ b/apps/lol_analytics_web/lib/lol_analytics_web/live/role_live/show.html.heex @@ -3,5 +3,3 @@ <:subtitle>This is a role record from your database. <:actions> - -<.back navigate={~p"/roles"}>Back to roles diff --git a/config/prod.exs b/config/prod.exs index 16ff169..7e9d263 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -8,7 +8,7 @@ import Config config :lol_analytics_web, LoLAnalyticsWeb.Endpoint, server: true, http: [ip: {0, 0, 0, 0}, port: 4000], - url: [host: "lol-analytics.kaizer.cloud", port: 80], + url: [host: "localhost", port: 80], cache_static_manifest: "priv/static/cache_manifest.json" # Do not print debug messages in production diff --git a/config/runtime.exs b/config/runtime.exs index 833b490..aa71847 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -6,7 +6,7 @@ import Config # and secrets from environment variables or elsewhere. Do not define # any compile-time configuration in here, as it won't be applied. # The block below contains prod specific runtime configuration. -if config_env() == :prod do +if config_env() == :prod || true do database_url = System.get_env("DATABASE_URL") || raise """ diff --git a/mix.lock b/mix.lock index 57f45f9..ac923be 100644 --- a/mix.lock +++ b/mix.lock @@ -21,7 +21,7 @@ "gen_stage": {:hex, :gen_stage, "1.2.1", "19d8b5e9a5996d813b8245338a28246307fd8b9c99d1237de199d21efc4c76a1", [:mix], [], "hexpm", "83e8be657fa05b992ffa6ac1e3af6d57aa50aace8f691fcf696ff02f8335b001"}, "gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"}, "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"}, - "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized"]}, + "heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]}, "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},