Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: streaming-server urls bucket #724

Merged
merged 47 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
a0ca367
feat: streaming-server urls bucket
kKaskak Oct 3, 2024
80eaf4e
feat: add select_item fn
kKaskak Oct 3, 2024
d8a8240
chore(fmt): fmt --all
kKaskak Oct 3, 2024
5bee75a
delete: comments
kKaskak Oct 3, 2024
67baef4
refactor: rename base item variable
kKaskak Oct 3, 2024
18c06a1
refactor: use chrono for timestamps
kKaskak Oct 3, 2024
698c83e
refactor: rename bucket
kKaskak Oct 3, 2024
84f4dc2
refactor: bucket logic
kKaskak Oct 4, 2024
f1c0224
refactor: use anyhow for better err handling
kKaskak Oct 4, 2024
768a432
refactor: impl update_server_urls
kKaskak Oct 4, 2024
142591d
refactor: bucket logic
kKaskak Oct 7, 2024
eae1404
remove: serverurl bucket from server_settings
kKaskak Oct 7, 2024
4c449ef
refactor: model seralization
kKaskak Oct 7, 2024
bbb638f
refactor: remove unecessary logic
kKaskak Oct 7, 2024
662672c
remove: selected field in ServerUrlItem
kKaskak Oct 7, 2024
3a09e3a
chore(fmt): fmt
kKaskak Oct 7, 2024
c0b638c
add: ctx serialization for server_urls
kKaskak Oct 7, 2024
4fccc7e
add: migation to v15
kKaskak Oct 7, 2024
5743f34
chore: fmt
kKaskak Oct 7, 2024
8366e31
rename: var streaming_server_urls
kKaskak Oct 7, 2024
c6f5405
chore: fmt & clippy
kKaskak Oct 7, 2024
4fa6ffd
fix: env storage key missmatch
kKaskak Oct 7, 2024
1cf708f
feat: tests
kKaskak Oct 7, 2024
784a00f
remove: unnecessary bucket result
kKaskak Oct 7, 2024
23a04e4
refactor: serialization of streaming_server_urls
kKaskak Oct 9, 2024
c9c1844
refactor: update variable name
kKaskak Oct 9, 2024
2184cf7
fix: serde + correct key for storage
kKaskak Oct 9, 2024
f746137
chore: fmt & clippy
kKaskak Oct 9, 2024
dba9afd
remove: unnecessary serde and merge_bucket fn
kKaskak Oct 9, 2024
01776ed
refactor: mtime on URLs bucket
kKaskak Oct 10, 2024
cd903bb
refactor: simplify bucket logic
kKaskak Oct 10, 2024
1aac7ce
fix: errors
kKaskak Oct 10, 2024
cafe0eb
remove: edit URL feature
kKaskak Oct 15, 2024
6f32b60
refactor: move the URL actions to CtxAction
kKaskak Oct 21, 2024
2f663b1
add: Env implementation for the bucket
kKaskak Oct 23, 2024
3eeca2d
refactor: delete the max items constrains
kKaskak Oct 23, 2024
5ab960d
feat: add add_url function
kKaskak Oct 23, 2024
463ba07
add: tests for add_url
kKaskak Oct 23, 2024
2b8c6ae
refactor: address comments
kKaskak Oct 24, 2024
923c51d
refactor: add sorting in serialization
kKaskak Oct 24, 2024
5dc65a9
remove: unnecessary const
kKaskak Oct 28, 2024
7291403
Merge branch 'development' into feat/streming-server-urls-bucket
elpiel Nov 8, 2024
8ee6557
refactor: docs in server_urls_bucket.rs
kKaskak Nov 14, 2024
ee5b125
Merge branch 'development' into feat/streming-server-urls-bucket
kKaskak Nov 14, 2024
7cb5664
chore: cargo fmt
kKaskak Nov 14, 2024
4d6b954
Merge branch 'development' into feat/streming-server-urls-bucket
kKaskak Nov 18, 2024
44c23a7
fix: base_url stremio-video support
kKaskak Nov 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub const LIBRARY_STORAGE_KEY: &str = "library";
pub const LIBRARY_RECENT_STORAGE_KEY: &str = "library_recent";
pub const STREAMS_STORAGE_KEY: &str = "streams";
pub const SEARCH_HISTORY_STORAGE_KEY: &str = "search_history";
pub const STREAMING_SERVER_URLS_STORAGE_KEY: &str = "streaming_server_urls";
pub const NOTIFICATIONS_STORAGE_KEY: &str = "notifications";
pub const CALENDAR_STORAGE_KEY: &str = "calendar";
pub const DISMISSED_EVENTS_STORAGE_KEY: &str = "dismissed_events";
Expand All @@ -38,7 +39,7 @@ pub const CALENDAR_ITEMS_COUNT: usize = 100;
pub const WATCHED_THRESHOLD_COEF: f64 = 0.7;
pub const CREDITS_THRESHOLD_COEF: f64 = 0.9;
/// The latest migration scheme version
pub const SCHEMA_VERSION: u32 = 14;
pub const SCHEMA_VERSION: u32 = 15;
pub const IMDB_LINK_CATEGORY: &str = "imdb";
pub const GENRES_LINK_CATEGORY: &str = "Genres";
pub const CINEMETA_TOP_CATALOG_ID: &str = "top";
Expand Down
26 changes: 25 additions & 1 deletion src/models/ctx/ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::{
common::{DescriptorLoadable, Loadable, ResourceLoadable},
ctx::{
update_events, update_library, update_notifications, update_profile,
update_search_history, update_streams, update_trakt_addon, CtxError, OtherError,
update_search_history, update_streaming_server_urls, update_streams,
update_trakt_addon, CtxError, OtherError,
},
},
runtime::{
Expand All @@ -22,6 +23,7 @@ use crate::{
profile::{Auth, AuthKey, Profile},
resource::MetaItem,
search_history::SearchHistoryBucket,
server_urls::ServerUrlsBucket,
streams::StreamsBucket,
},
};
Expand Down Expand Up @@ -54,6 +56,8 @@ pub struct Ctx {
#[serde(skip)]
pub streams: StreamsBucket,
#[serde(skip)]
pub streaming_server_urls: ServerUrlsBucket,
#[serde(skip)]
pub search_history: SearchHistoryBucket,
#[serde(skip)]
pub dismissed_events: DismissedEventsBucket,
Expand All @@ -78,6 +82,7 @@ impl Ctx {
profile: Profile,
library: LibraryBucket,
streams: StreamsBucket,
streaming_server_urls: ServerUrlsBucket,
notifications: NotificationsBucket,

search_history: SearchHistoryBucket,
Expand All @@ -87,6 +92,7 @@ impl Ctx {
profile,
library,
streams,
streaming_server_urls,
search_history,
dismissed_events,
notifications,
Expand Down Expand Up @@ -119,6 +125,11 @@ impl<E: Env + 'static> Update<E> for Ctx {
let library_effects =
update_library::<E>(&mut self.library, &self.profile, &self.status, msg);
let streams_effects = update_streams::<E>(&mut self.streams, &self.status, msg);
let server_urls_effects = update_streaming_server_urls::<E>(
&mut self.streaming_server_urls,
&self.status,
msg,
);
let search_history_effects =
update_search_history::<E>(&mut self.search_history, &self.status, msg);
let events_effects =
Expand All @@ -144,6 +155,7 @@ impl<E: Env + 'static> Update<E> for Ctx {
.join(profile_effects)
.join(library_effects)
.join(streams_effects)
.join(server_urls_effects)
.join(search_history_effects)
.join(events_effects)
.join(trakt_addon_effects)
Expand All @@ -169,6 +181,11 @@ impl<E: Env + 'static> Update<E> for Ctx {
msg,
);
let streams_effects = update_streams::<E>(&mut self.streams, &self.status, msg);
let server_urls_effects = update_streaming_server_urls::<E>(
&mut self.streaming_server_urls,
&self.status,
msg,
);
let search_history_effects =
update_search_history::<E>(&mut self.search_history, &self.status, msg);
let events_effects =
Expand Down Expand Up @@ -237,6 +254,7 @@ impl<E: Env + 'static> Update<E> for Ctx {
profile_effects
.join(library_effects)
.join(streams_effects)
.join(server_urls_effects)
.join(trakt_addon_effects)
.join(notifications_effects)
.join(search_history_effects)
Expand All @@ -249,6 +267,11 @@ impl<E: Env + 'static> Update<E> for Ctx {
let library_effects =
update_library::<E>(&mut self.library, &self.profile, &self.status, msg);
let streams_effects = update_streams::<E>(&mut self.streams, &self.status, msg);
let server_urls_effects = update_streaming_server_urls::<E>(
&mut self.streaming_server_urls,
&self.status,
msg,
);
let trakt_addon_effects = update_trakt_addon::<E>(
&mut self.trakt_addon,
&self.profile,
Expand All @@ -270,6 +293,7 @@ impl<E: Env + 'static> Update<E> for Ctx {
profile_effects
.join(library_effects)
.join(streams_effects)
.join(server_urls_effects)
.join(trakt_addon_effects)
.join(notifications_effects)
.join(search_history_effects)
Expand Down
3 changes: 3 additions & 0 deletions src/models/ctx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ use update_search_history::*;
mod update_trakt_addon;
use update_trakt_addon::*;

mod update_streaming_server_urls;
use update_streaming_server_urls::*;

mod error;
pub use error::*;

Expand Down
64 changes: 64 additions & 0 deletions src/models/ctx/update_streaming_server_urls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use futures::FutureExt;

use crate::constants::STREAMING_SERVER_URLS_STORAGE_KEY;
use crate::runtime::msg::{Action, ActionCtx, CtxAuthResponse};
use crate::runtime::{
msg::{Event, Internal, Msg},
Effect, EffectFuture, Effects, Env, EnvFutureExt,
};
use crate::types::server_urls::ServerUrlsBucket;

use super::{CtxError, CtxStatus};

pub fn update_streaming_server_urls<E: Env + 'static>(
streaming_server_urls: &mut ServerUrlsBucket,
status: &CtxStatus,
msg: &Msg,
) -> Effects {
match msg {
Msg::Action(Action::Ctx(ActionCtx::AddServerUrl(url))) => {
streaming_server_urls.add_url::<E>(url.clone());
Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged))
}
Msg::Action(Action::Ctx(ActionCtx::DeleteServerUrl(url))) => {
streaming_server_urls.delete_url(url);
Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged))
}
Msg::Internal(Internal::CtxAuthResult(auth_request, result)) => match (status, result) {
(CtxStatus::Loading(loading_auth_request), Ok(CtxAuthResponse { auth, .. }))
if loading_auth_request == auth_request =>
{
let next_server_urls = ServerUrlsBucket::new::<E>(Some(auth.user.id.to_owned()));
*streaming_server_urls = next_server_urls;
Effects::msg(Msg::Internal(Internal::StreamingServerUrlsBucketChanged))
}
_ => Effects::none().unchanged(),
},
Msg::Internal(Internal::StreamingServerUrlsBucketChanged) => {
Effects::one(push_server_urls_to_storage::<E>(streaming_server_urls)).unchanged()
}
_ => Effects::none().unchanged(),
}
}

