Skip to content

Commit

Permalink
feat: override include_watched w/ collection label (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
luukleenders authored Nov 25, 2023
1 parent 5a9070b commit aad5f7d
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 22 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Settings are set via [environment variables](https://kinsta.com/knowledgebase/wh
|---------------------------|----------|---------------------------------------------------------------------------|
| REPLEX_HOST | | Url of your plex instance. ex: http://0.0.0.0:32400 |
| REPLEX_HERO_ROWS | | Comma seperated list of hubidentifiers to make hero style, options are: <br />home.movies.recent<br />movies.recent <br />movie.recentlyadded<br />movie.topunwatched<br />movie.recentlyviewed<br />hub.movie.recentlyreleased<br />movie.recentlyreleased<br />home.television.recent<br />tv.recentlyadded<br />tv.toprated<br />tv.inprogress<br />tv.recentlyaired |
| REPLEX_INCLUDE_WATCHED | false | If set to false, hide watched items for recommended rows |
| REPLEX_EXCLUDE_WATCHED | false | If set to true, hide watched items for recommended rows |
| REPLEX_DISABLE_CONTINUE_WATCHING | false | Disable/remove the continue watching row |
| REPLEX_DISABLE_USER_STATE | false | Remove unplayed badges from row items |
| REPLEX_DISABLE_LEAF_COUNT| false | Remove episode count label from show artwork. |
Expand Down Expand Up @@ -122,6 +122,10 @@ For built in rows you can use the hubidentifier in the `REPLEX_HERO_ROWS`. See t
Note: hero style elements uses coverart from plex. Banner or background is not used.
Note: Hero elements are not supported for continue watching by plex. You can replicate this functionality by creating a smart collection which filters on in progress and settinf REPLEX_DISABLE_CONTINUE_WATCHING

## Exclude watched items

If you want to hide watched items from your rows, you can set `REPLEX_EXCLUDE_WATCHED` to true. Alternatively, you can add the label "REPLEX_EXCLUDE_WATCHED" to a collection to exclude watched items from that collection only.


## Remote access (force clients to use the proxy)

Expand Down Expand Up @@ -156,7 +160,7 @@ You can redirect streams by enabling `REPLEX_REDIRECT_STREAMS` and optionally se

- hero rows on Android devices dont load more content. so hero rows have a maximum of 100 items on Android.
- On android mobile hero elements in libraries are slightly cutoff. This is plex limitation.
- when include_watched is false a maximum item limit per library is opposed of 250 items. So if you have a mixed row of 2 libraries the max results of that row will be 500 items.
- when exclude_watched is true a maximum item limit per library is opposed of 250 items. So if you have a mixed row of 2 libraries the max results of that row will be 500 items.
- disable_user_state: For movies this works in the webapp. Shows work accross clients

## Help it doesnt work!
Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct Config {
default = "default_as_false",
deserialize_with = "figment::util::bool_from_str_or_int"
)]
pub include_watched: bool,
pub exclude_watched: bool,
#[serde(default = "default_cache_ttl")]
pub cache_ttl: u64,
#[serde(
Expand Down
39 changes: 39 additions & 0 deletions src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,34 @@ impl MetaData {
false
}

pub async fn exclude_watched(
&self,
plex_client: PlexClient,
) -> Result<bool> {
if !self.is_collection_hub() {
return Ok(false);
}

let config: Config = Config::figment().extract().unwrap();
let collection = plex_client
.clone()
.get_cached(
plex_client
.get_collection(get_collection_id_from_hub(self) as i32),
format!("collection:{}", get_collection_id_from_hub(self))
.to_string(),
)
.await?;

Ok(config.exclude_watched
|| collection
.media_container
.metadata
.get(0)
.unwrap()
.has_label("REPLEX_EXCLUDE_WATCHED".to_string()))
}

// TODO: Does not work when using a new instance
pub fn set_children(&mut self, value: Vec<MetaData>) {
let len: i32 = value.len().try_into().unwrap();
Expand Down Expand Up @@ -1684,6 +1712,17 @@ impl MediaContainer {
!self.hub.is_empty()
}

pub fn exclude_watched(&self) -> bool {
let config: Config = Config::figment().extract().unwrap();

return config.exclude_watched
|| self
.metadata
.get(0)
.unwrap()
.has_label("REPLEX_EXCLUDE_WATCHED".to_string());
}

pub fn set_type(&mut self, value: String) {
for hub in &mut self.hub {
hub.r#type = value.clone();
Expand Down
12 changes: 7 additions & 5 deletions src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ pub async fn transform_hubs_home(
_ => (),
}
// Hack, as the list could be smaller when removing watched items. So we request more.
if !config.include_watched && count < 50 {
if config.exclude_watched && count < 50 {
count = 50;
}

Expand All @@ -464,6 +464,7 @@ pub async fn transform_hubs_home(
TransformBuilder::new(plex_client, params.clone())
.with_transform(HubStyleTransform { is_home: true })
// .with_transform(HubSectionDirectoryTransform)
.with_transform(HubWatchedTransform)
.with_transform(HubMixTransform)
// .with_transform(HubChildrenLimitTransform {
// limit: params.clone().count.unwrap(),
Expand Down Expand Up @@ -495,7 +496,7 @@ pub async fn get_hubs_sections(
}

// Hack, as the list could be smaller when removing watched items. So we request more.
if !config.include_watched && count < 50 {
if config.exclude_watched && count < 50 {
count = 50;
}

Expand All @@ -522,11 +523,12 @@ pub async fn get_hubs_sections(
TransformBuilder::new(plex_client, params.clone())
.with_transform(HubSectionDirectoryTransform)
.with_transform(HubStyleTransform { is_home: false })
.with_transform(HubWatchedTransform)
.with_transform(UserStateTransform)
.with_transform(HubKeyTransform)
//.with_transform(MediaContainerScriptingTransform)
// .with_filter(CollectionHubPermissionFilter)
.with_filter(WatchedFilter)
// .with_filter(WatchedFilter)
.apply_to(&mut container)
.await;
// dbg!(container.media_container.count);
Expand Down Expand Up @@ -564,7 +566,7 @@ pub async fn get_collections_children(
let mut offset: i32 = 0;

// in we dont remove watched then we dont need to limit
if config.include_watched {
if !config.exclude_watched {
limit = params.container_size.unwrap_or(50);
offset = params.container_start.unwrap_or(0);
}
Expand Down Expand Up @@ -618,7 +620,7 @@ pub async fn default_transform(
let mut offset: i32 = 0;

// in we dont remove watched then we dont need to limit
if config.include_watched {
if !config.exclude_watched {
limit = params.container_size.unwrap_or(50);
offset = params.container_start.unwrap_or(0);
}
Expand Down
56 changes: 42 additions & 14 deletions src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,9 +327,6 @@ impl Transform for HubMixTransform {
continue;
}

if !config.include_watched {
hub.children_mut().retain(|x| !x.is_watched());
}
//hub.context = Some("hub.home.watchlist_available".to_string());
//hub.r#type = "clip".to_string();
// hub.placeholder = Some(SpecialBool::new(true));
Expand Down Expand Up @@ -422,7 +419,7 @@ impl Transform for LibraryMixTransform {
) -> MediaContainer {
let config: Config = Config::figment().extract().unwrap();
let mut children: Vec<MetaData> = vec![];
let mut total_size_including_watched = 0;
let mut total_size = 0;

for id in self.collection_ids.clone() {
let mut c = plex_client
Expand All @@ -441,12 +438,21 @@ impl Transform for LibraryMixTransform {
.await
.unwrap();

total_size_including_watched +=
c.media_container.total_size.unwrap();
if !config.include_watched {
let collection = plex_client
.clone()
.get_cached(
plex_client.get_collection(id as i32),
format!("collection:{}", id.to_string()),
)
.await
.unwrap();

if collection.media_container.exclude_watched() {
c.media_container.children_mut().retain(|x| !x.is_watched());
}

total_size += c.media_container.children().len() as i32;

match children.is_empty() {
false => {
children = children
Expand All @@ -457,11 +463,7 @@ impl Transform for LibraryMixTransform {
true => children.append(&mut c.media_container.children()),
}
}
if !config.include_watched {
item.total_size = Some(children.len() as i32);
} else {
item.total_size = Some(total_size_including_watched);
};
item.total_size = Some(total_size);
// always metadata
item.metadata = children;
item
Expand Down Expand Up @@ -689,6 +691,32 @@ impl Transform for HubStyleTransform {
}
}

#[derive(Default, Debug)]
pub struct HubWatchedTransform;

#[async_trait]
impl Transform for HubWatchedTransform {
async fn transform_metadata(
&self,
item: &mut MetaData,
plex_client: PlexClient,
options: PlexContext,
) {
let config: Config = Config::figment().extract().unwrap();

if item.is_hub() {
let exclude_watched = item
.exclude_watched(plex_client.clone())
.await
.unwrap_or(false);

if exclude_watched {
item.children_mut().retain(|x| !x.is_watched());
}
}
}
}

pub struct MediaStyleTransform {
pub style: Style,
}
Expand Down Expand Up @@ -816,8 +844,8 @@ impl Filter for WatchedFilter {
options: PlexContext,
) -> bool {
let config: Config = Config::figment().extract().unwrap();
if config.include_watched {
return true;
if config.exclude_watched {
return false;
}

if !item.is_hub() {
Expand Down

0 comments on commit aad5f7d

Please sign in to comment.