master
cynic 3 years ago
commit 79c5ed7d8e
  1. 4
      .formatter.exs
  2. 26
      .gitignore
  3. 14
      lib/tir_inna_noc.ex
  4. 44
      lib/tir_inna_noc/db.ex
  5. 20
      lib/tir_inna_noc/imageboard.ex
  6. 3
      lib/tir_inna_noc/imageboard/post.ex
  7. 3
      lib/tir_inna_noc/imageboard/thread.ex
  8. 29
      lib/tir_inna_noc/meldh.ex
  9. 20
      lib/tir_inna_noc/merlin.ex
  10. 14
      lib/tir_inna_noc/perenelle.ex
  11. 17
      lib/tir_inna_noc/sup.ex
  12. 33
      mix.exs
  13. 14
      mix.lock
  14. 15
      readme.txt
  15. 1
      test/test_helper.exs
  16. 5
      test/tir_inna_noc_test.exs

@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]

26
.gitignore vendored

@ -0,0 +1,26 @@
# The directory Mix will write compiled artifacts to.
/_build/
# If you run "mix test --cover", coverage assets end up here.
/cover/
# The directory Mix downloads your dependencies sources to.
/deps/
# Where third-party dependencies like ExDoc output generated docs.
/doc/
# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch
# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump
# Also ignore archive artifacts (built via "mix archive.build").
*.ez
# Ignore package tarball (built via "mix hex.build").
tir_inna_noc-*.tar
# Temporary files, for example, from tests.
/tmp/

@ -0,0 +1,14 @@
defmodule TirInnaNoc do
use Application
@impl true
def start(_type, _args) do
IO.puts("starting~")
TirInnaNoc.Sup.start_link(name: :overseer)
#{:ok, c} = Redix.start_link(host: "localhost", port: 6379, name: :redix)
#Redix.command!(c, ["SET", "lol", "jews"])
#Redix.command(c, ["GET", "lol"]) |> inspect |> IO.puts
#{:ok, c}
end
end

@ -0,0 +1,44 @@
defmodule TirInnaNoc.Db do
use GenServer
def start_link(_) do
{:ok, conn} = Redix.start_link(host: "localhost", port: 6379, name: :db)
GenServer.start_link(__MODULE__, conn, name: TirInnaNoc.Db)
end
def set(val, key) do
GenServer.call(TirInnaNoc.Db, {:cmd, ["SET", key, val]})
end
def get(key) do
GenServer.call(TirInnaNoc.Db, {:cmd, ["GET", key]})
end
def exists(key) do
GenServer.call(TirInnaNoc.Db, {:cmd, ["EXISTS", key]})
end
def keys(pattern) do
GenServer.call(TirInnaNoc.Db, {:cmd, ["KEYS", pattern]})
end
def hset(val, key, field) do
GenServer.call(TirInnaNoc.Db, {:cmd, ["HSET", key, field, val]})
end
def hget(key, field) do
GenServer.call(TirInnaNoc.Db, {:cmd, ["HGET", key, field]})
end
def sadd(member, key) do
GenServer.call(TirInnaNoc.Db, {:cmd, ["SADD", key, member]})
end
def smembers(key) do
GenServer.call(TirInnaNoc.Db, {:cmd, ["SMEMBERS", key]})
end
@impl true
def init(c) do
{:ok, c}
end
@impl true
def handle_call({:cmd, command}, _from, c) do
resp = Redix.command(c, command)
{:reply, resp, c}
end
end

@ -0,0 +1,20 @@
defmodule TirInnaNoc.Imageboard do
use Tesla
plug Tesla.Middleware.BaseUrl, "https://a.4cdn.org"
#plug Tesla.Middleware.Headers, [{"authorization", "token xyz"}]
plug Tesla.Middleware.JSON
def boards() do
get("/boards.json")
end
def threads(board) do
get("/"<>board<>"/threads.json")
end
def thread(board, id) do
get("/"<>board<>"/thread/"<>to_string(id)<>".json")
end
def catalog(board) do
get("/"<>board<>"/catalog.json")
end
end

@ -0,0 +1,3 @@
defmodule TirInnaNoc.Imageboard.Post do
defstruct postJson: "", sage: "u"
end

@ -0,0 +1,3 @@
defmodule TirInnaNoc.Imageboard.Thread do
defstruct last_update: 0, on_page: 0, reply_number: 0, posts: ""
end

@ -0,0 +1,29 @@
defmodule TirInnaNoc.Meldh do
use GenServer
def start_link(state) do
GenServer.start_link(__MODULE__, state, name: String.to_atom(elem(state, 0)<>"Meldh"))
end
@impl true
def handle_info({:checkin, no, pid}, state) do
state = {elem(state, 0), Map.put(elem(state, 1), no, pid)}
{:noreply, state}
end
@impl true
def init(state) do
IO.puts("started meldh to archive board "<>elem(state, 0))
{:ok, res} = TirInnaNoc.Imageboard.threads(elem(state, 0))
res.body
|> Enum.each(fn page ->
Enum.each(page["threads"], fn thread ->
DynamicSupervisor.start_child(
String.to_atom(elem(state, 0)<>"Supervisor"),
{TirInnaNoc.Perenelle, {elem(state, 0), thread["no"]}}
)
end)
end)
{:ok, state}
end
end

