aboutsummaryrefslogtreecommitdiffstats
path: root/crates/yt_dlp/src/post_processors
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-06-17 08:52:28 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-06-17 08:52:28 +0200
commit0a1700131341c5dac55a395ce5ccdac4f8ec0c9e (patch)
tree1fa1e3322cd19d640a1847d2bf3e27da771fea2b /crates/yt_dlp/src/post_processors
parentfix(yt_dlp/): Include the frozen python stdlib (diff)
downloadyt-0a1700131341c5dac55a395ce5ccdac4f8ec0c9e.zip
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.
Diffstat (limited to 'crates/yt_dlp/src/post_processors')
-rw-r--r--crates/yt_dlp/src/post_processors/dearrow.rs86
1 files changed, 55 insertions, 31 deletions
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 <https://www.gnu.org/licenses/gpl-3.0.txt>.
-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<InfoJson, super::Error> {
- let mut output: DeArrowApi = reqwest::blocking::get(format!(
- "https://sponsor.ajay.app/api/branding?videoID={}",
- json_get!(info, "id", as_str)
- ))?
- .json()?;
+ let mut output: DeArrowApi = {
+ let output_bytes = {
+ let mut dst = Vec::new();
- output.titles.reverse();
+ 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 title_len = output.titles.len();
- loop {
- let Some(title) = output.titles.pop() else {
- break;
- };
+ let mut transfer = easy.transfer();
+ transfer.write_function(|data| {
+ dst.extend_from_slice(data);
+ Ok(data.len())
+ })?;
+ transfer.perform()?;
+ drop(transfer);
- 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;
- }
+ dst
+ };
- 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);
- }
+ serde_json::from_slice(&output_bytes)?
+ };
- break;
+ // 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)]