Import rough implementation of matrix.client
This commit is contained in:
174
matrix/client.lua
Normal file
174
matrix/client.lua
Normal file
@@ -0,0 +1,174 @@
|
||||
#! /usr/bin/env lua
|
||||
--
|
||||
-- client.lua
|
||||
-- Copyright (C) 2016 Adrian Perez <aperez@igalia.com>
|
||||
--
|
||||
-- Distributed under terms of the MIT license.
|
||||
--
|
||||
|
||||
local User = {}
|
||||
User.__index = User
|
||||
|
||||
setmetatable(User, { __call = function (self, client, user_id)
|
||||
return setmetatable({ user_id = user_id, _client = client }, User)
|
||||
end })
|
||||
|
||||
function User:get_display_name()
|
||||
return self._client._api:get_display_name(self.user_id)
|
||||
end
|
||||
|
||||
function User:set_display_name(display_name)
|
||||
return self._client._api:set_display_name(self.user_id, display_name)
|
||||
end
|
||||
|
||||
function User:get_avatar_url()
|
||||
local mxc_url = self._client._api:get_avatar_url(self.user_id)
|
||||
return self._client._api:get_download_url(mxc_url)
|
||||
end
|
||||
|
||||
function User:set_avatar_url(avatar_url)
|
||||
return self._client._api:set_avatar_url(self.user_id, avatar_url)
|
||||
end
|
||||
|
||||
|
||||
local Room = {}
|
||||
Room.__index = Room
|
||||
|
||||
setmetatable(Room, { __call = function (self, client, room_id)
|
||||
return setmetatable({
|
||||
room_id = room_id,
|
||||
aliases = {},
|
||||
events = {},
|
||||
_client = client,
|
||||
}, Room)
|
||||
end })
|
||||
|
||||
function Room:send_text(text)
|
||||
return self._client._api:send_message(self.room_id, text)
|
||||
end
|
||||
|
||||
function Room:send_emote(text)
|
||||
return self._client._api:send_emote(self.room_id, text)
|
||||
end
|
||||
|
||||
function Room:send_notice(text)
|
||||
return self._client._api:send_notice(self.room_id, text)
|
||||
end
|
||||
|
||||
function Room:invite_user(user_id)
|
||||
-- XXX: Do we really want to pcall(), or should error propagate?
|
||||
return pcall(self._client._api.invite_user,
|
||||
self._client._api, self.room_id, user_id)
|
||||
end
|
||||
|
||||
function Room:kick_user(user_id)
|
||||
-- XXX: Do we really want to pcall(), or should error propagate?
|
||||
return pcall(self._client._api.kick_user,
|
||||
self._client._api, self.room_id, user_id)
|
||||
end
|
||||
|
||||
function Room:ban_user(user_id)
|
||||
-- XXX: Do we really want to pcall(), or should error propagate?
|
||||
return pcall(self._client._api.ban_user,
|
||||
self._client._api, self.room_id, user_id)
|
||||
end
|
||||
|
||||
function Room:leave()
|
||||
-- XXX: Maybe this should use pcall()?
|
||||
self._client._api:leave_room(self.room_id)
|
||||
self._client.rooms[self.room_id] = nil
|
||||
end
|
||||
|
||||
|
||||
local Client = {}
|
||||
Client.__index = Client
|
||||
|
||||
setmetatable(Client, { __call = function (self, base_url, token, http_factory)
|
||||
local c = setmetatable({
|
||||
rooms = {}, -- Indexed by room_id
|
||||
_api = require("matrix.api")(base_url, token, http_factory),
|
||||
}, Client)
|
||||
-- Do an initial sync if a token was provided on construction.
|
||||
if token then
|
||||
c:_sync()
|
||||
end
|
||||
return c
|
||||
end })
|
||||
|
||||
function Client:register_with_password(username, password, limit)
|
||||
return self:_logged_in(self._api:register("m.login.password",
|
||||
{ user = username, password = password }), limit)
|
||||
end
|
||||
|
||||
function Client:login_with_password(username, password, limit)
|
||||
return self:_logged_in(self._api:login("m.login.password",
|
||||
{ user = username, password = password }), limit)
|
||||
end
|
||||
|
||||
function Client:_logged_in(response, limit)
|
||||
self.user_id = response.user_id
|
||||
self.homeserver = response.home_server
|
||||
self.token = response.access_token
|
||||
self._api.token = response.access_token
|
||||
self:_sync(limit)
|
||||
return self.token
|
||||
end
|
||||
|
||||
function Client:logout()
|
||||
return self._api:logout()
|
||||
end
|
||||
|
||||
function Client:get_user()
|
||||
return self.user_id and User(self, self.user_id) or nil
|
||||
end
|
||||
|
||||
function Client:create_room(alias, public, invite)
|
||||
local response = self._api:create_room {
|
||||
alias = alias,
|
||||
public = public,
|
||||
invite = invite,
|
||||
}
|
||||
return self:_make_room(response.room_id)
|
||||
end
|
||||
|
||||
function Client:join_room(room_id_or_alias)
|
||||
local response = self._api:join_room(room_id_or_alias)
|
||||
return self:_make_room(response.room_id or room_id_or_alias)
|
||||
end
|
||||
|
||||
function Client:_make_room(room_id)
|
||||
local room = Room(self, room_id)
|
||||
self.rooms[room_id] = room
|
||||
return room
|
||||
end
|
||||
|
||||
function Client:_sync(limit)
|
||||
local response = self._api:initial_sync(limit)
|
||||
self._end = response._end
|
||||
for _, room in ipairs(response.rooms) do
|
||||
local current_room = self:_make_room(room.room_id)
|
||||
for _, chunk in ipairs(room.messages.chunk) do
|
||||
table.insert(current_room.events, chunk)
|
||||
end
|
||||
for _, state_event in ipairs(room.state) do
|
||||
self:_process_state_event(state_event, current_room)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Client:_process_state_event(event, room)
|
||||
local event_type = event.type
|
||||
if not event_type then
|
||||
return -- Ignore event
|
||||
end
|
||||
if event_type == "m.room.name" then
|
||||
room.name = event.content.name
|
||||
elseif event_type == "m.room.topic" then
|
||||
room.topic = event.content.topic
|
||||
elseif event_type == "m.room.aliases" then
|
||||
room.aliases = event.content.aliases
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return { room = Room, user = User, client = Client }
|
||||
Reference in New Issue
Block a user