feat(lib): carry audio attributes in browse and folder listings

A browse listed each file as a name and a size, so a searcher who saw a
bitrate in a search reply lost it the moment they opened the sharer's
files. Listings (codes 5 and 37) now carry each file's attributes the
way Nicotine+ sends them, as a SharedFileEntry with name, size and
attributes in place of the (name, size) pair; the CLI's browse record
gains bitrate and duration, and the daemon protocol moves to version 2
for the new listing shape.
This commit is contained in:
Michel de Graaf
2026-09-08 01:44:49 +02:00
parent 5a20d69056
commit f6423a2ed6
20 changed files with 307 additions and 95 deletions
+5 -3
View File
@@ -61,13 +61,15 @@ pub fn browse(ctx: &Ctx, args: &BrowseArgs) -> CliResult {
let mut files = 0usize;
for directory in &directories {
for (basename, size) in &directory.files {
for file in &directory.files {
files += 1;
ctx.out.emit(&BrowseRecord {
user: args.user.clone(),
directory: directory.name.clone(),
path: full_path(&directory.name, basename),
size: *size,
path: full_path(&directory.name, &file.name),
size: file.size,
bitrate: file.attribute(super::transfer::ATTR_BITRATE),
duration: file.attribute(super::transfer::ATTR_DURATION),
});
}
}
+5 -5
View File
@@ -19,8 +19,8 @@ use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
/// Soulseek file attribute codes the network agrees on.
const ATTR_BITRATE: u32 = 0;
const ATTR_DURATION: u32 = 1;
pub const ATTR_BITRATE: u32 = 0;
pub const ATTR_DURATION: u32 = 1;
/// What to keep out of the raw result set. Every field is a further
/// restriction: a candidate has to satisfy all of them.
@@ -388,10 +388,10 @@ fn resolve_sizes(
listing
.iter()
.flat_map(|directory| {
directory.files.iter().map(|(basename, size)| {
directory.files.iter().map(|file| {
(
social::full_path(&directory.name, basename),
*size,
social::full_path(&directory.name, &file.name),
file.size,
)
})
})