@ -0,0 +1,20 @@
defmodule TirInnaNoc.Merlin do
use GenServer
def start_link(a) do
GenServer.start_link(__MODULE__, a)
end
@impl true
def init(a) do
{:ok, relevant} = TirInnaNoc.Db.smembers("boards")
relevant
|> Enum.each(fn board ->
DynamicSupervisor.start_child(
MerlinSupervisor, {DynamicSupervisor, strategy: :one_for_one, name: String.to_atom(board<>"Supervisor")}
)
DynamicSupervisor.start_child(MerlinSupervisor, {TirInnaNoc.Meldh, {board, %{}}})
end)
{:ok, a}
end
end

@ -0,0 +1,14 @@
defmodule TirInnaNoc.Perenelle do
use GenServer
def start_link(state) do
GenServer.start_link(__MODULE__, state, name: String.to_atom(elem(state, 0)<>to_string(elem(state, 1))<>"Perenelle"))
end
@impl true
def init(state) do
IO.puts("watching thread "<>inspect(state))
send(String.to_atom(elem(state, 0)<>"Meldh"), {:checkin, elem(state, 1), self()})
{:ok, state}
end
end

@ -0,0 +1,17 @@
defmodule TirInnaNoc.Sup do
use Supervisor
def start_link(opts) do
Supervisor.start_link(__MODULE__, :ok, opts)
end
@impl true
def init(:ok) do
children = [
{TirInnaNoc.Db, [nil]},
{DynamicSupervisor, strategy: :one_for_one, name: MerlinSupervisor},
{TirInnaNoc.Merlin, [nil]}
]
Supervisor.init(children, strategy: :one_for_one)
end
end

@ -0,0 +1,33 @@
defmodule TirInnaNoc.MixProject do
use Mix.Project
def project do
[
app: :tir_inna_noc,
version: "0.1.0",
elixir: "~> 1.13",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
# Run "mix help compile.app" to learn about applications.
def application do
[
mod: {TirInnaNoc, []},
extra_applications: [:logger]
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:redix, "~> 1.1"},
{:tesla, "~> 1.4.0"},
{:jason, "~> 1.3"},
{:html_entities, "~> 0.5.2"}
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
end
end

@ -0,0 +1,14 @@
%{
"castore": {:hex, :castore, "0.1.18", "deb5b9ab02400561b6f5708f3e7660fc35ca2d51bfc6a940d2f513f89c2975fc", [:mix], [], "hexpm", "61bbaf6452b782ef80b33cdb45701afbcf0a918a45ebe7e73f1130d661e66a06"},
"finch": {:hex, :finch, "0.13.0", "c881e5460ec563bf02d4f4584079e62201db676ed4c0ef3e59189331c4eddf7b", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "49957dcde10dcdc042a123a507a9c5ec5a803f53646d451db2f7dea696fba6cc"},
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
"jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"},
"mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"},
"mint": {:hex, :mint, "1.4.2", "50330223429a6e1260b2ca5415f69b0ab086141bc76dc2fbf34d7c389a6675b2", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "ce75a5bbcc59b4d7d8d70f8b2fc284b1751ffb35c7b6a6302b5192f8ab4ddd80"},
"nimble_options": {:hex, :nimble_options, "0.4.0", "c89babbab52221a24b8d1ff9e7d838be70f0d871be823165c94dd3418eea728f", [:mix], [], "hexpm", "e6701c1af326a11eea9634a3b1c62b475339ace9456c1a23ec3bc9a847bca02d"},
"nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"},
"redix": {:hex, :redix, "1.1.5", "6fc460d66a5c2287e83e6d73dddc8d527ff59cb4d4f298b41e03a4db8c3b2bd5", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "679afdd4c14502fe9c11387ff1cdcb33065a1cf511097da1eee407f17c7a418b"},
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
"tesla": {:hex, :tesla, "1.4.4", "bb89aa0c9745190930366f6a2ac612cdf2d0e4d7fff449861baa7875afd797b2", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "d5503a49f9dec1b287567ea8712d085947e247cb11b06bc54adb05bfde466457"},
}

@ -0,0 +1,15 @@
hash post/<board>/<id> ->
string postjson
string sage //y/n/m/u
hash thread/<board>/<id> ->
string last_update
string on_page
string reply_number
string posts //<id>,<id>,<id>,...
hash img ->
string <board>/<tim>/<ext> // binary
set boards -> // all archived boards
string <board>

@ -0,0 +1 @@
ExUnit.start()

@ -0,0 +1,5 @@
defmodule TirInnaNocTest do
use ExUnit.Case
doctest TirInnaNoc
end
Loading…
Cancel
Save