2021-01-20 21:37:59 +00:00
|
|
|
import logging, requests
|
|
|
|
from modules import util
|
|
|
|
from modules.util import Failed
|
2021-05-11 01:22:18 +00:00
|
|
|
from plexapi.exceptions import BadRequest, NotFound
|
|
|
|
from plexapi.video import Movie, Show
|
2021-01-20 21:37:59 +00:00
|
|
|
from retrying import retry
|
|
|
|
|
|
|
|
logger = logging.getLogger("Plex Meta Manager")
|
|
|
|
|
2021-03-30 05:50:53 +00:00
|
|
|
builders = ["tautulli_popular", "tautulli_watched"]
|
|
|
|
|
2021-01-20 21:37:59 +00:00
|
|
|
class TautulliAPI:
|
|
|
|
def __init__(self, params):
|
|
|
|
try:
|
2021-02-24 06:44:06 +00:00
|
|
|
response = requests.get(f"{params['url']}/api/v2?apikey={params['apikey']}&cmd=get_library_names").json()
|
2021-02-24 06:42:58 +00:00
|
|
|
except Exception:
|
2021-01-20 21:37:59 +00:00
|
|
|
util.print_stacktrace()
|
|
|
|
raise Failed("Tautulli Error: Invalid url")
|
|
|
|
if response["response"]["result"] != "success":
|
2021-02-24 06:44:06 +00:00
|
|
|
raise Failed(f"Tautulli Error: {response['response']['message']}")
|
2021-01-20 21:37:59 +00:00
|
|
|
self.url = params["url"]
|
|
|
|
self.apikey = params["apikey"]
|
|
|
|
|
2021-05-09 05:37:45 +00:00
|
|
|
def get_items(self, library, time_range=30, stats_count=20, list_type="popular", stats_count_buffer=20):
|
|
|
|
logger.info(f"Processing Tautulli Most {'Popular' if list_type == 'popular' else 'Watched'}: {stats_count} {'Movies' if library.is_movie else 'Shows'}")
|
2021-05-07 19:53:54 +00:00
|
|
|
response = self._request(f"{self.url}/api/v2?apikey={self.apikey}&cmd=get_home_stats&time_range={time_range}&stats_count={int(stats_count) + int(stats_count_buffer)}")
|
2021-02-24 06:44:06 +00:00
|
|
|
stat_id = f"{'popular' if list_type == 'popular' else 'top'}_{'movies' if library.is_movie else 'tv'}"
|
2021-01-20 21:37:59 +00:00
|
|
|
|
|
|
|
items = None
|
|
|
|
for entry in response["response"]["data"]:
|
|
|
|
if entry["stat_id"] == stat_id:
|
|
|
|
items = entry["rows"]
|
|
|
|
break
|
|
|
|
if items is None:
|
|
|
|
raise Failed("Tautulli Error: No Items found in the response")
|
|
|
|
|
2021-05-07 19:53:54 +00:00
|
|
|
section_id = self._section_id(library.name)
|
2021-01-20 21:37:59 +00:00
|
|
|
rating_keys = []
|
|
|
|
count = 0
|
|
|
|
for item in items:
|
|
|
|
if item["section_id"] == section_id and count < int(stats_count):
|
2021-05-11 01:22:18 +00:00
|
|
|
rk = None
|
|
|
|
try:
|
|
|
|
library.fetchItem(int(item["rating_key"]))
|
|
|
|
rk = item["rating_key"]
|
|
|
|
except (BadRequest, NotFound):
|
|
|
|
new_item = library.exact_search(item["title"])
|
|
|
|
if new_item:
|
|
|
|
rk = new_item[0].ratingKey
|
|
|
|
else:
|
|
|
|
logger.error(f"Plex Error: Item {item} not found")
|
|
|
|
continue
|
|
|
|
rating_keys.append(rk)
|
2021-01-20 21:37:59 +00:00
|
|
|
count += 1
|
|
|
|
return rating_keys
|
|
|
|
|
2021-05-07 19:53:54 +00:00
|
|
|
def _section_id(self, library_name):
|
|
|
|
response = self._request(f"{self.url}/api/v2?apikey={self.apikey}&cmd=get_library_names")
|
2021-01-20 21:37:59 +00:00
|
|
|
section_id = None
|
|
|
|
for entry in response["response"]["data"]:
|
|
|
|
if entry["section_name"] == library_name:
|
|
|
|
section_id = entry["section_id"]
|
|
|
|
break
|
|
|
|
if section_id: return section_id
|
2021-02-24 06:44:06 +00:00
|
|
|
else: raise Failed(f"Tautulli Error: No Library named {library_name} in the response")
|
2021-01-20 21:37:59 +00:00
|
|
|
|
|
|
|
@retry(stop_max_attempt_number=6, wait_fixed=10000)
|
2021-05-07 19:53:54 +00:00
|
|
|
def _request(self, url):
|
2021-02-24 06:44:06 +00:00
|
|
|
logger.debug(f"Tautulli URL: {url.replace(self.apikey, '################################')}")
|
2021-01-20 21:37:59 +00:00
|
|
|
return requests.get(url).json()
|