Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F51244
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
16 KB
Subscribers
None
View Options
diff --git a/config/config.exs b/config/config.exs
index 8a1faa6..e1bbf1f 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -1,58 +1,59 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
#
# This configuration file is loaded before any dependency and
# is restricted to this project.
use Mix.Config
config :logger, level: :debug
config :logger, :console,
format: "$date $time [$level$levelpad] $metadata$message\n",
metadata: :all
config :phoenix, :json_library, Jason
# General application configuration
config :lsg,
namespace: LSG
config :lsg, :data_path, "priv"
-config :lsg, :irc,
- name: "ircbot"
+config :lsg, :brand,
+ name: "Nola",
+ source_url: "https://phab.random.sh/source/Bot/"
config :ex_aws,
region: "us-east-1",
host: "s3.wasabisys.com",
s3: [
host: "s3.wasabisys.com",
region: "us-east-1",
scheme: "https://"
]
# Configures the endpoint
config :lsg, LSGWeb.Endpoint,
url: [host: "localhost"],
secret_key_base: "cAFb7x2p/D7PdV8/C6Os18uygoD0FVQh3efNEFc5+5L529q3dofZtZye/BG12MRZ",
render_errors: [view: LSGWeb.ErrorView, accepts: ~w(html json)],
server: true,
live_view: [signing_salt: "CHANGE_ME_FFS"],
pubsub: [name: LSG.PubSub,
adapter: Phoenix.PubSub.PG2]
config :mime, :types, %{"text/event-stream" => ["sse"]}
config :lsg, LSG.IRC.LastFmHandler,
api_key: "x",
api_secret: "x"
config :lsg, LSG.IRC.YouTubeHandler,
api_key: "x",
invidious: "yewtu.be"
config :mnesia,
dir: '.mnesia/#{Mix.env}/#{node()}'
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{Mix.env}.exs"
diff --git a/lib/irc/irc.ex b/lib/irc/irc.ex
index fbad6e1..d9fdfb5 100644
--- a/lib/irc/irc.ex
+++ b/lib/irc/irc.ex
@@ -1,79 +1,79 @@
defmodule IRC do
defmodule Message do
@derive {Poison.Encoder, except: [:replyfun]}
defstruct [:id,
:text,
{:transport, :irc},
:network,
:account,
:sender,
:channel,
:trigger,
:replyfun,
:at,
{:meta, %{}}
]
end
defmodule Trigger do
@derive Poison.Encoder
defstruct [:type, :trigger, :args]
end
def send_message_as(account, network, channel, text, force_puppet \\ false) do
connection = IRC.Connection.get_network(network)
if connection && (force_puppet || IRC.PuppetConnection.whereis(account, connection)) do
IRC.PuppetConnection.start_and_send_message(account, connection, channel, text)
else
user = IRC.UserTrack.find_by_account(network, account)
nick = if(user, do: user.nick, else: account.name)
IRC.Connection.broadcast_message(network, channel, "<#{nick}> #{text}")
end
end
def register(key) do
case Registry.register(IRC.PubSub, key, []) do
{:ok, _} -> :ok
error -> error
end
end
def admin?(%Message{sender: sender}), do: admin?(sender)
def admin?(%{nick: nick, user: user, host: host}) do
- for {n, u, h} <- Application.get_env(:lsg, :irc, [])[:admins]||[] do
+ for {n, u, h} <- LSG.IRC.env(:admins, []) do
admin_part_match?(n, nick) && admin_part_match?(u, user) && admin_part_match?(h, host)
end
|> Enum.any?
end
defp admin_part_match?(:_, _), do: true
defp admin_part_match?(a, a), do: true
defp admin_part_match?(_, _), do: false
@max_chars 440
def splitlong(string, max_chars \\ 440)
def splitlong(string, max_chars) when is_list(string) do
Enum.map(string, fn(s) -> splitlong(s, max_chars) end)
|> List.flatten()
end
def splitlong(string, max_chars) do
string
|> String.codepoints
|> Enum.chunk_every(max_chars)
|> Enum.map(&Enum.join/1)
end
def splitlong_with_prefix(string, prefix, max_chars \\ 440) do
prefix = "#{prefix} "
max_chars = max_chars - (length(String.codepoints(prefix)))
string
|> String.codepoints
|> Enum.chunk_every(max_chars)
|> Enum.map(fn(line) -> prefix <> Enum.join(line) end)
end
end
diff --git a/lib/lsg/lsg.ex b/lib/lsg/lsg.ex
index 25f127f..b5da5e0 100644
--- a/lib/lsg/lsg.ex
+++ b/lib/lsg/lsg.ex
@@ -1,19 +1,30 @@
defmodule LSG do
- def source_url() do
- "https://git.random.sh/ircbot.git"
- end
+ @default_brand [
+ name: "Nola,
+ source_url: "https://phab.random.sh/source/Bot/",
+ owner: "Ashamed owner",
+ owner_email: "contact@my.nola.bot"
+ ]
+
+ def env(), do: Application.get_env(:lsg)
+ def env(key, default \\ nil), do: Application.get_env(:lsg, key, default)
+
+ def brand(), do: env(:brand, @default_brand)
+ def brand(key), do: Keyword.get(brand(), key)
+ def name(), do: brand(:name)
+ def source_url(), do: brand(:source_url)
def data_path(suffix) do
Path.join(data_path(), suffix)
end
def data_path do
Application.get_env(:lsg, :data_path)
end
def version do
Application.spec(:lsg)[:vsn]
end
end
diff --git a/lib/lsg_irc/logger_plugin.ex b/lib/lsg_irc/logger_plugin.ex
index e5307bc..de601a6 100644
--- a/lib/lsg_irc/logger_plugin.ex
+++ b/lib/lsg_irc/logger_plugin.ex
@@ -1,69 +1,70 @@
defmodule LSG.IRC.LoggerPlugin do
require Logger
@couch_db "bot-logs"
def irc_doc(), do: nil
def start_link() do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def init([]) do
regopts = [plugin: __MODULE__]
{:ok, _} = Registry.register(IRC.PubSub, "triggers", regopts)
{:ok, _} = Registry.register(IRC.PubSub, "messages", regopts)
+ {:ok, _} = Registry.register(IRC.PubSub, "irc:outputs", regopts)
{:ok, _} = Registry.register(IRC.PubSub, "messages:private", regopts)
{:ok, nil}
end
def handle_info({:irc, :trigger, _, m}, state) do
{:noreply, log(m, state)}
end
def handle_info({:irc, :text, m}, state) do
{:noreply, log(m, state)}
end
def handle_info(info, state) do
Logger.debug("logger_plugin: unhandled info: #{info}")
{:noreply, state}
end
def log(entry, state) do
case Couch.post(@couch_db, format_to_db(entry)) do
{:ok, id, _rev} ->
Logger.debug("logger_plugin: saved: #{inspect id}")
state
error ->
Logger.error("logger_plugin: save failed: #{inspect error}")
end
rescue
e ->
Logger.error("logger_plugin: rescued processing for #{inspect entry}: #{inspect e}")
Logger.error(Exception.format(:error, e, __STACKTRACE__))
state
catch
e, b ->
Logger.error("logger_plugin: catched processing for #{inspect entry}: #{inspect e}")
Logger.error(Exception.format(e, b, __STACKTRACE__))
state
end
def format_to_db(msg = %IRC.Message{id: id}) do
msg
|> Poison.encode!()
|> Map.drop("id")
%{"_id" => id || FlakeId.get(),
"type" => "irc.message/v1",
"object" => msg}
end
def format_to_db(anything) do
%{"_id" => FlakeId.get(),
"type" => "object",
"object" => anything}
end
end
diff --git a/lib/lsg_irc/lsg_irc.ex b/lib/lsg_irc/lsg_irc.ex
index c2782ad..a50abed 100644
--- a/lib/lsg_irc/lsg_irc.ex
+++ b/lib/lsg_irc/lsg_irc.ex
@@ -1,37 +1,34 @@
defmodule LSG.IRC do
require Logger
+ def env(), do: LSG.env(:irc)
+ def env(key, default \\ nil), do: Keyword.get(env(), key, default)
def application_childs do
- env = Application.get_env(:lsg, :irc)
import Supervisor.Spec
IRC.Connection.setup()
IRC.Plugin.setup()
- # Probably just needed for migration
- #for plugin <- Application.get_env(:lsg, :irc)[:plugins], do: IRC.Plugin.declare(plugin)
-
[
worker(Registry, [[keys: :duplicate, name: IRC.ConnectionPubSub]], id: :registr_irc_conn),
worker(Registry, [[keys: :duplicate, name: IRC.PubSub]], id: :registry_irc),
worker(IRC.Membership, []),
worker(IRC.Account, []),
worker(IRC.UserTrack.Storage, []),
worker(IRC.Account.AccountPlugin, []),
supervisor(IRC.Plugin.Supervisor, [], [name: IRC.Plugin.Supervisor]),
supervisor(IRC.Connection.Supervisor, [], [name: IRC.Connection.Supervisor]),
supervisor(IRC.PuppetConnection.Supervisor, [], [name: IRC.PuppetConnection.Supervisor]),
]
end
+ # Start plugins first to let them get on connection events.
def after_start() do
- # Start plugins first to let them get on connection events.
- Logger.debug("IRC.after_start - initializing plugins")
+ Logger.info("Starting plugins")
IRC.Plugin.start_all()
- Logger.debug("IRC.after_start - initializing connections")
+ Logger.info("Starting connections")
IRC.Connection.start_all()
- Logger.debug("IRC.after_start - ok")
end
end
diff --git a/lib/lsg_web/controllers/page_controller.ex b/lib/lsg_web/controllers/page_controller.ex
index a87cf1d..94c9c70 100644
--- a/lib/lsg_web/controllers/page_controller.ex
+++ b/lib/lsg_web/controllers/page_controller.ex
@@ -1,53 +1,53 @@
defmodule LSGWeb.PageController do
use LSGWeb, :controller
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 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
- bot_helps = for mod <- Application.get_env(:lsg, :irc)[:handlers] do
+ bot_helps = for mod <- LSG.IRC.env(:handlers) do
mod.irc_doc()
end
render conn, "irc.html", bot_helps: bot_helps
end
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/views/layout_view.ex b/lib/lsg_web/views/layout_view.ex
index 41c5341..720281d 100644
--- a/lib/lsg_web/views/layout_view.ex
+++ b/lib/lsg_web/views/layout_view.ex
@@ -1,81 +1,81 @@
defmodule LSGWeb.LayoutView do
use LSGWeb, :view
def liquid_markdown(conn, text) do
context_path = cond do
conn.assigns[:chan] -> "/#{conn.assigns[:network]}/#{LSGWeb.format_chan(conn.assigns[:chan])}"
conn.assigns[:network] -> "/#{conn.assigns[:network]}/-"
true -> "/-"
end
{:ok, ast} = Liquex.parse(text)
context = Liquex.Context.new(%{
"context_path" => context_path
})
{content, _} = Liquex.render(ast, context)
content
|> to_string()
|> Earmark.as_html!()
|> raw()
end
def page_title(conn) do
target = cond do
conn.assigns[:chan] ->
"#{conn.assigns.chan} @ #{conn.assigns.network}"
conn.assigns[:network] -> conn.assigns.network
- true -> Keyword.get(Application.get_env(:lsg, :irc), :name, "ircbot")
+ true -> Keyword.get(LSG.name())
end
breadcrumb_title = Enum.map(Map.get(conn.assigns, :breadcrumbs)||[], fn({title, _href}) -> title end)
title = [conn.assigns[:title], breadcrumb_title, target]
|> List.flatten()
|> Enum.uniq()
|> Enum.filter(fn(x) -> x end)
|> Enum.intersperse(" / ")
|> Enum.join()
content_tag(:title, title)
end
def format_time(date, with_relative \\ true) do
alias Timex.Format.DateTime.Formatters
alias Timex.Timezone
date = if is_integer(date) do
date
|> DateTime.from_unix!(:millisecond)
|> DateTime.shift_zone!("Europe/Paris", Tzdata.TimeZoneDatabase)
else
date
|> DateTime.shift_zone!("Europe/Paris", Tzdata.TimeZoneDatabase)
end
now = DateTime.now!("Europe/Paris", Tzdata.TimeZoneDatabase)
now_week = Timex.iso_week(now)
date_week = Timex.iso_week(date)
{y, w} = now_week
now_last_week = {y, w-1}
now_last_roll = 7-Timex.days_to_beginning_of_week(now)
date_date = DateTime.to_date(date)
now_date = DateTime.to_date(date)
format = cond do
date.year != now.year -> "{D}/{M}/{YYYY} {h24}:{m}"
date_date == now_date -> "{h24}:{m}"
(now_week == date_week) || (date_week == now_last_week && (Date.day_of_week(date) >= now_last_roll)) -> "{WDfull} {h24}:{m}"
(now.year == date.year && now.month == date.month) -> "{WDfull} {D} {h24}:{m}"
true -> "{WDfull} {D} {M} {h24}:{m}"
end
{:ok, relative} = Formatters.Relative.relative_to(date, Timex.now("Europe/Paris"), "{relative}", "fr")
{:ok, full} = Formatters.Default.lformat(date, "{WDfull} {D} {YYYY} {h24}:{m}", "fr") #"{h24}:{m} {WDfull} {D}", "fr")
{:ok, detail} = Formatters.Default.lformat(date, format, "fr") #"{h24}:{m} {WDfull} {D}", "fr")
content_tag(:time, if(with_relative, do: relative, else: detail), [title: full])
end
end
diff --git a/mix.exs b/mix.exs
index 427aeeb..1778206 100644
--- a/mix.exs
+++ b/mix.exs
@@ -1,98 +1,98 @@
-defmodule LSG.Mixfile do
+defmodule Nola.Mixfile do
use Mix.Project
def project do
[
- app: :lsg,
- version: version("0.2.6"),
+ app: :nola,
+ version: version("0.2.7"),
elixir: "~> 1.4",
elixirc_paths: elixirc_paths(Mix.env),
compilers: [:phoenix, :gettext] ++ Mix.compilers,
start_permanent: Mix.env == :prod,
deps: deps()
]
end
def application do
[
mod: {LSG.Application, []},
extra_applications: [:logger, :runtime_tools]
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
defp aliases do
[
"assets.deploy": ["make -C assets", "phx.digest"]
]
end
defp deps do
[
{:phoenix, "~> 1.6.0-rc.0", override: true},
{:phoenix_pubsub, "~> 2.0"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:phoenix_html, "~> 3.0"},
{:phoenix_live_view, "~> 0.16.0"},
{:phoenix_live_dashboard, "~> 0.5"},
{:telemetry, "~> 1.0.0", override: true},
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 0.5"},
{:plug_cowboy, "~> 2.0"},
{:cowlib, "~> 2.9.1", override: true},
{:plug, "~> 1.7"},
{:gettext, "~> 0.11"},
{:httpoison, "~> 1.8", override: true},
{:jason, "~> 1.0"},
{:poison, "~> 4.0", override: true},
{:floki, "~> 0.19.3"},
{:ecto, "~> 3.4"},
{:exirc, git: "https://git.random.sh/ircbot/exirc.git", branch: "fix-who-nick"},
{:distillery, "~> 2.0"},
{:earmark, "~> 1.2"},
{:oauther, "~> 1.1"},
{:extwitter, "~> 0.14.0"},
{:entropy_string, "~> 1.0.0"},
{:abacus, "~> 0.3.3"},
{:ex_chain, github: "eljojo/ex_chain"},
{:timex, "~> 3.6"},
{:muontrap, "~> 0.5.1"},
{:tzdata, "~> 1.0"},
{:nimble_csv, "~> 0.7.0"},
{:backoff, git: "https://github.com/ferd/backoff", branch: "master"},
{:telegram, git: "https://github.com/hrefhref/telegram.git", branch: "master"},
{:ex_aws, "~> 2.0"},
{:ex_aws_s3, "~> 2.0"},
{:gen_magic, git: "https://github.com/hrefhref/gen_magic", branch: "develop"},
{:liquex, "~> 0.3"},
{:html_entities, "0.4.0", override: true},
{:file_size, "~> 3.0"},
{:ex2ms, "~> 1.0"},
{:polyjuice_client, git: "https://git.random.sh/ircbot/polyjuice_client.git", branch: "master", override: true},
{:matrix_app_service, git: "https://git.random.sh/ircbot/matrix_app_service.ex.git", branch: "master"},
{:sentry, "~> 8.0.5"},
{:logger_json, "~> 4.3"},
{:oauth2, "~> 2.0"},
{:powerdnsex, git: "https://git.random.sh/ircbot/powerdnsex.git", branch: "master"},
{:pfx, "~> 0.7.0"},
{:flake_id, "~> 0.1.0"}
]
end
defp version(v) do
{describe, 0} = System.cmd("git", ~w(describe --dirty --broken --all --tags --long))
[_, rest] = String.split(describe, "/")
info = String.trim(rest)
env = cond do
Mix.env() == :prod -> ""
true -> "." <> to_string(Mix.env())
end
#build_date_tag = Timex.format!(DateTime.utc_now(), ".build%y%m%d@%H%M", :strftime)
build_date_tag = ".build"
v <> "+" <> info <> env <> build_date_tag
end
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Mar 14, 4:23 PM (20 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33601
Default Alt Text
(16 KB)
Attached To
rNOLA Nola
Event Timeline
Log In to Comment