Skip to content

Commit

Permalink
Merge pull request #458 from Stremio/more-external-players-profile-se…
Browse files Browse the repository at this point in the history
…ttings

More external players profile settings
  • Loading branch information
elpiel authored May 30, 2023
2 parents 1b2f6d7 + 6d648be commit adc48f4
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 26 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ itertools = "0.10"
magnet-url = "2.0"
hex = "0.4"
anyhow = "1.0"
regex = "1.8"

# Tracing
tracing = "0.1"
Expand Down
105 changes: 92 additions & 13 deletions src/deep_links/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,95 @@ use crate::models::installed_addons_with_filters::InstalledAddonsRequest;
use crate::models::library_with_filters::LibraryRequest;
use crate::types::addon::{ExtraValue, ResourcePath, ResourceRequest};
use crate::types::library::LibraryItem;
use crate::types::profile::Settings;
use crate::types::query_params_encode;
use crate::types::resource::{MetaItem, MetaItemPreview, Stream, StreamSource, Video};
use percent_encoding::utf8_percent_encode;
use regex::Regex;
use serde::Serialize;
use url::Url;

#[derive(Default, Serialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct OpenPlayerLink {
pub ios: Option<String>,
pub android: Option<String>,
pub windows: Option<String>,
pub macos: Option<String>,
pub linux: Option<String>,
pub tizen: Option<String>,
pub webos: Option<String>,
pub chromeos: Option<String>,
pub roku: Option<String>,
}

#[derive(Default, Serialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct ExternalPlayerLink {
pub href: Option<String>,
pub download: Option<String>,
pub streaming: Option<String>,
pub open_player: Option<OpenPlayerLink>,
pub android_tv: Option<String>,
pub tizen: Option<String>,
pub webos: Option<String>,
pub file_name: Option<String>,
}

