Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F77382
matrix.ex
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Subscribers
None
matrix.ex
View Options
defmodule
Nola.Matrix
do
require
Logger
alias
Polyjuice.Client
@behaviour
MatrixAppService.Adapter.Room
@behaviour
MatrixAppService.Adapter.Transaction
@behaviour
MatrixAppService.Adapter.User
@env
Mix
.
env
def
dets
(
part
)
do
(
Nola
.
data_path
()
<>
"/matrix-
#{
to_string
(
part
)
}
.dets"
)
|>
String
.
to_charlist
()
end
def
setup
()
do
{
:ok
,
_
}
=
:dets
.
open_file
(
dets
(
:rooms
),
[])
{
:ok
,
_
}
=
:dets
.
open_file
(
dets
(
:room_aliases
),
[])
{
:ok
,
_
}
=
:dets
.
open_file
(
dets
(
:users
),
[])
:ok
end
def
myself?
(
"@_dev:random.sh"
),
do
:
true
def
myself?
(
"@_bot:random.sh"
),
do
:
true
def
myself?
(
"@_dev."
<>
_
),
do
:
true
def
myself?
(
"@_bot."
<>
_
),
do
:
true
def
myself?
(
_
),
do
:
false
def
mxc_to_http
(
mxc
=
"mxc://"
<>
_
)
do
uri
=
URI
.
parse
(
mxc
)
%
URI
{
uri
|
scheme
:
"https"
,
path
:
"/_matrix/media/r0/download/
#{
uri
.
authority
}#{
uri
.
path
}
"
}
|>
URI
.
to_string
()
end
def
get_or_create_matrix_user
(
id
)
do
if
mxid
=
lookup_user
(
id
)
do
mxid
else
opts
=
[
type
:
"m.login.application_service"
,
inhibit_login
:
true
,
device_id
:
"APP_SERVICE"
,
initial_device_display_name
:
"Application Service"
,
username
:
if
(
@env
==
:dev
,
do
:
"_dev.
#{
id
}
"
,
else
:
"_bot.
#{
id
}
"
)
]
Logger
.
debug
(
"Registering user for
#{
id
}
"
)
{
:ok
,
%{
"user_id"
=>
mxid
}}
=
Polyjuice.Client.LowLevel
.
register
(
client
(),
opts
)
:dets
.
insert
(
dets
(
:users
),
{
id
,
mxid
})
end
end
def
lookup_user
(
id
)
do
case
:dets
.
lookup
(
dets
(
:users
),
id
)
do
[{
_
,
matrix_id
}]
->
matrix_id
_
->
nil
end
end
def
user_name
(
"@"
<>
name
)
do
[
username
,
_
]
=
String
.
split
(
name
,
":"
,
parts
:
2
)
username
end
def
application_childs
()
do
import
Supervisor.Spec
[
supervisor
(
Nola.Matrix.Room.Supervisor
,
[],
[
name
:
Nola.Irc.PuppetConnection.Supervisor
]),
]
end
def
after_start
()
do
rooms
=
:dets
.
foldl
(
fn
({
id
,
_
,
_
,
_
},
acc
)
->
[
id
|
acc
]
end
,
[],
dets
(
:rooms
))
for
room
<-
rooms
,
do
:
Nola.Matrix.Room
.
start
(
room
)
end
def
lookup_room
(
room
)
do
case
:dets
.
lookup
(
dets
(
:rooms
),
room
)
do
[{
_
,
network
,
channel
,
opts
}]
->
{
:ok
,
Map
.
merge
(
opts
,
%{
network
:
network
,
channel
:
channel
})}
_
->
{
:error
,
:no_such_room
}
end
end
def
lookup_room_alias
(
room_alias
)
do
case
:dets
.
lookup
(
dets
(
:room_aliases
),
room_alias
)
do
[{
_
,
room_id
}]
->
{
:ok
,
room_id
}
_
->
{
:error
,
:no_such_room_alias
}
end
end
def
lookup_or_create_room
(
room_alias
)
do
case
lookup_room_alias
(
room_alias
)
do
{
:ok
,
room_id
}
->
{
:ok
,
room_id
}
{
:error
,
:no_such_room_alias
}
->
create_room
(
room_alias
)
end
end
def
create_room
(
room_alias
)
do
Logger
.
debug
(
"Matrix: creating room
#{
inspect
room_alias
}
"
)
localpart
=
localpart
(
room_alias
)
with
{
:ok
,
network
,
channel
}
<-
extract_network_channel_from_localpart
(
localpart
),
%
Nola.Irc.Connection
{}
<-
Nola.Irc.Connection
.
get_network
(
network
,
channel
),
room
=
[
visibility
:
:public
,
room_alias_name
:
localpart
,
name
:
if
(
network
==
"random"
,
do
:
channel
,
else
:
"
#{
network
}
/
#{
channel
}
"
)],
{
:ok
,
%{
"room_id"
=>
room_id
}}
<-
Client.Room
.
create_room
(
client
(),
room
)
do
Logger
.
info
(
"Matrix: created room
#{
room_alias
}
#{
room_id
}
"
)
:dets
.
insert
(
dets
(
:rooms
),
{
room_id
,
network
,
channel
,
%{}})
:dets
.
insert
(
dets
(
:room_aliases
),
{
room_alias
,
room_id
})
{
:ok
,
room_id
}
else
nil
->
{
:error
,
:no_such_network_channel
}
error
->
error
end
end
def
localpart
(
room_alias
)
do
[<<
"
#
"
,
localpart
::
binary
>>,
_
]
=
String
.
split
(
room_alias
,
":"
,
parts
:
2
)
localpart
end
def
extract_network_channel_from_localpart
(
localpart
)
do
s
=
localpart
|>
String
.
replace
(
"dev."
,
""
)
|>
String
.
split
(
"/"
,
parts
:
2
)
case
s
do
[
network
,
channel
]
->
{
:ok
,
network
,
channel
}
[
channel
]
->
{
:ok
,
"random"
,
channel
}
_
->
{
:error
,
:invalid_localpart
}
end
end
@impl
MatrixAppService.Adapter.Room
def
query_alias
(
room_alias
)
do
case
lookup_or_create_room
(
room_alias
)
do
{
:ok
,
room_id
}
->
Nola.Matrix.Room
.
start
(
room_id
)
:ok
error
->
error
end
end
@impl
MatrixAppService.Adapter.Transaction
def
new_event
(
event
=
%
MatrixAppService.Event
{})
do
Logger
.
debug
(
"New matrix event:
#{
inspect
event
}
"
)
if
event
.
room_id
do
Nola.Matrix.Room
.
start_and_send_matrix_event
(
event
.
room_id
,
event
)
end
:noop
end
@impl
MatrixAppService.Adapter.User
def
query_user
(
user_id
)
do
Logger
.
warn
(
"Matrix lookup user:
#{
inspect
user_id
}
"
)
:error
end
def
client
(
opts
\\
[])
do
base_url
=
Application
.
get_env
(
:matrix_app_service
,
:base_url
)
access_token
=
Application
.
get_env
(
:matrix_app_service
,
:access_token
)
default_opts
=
[
access_token
:
access_token
,
device_id
:
"APP_SERVICE"
,
application_service
:
true
,
user_id
:
nil
]
opts
=
Keyword
.
merge
(
default_opts
,
opts
)
Polyjuice.Client.LowLevel
.
create
(
base_url
,
opts
)
end
end
File Metadata
Details
Attached
Mime Type
text/x-ruby
Expires
Mon, Jul 7, 7:53 AM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
49874
Default Alt Text
matrix.ex (4 KB)
Attached To
rNOLA Nola
Event Timeline
Log In to Comment