feat(config): RemoteKind + username for PeerTube remotes

Non-breaking: existing [[remote]] entries default to kind=catacomb.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Luna 2026-07-10 04:39:44 -07:00
parent 96965aaa32
commit bf3f2b0030
No known key found for this signature in database

View file

@ -39,12 +39,29 @@ pub struct RemoteSection {
/// Base URL of the peer's web server, e.g. `http://woofbox:8081` or /// Base URL of the peer's web server, e.g. `http://woofbox:8081` or
/// `https://archive.example`. No trailing slash needed. /// `https://archive.example`. No trailing slash needed.
pub url: String, pub url: String,
/// Peer kind — a catacomb federation peer (default) or a PeerTube target.
#[serde(default)]
pub kind: RemoteKind,
/// Username for PeerTube OAuth2. `None` for catacomb peers / public
/// PeerTube instances.
#[serde(default)]
pub username: Option<String>,
/// Password for the peer, if it has one set. `None`/absent = open peer /// Password for the peer, if it has one set. `None`/absent = open peer
/// (e.g. bound to a trusted tailnet). Stored plaintext like `cookies`. /// (e.g. bound to a trusted tailnet). Stored plaintext like `cookies`.
#[serde(default)] #[serde(default)]
pub password: Option<String>, pub password: Option<String>,
} }
/// Which kind of peer a `[[remote]]` is. Defaults to a catacomb peer so
/// pre-existing config.toml entries keep working unchanged.
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum RemoteKind {
#[default]
Catacomb,
Peertube,
}
/// `[convert]` table — global post-download format-conversion defaults. /// `[convert]` table — global post-download format-conversion defaults.
/// A separate ffmpeg pass runs after the download completes. Per-channel /// A separate ffmpeg pass runs after the download completes. Per-channel
/// [`crate::download_options::DownloadOptions`] can override `mode`. /// [`crate::download_options::DownloadOptions`] can override `mode`.
@ -343,4 +360,40 @@ mod tests {
let back: UiSection = toml::from_str(&s).unwrap(); let back: UiSection = toml::from_str(&s).unwrap();
assert_eq!(back.default_view_mode, "grid"); assert_eq!(back.default_view_mode, "grid");
} }
#[test]
fn remote_kind_defaults_to_catacomb() {
// A legacy [[remote]] with no `kind`/`username` still parses. `[backup]`
// has no serde default (directory is required), so include a minimal one.
let toml = r#"
[backup]
directory = "/tmp/lib"
[[remote]]
name = "peer"
url = "http://peer:8081"
"#;
let cfg: Config = toml::from_str(toml).unwrap();
assert_eq!(cfg.remotes.len(), 1);
assert_eq!(cfg.remotes[0].kind, RemoteKind::Catacomb);
assert!(cfg.remotes[0].username.is_none());
}
#[test]
fn remote_kind_parses_peertube_and_username() {
let toml = r#"
[backup]
directory = "/tmp/lib"
[[remote]]
name = "frama"
url = "https://framatube.org"
kind = "peertube"
username = "alice"
password = "secret"
"#;
let cfg: Config = toml::from_str(toml).unwrap();
assert_eq!(cfg.remotes[0].kind, RemoteKind::Peertube);
assert_eq!(cfg.remotes[0].username.as_deref(), Some("alice"));
}
} }