Skip to content

Commit

Permalink
Merge pull request #565 from Stremio/feat/streaming-server-remote-end…
Browse files Browse the repository at this point in the history
…point

Implement streaming server remote endpoint
  • Loading branch information
tymmesyde authored Dec 12, 2023
2 parents 15e540e + 729b649 commit 39fb65e
Show file tree
Hide file tree
Showing 10 changed files with 361 additions and 75 deletions.
203 changes: 140 additions & 63 deletions src/models/streaming_server.rs

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions src/runtime/msg/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,15 @@ use crate::{
library_with_filters::Selected as LibraryWithFiltersSelected,
meta_details::Selected as MetaDetailsSelected,
player::{Selected as PlayerSelected, VideoParams},
streaming_server::{
Settings as StreamingServerSettings,
StatisticsRequest as StreamingServerStatisticsRequest,
},
streaming_server::StatisticsRequest as StreamingServerStatisticsRequest,
},
types::{
addon::Descriptor,
api::AuthRequest,
library::LibraryItemId,
profile::Settings as ProfileSettings,
resource::{MetaItemId, MetaItemPreview, Video},
streaming_server::Settings as StreamingServerSettings,
},
};

Expand Down
12 changes: 7 additions & 5 deletions src/runtime/msg/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use url::Url;
use crate::models::ctx::CtxError;
use crate::models::link::LinkError;
use crate::models::local_search::Searchable;
use crate::models::streaming_server::{
PlaybackDevice, Settings as StreamingServerSettings, StatisticsRequest,
};
use crate::models::streaming_server::{PlaybackDevice, StatisticsRequest};
use crate::runtime::EnvError;
use crate::types::addon::{Descriptor, Manifest, ResourceRequest, ResourceResponse};
use crate::types::api::{
Expand All @@ -16,7 +14,7 @@ use crate::types::api::{
use crate::types::library::{LibraryBucket, LibraryItem, LibraryItemId};
use crate::types::profile::{Auth, AuthKey, Profile, User};
use crate::types::resource::{MetaItem, Stream};
use crate::types::streaming_server::Statistics;
use crate::types::streaming_server::{GetHTTPSResponse, NetworkInfo, SettingsResponse, Statistics};
use crate::types::streams::StreamItemState;

pub type CtxStorageResponse = (
Expand Down Expand Up @@ -91,17 +89,21 @@ pub enum Internal {
/// Result for loading link data.
LinkDataResult(String, Result<LinkDataResponse, LinkError>),
/// Result for loading streaming server settings.
StreamingServerSettingsResult(Url, Result<StreamingServerSettings, EnvError>),
StreamingServerSettingsResult(Url, Result<SettingsResponse, EnvError>),
/// Result for loading streaming server base url.
StreamingServerBaseURLResult(Url, Result<Url, EnvError>),
// Result for loading streaming server playback devices.
StreamingServerPlaybackDevicesResult(Url, Result<Vec<PlaybackDevice>, EnvError>),
// Result for network info.
StreamingServerNetworkInfoResult(Url, Result<NetworkInfo, EnvError>),
/// Result for updating streaming server settings.
StreamingServerUpdateSettingsResult(Url, Result<(), EnvError>),
/// Result for creating a torrent.
StreamingServerCreateTorrentResult(String, Result<(), EnvError>),
/// Result for playing on device.
StreamingServerPlayOnDeviceResult(String, Result<(), EnvError>),
// Result for get https endpoint request
StreamingServerGetHTTPSResult(Url, Result<GetHTTPSResponse, EnvError>),
/// Result for streaming server statistics.
///
/// Server will return None (or `null`) in response for [`Statistics`]`,
Expand Down
9 changes: 9 additions & 0 deletions src/types/streaming_server/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
mod network_info;
pub use network_info::*;

mod response;
pub use response::*;

mod settings;
pub use settings::*;

mod statistics;
pub use statistics::*;
7 changes: 7 additions & 0 deletions src/types/streaming_server/network_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use serde::{Deserialize, Serialize};

#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct NetworkInfo {
pub available_interfaces: Vec<String>,
}
19 changes: 19 additions & 0 deletions src/types/streaming_server/response.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use serde::{Deserialize, Serialize};
use url::Url;

use crate::types::streaming_server::Settings;

#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct SettingsResponse {
pub base_url: Url,
pub values: Settings,
}

#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct GetHTTPSResponse {
pub ip_address: String,
pub domain: String,
pub port: u16,
}
17 changes: 17 additions & 0 deletions src/types/streaming_server/settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use serde::{Deserialize, Serialize};

#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Settings {
pub app_path: String,
pub cache_root: String,
pub server_version: String,
pub remote_https: Option<String>,
pub cache_size: Option<f64>,
pub bt_max_connections: u64,
pub bt_handshake_timeout: u64,
pub bt_request_timeout: u64,
pub bt_download_speed_soft_limit: f64,
pub bt_download_speed_hard_limit: f64,
pub bt_min_peers_for_stable: u64,
}
6 changes: 3 additions & 3 deletions src/unit_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ pub use env::*;

