summaryrefslogtreecommitdiff
path: root/lib/lsg_web/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lsg_web/controllers')
-rw-r--r--lib/lsg_web/controllers/alcoolog_controller.ex56
-rw-r--r--lib/lsg_web/controllers/irc_auth_sse_controller.ex66
-rw-r--r--lib/lsg_web/controllers/irc_controller.ex27
-rw-r--r--lib/lsg_web/controllers/network_controller.ex11
-rw-r--r--lib/lsg_web/controllers/page_controller.ex50
-rw-r--r--lib/lsg_web/controllers/sms_controller.ex10
-rw-r--r--lib/lsg_web/controllers/untappd_controller.ex18
7 files changed, 207 insertions, 31 deletions
diff --git a/lib/lsg_web/controllers/alcoolog_controller.ex b/lib/lsg_web/controllers/alcoolog_controller.ex
index 9d5d9d9..b88faa3 100644
--- a/lib/lsg_web/controllers/alcoolog_controller.ex
+++ b/lib/lsg_web/controllers/alcoolog_controller.ex
@@ -2,9 +2,12 @@ defmodule LSGWeb.AlcoologController do
use LSGWeb, :controller
require Logger
- def index(conn, %{"channel" => channel}) do
- case LSG.Token.lookup(channel) do
- {:ok, obj} -> index(conn, obj)
+ plug LSGWeb.ContextPlug when action not in [:token]
+ plug LSGWeb.ContextPlug, [restrict: :public] when action in [:token]
+
+ def token(conn, %{"token" => token}) do
+ case LSG.Token.lookup(token) do
+ {:ok, {:alcoolog, :index, network, channel}} -> index(conn, nil, network, channel)
err ->
Logger.debug("AlcoologControler: token #{inspect err} invalid")
conn
@@ -13,8 +16,31 @@ defmodule LSGWeb.AlcoologController do
end
end
- def index(conn, {:alcoolog, :index, channel}) do
- aday = 7*((24 * 60)*60)
+ def index(conn = %{assigns: %{account: account}}, %{"network" => network, "chan" => channel}) do
+ index(conn, account, network, LSGWeb.reformat_chan(channel))
+ end
+
+ def index(conn = %{assigns: %{account: account}}, _) do
+ index(conn, account, nil, nil)
+ end
+
+ #def index(conn, params) do
+ # network = Map.get(params, "network")
+ # chan = if c = Map.get(params, "chan") do
+ # LSGWeb.reformat_chan(c)
+ # end
+ # irc_conn = if network do
+ # IRC.Connection.get_network(network, chan)
+ # end
+ # bot = if(irc_conn, do: irc_conn.nick)#
+ #
+ # conn
+ # |> put_status(403)
+ # |> render("auth.html", network: network, channel: chan, irc_conn: conn, bot: bot)
+ #end
+
+ def index(conn, account, network, channel) do
+ aday = 18*((24 * 60)*60)
now = DateTime.utc_now()
before = now
|> DateTime.add(-aday, :second)
@@ -27,22 +53,28 @@ defmodule LSGWeb.AlcoologController do
], [:"$_"]}
]
- nicks_in_channel = IRC.UserTrack.channel(channel)
- |> Enum.map(fn({_, nick, _, _, _, _, _}) -> String.downcase(nick) end)
# tuple ets: {{nick, date}, volumes, current, nom, commentaire}
+ members = IRC.Membership.expanded_members_or_friends(account, network, channel)
+ members_ids = Enum.map(members, fn({account, _, nick}) -> account.id end)
+ member_names = Enum.reduce(members, %{}, fn({account, _, nick}, acc) -> Map.put(acc, account.id, nick) end)
drinks = :ets.select(LSG.IRC.AlcoologPlugin.ETS, match)
- #|> Enum.filter(fn({{nick, _}, _, _, _, _}) -> Enum.member?(nicks_in_channel, nick) end)
- |> Enum.sort_by(fn({{_, ts}, _, _, _, _}) -> ts end, &>/2)
+ |> Enum.filter(fn({{account, _}, _, _, _, _}) -> Enum.member?(members_ids, account) end)
+ |> Enum.map(fn({{account, _}, _, _, _, _} = object) -> {object, Map.get(member_names, account)} end)
+ |> Enum.sort_by(fn({{{_, ts}, _, _, _, _}, _}) -> ts end, &>/2)
- stats = LSG.IRC.AlcoologPlugin.get_channel_statistics(channel)
+ stats = LSG.IRC.AlcoologPlugin.get_channel_statistics(account, network, channel)
- top = Enum.reduce(drinks, %{}, fn({{nick, _}, vol, _, _, _}, acc) ->
+ top = Enum.reduce(drinks, %{}, fn({{{account_id, _}, vol, _, _, _}, _}, acc) ->
+ nick = Map.get(member_names, account_id)
all = Map.get(acc, nick, 0)
Map.put(acc, nick, all + vol)
end)
|> Enum.sort_by(fn({_nick, count}) -> count end, &>/2)
# {date, single_peak}
- render(conn, "index.html", channel: channel, drinks: drinks, top: top, stats: stats)
+ #
+ conn
+ |> assign(:title, "alcoolog")
+ |> render("index.html", network: network, channel: channel, drinks: drinks, top: top, stats: stats)
end
end
diff --git a/lib/lsg_web/controllers/irc_auth_sse_controller.ex b/lib/lsg_web/controllers/irc_auth_sse_controller.ex
new file mode 100644
index 0000000..c39a866
--- /dev/null
+++ b/lib/lsg_web/controllers/irc_auth_sse_controller.ex
@@ -0,0 +1,66 @@
+defmodule LSGWeb.IrcAuthSseController do
+ use LSGWeb, :controller
+ require Logger
+
+ @ping_interval 20_000
+ @expire_delay :timer.minutes(3)
+
+ def sse(conn, params) do
+ perks = if uri = Map.get(params, "redirect_to") do
+ {:redirect, uri}
+ else
+ nil
+ end
+ token = String.downcase(EntropyString.random_string(65))
+ conn
+ |> assign(:token, token)
+ |> assign(:perks, perks)
+ |> put_resp_header("X-Accel-Buffering", "no")
+ |> put_resp_header("content-type", "text/event-stream")
+ |> send_chunked(200)
+ |> subscribe()
+ |> send_sse_message("token", token)
+ |> sse_loop
+ end
+
+ def subscribe(conn) do
+ :timer.send_interval(@ping_interval, {:event, :ping})
+ :timer.send_after(@expire_delay, {:event, :expire})
+ {:ok, _} = Registry.register(IRC.PubSub, "message:private", [])
+ conn
+ end
+
+ def sse_loop(conn) do
+ {type, event, exit} = receive do
+ {:event, :ping} -> {"ping", "ping", false}
+ {:event, :expire} -> {"expire", "expire", true}
+ {:irc, :text, %{account: account, text: token} = m} ->
+ if String.downcase(String.trim(token)) == conn.assigns.token do
+ path = LSG.AuthToken.new_path(account.id, conn.assigns.perks)
+ m.replyfun.("ok!")
+ {"authenticated", path, true}
+ else
+ {nil, nil, false}
+ end
+ _ -> {nil, nil, false}
+ end
+
+ conn = if type do
+ send_sse_message(conn, type, event)
+ else
+ conn
+ end
+
+ if exit do
+ conn
+ else
+ sse_loop(conn)
+ end
+ end
+
+ defp send_sse_message(conn, type, data) do
+ {:ok, conn} = chunk(conn, "event: #{type}\ndata: #{data}\n\n")
+ conn
+ end
+
+end
diff --git a/lib/lsg_web/controllers/irc_controller.ex b/lib/lsg_web/controllers/irc_controller.ex
index 022807d..e0bf24d 100644
--- a/lib/lsg_web/controllers/irc_controller.ex
+++ b/lib/lsg_web/controllers/irc_controller.ex
@@ -1,13 +1,21 @@
defmodule LSGWeb.IrcController do
use LSGWeb, :controller
- def index(conn, _) do
- commands = for mod <- (Application.get_env(:lsg, :irc)[:plugins] ++ Application.get_env(:lsg, :irc)[:handlers]) do
+ plug LSGWeb.ContextPlug
+
+ def index(conn, params) do
+ network = Map.get(params, "network")
+ channel = if c = Map.get(params, "channel"), do: LSGWeb.reformat_chan(c)
+ commands = for mod <- ([IRC.Account.AccountPlugin] ++ Application.get_env(:lsg, :irc)[:plugins] ++ Application.get_env(:lsg, :irc)[:handlers]) do
identifier = Module.split(mod) |> List.last |> String.replace("Plugin", "") |> Macro.underscore
{identifier, mod.irc_doc()}
end
|> Enum.reject(fn({_, i}) -> i == nil end)
- render conn, "index.html", commands: commands
+ members = cond do
+ network -> IRC.Membership.expanded_members_or_friends(conn.assigns.account, network, channel)
+ true -> IRC.Membership.of_account(conn.assigns.account)
+ end
+ render conn, "index.html", network: network, commands: commands, channel: channel, members: members
end
def txt(conn, %{"name" => name}) do
@@ -33,13 +41,22 @@ defmodule LSGWeb.IrcController do
doc = LSG.IRC.TxtPlugin.irc_doc()
data = data()
lines = Enum.reduce(data, 0, fn({_, lines}, acc) -> acc + Enum.count(lines) end)
- render conn, "txts.html", data: data, doc: doc, files: Enum.count(data), lines: lines
+ conn
+ |> assign(:title, "txt")
+ |> render("txts.html", data: data, doc: doc, files: Enum.count(data), lines: lines)
end
defp do_txt(conn, txt) do
data = data()
+ base_url = cond do
+ conn.assigns[:chan] -> "/#{conn.assigns.network}/#{LSGWeb.format_chan(conn.assigns.chan)}"
+ true -> "/-"
+ end
if Map.has_key?(data, txt) do
- render(conn, "txt.html", name: txt, data: data[txt], doc: nil)
+ conn
+ |> assign(:breadcrumbs, [{"txt", "#{base_url}/txt"}])
+ |> assign(:title, "#{txt}.txt")
+ |> render("txt.html", name: txt, data: data[txt], doc: nil)
else
conn
|> put_status(404)
diff --git a/lib/lsg_web/controllers/network_controller.ex b/lib/lsg_web/controllers/network_controller.ex
new file mode 100644
index 0000000..537c2f6
--- /dev/null
+++ b/lib/lsg_web/controllers/network_controller.ex
@@ -0,0 +1,11 @@
+defmodule LSGWeb.NetworkController do
+ use LSGWeb, :controller
+ plug LSGWeb.ContextPlug
+
+ def index(conn, %{"network" => network}) do
+ conn
+ |> assign(:title, network)
+ |> render("index.html")
+ end
+
+end
diff --git a/lib/lsg_web/controllers/page_controller.ex b/lib/lsg_web/controllers/page_controller.ex
index b356b9c..a87cf1d 100644
--- a/lib/lsg_web/controllers/page_controller.ex
+++ b/lib/lsg_web/controllers/page_controller.ex
@@ -1,12 +1,35 @@
defmodule LSGWeb.PageController do
use LSGWeb, :controller
- def index(conn, _params) do
- render conn, "index.html"
+ plug LSGWeb.ContextPlug when action not in [:token]
+ plug LSGWeb.ContextPlug, [restrict: :public] when action in [:token]
+
+ def token(conn, %{"token" => token}) do
+ with \
+ {:ok, account, perks} <- LSG.AuthToken.lookup(token)
+ do
+ IO.puts("Authenticated account #{inspect account}")
+ conn = put_session(conn, :account, account)
+ case perks do
+ nil -> redirect(conn, to: "/")
+ {:redirect, path} -> redirect(conn, to: path)
+ {:external_redirect, url} -> redirect(conn, external: url)
+ end
+ else
+ z ->
+ IO.inspect(z)
+ text(conn, "Error: invalid or expired token")
+ end
end
- def api(conn, _params) do
- render conn, "api.html"
+ def index(conn = %{assigns: %{account: account}}, _) do
+ memberships = IRC.Membership.of_account(account)
+ users = IRC.UserTrack.find_by_account(account)
+ metas = IRC.Account.get_all_meta(account)
+ predicates = IRC.Account.get_predicates(account)
+ conn
+ |> assign(:title, account.name)
+ |> render("user.html", users: users, memberships: memberships, metas: metas, predicates: predicates)
end
def irc(conn, _) do
@@ -16,16 +39,15 @@ defmodule LSGWeb.PageController do
render conn, "irc.html", bot_helps: bot_helps
end
- def icecast(conn, _params) do
- conn
- |> json(LSG.IcecastAgent.get)
- end
-
- def widget(conn, options) do
- icecast = LSG.IcecastAgent.get
- conn
- |> put_layout(false)
- |> render("widget.html", icecast: icecast)
+ def authenticate(conn, _) do
+ with \
+ {:account, account_id} when is_binary(account_id) <- {:account, get_session(conn, :account)},
+ {:account, account} when not is_nil(account) <- {:account, IRC.Account.get(account_id)}
+ do
+ assign(conn, :account, account)
+ else
+ _ -> conn
+ end
end
end
diff --git a/lib/lsg_web/controllers/sms_controller.ex b/lib/lsg_web/controllers/sms_controller.ex
new file mode 100644
index 0000000..00c6352
--- /dev/null
+++ b/lib/lsg_web/controllers/sms_controller.ex
@@ -0,0 +1,10 @@
+defmodule LSGWeb.SmsController do
+ use LSGWeb, :controller
+ require Logger
+
+ def ovh_callback(conn, %{"senderid" => from, "message" => message}) do
+ spawn(fn() -> LSG.IRC.SmsPlugin.incoming(from, String.trim(message)) end)
+ text(conn, "")
+ end
+
+end
diff --git a/lib/lsg_web/controllers/untappd_controller.ex b/lib/lsg_web/controllers/untappd_controller.ex
new file mode 100644
index 0000000..1c3ceb1
--- /dev/null
+++ b/lib/lsg_web/controllers/untappd_controller.ex
@@ -0,0 +1,18 @@
+defmodule LSGWeb.UntappdController do
+ use LSGWeb, :controller
+
+ def callback(conn, %{"code" => code}) do
+ with \
+ {:account, account_id} when is_binary(account_id) <- {:account, get_session(conn, :account)},
+ {:account, account} when not is_nil(account) <- {:account, IRC.Account.get(account_id)},
+ {:ok, auth_token} <- Untappd.auth_callback(code)
+ do
+ IRC.Account.put_meta(account, "untappd-token", auth_token)
+ text(conn, "OK!")
+ else
+ {:account, _} -> text(conn, "Error: account not found")
+ :error -> text(conn, "Error: untappd authentication failed")
+ end
+ end
+
+end