diff options
author | href <href@random.sh> | 2020-04-17 15:53:14 +0200 |
---|---|---|
committer | href <href@random.sh> | 2020-04-17 15:53:14 +0200 |
commit | 919725a6941830ce82c835ed3288c1722ddd8c9f (patch) | |
tree | 49a95b0ce716a24c7e056036d3353ceca1debe4a /lib/lsg_irc/coronavirus_plugin.ex | |
parent | welp (diff) |
bleh
Diffstat (limited to 'lib/lsg_irc/coronavirus_plugin.ex')
-rw-r--r-- | lib/lsg_irc/coronavirus_plugin.ex | 116 |
1 files changed, 75 insertions, 41 deletions
diff --git a/lib/lsg_irc/coronavirus_plugin.ex b/lib/lsg_irc/coronavirus_plugin.ex index 9a017f3..debefa3 100644 --- a/lib/lsg_irc/coronavirus_plugin.ex +++ b/lib/lsg_irc/coronavirus_plugin.ex @@ -1,5 +1,6 @@ defmodule LSG.IRC.CoronavirusPlugin do require Logger + NimbleCSV.define(CovidCsv, separator: ",", escape: "\"") @moduledoc """ # Corona Virus @@ -17,7 +18,9 @@ defmodule LSG.IRC.CoronavirusPlugin do def init(_) do {:ok, _} = Registry.register(IRC.PubSub, "trigger:coronavirus", []) - {data, next} = fetch_data(%{}) + date = Date.add(Date.utc_today(), -2) + {data, _} = fetch_data(%{}, date) + {data, next} = fetch_data(data) :timer.send_after(next, :update) {:ok, %{data: data}} end @@ -28,32 +31,48 @@ defmodule LSG.IRC.CoronavirusPlugin do {:noreply, %{data: data}} end - def handle_info({:irc, :trigger, "coronavirus", m = %IRC.Message{trigger: %{type: :bang, args: args}}}, state) when args in [[], ["morts"], ["confirmés"], ["soignés"], ["malades"]] do + def handle_info({:irc, :trigger, "coronavirus", m = %IRC.Message{trigger: %{type: :bang, args: args}}}, state) when args in [ + [], ["morts"], ["confirmés"], ["soignés"], ["malades"], ["n"], ["nmorts"], ["nsoignés"], ["nconfirmés"]] do {field, name} = case args do ["confirmés"] -> {:confirmed, "confirmés"} ["morts"] -> {:deaths, "morts"} ["soignés"] -> {:recovered, "soignés"} + ["nmorts"] -> {:new_deaths, "nouveaux morts"} + ["nconfirmés"] -> {:new_confirmed, "nouveaux confirmés"} + ["n"] -> {:new_current, "nouveaux malades"} + ["nsoignés"] -> {:new_recovered, "nouveaux soignés"} _ -> {:current, "malades"} end + IO.puts("FIELD #{inspect field}") + field_evol = String.to_atom("new_#{field}") sorted = state.data |> Enum.filter(fn({_, %{region: region}}) -> region == true end) - |> Enum.map(fn({location, data}) -> {location, Map.get(data, field, 0)} end) - |> Enum.sort_by(fn({_,count}) -> count end, &>=/2) + |> Enum.map(fn({location, data}) -> {location, Map.get(data, field, 0), Map.get(data, field_evol, 0)} end) + |> Enum.sort_by(fn({_,count,_}) -> count end, &>=/2) |> Enum.take(10) |> Enum.with_index() - |> Enum.map(fn({{location, count}, index}) -> - "##{index+1}: #{location} #{count}" + |> Enum.map(fn({{location, count, evol}, index}) -> + ev = if String.starts_with?(name, "nouveaux") do + "" + else + " (#{Util.plusminus(evol)})" + end + "##{index+1}: #{location} #{count}#{ev}" end) |> Enum.intersperse(" - ") |> Enum.join() - m.replyfun.("Corona virus top 10 #{name}: " <> sorted) + m.replyfun.("CORONAVIRUS TOP10 #{name}: " <> sorted) {:noreply, state} end def handle_info({:irc, :trigger, "coronavirus", m = %IRC.Message{trigger: %{type: :bang, args: location}}}, state) do location = Enum.join(location, " ") |> String.downcase() if data = Map.get(state.data, location) do - m.replyfun.("Corona virus: #{location}: #{data.current} malades, #{data.confirmed} confirmés, #{data.deaths} morts, #{data.recovered} soignés") + m.replyfun.("coronavirus: #{location}: " + <> "#{data.current} malades (#{Util.plusminus(data.new_current)}), " + <> "#{data.confirmed} confirmés (#{Util.plusminus(data.new_confirmed)}), " + <> "#{data.deaths} morts (#{Util.plusminus(data.new_deaths)}), " + <> "#{data.recovered} soignés (#{Util.plusminus(data.new_recovered)}) (@ #{data.update})") end {:noreply, state} end @@ -79,41 +98,56 @@ defmodule LSG.IRC.CoronavirusPlugin do {:ok, %HTTPoison.Response{status_code: 200, body: csv}} -> # Parse CSV update data data = csv - |> String.strip() - |> String.split("\n") - |> Enum.drop(1) + |> CovidCsv.parse_string() |> Enum.reduce(%{}, fn(line, acc) -> - [state, region, update, confirmed, deaths, recovered,_lat, _lng] = line - |> String.strip() - |> String.split(",") - - state = String.downcase(state) - region = String.downcase(region) - confirmed = String.to_integer(confirmed) - deaths = String.to_integer(deaths) - recovered = String.to_integer(recovered) - - current = (confirmed - recovered) - deaths - - entry = %{update: update, confirmed: confirmed, deaths: deaths, recovered: recovered, current: current, region: region} - - acc = if state && state != "" do - Map.put(acc, state, entry) - else - acc + case line do + # FIPS,Admin2,Province_State,Country_Region,Last_Update,Lat,Long_,Confirmed,Deaths,Recovered,Active,Combined_Key + [_, _, state, region, update, _lat, _lng, confirmed, deaths, recovered, _active, _combined_key] -> + state = String.downcase(state) + region = String.downcase(region) + confirmed = String.to_integer(confirmed) + deaths = String.to_integer(deaths) + recovered = String.to_integer(recovered) + + current = (confirmed - recovered) - deaths + + entry = %{update: update, confirmed: confirmed, deaths: deaths, recovered: recovered, current: current, region: region} + + region_entry = Map.get(acc, region, %{update: nil, confirmed: 0, deaths: 0, recovered: 0, current: 0}) + region_entry = %{ + update: region_entry.update || update, + confirmed: region_entry.confirmed + confirmed, + deaths: region_entry.deaths + deaths, + current: region_entry.current + current, + recovered: region_entry.recovered + recovered, + region: true + } + + changes = if old = Map.get(current_data, region) do + %{ + new_confirmed: region_entry.confirmed - old.confirmed, + new_current: region_entry.current - old.current, + new_deaths: region_entry.deaths - old.deaths, + new_recovered: region_entry.recovered - old.recovered, + } + else + %{new_confirmed: 0, new_current: 0, new_deaths: 0, new_recovered: 0} + end + + region_entry = Map.merge(region_entry, changes) + + acc = Map.put(acc, region, region_entry) + + acc = if state && state != "" do + Map.put(acc, state, entry) + else + acc + end + + other -> + Logger.info("Coronavirus line failed: #{inspect line}") + acc end - - region_entry = Map.get(acc, region, %{update: nil, confirmed: 0, deaths: 0, recovered: 0, current: 0}) - region_entry = %{ - update: region_entry.update || update, - confirmed: region_entry.confirmed + confirmed, - deaths: region_entry.deaths + deaths, - current: region_entry.current + current, - recovered: region_entry.recovered + recovered, - region: true - } - - Map.put(acc, region, region_entry) end) Logger.info "Updated coronavirus database" {data, :timer.minutes(60)} |