Deliver ytdlpCommand for an allowlist of verified channels
decorate_channel ignored every provider-declared ytdlpCommand except pimpbunny's. Send the declared command for freepornvideosxxx and missav, where plain yt-dlp is verified to fail; other channels stay unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUYdCh2nCVsQYgJAT7gwSi
This commit is contained in:
@@ -64,13 +64,16 @@ Status: `[ ]` open, `[~]` in progress, `[x]` fixed and verified, `[-]` not repro
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| [x] | `check.py` "url points to hottub server" | contradicted the hottub skill | proxied `video.url` is now verified to resolve (redirect target reachable, CF hosts -> warning) instead of hard-failing. Affected: spankbang, hqporner, pornhd3x, pimpbunny, sxyprn, noodlemagazine |
|
| [x] | `check.py` "url points to hottub server" | contradicted the hottub skill | proxied `video.url` is now verified to resolve (redirect target reachable, CF hosts -> warning) instead of hard-failing. Affected: spankbang, hqporner, pornhd3x, pimpbunny, sxyprn, noodlemagazine |
|
||||||
|
|
||||||
## Open decision (needs the owner)
|
## Decision: `ytdlpCommand` delivery (agreed: targeted rollout)
|
||||||
|
|
||||||
`ytdlpCommand` set on providers (`Channel.ytdlpCommand`, ~90 channels, e.g. `yt-dlp --impersonate chrome-120`) is **never sent to clients**:
|
Providers declare `Channel.ytdlpCommand` (~90 channels), but `/api/status` used to send it only for `pimpbunny`.
|
||||||
`decorate_channel` in `src/providers/mod.rs` builds `ChannelView.ytdlpCommand` from a hardcoded `match` (only `pimpbunny`), and
|
Delivering all of them at once risks breaking working channels if the app's yt-dlp lacks impersonation support, so
|
||||||
`decorates_channel_with_group_and_tags` pins `hsex` to `None`. `/api/status` therefore reports `null` for all of them. Either deliver
|
`decorate_channel` now delivers a provider's declared command **only for channels in `YTDLP_COMMAND_CHANNELS`**
|
||||||
`channel.ytdlpCommand` (clients then need yt-dlp impersonation support) or drop the dead declarations. Channels that only fail
|
(`src/providers/mod.rs`): `freepornvideosxxx`, `missav`. Add a channel there once plain yt-dlp is verified to fail for it.
|
||||||
under plain yt-dlp TLS (freepornvideosxxx, missav, ...) depend on this. `check.py` now applies whatever `/api/status` exposes.
|
|
||||||
|
Still to do with the app side: confirm the app applies `ytdlpCommand` for non-pimpbunny channels and that its yt-dlp has an
|
||||||
|
impersonation target; if a minimum client version is needed, gate on `ClientVersion` (not done, the minimum is unknown).
|
||||||
|
`check.py` applies whatever `/api/status` exposes, so it verifies each addition.
|
||||||
|
|
||||||
## Found while fixing (pre-existing, unrelated)
|
## Found while fixing (pre-existing, unrelated)
|
||||||
|
|
||||||
|
|||||||
@@ -778,11 +778,20 @@ fn sanitize_status_options(options: Vec<ChannelOption>) -> Vec<ChannelOption> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Channels whose own declared `ytdlpCommand` is delivered in `/api/status`.
|
||||||
|
/// Verified: `freepornvideosxxx` (plain yt-dlp gets 502 on its pages, fine with
|
||||||
|
/// `--impersonate chrome-120`) and `missav` (Cloudflare 403 without it).
|
||||||
|
const YTDLP_COMMAND_CHANNELS: &[&str] = &["freepornvideosxxx", "missav"];
|
||||||
|
|
||||||
pub fn decorate_channel(channel: Channel) -> ChannelView {
|
pub fn decorate_channel(channel: Channel) -> ChannelView {
|
||||||
let metadata = channel_metadata_for(&channel.id);
|
let metadata = channel_metadata_for(&channel.id);
|
||||||
let runtime_status = current_provider_channel_status(&channel.id);
|
let runtime_status = current_provider_channel_status(&channel.id);
|
||||||
let ytdlp_command = match channel.id.as_str() {
|
let ytdlp_command = match channel.id.as_str() {
|
||||||
"pimpbunny" => Some("yt-dlp --compat-options allow-unsafe-ext".to_string()),
|
"pimpbunny" => Some("yt-dlp --compat-options allow-unsafe-ext".to_string()),
|
||||||
|
// Providers declare a `ytdlpCommand`, but it is only sent to clients
|
||||||
|
// for channels where plain yt-dlp was verified to fail (TLS-fingerprint
|
||||||
|
// 403/502 that real clients hit). Widen this list one channel at a time.
|
||||||
|
id if YTDLP_COMMAND_CHANNELS.contains(&id) => channel.ytdlpCommand.clone(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
ChannelView {
|
ChannelView {
|
||||||
@@ -1372,6 +1381,25 @@ mod tests {
|
|||||||
assert_eq!(groups[2].id, "jav");
|
assert_eq!(groups[2].id, "jav");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn delivers_declared_ytdlp_command_only_for_allowlisted_channels() {
|
||||||
|
for id in ["freepornvideosxxx", "missav"] {
|
||||||
|
PROVIDER_RUNTIME_STATUS.remove(id);
|
||||||
|
assert_eq!(
|
||||||
|
decorate_channel(base_channel(id)).ytdlpCommand.as_deref(),
|
||||||
|
Some("yt-dlp --impersonate chrome-120"),
|
||||||
|
"{id} should deliver its declared command"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Declares the same command but is not allowlisted.
|
||||||
|
PROVIDER_RUNTIME_STATUS.remove("hsex");
|
||||||
|
assert_eq!(decorate_channel(base_channel("hsex")).ytdlpCommand, None);
|
||||||
|
// An allowlisted id that declares nothing stays None.
|
||||||
|
let mut undeclared = base_channel("missav");
|
||||||
|
undeclared.ytdlpCommand = None;
|
||||||
|
assert_eq!(decorate_channel(undeclared).ytdlpCommand, None);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decorates_pimpbunny_with_ytdlp_command() {
|
fn decorates_pimpbunny_with_ytdlp_command() {
|
||||||
PROVIDER_RUNTIME_STATUS.remove("pimpbunny");
|
PROVIDER_RUNTIME_STATUS.remove("pimpbunny");
|
||||||
|
|||||||
Reference in New Issue
Block a user