diff --git a/Cargo.toml b/Cargo.toml index f200bc2..65adfc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,4 @@ serde_json = "1.0.140" tokio = { version = "1", features = ["full"] } wreq = { version = "5", features = ["full"] } wreq-util = "2" +percent-encoding = "2.1" \ No newline at end of file diff --git a/src/providers/pmvhaven.rs b/src/providers/pmvhaven.rs index ffa9a3d..e0c03f3 100644 --- a/src/providers/pmvhaven.rs +++ b/src/providers/pmvhaven.rs @@ -9,6 +9,7 @@ use crate::videos::{VideoFormat, VideoItem}; use cute::c; use error_chain::error_chain; use htmlentity::entity::{ICodedDataTrait, decode}; +use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; use std::env; use std::vec; use wreq::{Client, Proxy}; @@ -187,19 +188,23 @@ struct PmvhavenVideo { impl PmvhavenVideo { fn to_videoitem(self) -> VideoItem { + let encoded_title = percent_encode_emojis(&self.title); + let thumbnail = self.thumbnails[self.thumbnails.len()-1].clone().unwrap_or("".to_string()); + let video_id = thumbnail.split("_").collect::>().last().unwrap_or(&"").to_string().split('.').next().unwrap_or("").to_string(); let mut item = VideoItem::new( self._id.clone(), self.title.clone(), format!("https://pmvhaven.com/video/{}_{}", self.title.replace(" ","-"), self._id), // format!("https://storage.pmvhaven.com/{}/{}_{}.mp4", self._id.clone(), self.title.replace(" ","-"), self._id), "pmvhaven".to_string(), - self.thumbnails[self.thumbnails.len()-1].clone().unwrap_or("".to_string()), + thumbnail, self.duration as u32, ) .formats(vec![ - VideoFormat::new(format!("https://storage.pmvhaven.com/{}/{}_{}.mp4", self._id.clone(), self.title.replace(" ","-"), self._id), "1080".to_string(), "mp4".to_string()), - VideoFormat::new(format!("https://storage.pmvhaven.com/{}/264_{}.mp4", self._id.clone(), self._id), "1080".to_string(), "mp4".to_string()) + VideoFormat::new(format!("https://storage.pmvhaven.com/{}/{}_{}.mp4", video_id, encoded_title, video_id), "1080".to_string(), "mp4".to_string()).protocol("https".to_string()), + VideoFormat::new(format!("https://storage.pmvhaven.com/{}/264_{}.mp4", video_id, video_id), "1080".to_string(), "mp4".to_string()).protocol("https".to_string()) ]) + .views(self.views); item = match self.creator{ Some(c) => item.uploader(c), @@ -214,6 +219,14 @@ impl PmvhavenVideo { } } +// Define a percent-encoding set that encodes all non-ASCII characters +const EMOJI_ENCODE_SET: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'#').add(b'%').add(b'<').add(b'>').add(b'?').add(b'[').add(b'\\').add(b']').add(b'^').add(b'`').add(b'{').add(b'|').add(b'}'); + +// Helper function to percent-encode emojis and other non-ASCII chars +fn percent_encode_emojis(s: &str) -> String { + utf8_percent_encode(s, EMOJI_ENCODE_SET).to_string() +} + #[derive(serde::Deserialize)] struct PmvhavenResponse { httpStatusCode: Option, diff --git a/src/videos.rs b/src/videos.rs index a5405ea..c80bd16 100644 --- a/src/videos.rs +++ b/src/videos.rs @@ -213,6 +213,11 @@ impl VideoFormat { headers.insert(key, value); } } + + pub fn protocol(mut self, protocol: String) -> Self { + self.protocol = Some(protocol); + self + } } #[derive(serde::Serialize, Debug)] pub struct Videos {