summaryrefslogtreecommitdiff
path: root/lib/lsg_irc/coronavirus_plugin.ex
diff options
context:
space:
mode:
authorhref <href@random.sh>2020-04-17 15:53:14 +0200
committerhref <href@random.sh>2020-04-17 15:53:14 +0200
commit919725a6941830ce82c835ed3288c1722ddd8c9f (patch)
tree49a95b0ce716a24c7e056036d3353ceca1debe4a /lib/lsg_irc/coronavirus_plugin.ex
parentwelp (diff)
bleh
Diffstat (limited to 'lib/lsg_irc/coronavirus_plugin.ex')
-rw-r--r--lib/lsg_irc/coronavirus_plugin.ex116
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)}