From fe3d04097877a68255504cb7b5ba85cc2507ffd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Girona=20Arias?= Date: Thu, 6 Jun 2024 19:03:30 +0200 Subject: [PATCH] wip champion picked summoner spell --- .../analyzer/champion_analyzer.ex | 2 - .../summoner_spell/summoner_spell_repo.ex | 5 +- .../fact_processor.ex | 52 +++++++++++++++ .../champion_picked_summoner_spell/repo.ex | 65 +++++++++++++++++++ .../champion_picked_summoner_spell/schema.ex | 34 ++++++++++ ...20240603091346_summoner_spell_win_rate.exs | 31 +++++++++ 6 files changed, 186 insertions(+), 3 deletions(-) create mode 100644 apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/fact_processor.ex create mode 100644 apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/repo.ex create mode 100644 apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/schema.ex create mode 100644 apps/lol_analytics/priv/repo/migrations/20240603091346_summoner_spell_win_rate.exs diff --git a/apps/lol_analytics/lib/lol_analytics/analyzer/champion_analyzer.ex b/apps/lol_analytics/lib/lol_analytics/analyzer/champion_analyzer.ex index 84e9d20..097e26a 100644 --- a/apps/lol_analytics/lib/lol_analytics/analyzer/champion_analyzer.ex +++ b/apps/lol_analytics/lib/lol_analytics/analyzer/champion_analyzer.ex @@ -18,12 +18,10 @@ defmodule LolAnalytics.Analyzer.ChampionAnalyzer do @doc """ iex> LolAnalytics.Analyzer.ChampionAnalyzer.analyze(:url, "http://localhost:9000/ranked/14.9.580.2108/EUW1_6923309745.json") """ - @spec analyze(any(), any()) :: none() @impl true def analyze(:url, path) do data = HTTPoison.get!(path) analyze(:data, data.body) - :ok end @impl true 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 c1ff76c..14b5dec 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 @@ -1,9 +1,12 @@ defmodule LolAnalytics.Dimensions.SummonerSpell.SummonerSpellRepo do + import Ecto.Query + alias LolAnalytics.Dimensions.SummonerSpell.SummonerSpellSchema alias LoLAnalytics.Repo def get_or_create(spell_id) do - spell = Repo.get(SummonerSpellSchema, spell_id: spell_id) + query = from s in SummonerSpellSchema, where: s.spell_id == ^spell_id + spell = Repo.one(query) case spell do nil -> diff --git a/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/fact_processor.ex b/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/fact_processor.ex new file mode 100644 index 0000000..d21c314 --- /dev/null +++ b/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/fact_processor.ex @@ -0,0 +1,52 @@ +defmodule LolAnalytics.Facts.ChampionPickedSummonerSpell.FactProcessor do +alias LolAnalytics.Facts.ChampionPickedSummonerSpell + + def process_game_at_url(url) do + data = HTTPoison.get!(url) + process_game_data(data.body) + end + + defp process_game_data(data) do + decoded_match = Poison.decode!(data, as: %LoLAPI.Model.MatchResponse{}) + participants = decoded_match.info.participants + version = extract_game_version(decoded_match) + + participants + |> Enum.each(fn participant = %LoLAPI.Model.Participant{} -> + if participant.teamPosition != "" do + + attrs_spell_1 = %{ + champion_id: participant.championId, + match_id: decoded_match.metadata.matchId, + is_win: participant.win, + summoner_spell_id: participant.summoner1Id, + game_length_seconds: decoded_match.info.gameDuration, + queue_id: decoded_match.info.queueId, + puuid: participant.puuid, + team_position: participant.teamPosition, + patch_number: version + } + attrs_spell_2 = %{ + champion_id: participant.championId, + match_id: decoded_match.metadata.matchId, + is_win: participant.win, + summoner_spell_id: participant.summoner2Id, + game_length_seconds: decoded_match.info.gameDuration, + queue_id: decoded_match.info.queueId, + puuid: participant.puuid, + team_position: participant.teamPosition, + patch_number: version + } + ChampionPickedSummonerSpell.Repo.insert(attrs_spell_1) + ChampionPickedSummonerSpell.Repo.insert(attrs_spell_2) + end + end) + end + + defp extract_game_version(game_data) do + game_data.info.gameVersion + |> String.split(".") + |> Enum.take(2) + |> Enum.join(".") + 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 new file mode 100644 index 0000000..f2607cc --- /dev/null +++ b/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/repo.ex @@ -0,0 +1,65 @@ +defmodule LolAnalytics.Facts.ChampionPickedSummonerSpell.Repo do + import Ecto.Query + + alias LolAnalytics.Dimensions.SummonerSpell.SummonerSpellRepo + alias LolAnalytics.Dimensions.Champion.ChampionSchema + + alias LolAnalytics.Facts.ChampionPickedSummonerSpell.Schema + + alias LolAnalytics.Dimensions.Player.PlayerRepo + alias LolAnalytics.Dimensions.Champion.ChampionRepo + alias LolAnalytics.Dimensions.Match.MatchRepo + + alias LoLAnalytics.Repo + + @type insert_attrs :: %{ + match_id: String.t(), + champion_id: String.t(), + puuid: String.t(), + summoner_spell_id: :integer + } + + @spec insert(insert_attrs()) :: any() + def insert(attrs) do + _match = MatchRepo.get_or_create(attrs.match_id) + _champion = ChampionRepo.get_or_create(attrs.champion_id) + _player = PlayerRepo.get_or_create(attrs.puuid) + _spell = SummonerSpellRepo.get_or_create(attrs.summoner_spell_id) + changeset = Schema.changeset(%Schema{}, attrs) + + IO.inspect(attrs) + + Repo.insert(changeset) + |> IO.inspect() + end + + def get_champion_picked_summoners() do + query = + from f in Schema, + join: c in ChampionSchema, + on: c.champion_id == f.champion_id, + select: %{ + wins: fragment("count(CASE WHEN ? THEN 1 END)", f.is_win), + win_rate: + fragment( + " + ((cast(count(CASE WHEN ? THEN 1 END) as float) / cast(count(*) as float)) * 100.0 + )", + f.is_win + ), + id: f.champion_id, + spell_id: f.spell_id, + name: c.name, + 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] + + Repo.all(query) + end + + def list_facts() do + Repo.all(Schema) + end +end diff --git a/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/schema.ex b/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/schema.ex new file mode 100644 index 0000000..b20e049 --- /dev/null +++ b/apps/lol_analytics/lib/lol_analytics/facts/champion_picked_summoner_spell/schema.ex @@ -0,0 +1,34 @@ +defmodule LolAnalytics.Facts.ChampionPickedSummonerSpell.Schema do + use Ecto.Schema + + import Ecto.Changeset + + @params [ + :champion_id, + :summoner_spell_id, + :match_id, + :is_win, + :game_length_seconds, + :queue_id, + :team_position, + :puuid + ] + + schema "fact_champion_picked_summoner_spell" do + field :champion_id, :integer + field :summoner_spell_id, :integer + field :match_id, :string + field :is_win, :boolean + field :game_length_seconds, :integer + field :queue_id, :integer + field :team_position, :string + field :puuid, :string + end + + def changeset(fact = %__MODULE__{}, attrs \\ %{}) do + fact + |> cast(attrs, @params) + |> validate_required(@params) + |> unique_constraint([:puuid, :match_id, :summoner_spell_id]) + end +end diff --git a/apps/lol_analytics/priv/repo/migrations/20240603091346_summoner_spell_win_rate.exs b/apps/lol_analytics/priv/repo/migrations/20240603091346_summoner_spell_win_rate.exs new file mode 100644 index 0000000..1c21e3a --- /dev/null +++ b/apps/lol_analytics/priv/repo/migrations/20240603091346_summoner_spell_win_rate.exs @@ -0,0 +1,31 @@ +defmodule LoLAnalytics.Repo.Migrations.SummonerSpellWinRate do + use Ecto.Migration + + def change do + create table("fact_champion_picked_summoner_spell") do + add :champion_id, references("dim_champion", column: :champion_id, type: :integer) + add :summoner_spell_id, references("dim_summoner_spell", column: :spell_id, type: :integer) + add :match_id, references("dim_match", column: :match_id, type: :string) + add :is_win, :boolean + add :game_length_seconds, :integer + add :queue_id, :integer + add :team_position, :string + add :puuid, references("dim_player", column: :puuid, type: :string) + add :patch_number, references("dim_patch", column: :patch_number, type: :string) + end + + create index( + "fact_champion_picked_summoner_spell", + [:puuid, :match_id, :summoner_spell_id], + unique: true + ) + + create index("fact_champion_picked_summoner_spell", [ + :is_win, + :team_position, + :queue_id, + :summoner_spell_id, + :patch_number + ]) + end +end