From 0a1700131341c5dac55a395ce5ccdac4f8ec0c9e Mon Sep 17 00:00:00 2001 From: Benedikt Peetz Date: Tue, 17 Jun 2025 08:52:28 +0200 Subject: fix(yt_dlp/post_processors/dearrow): Migrate to curl for api requests The reqwest crate will panic if it is blockingly run inside another executor. But we cannot make this function async, as the whole api is forced to be sync by python ffi. --- crates/yt_dlp/Cargo.toml | 2 +- crates/yt_dlp/src/post_processors/dearrow.rs | 96 +++++++++++++++++----------- 2 files changed, 61 insertions(+), 37 deletions(-) (limited to 'crates') diff --git a/crates/yt_dlp/Cargo.toml b/crates/yt_dlp/Cargo.toml index 3eff9a2..4f62eec 100644 --- a/crates/yt_dlp/Cargo.toml +++ b/crates/yt_dlp/Cargo.toml @@ -22,9 +22,9 @@ rust-version.workspace = true publish = true [dependencies] +curl = "0.4.48" indexmap = { version = "2.9.0", default-features = false } log.workspace = true -reqwest = { version = "0.12.20", features = ["blocking", "json"] } rustpython = { git = "https://github.com/RustPython/RustPython.git", features = [ "threading", "stdlib", diff --git a/crates/yt_dlp/src/post_processors/dearrow.rs b/crates/yt_dlp/src/post_processors/dearrow.rs index bdbea7c..7dc6bbb 100644 --- a/crates/yt_dlp/src/post_processors/dearrow.rs +++ b/crates/yt_dlp/src/post_processors/dearrow.rs @@ -8,7 +8,12 @@ // You should have received a copy of the License along with this program. // If not, see . -use log::{info, warn}; +use curl::easy::Easy; +use log::{error, info, warn}; +use rustpython::vm::{ + PyRef, VirtualMachine, + builtins::{PyDict, PyStr}, +}; use serde::{Deserialize, Serialize}; use crate::{InfoJson, json_get}; @@ -24,44 +29,63 @@ impl PostProcessor for DeArrowPP { } fn process(&self, mut info: InfoJson) -> Result { - let mut output: DeArrowApi = reqwest::blocking::get(format!( - "https://sponsor.ajay.app/api/branding?videoID={}", - json_get!(info, "id", as_str) - ))? - .json()?; - - output.titles.reverse(); - - let title_len = output.titles.len(); - loop { - let Some(title) = output.titles.pop() else { - break; - }; - - if (title.locked || title.votes < 1) && title_len > 1 { - info!( - "Skipping title {:#?}, as it is not good enough", - title.value - ); - // Skip titles that are not “good” enough. - continue; - } - - if let Some(old_title) = info.insert( - "title".to_owned(), - serde_json::Value::String(title.value.clone()), - ) { - warn!("Updating title from {:#?} to {:#?}", old_title, title.value); - info.insert("original_title".to_owned(), old_title); - } else { - warn!("Setting title to {:#?}", title.value); - } - - break; + let mut output: DeArrowApi = { + let output_bytes = { + let mut dst = Vec::new(); + + let mut easy = Easy::new(); + easy.url( + format!( + "https://sponsor.ajay.app/api/branding?videoID={}", + pydict_get!(@vm, info, "id", PyStr).as_str() + ) + .as_str(), + )?; + + let mut transfer = easy.transfer(); + transfer.write_function(|data| { + dst.extend_from_slice(data); + Ok(data.len()) + })?; + transfer.perform()?; + drop(transfer); + + dst + }; + + serde_json::from_slice(&output_bytes)? + }; + + // We pop the titles, so we need this vector reversed. + output.titles.reverse(); + + let title_len = output.titles.len(); + let selected = loop { + let Some(title) = output.titles.pop() else { + break false; + }; + + if (title.locked || title.votes < 1) && title_len > 1 { + info!( + "DeArrow: Skipping title {:#?}, as it is not good enough", + title.value + ); + // Skip titles that are not “good” enough. + continue; } - Ok(info) + update_title(&info, &title.value, vm); + + break true; + }; + + if !selected && title_len != 0 { + // No title was selected, even though we had some titles. + // Just pick the first one in this case. + update_title(&info, &output.titles[0].value, vm); } + + Ok(info) } #[derive(Serialize, Deserialize)] -- cgit 1.4.1