impl From<(&Stream, &Option<Url>)> for ExternalPlayerLink {
fn from((stream, streaming_server_url): (&Stream, &Option<Url>)) -> Self {
impl From<(&Stream, &Option<Url>, &Settings)> for ExternalPlayerLink {
fn from((stream, streaming_server_url, settings): (&Stream, &Option<Url>, &Settings)) -> Self {
let http_regex = Regex::new(r"https?://").unwrap();
let download = stream.download_url();
let streaming = stream.streaming_url(streaming_server_url.as_ref());
let m3u_uri = stream.m3u_data_uri(streaming_server_url.as_ref());
let file_name = m3u_uri.as_ref().map(|_| "playlist.m3u".to_owned());
let href = m3u_uri.or_else(|| download.to_owned());
let open_player = match &streaming {
Some(url) => match settings.player_type.as_ref() {
Some(player_type) => match player_type.as_str() {
"choose" => Some(OpenPlayerLink {
android: Some(format!(
"{}#Intent;type=video/any;scheme=https;end",
http_regex.replace(url, "intent://"),
)),
..Default::default()
}),
"vlc" => Some(OpenPlayerLink {
ios: Some(format!("vlc-x-callback://x-callback-url/stream?url={url}")),
android: Some(format!(
"{}#Intent;package=org.videolan.vlc;type=video;scheme=https;end",
http_regex.replace(url, "intent://"),
)),
..Default::default()
}),
"mxplayer" => Some(OpenPlayerLink {
android: Some(format!(
"{}#Intent;package=com.mxtech.videoplayer.ad;type=video;scheme=https;end",
http_regex.replace(url, "intent://"),
)),
..Default::default()
}),
"justplayer" => Some(OpenPlayerLink {
android: Some(format!(
"{}#Intent;package=com.brouken.player;type=video;scheme=https;end",
http_regex.replace(url, "intent://"),
)),
..Default::default()
}),
"outplayer" => Some(OpenPlayerLink {
ios: Some(format!("{}", http_regex.replace(url, "outplayer://"))),
..Default::default()
}),
"infuse" => Some(OpenPlayerLink {
ios: Some(format!("{}", http_regex.replace(url, "infuse://"))),
..Default::default()
}),
_ => None,
},
None => None,
},
None => None,
};
let (android_tv, tizen, webos) = match &stream.source {
StreamSource::External {
android_tv_url,
Expand All @@ -48,6 +112,7 @@ impl From<(&Stream, &Option<Url>)> for ExternalPlayerLink {
href,
download,
streaming,
open_player,
android_tv,
tizen,
webos,
Expand Down Expand Up @@ -183,9 +248,14 @@ pub struct VideoDeepLinks {
pub external_player: Option<ExternalPlayerLink>,
}

impl From<(&Video, &ResourceRequest, &Option<Url>)> for VideoDeepLinks {
impl From<(&Video, &ResourceRequest, &Option<Url>, &Settings)> for VideoDeepLinks {
fn from(
(video, request, streaming_server_url): (&Video, &ResourceRequest, &Option<Url>),
(video, request, streaming_server_url, settings): (
&Video,
&ResourceRequest,
&Option<Url>,
&Settings,
),
) -> Self {
let stream = video.stream();
VideoDeepLinks {
Expand All @@ -210,9 +280,9 @@ impl From<(&Video, &ResourceRequest, &Option<Url>)> for VideoDeepLinks {
})
.transpose()
.unwrap_or_else(|error| Some(ErrorLink::from(error).into())),
external_player: stream
.as_ref()
.map(|stream| ExternalPlayerLink::from((stream.as_ref(), streaming_server_url))),
external_player: stream.as_ref().map(|stream| {
ExternalPlayerLink::from((stream.as_ref(), streaming_server_url, settings))
}),
}
}
}
Expand All @@ -224,8 +294,8 @@ pub struct StreamDeepLinks {
pub external_player: ExternalPlayerLink,
}

impl From<(&Stream, &Option<Url>)> for StreamDeepLinks {
fn from((stream, streaming_server_url): (&Stream, &Option<Url>)) -> Self {
impl From<(&Stream, &Option<Url>, &Settings)> for StreamDeepLinks {
fn from((stream, streaming_server_url, settings): (&Stream, &Option<Url>, &Settings)) -> Self {
StreamDeepLinks {
player: stream
.encode()
Expand All @@ -236,18 +306,27 @@ impl From<(&Stream, &Option<Url>)> for StreamDeepLinks {
)
})
.unwrap_or_else(|error| ErrorLink::from(error).into()),
external_player: ExternalPlayerLink::from((stream, streaming_server_url)),
external_player: ExternalPlayerLink::from((stream, streaming_server_url, settings)),
}
}
}

impl From<(&Stream, &ResourceRequest, &ResourceRequest, &Option<Url>)> for StreamDeepLinks {
impl
From<(
&Stream,
&ResourceRequest,
&ResourceRequest,
&Option<Url>,
&Settings,
)> for StreamDeepLinks
{
fn from(
(stream, stream_request, meta_request, streaming_server_url): (
(stream, stream_request, meta_request, streaming_server_url, settings): (
&Stream,
&ResourceRequest,
&ResourceRequest,
&Option<Url>,
&Settings,
),
) -> Self {
StreamDeepLinks {
Expand All @@ -265,7 +344,7 @@ impl From<(&Stream, &ResourceRequest, &ResourceRequest, &Option<Url>)> for Strea
)
})
.unwrap_or_else(|error| ErrorLink::from(error).into()),
external_player: ExternalPlayerLink::from((stream, streaming_server_url)),
external_player: ExternalPlayerLink::from((stream, streaming_server_url, settings)),
}
}
}
Expand Down
19 changes: 13 additions & 6 deletions src/unit_tests/deep_links/external_player_link.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::constants::{BASE64, URI_COMPONENT_ENCODE_SET};
use crate::deep_links::ExternalPlayerLink;
use crate::types::profile::Settings;
use crate::types::resource::{Stream, StreamSource};
use base64::Engine;
use percent_encoding::utf8_percent_encode;
Expand All @@ -25,7 +26,8 @@ fn external_player_link_magnet() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(epl.href, Some(MAGNET_STR_URL.to_owned()));
assert_eq!(epl.file_name, None);
}
Expand All @@ -43,7 +45,8 @@ fn external_player_link_http() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(epl.href, Some(BASE64_HTTP_URL.to_owned()));
assert_eq!(epl.file_name, Some("playlist.m3u".to_string()));
}
Expand All @@ -69,7 +72,8 @@ fn external_player_link_torrent() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(
epl.href,
Some(format!(
Expand Down Expand Up @@ -109,7 +113,8 @@ fn external_player_link_external() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(epl.href, Some(HTTP_STR_URL.to_owned()));
assert_eq!(epl.file_name, None);
}
Expand All @@ -128,7 +133,8 @@ fn external_player_link_youtube() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(
epl.href,
Some(format!(
Expand All @@ -155,7 +161,8 @@ fn external_player_link_player_frame() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let epl = ExternalPlayerLink::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(epl.href, Some(HTTP_STR_URL.to_owned()));
assert_eq!(epl.file_name, None);
}
21 changes: 15 additions & 6 deletions src/unit_tests/deep_links/stream_deep_links.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::constants::{BASE64, URI_COMPONENT_ENCODE_SET};
use crate::deep_links::StreamDeepLinks;
use crate::types::addon::{ResourcePath, ResourceRequest};
use crate::types::profile::Settings;
use crate::types::resource::{Stream, StreamSource};
use base64::Engine;
use percent_encoding::utf8_percent_encode;
Expand All @@ -27,7 +28,8 @@ fn stream_deep_links_magnet() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(sdl.player, "stremio:///player/eAEBRgC5%2F3sidXJsIjoibWFnbmV0Oj94dD11cm46YnRpaDpkZDgyNTVlY2RjN2NhNTVmYjBiYmY4MTMyM2Q4NzA2MmRiMWY2ZDFjIn0%2BMhZF".to_string());
assert_eq!(sdl.external_player.href, Some(MAGNET_STR_URL.to_owned()));
assert_eq!(sdl.external_player.file_name, None);
Expand All @@ -46,7 +48,8 @@ fn stream_deep_links_http() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(
sdl.player,
"stremio:///player/eAEBIQDe%2F3sidXJsIjoiaHR0cDovL2RvbWFpbi5yb290L3BhdGgifcEEC6w%3D"
Expand Down Expand Up @@ -80,7 +83,8 @@ fn stream_deep_links_torrent() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(sdl.player, "stremio:///player/eAEBdwCI%2F3siaW5mb0hhc2giOiJkZDgyNTVlY2RjN2NhNTVmYjBiYmY4MTMyM2Q4NzA2MmRiMWY2ZDFjIiwiZmlsZUlkeCI6MCwiYW5ub3VuY2UiOlsiaHR0cDovL2J0MS5hcmNoaXZlLm9yZzo2OTY5L2Fubm91bmNlIl19ndAlsw%3D%3D".to_string());
assert_eq!(
sdl.external_player.href,
Expand Down Expand Up @@ -123,7 +127,8 @@ fn stream_deep_links_external() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(sdl.player, "stremio:///player/eAEBKQDW%2F3siZXh0ZXJuYWxVcmwiOiJodHRwOi8vZG9tYWluLnJvb3QvcGF0aCJ9OoEO7w%3D%3D".to_string());
assert_eq!(sdl.external_player.href, Some(HTTP_STR_URL.to_owned()));
assert_eq!(sdl.external_player.file_name, None);
Expand All @@ -142,7 +147,8 @@ fn stream_deep_links_youtube() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(
sdl.player,
"stremio:///player/eAEBFgDp%2F3sieXRJZCI6ImFxei1LRS1icEtRIn1RRQb5".to_string()
Expand Down Expand Up @@ -176,7 +182,8 @@ fn stream_deep_links_player_frame() {
behavior_hints: Default::default(),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url)).unwrap();
let settings = Settings::default();
let sdl = StreamDeepLinks::try_from((&stream, &streaming_server_url, &settings)).unwrap();
assert_eq!(sdl.player, "stremio:///player/eAEBLADT%2F3sicGxheWVyRnJhbWVVcmwiOiJodHRwOi8vZG9tYWluLnJvb3QvcGF0aCJ9abUQBA%3D%3D".to_string());
assert_eq!(sdl.external_player.href, Some(HTTP_STR_URL.to_owned()));
assert_eq!(sdl.external_player.file_name, None);
Expand Down Expand Up @@ -204,11 +211,13 @@ fn stream_deep_links_requests() {
};

let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let settings = Settings::default();
let sdl = StreamDeepLinks::try_from((
&stream,
&stream_request,
&meta_request,
&streaming_server_url,
&settings,
))
.unwrap();
assert_eq!(sdl.player, format!(
Expand Down
5 changes: 4 additions & 1 deletion src/unit_tests/deep_links/video_deep_links.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::constants::BASE64;
use crate::deep_links::{ExternalPlayerLink, VideoDeepLinks};
use crate::types::addon::{ResourcePath, ResourceRequest};
use crate::types::profile::Settings;
use crate::types::resource::Video;
use base64::Engine;
use std::convert::TryFrom;
Expand All @@ -27,7 +28,9 @@ fn video_deep_links() {
path: ResourcePath::without_extra("meta", "movie", format!("yt_id:{YT_ID}").as_str()),
};
let streaming_server_url = Some(Url::parse(STREAMING_SERVER_URL).unwrap());
let vdl = VideoDeepLinks::try_from((&video, &request, &streaming_server_url)).unwrap();
let settings = Settings::default();
let vdl =
VideoDeepLinks::try_from((&video, &request, &streaming_server_url, &settings)).unwrap();
assert_eq!(
vdl.meta_details_streams,
format!(
Expand Down

0 comments on commit adc48f4

Please sign in to comment.