Skip to content

Commit

Permalink
feat: Add Most Wanted items from Trakt (#777)
Browse files Browse the repository at this point in the history
* feat: fetch most wanted items from trakt

* feat: only fetch trakt trending, popular and watched lists once a day

* refactor: Add last_update attribute to TraktContent class

* refactor: Remove unused code in TraktContent class

* fix: minor fixes to trakt content

---------

Co-authored-by: Spoked <[email protected]>
Co-authored-by: Spoked <[email protected]>
  • Loading branch information
3 people authored Oct 26, 2024
1 parent 19cedc8 commit 325df42
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
48 changes: 28 additions & 20 deletions src/program/content/trakt.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Trakt content module"""
import re
import time
from typing import Union
from urllib.parse import urlencode
from datetime import datetime, timedelta

from requests import RequestException

Expand All @@ -28,8 +28,7 @@ def __init__(self):
self.initialized = self.validate()
if not self.initialized:
return
self.next_run_time = 0
self.missing()
self.last_update = None
logger.success("Trakt initialized!")

def validate(self) -> bool:
Expand Down Expand Up @@ -58,30 +57,28 @@ def validate(self) -> bool:
logger.error(f"Exception during Trakt validation: {str(e)}")
return False

def missing(self):
"""Log missing items from Trakt"""
if not self.settings.watchlist:
logger.log("TRAKT", "No watchlist configured.")
if not self.settings.collection:
logger.log("TRAKT", "No collection configured.")
if not self.settings.user_lists:
logger.log("TRAKT", "No user lists configured.")
if not self.settings.fetch_trending:
logger.log("TRAKT", "Trending fetching is disabled.")
if not self.settings.fetch_popular:
logger.log("TRAKT", "Popular fetching is disabled.")

def run(self):
"""Fetch media from Trakt and yield Movie, Show, or MediaItem instances."""

watchlist_ids = self._get_watchlist(self.settings.watchlist) if self.settings.watchlist else []
collection_ids = self._get_collection(self.settings.collection) if self.settings.collection else []
user_list_ids = self._get_list(self.settings.user_lists) if self.settings.user_lists else []
trending_ids = self._get_trending_items() if self.settings.fetch_trending else []
popular_ids = self._get_popular_items() if self.settings.fetch_popular else []

# Check if it's the first run or if a day has passed since the last update
current_time = datetime.now()
if self.last_update is None or (current_time - self.last_update) > timedelta(days=1):
trending_ids = self._get_trending_items() if self.settings.fetch_trending else []
popular_ids = self._get_popular_items() if self.settings.fetch_popular else []
most_watched_ids = self._get_most_watched_items() if self.settings.fetch_most_watched else []
self.last_update = current_time
logger.log("TRAKT", "Updated trending, popular, and most watched items.")
else:
trending_ids = []
popular_ids = []
most_watched_ids = []
logger.log("TRAKT", "Skipped updating trending, popular, and most watched items (last update was less than a day ago).")

# Combine all IMDb IDs and types into a set to avoid duplicates
all_ids = set(watchlist_ids + collection_ids + user_list_ids + trending_ids + popular_ids)
all_ids = set(watchlist_ids + collection_ids + user_list_ids + trending_ids + popular_ids + most_watched_ids)

items_to_yield = []
for imdb_id, _ in all_ids:
Expand Down Expand Up @@ -149,6 +146,12 @@ def _get_popular_items(self) -> list:
popular_movies = get_popular_items(self.api_url, self.headers, "movies", self.settings.popular_count)
popular_shows = get_popular_items(self.api_url, self.headers, "shows", self.settings.popular_count)
return self._extract_imdb_ids_with_none_type(popular_movies[:self.settings.popular_count] + popular_shows[:self.settings.popular_count])

def _get_most_watched_items(self) -> list:
"""Get IMDb IDs from Trakt popular items"""
most_watched_movies = get_most_watched_items(self.api_url, self.headers, "movies", self.settings.most_watched_period, self.settings.most_watched_count)
most_watched_shows = get_most_watched_items(self.api_url, self.headers, "shows", self.settings.most_watched_period, self.settings.most_watched_count)
return self._extract_imdb_ids(most_watched_movies[:self.settings.most_watched_count] + most_watched_shows[:self.settings.most_watched_count])

def _extract_imdb_ids(self, items: list) -> list:
"""Extract IMDb IDs and types from a list of items"""
Expand Down Expand Up @@ -274,6 +277,11 @@ def get_popular_items(api_url, headers, media_type, limit=10):
url = f"{api_url}/{media_type}/popular"
return _fetch_data(url, headers, {"limit": limit})

def get_most_watched_items(api_url, headers, media_type, period="weekly", limit=10):
"""Get popular items from Trakt with pagination support."""
url = f"{api_url}/{media_type}/watched/{period}"
return _fetch_data(url, headers, {"limit": limit})

# UNUSED
def get_favorited_items(api_url, headers, user, limit=10):
"""Get favorited items from Trakt with pagination support."""
Expand Down
3 changes: 3 additions & 0 deletions src/program/settings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ class TraktModel(Updatable):
trending_count: int = 10
fetch_popular: bool = False
popular_count: int = 10
fetch_most_watched: bool = False
most_watched_period: str = "weekly"
most_watched_count: int = 10
update_interval: int = 86400
# oauth: TraktOauthModel = TraktOauthModel()

Expand Down

0 comments on commit 325df42

Please sign in to comment.