mod catalog_with_filters;
mod ctx;
mod data_export;
mod deep_links;
mod link;
mod meta_details;
mod player;
mod serde;

mod data_export;
mod link;
mod streaming_server;
1 change: 1 addition & 0 deletions src/unit_tests/streaming_server/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod remote_endpoint;
156 changes: 156 additions & 0 deletions src/unit_tests/streaming_server/remote_endpoint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
use std::any::Any;

use futures::future;
use stremio_derive::Model;
use url::Url;

use crate::{
models::{
ctx::Ctx,
streaming_server::{PlaybackDevice, StreamingServer},
},
runtime::{
msg::{Action, ActionStreamingServer},
EnvFutureExt, Runtime, RuntimeAction, TryEnvFuture,
},
types::{
api::SuccessResponse,
profile::{Auth, AuthKey, Profile},
streaming_server::{
GetHTTPSResponse, NetworkInfo, Settings as StreamingServerSettings, SettingsResponse,
},
True,
},
unit_tests::{default_fetch_handler, Request, TestEnv, FETCH_HANDLER},
};

const STREAMING_SERVER_URL: &str = "http://127.0.0.1:11470";
const STREAMING_SERVER_SETTINGS: StreamingServerSettings = StreamingServerSettings {
remote_https: None,
app_path: String::new(),
cache_root: String::new(),
server_version: String::new(),
cache_size: None,
bt_max_connections: 0,
bt_handshake_timeout: 0,
bt_request_timeout: 0,
bt_download_speed_soft_limit: 0.0,
bt_download_speed_hard_limit: 0.0,
bt_min_peers_for_stable: 0,
};

const AVAILABLE_INTERFACE: &str = "192.168.0.10";

#[test]
fn remote_endpoint() {
#[derive(Model, Clone, Debug)]
#[model(TestEnv)]
struct TestModel {
ctx: Ctx,
streaming_server: StreamingServer,
}

fn fetch_handler(request: Request) -> TryEnvFuture<Box<dyn Any + Send>> {
match request {
Request { url, method, .. }
if method == "GET" && url == "http://127.0.0.1:11470/settings" =>
{
future::ok(Box::new(SettingsResponse {
base_url: Url::parse(&STREAMING_SERVER_URL.to_string()).unwrap(),
values: STREAMING_SERVER_SETTINGS,
}) as Box<dyn Any + Send>)
.boxed_env()
}
Request { url, method, .. }
if method == "POST" && url == "http://127.0.0.1:11470/settings" =>
{
future::ok(Box::new(SuccessResponse { success: True }) as Box<dyn Any + Send>)
.boxed_env()
}
Request { url, .. } if url == "http://127.0.0.1:11470/casting" => {
future::ok(Box::new(Vec::<PlaybackDevice>::new()) as Box<dyn Any + Send>)
.boxed_env()
}
Request { url, .. } if url == "http://127.0.0.1:11470/network-info" => {
future::ok(Box::new(NetworkInfo {
available_interfaces: vec![AVAILABLE_INTERFACE.to_string()],
}) as Box<dyn Any + Send>)
.boxed_env()
}
Request { url, .. } if url.starts_with("http://127.0.0.1:11470/get-https") => {
future::ok(Box::new(GetHTTPSResponse {
ip_address: AVAILABLE_INTERFACE.to_string(),
domain: "https://stremio.com".to_string(),
port: 3333,
}) as Box<dyn Any + Send>)
.boxed_env()
}
_ => default_fetch_handler(request),
}
}

let _env_mutex = TestEnv::reset().expect("Should have exclusive lock to TestEnv");

*FETCH_HANDLER.write().unwrap() = Box::new(fetch_handler);

let profile = Profile {
auth: Some(Auth {
key: AuthKey("auth_key".to_owned()),
..Default::default()
}),
..Default::default()
};

let (streaming_server, ..) = StreamingServer::new::<TestEnv>(&profile);

let (runtime, _rx) = Runtime::<TestEnv, _>::new(
TestModel {
ctx: Ctx {
profile,
..Default::default()
},
streaming_server,
},
vec![],
1000,
);

assert!(
runtime
.model()
.unwrap()
.streaming_server
.remote_url
.is_none(),
"Remote url should not be set"
);

TestEnv::run(|| {
runtime.dispatch(RuntimeAction {
field: None,
action: Action::StreamingServer(ActionStreamingServer::Reload),
});
});

TestEnv::run(|| {
runtime.dispatch(RuntimeAction {
field: None,
action: Action::StreamingServer(ActionStreamingServer::UpdateSettings(
StreamingServerSettings {
remote_https: Some(AVAILABLE_INTERFACE.to_string()),
..STREAMING_SERVER_SETTINGS
},
)),
});
});

assert!(
runtime
.model()
.unwrap()
.streaming_server
.remote_url
.is_some(),
"Remote url should be set"
);
}

0 comments on commit 39fb65e

Please sign in to comment.