fn push_server_urls_to_storage<E: Env + 'static>(
streaming_server_urls: &ServerUrlsBucket,
) -> Effect {
let uid: Option<String> = streaming_server_urls.uid.clone();

EffectFuture::Sequential(
E::set_storage(
STREAMING_SERVER_URLS_STORAGE_KEY,
Some(streaming_server_urls),
)
.map(move |result| match result {
Ok(_) => Msg::Event(Event::StreamingServerUrlsPushedToStorage { uid: uid.clone() }),
Err(error) => Msg::Event(Event::Error {
error: CtxError::from(error),
source: Box::new(Event::StreamingServerUrlsPushedToStorage { uid: uid.clone() }),
}),
})
.boxed_env(),
)
.into()
}
3 changes: 1 addition & 2 deletions src/models/streaming_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,7 @@ impl<E: Env + 'static> UpdateWithCtx<E> for StreamingServer {
&mut self.settings,
Loadable::Ready(settings.values.to_owned()),
);
let base_url_effects =
eq_update(&mut self.base_url, Some(settings.base_url.to_owned()));
let base_url_effects = eq_update(&mut self.base_url, Some(url.to_owned()));
let remote_url_effects = update_remote_url::<E>(
&mut self.remote_url,
&self.selected,
Expand Down
33 changes: 29 additions & 4 deletions src/runtime/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::addon_transport::{AddonHTTPTransport, AddonTransport, UnsupportedTran
use crate::constants::{
DISMISSED_EVENTS_STORAGE_KEY, LIBRARY_RECENT_STORAGE_KEY, LIBRARY_STORAGE_KEY,
PROFILE_STORAGE_KEY, SCHEMA_VERSION, SCHEMA_VERSION_STORAGE_KEY, SEARCH_HISTORY_STORAGE_KEY,
STREAMS_STORAGE_KEY,
STREAMING_SERVER_URLS_STORAGE_KEY, STREAMS_STORAGE_KEY,
};
use crate::models::ctx::Ctx;
use crate::models::streaming_server::StreamingServer;
Expand Down Expand Up @@ -265,6 +265,12 @@ pub trait Env {
.await?;
schema_version = 14;
}
if schema_version == 14 {
migrate_storage_schema_to_v15::<Self>()
.map_err(|error| EnvError::StorageSchemaVersionUpgrade(Box::new(error)))
.await?;
schema_version = 15;
}
if schema_version != SCHEMA_VERSION {
panic!(
"Storage schema version must be upgraded from {} to {}",
Expand Down Expand Up @@ -594,6 +600,12 @@ fn migrate_storage_schema_to_v14<E: Env>() -> TryEnvFuture<()> {
.boxed_env()
}

fn migrate_storage_schema_to_v15<E: Env>() -> TryEnvFuture<()> {
E::set_storage::<()>(STREAMING_SERVER_URLS_STORAGE_KEY, None)
.and_then(|_| E::set_storage(SCHEMA_VERSION_STORAGE_KEY, Some(&15)))
.boxed_env()
}

#[cfg(test)]
mod test {
use serde_json::{json, Value};
Expand All @@ -606,9 +618,9 @@ mod test {
env::{
migrate_storage_schema_to_v10, migrate_storage_schema_to_v11,
migrate_storage_schema_to_v12, migrate_storage_schema_to_v13,
migrate_storage_schema_to_v14, migrate_storage_schema_to_v6,
migrate_storage_schema_to_v7, migrate_storage_schema_to_v8,
migrate_storage_schema_to_v9,
migrate_storage_schema_to_v14, migrate_storage_schema_to_v15,
migrate_storage_schema_to_v6, migrate_storage_schema_to_v7,
migrate_storage_schema_to_v8, migrate_storage_schema_to_v9,
},
Env,
},
Expand Down Expand Up @@ -1125,4 +1137,17 @@ mod test {
"Profile should match"
);
}

#[tokio::test]
async fn test_migration_from_14_to_15() {
let _test_env_guard = TestEnv::reset().expect("Should lock TestEnv");

migrate_storage_schema_to_v15::<TestEnv>()
.await
.expect("Should migrate");

{
assert_storage_schema_version(15);
}
}
}
4 changes: 4 additions & 0 deletions src/runtime/msg/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ pub enum ActionCtx {
GetEvents,
/// Dismiss an event by id, either a Modal or Notification
DismissEvent(String),
/// Add a server URL to the list of available streaming servers
AddServerUrl(Url),
/// Delete a server URL from the list of available streaming servers
DeleteServerUrl(Url),
}

#[derive(Clone, Deserialize, Debug)]
Expand Down
6 changes: 6 additions & 0 deletions src/runtime/msg/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ pub enum Event {
PlayingOnDevice {
device: String,
},
StreamingServerUrlsBucketChanged {
uid: UID,
},
StreamingServerUrlsPushedToStorage {
uid: UID,
},
Error {
error: CtxError,
source: Box<Event>,
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/msg/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ pub enum Internal {
StreamsChanged(bool),
/// Search history has changed.
SearchHistoryChanged,
/// Server URLs bucket has changed.
StreamingServerUrlsBucketChanged,
/// User notifications have changed
NotificationsChanged,
/// Pulling of notifications triggered either by the user (with an action) or
Expand Down
1 change: 1 addition & 0 deletions src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod player;
pub mod profile;
pub mod resource;
pub mod search_history;
pub mod server_urls;
pub mod streaming_server;
pub mod streams;
pub mod torrent;
Expand Down
2 changes: 2 additions & 0 deletions src/types/server_urls/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod server_urls_bucket;
pub use server_urls_bucket::*;
39 changes: 39 additions & 0 deletions src/types/server_urls/server_urls_bucket.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::{constants::STREAMING_SERVER_URL, runtime::Env, types::profile::UID};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use url::Url;

#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct ServerUrlsBucket {
/// User ID
pub uid: UID,
/// A map of the the server Url as a key and the modified/added datetime of that particular url.
pub items: HashMap<Url, DateTime<Utc>>,
kKaskak marked this conversation as resolved.
Show resolved Hide resolved
}

impl ServerUrlsBucket {
/// Create a new `ServerUrlsBucket` with the base URL inserted.
pub fn new<E: Env + 'static>(uid: UID) -> Self {
let mut items = HashMap::new();
let base_url: &Url = &STREAMING_SERVER_URL;
let mtime = E::now();
items.insert(base_url.clone(), mtime);

ServerUrlsBucket { uid, items }
}

/// Add a URL to the bucket.
pub fn add_url<E: Env + 'static>(&mut self, url: Url) {
let mtime = E::now();
self.items.insert(url, mtime);
}

/// Delete a URL from the bucket.
pub fn delete_url(&mut self, url: &Url) {
let default_url: &Url = &STREAMING_SERVER_URL;
if url != default_url {
self.items.remove(url);
}
}
}
3 changes: 3 additions & 0 deletions src/unit_tests/catalog_with_filters/load_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::types::notifications::NotificationsBucket;
use crate::types::profile::Profile;
use crate::types::resource::MetaItemPreview;
use crate::types::search_history::SearchHistoryBucket;
use crate::types::server_urls::ServerUrlsBucket;
use crate::types::streams::StreamsBucket;
use crate::unit_tests::{
default_fetch_handler, Request, TestEnv, EVENTS, FETCH_HANDLER, REQUESTS, STATES,
Expand Down Expand Up @@ -50,6 +51,7 @@ fn default_catalog() {
Profile::default(),
LibraryBucket::default(),
StreamsBucket::default(),
ServerUrlsBucket::new::<TestEnv>(None),
NotificationsBucket::new::<TestEnv>(None, vec![]),
SearchHistoryBucket::default(),
DismissedEventsBucket::default(),
Expand Down Expand Up @@ -151,6 +153,7 @@ fn search_catalog() {
Profile::default(),
LibraryBucket::default(),
StreamsBucket::default(),
ServerUrlsBucket::new::<TestEnv>(None),
NotificationsBucket::new::<TestEnv>(None, vec![]),
SearchHistoryBucket::default(),
DismissedEventsBucket::default(),
Expand Down
Loading