1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
require Logger
alias Nosedrum.TextCommand.Predicates
alias Nostrum.Struct.Message
alias Thulani.Command.Util
alias Thulani.Schema.Meme
alias Thulani.Schema.Image
defmodule Thulani.Command.AddMeme do
@behaviour Nosedrum.TextCommand
@impl true
def aliases, do: ["addmeme"]
@impl true
# TODO
def usage, do: ["addmeme <title:str>"]
@impl true
def predicates, do: [&Predicates.guild_only/1]
@impl true
def description, do: "add a meme to the db"
@impl true
def command(
msg,
[title, content]
) do
result =
Thulani.Repo.transaction(fn ->
%{
content: content,
title: title,
metadata: Util.metadata(msg)
}
|> Map.merge(media(msg))
|> dbg
|> Meme.insert_changeset()
|> Thulani.Repo.insert()
end)
case result do
{:ok, _meme} ->
Logger.debug("inserted meme ok")
msg |> Util.react!("👌")
{:error, changeset} ->
Logger.error("updating")
Ecto.Changeset.traverse_errors(
changeset,
fn {msg, opts} ->
dbg({msg, opts})
end
)
end
{:ok}
end
defp media(
%Message{
attachments: [
%Message.Attachment{
url: url,
filename: filename
}
]
} = msg
) do
data = Req.get!(url).body
hash = :crypto.hash(:sha, data)
existing_image = image_with_hash(hash) |> Thulani.Repo.one()
if is_nil(existing_image) do
Logger.debug("no existing image")
%{
image: %{
filename: filename,
data: data,
data_hash: hash,
metadata: Util.metadata(msg)
}
}
else
Logger.debug("found existing image", existing_image: existing_image)
%{
image_id: existing_image.id
}
end
end
defp media(_invalid), do: %{}
defp image_with_hash(hash) when is_binary(hash) do
import Ecto.Query
from(i in Image, where: i.data_hash == ^hash, limit: 1)
end
end
|