feat(daemon): publish room member statistics over RPC and the CLI

The statistics parsed from the JoinRoom reply were reachable only from the
library. They answer the question `room users` already exists to ask -- who
is in here, and are they worth downloading from -- so they belong on its
output rather than behind a second call.

- proto: room.member_stats, with a RoomUserStatsDto carrying status, share
  counts, free slots and country
- SessionApi::room_member_stats, so local and remote sessions stay
  interchangeable; the status word is decoded through one shared helper
  rather than a third copy of the match
- `room users` now emits status, average_speed, shared_files,
  shared_folders, slots_free and country, each null when the server said
  nothing, documented in SKILL.md
- docs/openrpc.json regenerated from the wire types
This commit is contained in:
Michel de Graaf
2026-08-28 13:27:09 +00:00
parent fa49ebd2eb
commit 60f7100e30
12 changed files with 288 additions and 27 deletions
+13 -7
View File
@@ -11,10 +11,11 @@
use super::proto::{
Ack, AuthParams, AuthResult, BrowseEvent, DaemonStatus, DirectoriesParams,
DirectoryParams, DownloadStartParams, DownloadStarted, DownloadStatusEvent,
Downloads, Event, IntervalSeconds, Members, MessageParams, Messages,
Method, QueryParams, RoomEventDto, RoomRef, SayParams, SearchResults,
Searches, Seconds, SessionLossEvent, SharesStatus, SlotsParams,
TransferRef, UploadInfoDto, Uploads, UserMessageDto, UserRef, UserResult,
Downloads, Event, IntervalSeconds, MemberStats, Members, MessageParams,
Messages, Method, QueryParams, RoomEventDto, RoomRef, SayParams,
SearchResults, Searches, Seconds, SessionLossEvent, SharesStatus,
SlotsParams, TransferRef, UploadInfoDto, Uploads, UserMessageDto, UserRef,
UserResult,
};
use schemars::{JsonSchema, SchemaGenerator, generate::SchemaSettings};
use serde_json::{Value, json};
@@ -46,9 +47,10 @@ fn params_schema(method: Method, generator: &mut SchemaGenerator) -> Value {
| Method::UploadCancel => schema_of::<TransferRef>(generator),
Method::DownloadSetDir => schema_of::<DirectoryParams>(generator),
Method::UploadSlots => schema_of::<SlotsParams>(generator),
Method::RoomJoin | Method::RoomLeave | Method::RoomMembers => {
schema_of::<RoomRef>(generator)
}
Method::RoomJoin
| Method::RoomLeave
| Method::RoomMembers
| Method::RoomMemberStats => schema_of::<RoomRef>(generator),
Method::RoomSay => schema_of::<SayParams>(generator),
Method::MessageSend => schema_of::<MessageParams>(generator),
Method::BrowseUser | Method::UserRequest | Method::UserInfoOf => {
@@ -88,6 +90,7 @@ fn result_schema(method: Method, generator: &mut SchemaGenerator) -> Value {
Method::UploadList => schema_of::<Uploads>(generator),
Method::PrivilegesOwn => schema_of::<Seconds>(generator),
Method::RoomMembers => schema_of::<Members>(generator),
Method::RoomMemberStats => schema_of::<MemberStats>(generator),
Method::MessageHistory => schema_of::<Messages>(generator),
Method::UserInfoOf => schema_of::<UserResult>(generator),
Method::SharesStatusOf | Method::SharesSet | Method::SharesReindex => {
@@ -172,6 +175,9 @@ fn summary(method: Method) -> &'static str {
Method::RoomLeave => "Leave a chat room.",
Method::RoomSay => "Post a message to a room.",
Method::RoomMembers => "Who is currently in a room.",
Method::RoomMemberStats => {
"What the server said about each member of a joined room."
}
Method::MessageSend => "Send a private message.",
Method::MessageHistory => {
"Private messages the daemon collected, including while nobody was attached."