Page MenuHomePhabricator

No OneTemporary

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 c9f2827..f2a0c48 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.12.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

Mime Type
text/x-diff
Expires
Fri, Mar 14, 4:56 PM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33624
Default Alt Text
(16 KB)

Event Timeline