Skip to content

Commit

Permalink
Implement rest sorting, add trakt rating to data in HA
Browse files Browse the repository at this point in the history
  • Loading branch information
downey-lv committed Jun 4, 2024
1 parent 1e72ccc commit 588f88f
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 11 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ trakt_tv:
- friendly_name: "2024 Academy Awards"
list_id: 26885014
max_medias: 5
sort_by: rating_trakt
sort_order: desc
- friendly_name: "Star Trek Movies"
list_id: 967660
media_type: "movie" # Filters the list to only show movies
Expand Down Expand Up @@ -193,11 +195,19 @@ Lists sensor allows you to fetch both public and private lists from Trakt, each

There are four parameters for each sensor:

- `friendly_name` (MANDATORY) should be a string for the name of the sensor. This has to be unique for each list.
- `list_id` (MANDATORY) should be the Trakt list ID. For public lists the ID has to be numeric, for private lists the ID can be either the numeric ID or the slug from the URL. To get the numeric ID of a public list, copy the link address of the list before opening it. This will give you a URL like `https://trakt.tv/lists/2142753`. The `2142753` part is the numeric ID you need to use.
- `private_list` (OPTIONAL) has to be set to `true` if using your own private list. Default is `false`
- `media_type` (OPTIONAL) can be used to filter the media type within the list, possible values are `show`, `movie`, `episode`. Default is blank, which will show all media types
- `max_medias` (OPTIONAL) should be a positive number for how many items to grab. Default is `3`
- `friendly_name` **MANDATORY** should be a string for the name of the sensor. This has to be unique for each list.
- `list_id` **MANDATORY** should be the Trakt list ID. For public lists the ID has to be numeric, for private lists the ID can be either the numeric ID or the slug from the URL. To get the numeric ID of a public list, copy the link address of the list before opening it or open the Report List window. This will give you a URL like `https://trakt.tv/lists/2142753`. The `2142753` part is the numeric ID you need to use.
- `private_list` _OPTIONAL_ has to be set to `true` if using your own private list. Default is `false`
- `media_type` _OPTIONAL_ can be used to filter the media type within the list, possible values are `show`, `movie`, `episode`. Default is blank, which will show all media types
- `max_medias` _OPTIONAL_ should be a positive number for how many items to grab. Default is `3`
- `sort_by` _OPTIONAL_ should be a string for how to sort the list. Default is `rank`. Possible values are:
- `rank` - Placement in the list
- `rating` - TMDB rating
- `rating_trakt` - Trakt rating
- `runtime`
- `released`
- `listed_at` - Date the item was added to the list
- `sort_order` _OPTIONAL_ should be a string for the sort order. Possible values are `asc`, `desc`. Default is `asc`

#### Example

Expand Down
4 changes: 2 additions & 2 deletions custom_components/trakt_tv/apis/trakt.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,8 @@ async def fetch_list(
LOGGER.warn(f"Filtering list on {media_type} is not supported")
return None

# Add the limit to the path
path = f"{path}?limit={max_items}"
# Add extended info used for sorting
path = f"{path}?extended=full"

return await self.request("get", path)

Expand Down
11 changes: 11 additions & 0 deletions custom_components/trakt_tv/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,14 @@
"za",
"zu",
]

SORT_BY_OPTIONS = [
"rating",
"rating_trakt",
"rank",
"runtime",
"released",
"listed_at"
]

SORT_HOW_OPTIONS = ["asc", "desc"]
19 changes: 17 additions & 2 deletions custom_components/trakt_tv/models/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def common_information(self) -> Dict[str, Any]:
"fanart": self.fanart,
"genres": self.genres,
"rating": self.rating,
"rating_trakt": self.rating_trakt,
"studio": self.studio,
}

Expand All @@ -98,6 +99,9 @@ class Movie(Media):
runtime: Optional[int] = None
studio: Optional[str] = None
released: Optional[datetime] = None # This one is actually mandatory
rank: Optional[int] = None
listed_at: Optional[datetime] = None
rating_trakt: Optional[int] = None

@staticmethod
def from_trakt(data) -> "Movie":
Expand All @@ -110,6 +114,9 @@ def from_trakt(data) -> "Movie":
name=movie["title"],
released=parse_utc_date(data.get("released")),
ids=Identifiers.from_trakt(movie),
rank=data.get("rank"),
listed_at=parse_utc_date(data.get("listed_at")),
rating_trakt=movie.get("rating"),
)

async def get_more_information(self, language):
Expand Down Expand Up @@ -188,6 +195,10 @@ class Show(Media):
studio: Optional[str] = None
episode: Optional[Episode] = None
released: Optional[datetime] = None
runtime: Optional[int] = None
rank: Optional[int] = None
listed_at: Optional[datetime] = None
rating_trakt: Optional[int] = None

@staticmethod
def from_trakt(data) -> "Show":
Expand All @@ -203,6 +214,10 @@ def from_trakt(data) -> "Show":
ids=Identifiers.from_trakt(show),
released=parse_utc_date(data.get("first_aired")),
episode=episode,
rank=data.get("rank"),
listed_at=parse_utc_date(data.get("listed_at")),
runtime=show.get("runtime"),
rating_trakt=show.get("rating"),
)

def update_common_information(self, data: Dict[str, Any]):
Expand Down Expand Up @@ -268,14 +283,14 @@ def to_homeassistant(self) -> Dict[str, Any]:
class Medias:
items: List[Media]

def to_homeassistant(self) -> Dict[str, Any]:
def to_homeassistant(self, sort_by = 'released', sort_order = 'asc') -> Dict[str, Any]:
"""
Convert the List of medias to recommendation data.
:return: The dictionary containing all necessary information for upcoming media
card
"""
medias = sorted(self.items, key=lambda media: media.released)
medias = sorted(self.items, key=lambda media: getattr(media, sort_by), reverse=sort_order == "desc")
medias = [media.to_homeassistant() for media in medias]
return [first_item] + medias

Expand Down
4 changes: 3 additions & 1 deletion custom_components/trakt_tv/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from homeassistant.helpers import config_validation as cv
from voluptuous import ALLOW_EXTRA, PREVENT_EXTRA, In, Required, Schema

from .const import DOMAIN, LANGUAGE_CODES
from .const import DOMAIN, LANGUAGE_CODES, SORT_BY_OPTIONS, SORT_HOW_OPTIONS
from .models.kind import BASIC_KINDS, NEXT_TO_WATCH_KINDS, TraktKind


Expand Down Expand Up @@ -84,6 +84,8 @@ def lists_schema() -> dict[Required, Any]:
Required("max_medias", default=3): cv.positive_int,
Required("private_list", default=False): cv.boolean,
Required("media_type", default=""): cv.string,
Required("sort_by", default="rank"): In(SORT_BY_OPTIONS),
Required("sort_order", default="asc"): In(SORT_HOW_OPTIONS),
}

return schema
Expand Down
5 changes: 4 additions & 1 deletion custom_components/trakt_tv/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@ def data(self):
if not self.medias:
return []
if self.trakt_kind == TraktKind.LIST:
return self.medias.to_homeassistant()
sort_by = self.config_entry["sort_by"]
sort_order = self.config_entry["sort_order"]
max_medias = self.config_entry["max_medias"]
return self.medias.to_homeassistant(sort_by, sort_order)[0 : max_medias + 1]
max_medias = self.configuration["max_medias"]
return self.medias.to_homeassistant()[0 : max_medias + 1]

Expand Down

0 comments on commit 588f88f

Please sign in to comment.