mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 23:14:13 +01:00
ircd:Ⓜ️🧾 Normalize module definition names / layout.
This commit is contained in:
parent
38d4718f20
commit
a1c8845e1e
5 changed files with 305 additions and 247 deletions
|
@ -14,7 +14,11 @@
|
|||
namespace ircd::m::receipt
|
||||
{
|
||||
// [GET]
|
||||
bool read(const id::room &, const id::user &, const event::id::closure &);
|
||||
bool exists(const id::room &, const id::user &, const id::event &);
|
||||
bool freshest(const id::room &, const id::user &, const id::event &);
|
||||
bool ignoring(const m::user &, const id::event &);
|
||||
bool ignoring(const m::user &, const id::room &);
|
||||
bool read(const id::room &, const id::user &, const id::event::closure &);
|
||||
id::event read(id::event::buf &out, const id::room &, const id::user &);
|
||||
|
||||
// [SET]
|
||||
|
|
82
ircd/m.cc
82
ircd/m.cc
|
@ -1276,25 +1276,25 @@ ircd::m::receipt::read(const id::room &room_id,
|
|||
}
|
||||
|
||||
ircd::m::event::id::buf
|
||||
ircd::m::receipt::read(const id::room &room_id,
|
||||
const id::user &user_id,
|
||||
const id::event &event_id,
|
||||
ircd::m::receipt::read(const room::id &room_id,
|
||||
const user::id &user_id,
|
||||
const event::id &event_id,
|
||||
const time_t &ms)
|
||||
{
|
||||
using prototype = event::id::buf (const id::room &, const id::user &, const id::event &, const time_t &);
|
||||
using prototype = event::id::buf (const room::id &, const user::id &, const event::id &, const time_t &);
|
||||
|
||||
static mods::import<prototype> function
|
||||
{
|
||||
"client_rooms", "commit__m_receipt_m_read"
|
||||
"m_receipt", "ircd::m::receipt::read"
|
||||
};
|
||||
|
||||
return function(room_id, user_id, event_id, ms);
|
||||
}
|
||||
|
||||
ircd::m::event::id
|
||||
ircd::m::receipt::read(id::event::buf &out,
|
||||
const id::room &room_id,
|
||||
const id::user &user_id)
|
||||
ircd::m::receipt::read(event::id::buf &out,
|
||||
const room::id &room_id,
|
||||
const user::id &user_id)
|
||||
{
|
||||
const event::id::closure copy{[&out]
|
||||
(const event::id &event_id)
|
||||
|
@ -1308,20 +1308,78 @@ ircd::m::receipt::read(id::event::buf &out,
|
|||
}
|
||||
|
||||
bool
|
||||
ircd::m::receipt::read(const id::room &room_id,
|
||||
const id::user &user_id,
|
||||
ircd::m::receipt::read(const room::id &room_id,
|
||||
const user::id &user_id,
|
||||
const event::id::closure &closure)
|
||||
{
|
||||
using prototype = bool (const id::room &, const id::user &, const id::event::closure &);
|
||||
using prototype = bool (const room::id &, const user::id &, const event::id::closure &);
|
||||
|
||||
static mods::import<prototype> function
|
||||
{
|
||||
"m_receipt", "last_receipt__event_id"
|
||||
"m_receipt", "ircd::m::receipt::read"
|
||||
};
|
||||
|
||||
return function(room_id, user_id, closure);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::receipt::ignoring(const user &user,
|
||||
const room::id &room_id)
|
||||
{
|
||||
using prototype = bool (const m::user &, const m::room::id &);
|
||||
|
||||
static mods::import<prototype> function
|
||||
{
|
||||
"m_receipt", "ircd::m::receipt::ignoring"
|
||||
};
|
||||
|
||||
return function(user, room_id);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::receipt::ignoring(const user &user,
|
||||
const event::id &event_id)
|
||||
{
|
||||
using prototype = bool (const m::user &, const m::event::id &);
|
||||
|
||||
static mods::import<prototype> function
|
||||
{
|
||||
"m_receipt", "ircd::m::receipt::ignoring"
|
||||
};
|
||||
|
||||
return function(user, event_id);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::receipt::freshest(const room::id &room_id,
|
||||
const user::id &user_id,
|
||||
const event::id &event_id)
|
||||
{
|
||||
using prototype = bool (const m::room::id &, const m::user::id &, const m::event::id &);
|
||||
|
||||
static mods::import<prototype> function
|
||||
{
|
||||
"m_receipt", "ircd::m::receipt::freshest"
|
||||
};
|
||||
|
||||
return function(room_id, user_id, event_id);
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::m::receipt::exists(const room::id &room_id,
|
||||
const user::id &user_id,
|
||||
const event::id &event_id)
|
||||
{
|
||||
using prototype = bool (const m::room::id &, const m::user::id &, const m::event::id &);
|
||||
|
||||
static mods::import<prototype> function
|
||||
{
|
||||
"m_receipt", "ircd::m::receipt::exists"
|
||||
};
|
||||
|
||||
return function(room_id, user_id, event_id);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// m/typing.h
|
||||
|
|
|
@ -32,14 +32,15 @@ post__read_markers(client &client,
|
|||
m_read?: m_fully_read
|
||||
};
|
||||
|
||||
m::event::id::buf head;
|
||||
if(marker) switch(m::sigil(marker))
|
||||
{
|
||||
case m::id::EVENT:
|
||||
m::receipt::read(room_id, request.user_id, marker);
|
||||
head = marker;
|
||||
break;
|
||||
|
||||
case m::id::ROOM:
|
||||
m::receipt::read(room_id, request.user_id, m::head(m::room::id(marker)));
|
||||
head = m::head(m::room::id(marker));
|
||||
break;
|
||||
|
||||
default: log::dwarning
|
||||
|
@ -49,6 +50,24 @@ post__read_markers(client &client,
|
|||
};
|
||||
}
|
||||
|
||||
const bool useful
|
||||
{
|
||||
head &&
|
||||
|
||||
// Check if the marker is more recent than the last marker they sent.
|
||||
// We currently don't do anything with markers targeting the past
|
||||
m::receipt::freshest(room_id, request.user_id, head) &&
|
||||
|
||||
// Check if the user wants to prevent sending a receipt to the room.
|
||||
!m::receipt::ignoring(request.user_id, room_id) &&
|
||||
|
||||
// Check if the user wants to prevent based on this event's specifics.
|
||||
!m::receipt::ignoring(request.user_id, head)
|
||||
};
|
||||
|
||||
if(useful)
|
||||
m::receipt::read(room_id, request.user_id, head);
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, http::OK
|
||||
|
|
|
@ -12,22 +12,6 @@
|
|||
|
||||
using namespace ircd;
|
||||
|
||||
extern "C" m::event::id::buf
|
||||
commit__m_receipt_m_read(const m::room::id &,
|
||||
const m::user::id &,
|
||||
const m::event::id &,
|
||||
const time_t &);
|
||||
|
||||
extern "C" bool
|
||||
exists__m_receipt_m_read(const m::room::id &,
|
||||
const m::user::id &,
|
||||
const m::event::id &);
|
||||
|
||||
extern "C" bool
|
||||
fresher__m_receipt_m_read(const m::room::id &,
|
||||
const m::user::id &,
|
||||
const m::event::id &);
|
||||
|
||||
resource::response
|
||||
post__receipt(client &client,
|
||||
const resource::request &request,
|
||||
|
@ -55,219 +39,24 @@ post__receipt(client &client,
|
|||
url::decode(event_id, request.parv[3])
|
||||
};
|
||||
|
||||
const auto eid
|
||||
const bool useful
|
||||
{
|
||||
m::receipt::read(room_id, request.user_id, event_id)
|
||||
// Check if event_id is more recent than the last receipt's event_id.
|
||||
// We currently don't do anything with receipts targeting the past.
|
||||
m::receipt::freshest(room_id, request.user_id, event_id) &&
|
||||
|
||||
// Check if user wants to prevent sending receipts to this room.
|
||||
!m::receipt::ignoring(request.user_id, room_id) &&
|
||||
|
||||
// Check if user wants to prevent based on this event's specifics.
|
||||
!m::receipt::ignoring(request.user_id, event_id)
|
||||
};
|
||||
|
||||
if(useful)
|
||||
m::receipt::read(room_id, request.user_id, event_id);
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, http::OK
|
||||
};
|
||||
}
|
||||
|
||||
/// Does the user wish to not send receipts for events sent by its specific
|
||||
/// sender?
|
||||
static bool
|
||||
user_ignoring_receipts_sender(const m::user::room &user_room,
|
||||
const m::event::id &event_id)
|
||||
{
|
||||
bool ret{false};
|
||||
m::get(std::nothrow, event_id, "sender", [&ret, &user_room]
|
||||
(const string_view &sender)
|
||||
{
|
||||
ret = user_room.has("ircd.read.ignore", sender);
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Does the user wish to not send receipts for events for this entire room?
|
||||
static bool
|
||||
user_ignoring_receipts_room(const m::user::room &user_room,
|
||||
const m::room::id &room_id)
|
||||
{
|
||||
return user_room.has("ircd.read.ignore", room_id);
|
||||
}
|
||||
|
||||
m::event::id::buf
|
||||
commit__m_receipt_m_read(const m::room::id &room_id,
|
||||
const m::user::id &user_id,
|
||||
const m::event::id &event_id,
|
||||
const time_t &ms)
|
||||
{
|
||||
if(!fresher__m_receipt_m_read(room_id, user_id, event_id))
|
||||
return {};
|
||||
|
||||
const m::user::room user_room
|
||||
{
|
||||
user_id
|
||||
};
|
||||
|
||||
// Check if receipts for the room are disabled first because we have the
|
||||
// room_id on the stack, whereas the event sender requires column queries
|
||||
// from the event_id.
|
||||
const bool ignored
|
||||
{
|
||||
user_ignoring_receipts_room(user_room, room_id) ||
|
||||
user_ignoring_receipts_sender(user_room, event_id)
|
||||
};
|
||||
|
||||
if(ignored)
|
||||
{
|
||||
log::debug
|
||||
{
|
||||
"no receipt for %s by %s in %s @ %zd (ircd.read.ignore)",
|
||||
string_view{event_id},
|
||||
string_view{user_id},
|
||||
string_view{room_id},
|
||||
ms
|
||||
};
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto evid
|
||||
{
|
||||
send(user_room, user_id, "ircd.read", room_id,
|
||||
{
|
||||
{ "event_id", event_id },
|
||||
{ "ts", ms }
|
||||
})
|
||||
};
|
||||
|
||||
log::info
|
||||
{
|
||||
"%s read by %s in %s @ %zd => %s (local)",
|
||||
string_view{event_id},
|
||||
string_view{user_id},
|
||||
string_view{room_id},
|
||||
ms,
|
||||
string_view{evid}
|
||||
};
|
||||
|
||||
const json::value event_ids[]
|
||||
{
|
||||
{ event_id }
|
||||
};
|
||||
|
||||
const json::members m_read
|
||||
{
|
||||
{ "data",
|
||||
{
|
||||
{ "ts", ms }
|
||||
}},
|
||||
{ "event_ids", { event_ids, 1 } },
|
||||
};
|
||||
|
||||
json::iov event, content;
|
||||
const json::iov::push push[]
|
||||
{
|
||||
{ event, { "type", "m.receipt" } },
|
||||
{ event, { "room_id", room_id } },
|
||||
{ content, { room_id,
|
||||
{
|
||||
{ "m.read",
|
||||
{
|
||||
{ user_id, m_read }
|
||||
}}
|
||||
}}}
|
||||
};
|
||||
|
||||
m::vm::copts opts;
|
||||
opts.add_hash = false;
|
||||
opts.add_sig = false;
|
||||
opts.add_event_id = false;
|
||||
opts.add_origin = true;
|
||||
opts.add_origin_server_ts = false;
|
||||
opts.conforming = false;
|
||||
return m::vm::eval
|
||||
{
|
||||
event, content, opts
|
||||
};
|
||||
}
|
||||
|
||||
bool
|
||||
fresher__m_receipt_m_read(const m::room::id &room_id,
|
||||
const m::user::id &user_id,
|
||||
const m::event::id &event_id)
|
||||
try
|
||||
{
|
||||
const m::user::room user_room
|
||||
{
|
||||
user_id
|
||||
};
|
||||
|
||||
bool ret{true};
|
||||
user_room.get("ircd.read", room_id, [&ret, &event_id]
|
||||
(const m::event &event)
|
||||
{
|
||||
const auto &content
|
||||
{
|
||||
at<"content"_>(event)
|
||||
};
|
||||
|
||||
const m::event::id &previous_id
|
||||
{
|
||||
unquote(content.get("event_id"))
|
||||
};
|
||||
|
||||
if(event_id == previous_id)
|
||||
{
|
||||
ret = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const m::event::idx &previous_idx
|
||||
{
|
||||
index(previous_id)
|
||||
};
|
||||
|
||||
const m::event::idx &event_idx
|
||||
{
|
||||
index(event_id)
|
||||
};
|
||||
|
||||
ret = event_idx > previous_idx;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::derror
|
||||
{
|
||||
m::log, "Freshness of receipt in %s from %s for %s :%s",
|
||||
string_view{room_id},
|
||||
string_view{user_id},
|
||||
string_view{event_id},
|
||||
e.what()
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
exists__m_receipt_m_read(const m::room::id &room_id,
|
||||
const m::user::id &user_id,
|
||||
const m::event::id &event_id)
|
||||
{
|
||||
const m::user::room user_room
|
||||
{
|
||||
user_id
|
||||
};
|
||||
|
||||
bool ret{false};
|
||||
user_room.get(std::nothrow, "ircd.read", room_id, [&ret, &event_id]
|
||||
(const m::event &event)
|
||||
{
|
||||
const auto &content
|
||||
{
|
||||
at<"content"_>(event)
|
||||
};
|
||||
|
||||
ret = unquote(content.get("event_id")) == event_id;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -10,19 +10,18 @@
|
|||
|
||||
using namespace ircd;
|
||||
|
||||
mapi::header
|
||||
IRCD_MODULE
|
||||
{
|
||||
"Matrix Receipts"
|
||||
};
|
||||
|
||||
extern "C" bool last_receipt__event_id(const m::room::id &, const m::user::id &, const m::event::id::closure &);
|
||||
static void handle_m_receipt_m_read(const m::room::id &, const m::user::id &, const m::event::id &, const time_t &);
|
||||
static void handle_m_receipt_m_read(const m::room::id &, const m::user::id &, const m::edu::m_receipt::m_read &);
|
||||
static void handle_m_receipt_m_read(const m::room::id &, const json::object &);
|
||||
static void handle_m_receipt(const m::room::id &, const json::object &);
|
||||
static void handle_edu_m_receipt(const m::event &, m::vm::eval &);
|
||||
|
||||
mapi::header
|
||||
IRCD_MODULE
|
||||
{
|
||||
"Matrix Receipts"
|
||||
};
|
||||
|
||||
const m::hookfn<m::vm::eval &>
|
||||
_m_receipt_eval
|
||||
{
|
||||
|
@ -215,8 +214,81 @@ catch(const std::exception &e)
|
|||
};
|
||||
}
|
||||
|
||||
m::event::id::buf
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::receipt::read(const m::room::id &room_id,
|
||||
const m::user::id &user_id,
|
||||
const m::event::id &event_id,
|
||||
const time_t &ms)
|
||||
{
|
||||
const m::user::room user_room
|
||||
{
|
||||
user_id
|
||||
};
|
||||
|
||||
const auto evid
|
||||
{
|
||||
send(user_room, user_id, "ircd.read", room_id,
|
||||
{
|
||||
{ "event_id", event_id },
|
||||
{ "ts", ms }
|
||||
})
|
||||
};
|
||||
|
||||
log::info
|
||||
{
|
||||
"%s read by %s in %s @ %zd => %s (local)",
|
||||
string_view{event_id},
|
||||
string_view{user_id},
|
||||
string_view{room_id},
|
||||
ms,
|
||||
string_view{evid}
|
||||
};
|
||||
|
||||
const json::value event_ids[]
|
||||
{
|
||||
{ event_id }
|
||||
};
|
||||
|
||||
const json::members m_read
|
||||
{
|
||||
{ "data",
|
||||
{
|
||||
{ "ts", ms }
|
||||
}},
|
||||
{ "event_ids", { event_ids, 1 } },
|
||||
};
|
||||
|
||||
json::iov event, content;
|
||||
const json::iov::push push[]
|
||||
{
|
||||
{ event, { "type", "m.receipt" } },
|
||||
{ event, { "room_id", room_id } },
|
||||
{ content, { room_id,
|
||||
{
|
||||
{ "m.read",
|
||||
{
|
||||
{ user_id, m_read }
|
||||
}}
|
||||
}}}
|
||||
};
|
||||
|
||||
m::vm::copts opts;
|
||||
opts.add_hash = false;
|
||||
opts.add_sig = false;
|
||||
opts.add_event_id = false;
|
||||
opts.add_origin = true;
|
||||
opts.add_origin_server_ts = false;
|
||||
opts.conforming = false;
|
||||
return m::vm::eval
|
||||
{
|
||||
event, content, opts
|
||||
};
|
||||
}
|
||||
|
||||
bool
|
||||
last_receipt__event_id(const m::room::id &room_id,
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::receipt::read(const m::room::id &room_id,
|
||||
const m::user::id &user_id,
|
||||
const m::event::id::closure &closure)
|
||||
{
|
||||
|
@ -244,3 +316,119 @@ last_receipt__event_id(const m::room::id &room_id,
|
|||
closure(event_id);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// Does the user wish to not send receipts for events sent by its specific
|
||||
/// sender?
|
||||
bool
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::receipt::ignoring(const m::user &user,
|
||||
const m::event::id &event_id)
|
||||
{
|
||||
bool ret{false};
|
||||
m::get(std::nothrow, event_id, "sender", [&ret, &user]
|
||||
(const string_view &sender)
|
||||
{
|
||||
const m::user::room user_room{user};
|
||||
ret = user_room.has("ircd.read.ignore", sender);
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Does the user wish to not send receipts for events for this entire room?
|
||||
bool
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::receipt::ignoring(const m::user &user,
|
||||
const m::room::id &room_id)
|
||||
{
|
||||
const m::user::room user_room{user};
|
||||
return user_room.has("ircd.read.ignore", room_id);
|
||||
}
|
||||
|
||||
bool
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::receipt::freshest(const m::room::id &room_id,
|
||||
const m::user::id &user_id,
|
||||
const m::event::id &event_id)
|
||||
try
|
||||
{
|
||||
const m::user::room user_room
|
||||
{
|
||||
user_id
|
||||
};
|
||||
|
||||
bool ret{true};
|
||||
user_room.get("ircd.read", room_id, [&ret, &event_id]
|
||||
(const m::event &event)
|
||||
{
|
||||
const auto &content
|
||||
{
|
||||
at<"content"_>(event)
|
||||
};
|
||||
|
||||
const m::event::id &previous_id
|
||||
{
|
||||
unquote(content.get("event_id"))
|
||||
};
|
||||
|
||||
if(event_id == previous_id)
|
||||
{
|
||||
ret = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const m::event::idx &previous_idx
|
||||
{
|
||||
index(previous_id)
|
||||
};
|
||||
|
||||
const m::event::idx &event_idx
|
||||
{
|
||||
index(event_id)
|
||||
};
|
||||
|
||||
ret = event_idx > previous_idx;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::derror
|
||||
{
|
||||
m::log, "Freshness of receipt in %s from %s for %s :%s",
|
||||
string_view{room_id},
|
||||
string_view{user_id},
|
||||
string_view{event_id},
|
||||
e.what()
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IRCD_MODULE_EXPORT
|
||||
ircd::m::receipt::exists(const m::room::id &room_id,
|
||||
const m::user::id &user_id,
|
||||
const m::event::id &event_id)
|
||||
{
|
||||
const m::user::room user_room
|
||||
{
|
||||
user_id
|
||||
};
|
||||
|
||||
bool ret{false};
|
||||
user_room.get(std::nothrow, "ircd.read", room_id, [&ret, &event_id]
|
||||
(const m::event &event)
|
||||
{
|
||||
const auto &content
|
||||
{
|
||||
at<"content"_>(event)
|
||||
};
|
||||
|
||||
ret = unquote(content.get("event_id")) == event_id;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue