mirror of
https://github.com/matrix-construct/construct
synced 2024-11-15 22:41:12 +01:00
modules: Start an m_rooms unit; move publicrooms summary chunk generation.
This commit is contained in:
parent
6f2c9631a1
commit
62177dca20
5 changed files with 233 additions and 123 deletions
|
@ -11,7 +11,8 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_M_ROOMS_H
|
||||
|
||||
/// Convenience iterface for iterations of rooms
|
||||
/// Convenience iterface for rooms; utilities for the server's collection of
|
||||
/// rooms and some rooms list related linkages.
|
||||
///
|
||||
namespace ircd::m::rooms
|
||||
{
|
||||
|
@ -26,4 +27,8 @@ namespace ircd::m::rooms
|
|||
void for_each(const user &, const string_view &membership, const user::rooms::closure &);
|
||||
void for_each(const user &, const user::rooms::closure_bool &);
|
||||
void for_each(const user &, const user::rooms::closure &);
|
||||
|
||||
// Linkage to utils that build a publicrooms summary from room state.
|
||||
void summary_chunk(const m::room &, json::stack::object &chunk);
|
||||
json::object summary_chunk(const m::room &, const mutable_buffer &out);
|
||||
}
|
||||
|
|
30
ircd/m/m.cc
30
ircd/m/m.cc
|
@ -1468,6 +1468,36 @@ ircd::m::event_filter::event_filter(const mutable_buffer &buf,
|
|||
// m/rooms.h
|
||||
//
|
||||
|
||||
ircd::json::object
|
||||
ircd::m::rooms::summary_chunk(const m::room &room,
|
||||
const mutable_buffer &buf)
|
||||
{
|
||||
json::stack out{buf};
|
||||
{
|
||||
json::stack::object obj{out};
|
||||
summary_chunk(room, obj);
|
||||
}
|
||||
|
||||
return json::object
|
||||
{
|
||||
out.completed()
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::rooms::summary_chunk(const m::room &room,
|
||||
json::stack::object &chunk)
|
||||
{
|
||||
using prototype = void (const m::room &, json::stack::object &);
|
||||
|
||||
static mods::import<prototype> function
|
||||
{
|
||||
"m_rooms", "_summary_chunk"
|
||||
};
|
||||
|
||||
return function(room, chunk);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::rooms::for_each(const user &user,
|
||||
const user::rooms::closure &closure)
|
||||
|
|
|
@ -92,6 +92,7 @@ m_event_la_SOURCES = m_event.cc
|
|||
m_typing_la_SOURCES = m_typing.cc
|
||||
m_receipt_la_SOURCES = m_receipt.cc
|
||||
m_presence_la_SOURCES = m_presence.cc
|
||||
m_rooms_la_SOURCES = m_rooms.cc
|
||||
m_room_la_SOURCES = m_room.cc
|
||||
m_room_create_la_SOURCES = m_room_create.cc
|
||||
m_room_member_la_SOURCES = m_room_member.cc
|
||||
|
@ -109,6 +110,7 @@ m_module_LTLIBRARIES = \
|
|||
m_typing.la \
|
||||
m_receipt.la \
|
||||
m_presence.la \
|
||||
m_rooms.la \
|
||||
m_room.la \
|
||||
m_room_create.la \
|
||||
m_room_member.la \
|
||||
|
|
|
@ -114,114 +114,22 @@ post__publicrooms(client &client,
|
|||
{
|
||||
json::stack::member chunk_m{top, "chunk"};
|
||||
json::stack::array chunk{chunk_m};
|
||||
publix.for_each("ircd.room", since, [&](const m::event &event)
|
||||
publix.for_each("ircd.room", since, [&]
|
||||
(const m::event &event)
|
||||
{
|
||||
const m::room::id room_id{at<"state_key"_>(event)};
|
||||
const m::room::state state{room_id};
|
||||
const m::room::id &room_id
|
||||
{
|
||||
at<"state_key"_>(event)
|
||||
};
|
||||
|
||||
json::stack::object obj{chunk};
|
||||
m::rooms::summary_chunk(room_id, obj);
|
||||
|
||||
if(!count && !empty(since))
|
||||
prev_batch_buf = room_id; //TODO: ???
|
||||
|
||||
// Aliases array
|
||||
{
|
||||
json::stack::member aliases_m{obj, "aliases"};
|
||||
json::stack::array array{aliases_m};
|
||||
state.for_each("m.room.aliases", [&array]
|
||||
(const m::event &event)
|
||||
{
|
||||
const json::array aliases
|
||||
{
|
||||
json::get<"content"_>(event).get("aliases")
|
||||
};
|
||||
|
||||
for(const string_view &alias : aliases)
|
||||
array.append(unquote(alias));
|
||||
});
|
||||
}
|
||||
|
||||
state.get(std::nothrow, "m.room.avatar_url", "", [&obj]
|
||||
(const m::event &event)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "avatar_url", unquote(json::get<"content"_>(event).get("url"))
|
||||
};
|
||||
});
|
||||
|
||||
state.get(std::nothrow, "m.room.canonical_alias", "", [&obj]
|
||||
(const m::event &event)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "canonical_alias", unquote(json::get<"content"_>(event).get("alias"))
|
||||
};
|
||||
});
|
||||
|
||||
state.get(std::nothrow, "m.room.guest_access", "", [&obj]
|
||||
(const m::event &event)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "guest_can_join", json::value
|
||||
{
|
||||
unquote(json::get<"content"_>(event).get("guest_access")) == "can_join"
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
state.get(std::nothrow, "m.room.name", "", [&obj]
|
||||
(const m::event &event)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "name", json::value
|
||||
{
|
||||
unquote(json::get<"content"_>(event).get("name"))
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// num_join_members
|
||||
{
|
||||
const m::room::members members{room_id};
|
||||
json::stack::member
|
||||
{
|
||||
obj, "num_joined_members", json::value
|
||||
{
|
||||
long(members.count("join"))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
json::stack::member
|
||||
{
|
||||
obj, "room_id", room_id
|
||||
};
|
||||
|
||||
state.get(std::nothrow, "m.room.topic", "", [&obj]
|
||||
(const m::event &event)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "topic", unquote(json::get<"content"_>(event).get("topic"))
|
||||
};
|
||||
});
|
||||
|
||||
state.get(std::nothrow, "m.room.history_visibility", "", [&obj]
|
||||
(const m::event &event)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "world_readable", json::value
|
||||
{
|
||||
unquote(json::get<"content"_>(event).get("history_visibility")) == "world_readable"
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
next_batch_buf = room_id;
|
||||
return count < limit;
|
||||
return ++count < limit;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -321,24 +229,3 @@ post__publicrooms_remote(client &client,
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
_create_public_room(const m::event &,
|
||||
m::vm::eval &)
|
||||
{
|
||||
m::create(public_room_id, m::me.user_id);
|
||||
}
|
||||
|
||||
/// Create the public rooms room at the appropriate time on startup.
|
||||
/// The startup event chosen here is when @ircd joins the !ircd room,
|
||||
/// which is a fundamental notification toward the end of init.
|
||||
const m::hookfn<m::vm::eval &>
|
||||
_create_public_hook
|
||||
{
|
||||
_create_public_room,
|
||||
{
|
||||
{ "_site", "vm.effect" },
|
||||
{ "room_id", "!ircd" },
|
||||
{ "type", "m.room.create" },
|
||||
}
|
||||
};
|
||||
|
|
186
modules/m_rooms.cc
Normal file
186
modules/m_rooms.cc
Normal file
|
@ -0,0 +1,186 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
namespace ircd::m::rooms
|
||||
{
|
||||
extern "C" void _summary_chunk(const m::room &room, json::stack::object &obj);
|
||||
static void create_public_room(const m::event &, m::vm::eval &);
|
||||
|
||||
extern const ircd::m::room::id::buf public_room_id;
|
||||
extern m::hookfn<m::vm::eval &> create_public_room_hook;
|
||||
}
|
||||
|
||||
ircd::mapi::header
|
||||
IRCD_MODULE
|
||||
{
|
||||
"Matrix rooms interface; modular components"
|
||||
};
|
||||
|
||||
decltype(ircd::m::rooms::public_room_id)
|
||||
ircd::m::rooms::public_room_id
|
||||
{
|
||||
"public", ircd::my_host()
|
||||
};
|
||||
|
||||
/// Create the public rooms room during initial database bootstrap.
|
||||
/// This hooks the creation of the !ircd room which is a fundamental
|
||||
/// event indicating the database has just been created.
|
||||
decltype(ircd::m::rooms::create_public_room_hook)
|
||||
ircd::m::rooms::create_public_room_hook
|
||||
{
|
||||
create_public_room,
|
||||
{
|
||||
{ "_site", "vm.effect" },
|
||||
{ "room_id", "!ircd" },
|
||||
{ "type", "m.room.create" },
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
ircd::m::rooms::create_public_room(const m::event &,
|
||||
m::vm::eval &)
|
||||
{
|
||||
m::create(public_room_id, m::me.user_id);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::m::rooms::_summary_chunk(const m::room &room,
|
||||
json::stack::object &obj)
|
||||
{
|
||||
static const event::keys keys
|
||||
{
|
||||
event::keys::include
|
||||
{
|
||||
"content",
|
||||
}
|
||||
};
|
||||
|
||||
const m::event::fetch::opts fopts
|
||||
{
|
||||
keys, room.fopts? room.fopts->gopts : db::gopts{}
|
||||
};
|
||||
|
||||
const m::room::state state
|
||||
{
|
||||
room, &fopts
|
||||
};
|
||||
|
||||
// Closure over boilerplate primary room state queries; i.e matrix
|
||||
// m.room.$type events with state key "" where the content is directly
|
||||
// presented to the closure.
|
||||
const auto query{[&state]
|
||||
(const string_view &type, const string_view &content_key, const auto &closure)
|
||||
{
|
||||
state.get(std::nothrow, type, "", [&content_key, &closure]
|
||||
(const m::event &event)
|
||||
{
|
||||
const auto &content(json::get<"content"_>(event));
|
||||
const auto &value(unquote(content.get(content_key)));
|
||||
closure(value);
|
||||
});
|
||||
}};
|
||||
|
||||
// Aliases array
|
||||
{
|
||||
json::stack::member aliases_m{obj, "aliases"};
|
||||
json::stack::array array{aliases_m};
|
||||
state.for_each("m.room.aliases", [&array]
|
||||
(const m::event &event)
|
||||
{
|
||||
const json::array aliases
|
||||
{
|
||||
json::get<"content"_>(event).get("aliases")
|
||||
};
|
||||
|
||||
for(const string_view &alias : aliases)
|
||||
array.append(unquote(alias));
|
||||
});
|
||||
}
|
||||
|
||||
query("m.room.avatar_url", "url", [&obj]
|
||||
(const string_view &value)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "avatar_url", value
|
||||
};
|
||||
});
|
||||
|
||||
query("m.room.canonical_alias", "alias", [&obj]
|
||||
(const string_view &value)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "canonical_alias", value
|
||||
};
|
||||
});
|
||||
|
||||
query("m.room.guest_access", "guest_access", [&obj]
|
||||
(const string_view &value)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "guest_can_join", json::value
|
||||
{
|
||||
value == "can_join"
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
query("m.room.name", "name", [&obj]
|
||||
(const string_view &value)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "name", value
|
||||
};
|
||||
});
|
||||
|
||||
// num_join_members
|
||||
{
|
||||
const m::room::members members{room};
|
||||
json::stack::member
|
||||
{
|
||||
obj, "num_joined_members", json::value
|
||||
{
|
||||
long(members.count("join"))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// room_id
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "room_id", room.room_id
|
||||
};
|
||||
}
|
||||
|
||||
query("m.room.topic", "topic", [&obj]
|
||||
(const string_view &value)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "topic", value
|
||||
};
|
||||
});
|
||||
|
||||
query("m.room.history_visibility", "history_visibility", [&obj]
|
||||
(const string_view &value)
|
||||
{
|
||||
json::stack::member
|
||||
{
|
||||
obj, "world_readable", json::value
|
||||
{
|
||||
value == "world_readable"
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue