Merge pull request #270 from blacktwin/last_played

Updating media_manager
This commit is contained in:
blacktwin 2021-03-22 10:41:19 -04:00 committed by GitHub
commit 4a67ece43d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -33,6 +33,7 @@ import re
from collections import Counter from collections import Counter
from plexapi.server import PlexServer from plexapi.server import PlexServer
from plexapi.server import CONFIG from plexapi.server import CONFIG
from plexapi.exceptions import NotFound
from requests import Session from requests import Session
from requests.adapters import HTTPAdapter from requests.adapters import HTTPAdapter
from requests.exceptions import RequestException from requests.exceptions import RequestException
@ -54,7 +55,7 @@ if not TAUTULLI_APIKEY:
VERIFY_SSL = False VERIFY_SSL = False
SELECTOR = ['watched', 'unwatched', 'transcoded', 'rating', 'size'] SELECTOR = ['watched', 'unwatched', 'transcoded', 'rating', 'size', 'lastPlayed']
ACTIONS = ['delete', 'move', 'archive', 'optimize', 'show'] ACTIONS = ['delete', 'move', 'archive', 'optimize', 'show']
OPERATORS = { '>': lambda v, q: v > q, OPERATORS = { '>': lambda v, q: v > q,
'>=': lambda v, q: v >= q, '>=': lambda v, q: v >= q,
@ -231,7 +232,8 @@ class Tautulli(object):
payload = {} payload = {}
return self._call_api('get_libraries', payload) return self._call_api('get_libraries', payload)
def get_library_media_info(self, section_id, start, length, unwatched=None, date=None, order_column=None): def get_library_media_info(self, section_id, start, length, unwatched=None, date=None, order_column=None,
last_played=None):
"""Call Tautulli's get_library_media_info api endpoint.""" """Call Tautulli's get_library_media_info api endpoint."""
payload = {'section_id': section_id} payload = {'section_id': section_id}
if start: if start:
@ -248,6 +250,8 @@ class Tautulli(object):
elif unwatched and date: elif unwatched and date:
return [d for d in library_stats['data'] if d['play_count'] is None return [d for d in library_stats['data'] if d['play_count'] is None
and (float(d['added_at'])) < date] and (float(d['added_at'])) < date]
elif last_played and date:
return [d for d in library_stats['data'] if d['play_count'] is not None]
else: else:
return [d for d in library_stats['data']] return [d for d in library_stats['data']]
@ -298,12 +302,17 @@ def plex_deletion(items, libraries, toggleDeletion):
print("The following items were added before {} and marked for deletion.".format(opts.date)) print("The following items were added before {} and marked for deletion.".format(opts.date))
for item in items: for item in items:
if isinstance(item, int): try:
plex_item = plex.fetchItem(item) if isinstance(item, int):
else: plex_item = plex.fetchItem(item)
plex_item = plex.fetchItem(int(item.rating_key)) elif isinstance(item, str):
plex_item.delete() plex_item = plex.fetchItem(int(item))
print("Item: {} was deleted".format(plex_item.title)) else:
plex_item = plex.fetchItem(int(item.rating_key))
plex_item.delete()
print("Item: {} was deleted".format(plex_item.title))
except NotFound:
print("Item: {} may already have been deleted.".format(item))
for _library in libraries: for _library in libraries:
section = plex.library.sectionByID(_library.key) section = plex.library.sectionByID(_library.key)
print("Emptying Trash from library {}".format(_library.title)) print("Emptying Trash from library {}".format(_library.title))
@ -313,6 +322,42 @@ def plex_deletion(items, libraries, toggleDeletion):
plex._allowMediaDeletion(False) plex._allowMediaDeletion(False)
def last_played_work(sectionID, date=None):
"""
Parameters
----------
sectionID (int): Library key
date (float): Epoch time
Returns
-------
last_played_lst (list): List of Metdata objects of last played items
"""
count = 25
start = 0
last_played_lst = []
while True:
# Getting all watched history
tt_history = tautulli_server.get_library_media_info(section_id=sectionID,
start=start, length=count, last_played=True,
date=date, order_column='last_played')
if all([tt_history]):
start += count
for item in tt_history:
_meta = tautulli_server.get_metadata(item['rating_key'])
metadata = Metadata(_meta)
if (float(item['last_played'])) < date:
metadata.last_played = item['last_played']
last_played_lst.append(metadata)
elif not all([tt_history]):
break
start += count
return last_played_lst
def unwatched_work(sectionID, date=None): def unwatched_work(sectionID, date=None):
""" """
Parameters Parameters
@ -422,6 +467,8 @@ def watched_work(user, sectionID=None, ratingKey=None):
if user.watch.get(metadata.rating_key): if user.watch.get(metadata.rating_key):
user.watch.get(metadata.rating_key).watched_status += 1 user.watch.get(metadata.rating_key).watched_status += 1
else: else:
_meta = tautulli_server.get_metadata(metadata.rating_key)
metadata = Metadata(_meta)
user.watch.update({metadata.rating_key: metadata}) user.watch.update({metadata.rating_key: metadata})
continue continue
@ -479,6 +526,46 @@ def transcode_work(sectionID, operator, value):
return transcoding_lst return transcoding_lst
def action_show(items, selector, date, users=None):
sizes = []
print("{} item(s) have been found.".format(len(items)))
if selector == 'lastPlayed':
print("The following items were last played before {}".format(date))
elif selector == 'watched':
print("The following items were watched by {}".format(", ".join([user.name for user in users])))
elif selector == 'unwatched':
print("The following items were added before {} and are unwatched".format(date))
else:
print("The following items were added before {}".format(date))
for item in items:
try:
if selector == 'watched':
item = users[0].watch[item]
added_at = datetime.datetime.utcfromtimestamp(float(item.added_at)).strftime("%Y-%m-%d")
size = int(item.file_size) if item.file_size else 0
sizes.append(size)
if selector == 'lastPlayed':
last_played = datetime.datetime.utcfromtimestamp(float(item.last_played)).strftime("%Y-%m-%d")
print(u"\t{} added {} and last played {}\tSize: {}\n\t\tFile: {}".format(
item.title, added_at, last_played, sizeof_fmt(size), item.file))
elif selector == 'transcoded':
print(u"\t{} added {}\tSize: {}\tTransocded: {} time(s)\n\t\tFile: {}".format(
item.title, added_at, sizeof_fmt(size), item.transcode_count, item.file))
else:
print(u"\t{} added {}\tSize: {}\n\t\tFile: {}".format(
item.title, added_at, sizeof_fmt(size), item.file))
except TypeError as e:
print("Item: {} caused the following error: {}".format(item.rating_key, e))
total_size = sum(sizes)
print("Total size: {}".format(sizeof_fmt(total_size)))
if __name__ == '__main__': if __name__ == '__main__':
session = Connection().session session = Connection().session
@ -541,15 +628,25 @@ if __name__ == '__main__':
all_sections = [] all_sections = []
watched_lst = [] watched_lst = []
unwatched_lst = [] unwatched_lst = []
last_played_lst = []
size_lst = [] size_lst = []
user_lst = [] user_lst = []
transcode_lst = [] transcode_lst = []
date_format = ''
if opts.date: # Check for days or date format
date = time.mktime(time.strptime(opts.date, "%Y-%m-%d")) if opts.date and opts.date.isdigit():
else: days = datetime.date.today() - datetime.timedelta(int(opts.date))
date = time.mktime(days.timetuple())
elif opts.date is None:
date = None date = None
else:
date = time.mktime(time.strptime(opts.date, "%Y-%m-%d"))
if date:
days = (datetime.datetime.utcnow() - datetime.datetime.fromtimestamp(date))
date_format = time.strftime("%Y-%m-%d", time.localtime(date))
date_format = '{} ({} days)'.format(date_format, days.days)
# Create a Tautulli instance # Create a Tautulli instance
tautulli_server = Tautulli(Connection(url=TAUTULLI_URL.rstrip("/"), tautulli_server = Tautulli(Connection(url=TAUTULLI_URL.rstrip("/"),
apikey=TAUTULLI_APIKEY, apikey=TAUTULLI_APIKEY,
@ -583,16 +680,7 @@ if __name__ == '__main__':
unwatched_lst += unwatched_work(sectionID=_library.key, date=date) unwatched_lst += unwatched_work(sectionID=_library.key, date=date)
if opts.action == "show": if opts.action == "show":
print("The following items were added before {}".format(opts.date)) action_show(unwatched_lst, opts.select, date_format)
sizes = []
for item in unwatched_lst:
added_at = datetime.datetime.utcfromtimestamp(float(item.added_at)).strftime("%Y-%m-%d")
size = int(item.file_size) if item.file_size else ''
sizes.append(size)
print(u"\t{} added {}\tSize: {}\n\t\tFile: {}".format(
item.title, added_at, sizeof_fmt(size), item.file))
total_size = sum(sizes)
print("Total size: {}".format(sizeof_fmt(total_size)))
if opts.action == "delete": if opts.action == "delete":
plex_deletion(unwatched_lst, libraries, opts.toggleDeletion) plex_deletion(unwatched_lst, libraries, opts.toggleDeletion)
@ -600,7 +688,7 @@ if __name__ == '__main__':
if opts.select == "watched": if opts.select == "watched":
if libraries: if libraries:
for user in user_lst: for user in user_lst:
print(("Finding watched items from user: {}",format(user.name))) print("Finding watched items from user: {}".format(user.name))
for _library in libraries: for _library in libraries:
print("Checking library: '{}' watch statuses...".format(_library.title)) print("Checking library: '{}' watch statuses...".format(_library.title))
watched_work(user=user, sectionID=_library.key) watched_work(user=user, sectionID=_library.key)
@ -619,19 +707,28 @@ if __name__ == '__main__':
watched_work(user=user, ratingKey=opts.ratingKey) watched_work(user=user, ratingKey=opts.ratingKey)
# Find all items watched by all users # Find all items watched by all users
all_watched = [key for user in user_lst for key in user.watch.keys()] all_watched = [key for user in user_lst for key in user.watch.keys() if key is not None]
counts = Counter(all_watched) counts = Counter(all_watched)
watched_by_all = [id for id in all_watched if counts[id] >= len(user_lst)] watched_by_all = [id for id in all_watched if counts[id] >= len(user_lst)]
watched_by_all = list(set(watched_by_all)) watched_by_all = list(set(watched_by_all))
if opts.action == "show": if opts.action == "show":
print("The following items were watched by {}".format(", ".join([user.name for user in user_lst]))) action_show(watched_by_all, opts.select, date_format, user_lst)
for watched in watched_by_all:
metadata = user_lst[0].watch[watched]
print(u" {}".format(metadata.full_title))
if opts.action == "delete": if opts.action == "delete":
plex_deletion(watched_by_all, libraries, opts.toggleDeletion) plex_deletion(watched_by_all, libraries, opts.toggleDeletion)
if opts.select == "lastPlayed":
if libraries:
for _library in libraries:
print("Checking library: '{}' watch statuses...".format(_library.title))
last_played_lst += last_played_work(sectionID=_library.key, date=date)
if opts.action == "show":
action_show(last_played_lst, opts.select, date_format)
if opts.action == "delete":
plex_deletion(last_played_lst, libraries, opts.toggleDeletion)
if opts.select in ["size", "rating", "transcoded"]: if opts.select in ["size", "rating", "transcoded"]:
if opts.selectValue: if opts.selectValue:
@ -654,15 +751,7 @@ if __name__ == '__main__':
size_lst += size_work(sectionID=_library.key, operator=op, value=size, episodes=opts.episodes) size_lst += size_work(sectionID=_library.key, operator=op, value=size, episodes=opts.episodes)
if opts.action == "show": if opts.action == "show":
sizes = [] action_show(size_lst, opts.select, opts.date)
for item in size_lst:
added_at = datetime.datetime.utcfromtimestamp(float(item.added_at)).strftime("%Y-%m-%d")
size = int(item.file_size) if item.file_size else 0
sizes.append(size)
print(u"\t{} added {}\tSize: {}\n\t\tFile: {}".format(
item.title, added_at, sizeof_fmt(size), item.file))
total_size = sum(sizes)
print("Total size: {}".format(sizeof_fmt(total_size)))
else: else:
print("Size must end with one of these notations: {}".format(", ".join(UNTIS.keys()))) print("Size must end with one of these notations: {}".format(", ".join(UNTIS.keys())))
pass pass
@ -677,10 +766,5 @@ if __name__ == '__main__':
transcode_lst += transcoded_lst transcode_lst += transcoded_lst
if opts.action == "show": if opts.action == "show":
print("{} item(s) have been found.".format(len(transcode_lst))) action_show(transcode_lst, opts.select, date_format)
for item in transcode_lst:
added_at = datetime.datetime.utcfromtimestamp(float(item.added_at)).strftime("%Y-%m-%d")
size = int(item.file_size) if item.file_size else 0
file_size = sizeof_fmt(size)
print(u"\t{} added {}\tSize: {}\tTransocded: {} time(s)\n\t\tFile: {}".format(
item.title, added_at, file_size, item.transcode_count, item.file))