initial work on size and rating

focusing on size
This commit is contained in:
blacktwin 2020-05-11 01:00:53 -04:00
parent fe490699f9
commit 87b82a5947

View File

@ -24,6 +24,7 @@ Enabling Scripts in Tautulli:
import argparse import argparse
import datetime import datetime
import time import time
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
@ -50,7 +51,12 @@ VERIFY_SSL = False
SELECTOR = ['watched', 'unwatched', 'transcoded', 'rating', 'size'] SELECTOR = ['watched', 'unwatched', 'transcoded', 'rating', 'size']
ACTIONS = ['delete', 'move', 'archive', 'optimize', 'show'] ACTIONS = ['delete', 'move', 'archive', 'optimize', 'show']
OPERATORS = ['>', '>=', '<', '<=', '==', '!='] OPERATORS = { '>': lambda v, q: v > q,
'>=': lambda v, q: v >= q,
'<': lambda v, q: v < q,
'<=': lambda v, q: v <= q,}
UNTIS = {"B": 1, "KB": 2**10, "MB": 2**20, "GB": 2**30, "TB": 2**40}
MOVEPATH = '' MOVEPATH = ''
ARCHIVEPATH = '' ARCHIVEPATH = ''
@ -126,8 +132,8 @@ class Metadata(object):
show = plex.fetchItem(int(self.rating_key)) show = plex.fetchItem(int(self.rating_key))
self.file = show.locations[0] self.file = show.locations[0]
show_size = [] show_size = []
episodes = show.episodes() self.episodes = show.episodes()
for episode in episodes: for episode in self.episodes:
show_size.append(episode.media[0].parts[0].size) show_size.append(episode.media[0].parts[0].size)
self.file_size = sum(show_size) self.file_size = sum(show_size)
@ -208,13 +214,16 @@ class Tautulli:
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): def get_library_media_info(self, section_id, start, length, unwatched=None, date=None, order_column=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:
payload["start"] = start payload["start"] = start
if length: if length:
payload["lengh"] = length payload["lengh"] = length
if order_column:
payload["order_column"] = order_column
payload['order_dir'] = 'desc'
library_stats = self._call_api('get_library_media_info', payload) library_stats = self._call_api('get_library_media_info', payload)
if unwatched and not date: if unwatched and not date:
@ -222,8 +231,10 @@ class Tautulli:
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]
else:
return [d for d in library_stats['data']]
def sizeof_fmt(num, suffix='B'): def sizeof_fmt(num, suffix='B'):
# Function found https://stackoverflow.com/a/1094933 # Function found https://stackoverflow.com/a/1094933
for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']: for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
@ -233,6 +244,14 @@ def sizeof_fmt(num, suffix='B'):
return "%.1f%s%s" % (num, 'Yi', suffix) return "%.1f%s%s" % (num, 'Yi', suffix)
def parseSize(size):
size = size.upper()
if not re.match(r' ', size):
size = re.sub(r'([KMGT]?B)', r' \1', size)
number, unit = [string.strip() for string in size.split()]
return int(float(number)*UNTIS[unit])
def plex_deletion(items, libraries, toggleDeletion): def plex_deletion(items, libraries, toggleDeletion):
""" """
Parameters Parameters
@ -303,6 +322,47 @@ def unwatched_work(sectionID, date=None):
return unwatched_lst return unwatched_lst
def size_work(sectionID, operator, value, episodes):
"""
Parameters
----------
sectionID (int): Library key
date (float): Epoch time
Returns
-------
unwatched_lst (list): List of Metdata objects of unwatched items
"""
count = 25
start = 0
size_lst = []
while True:
# Getting all watched history for userFrom
tt_size = tautulli_server.get_library_media_info(section_id=sectionID,
start=start, length=count,
order_column="file_size")
start += count
for item in tt_size:
_meta = tautulli_server.get_metadata(item['rating_key'])
metadata = Metadata(_meta)
if episodes:
for _episode in metadata.episodes:
file_size = _episode.media[0].parts[0].size
if operator(file_size, value):
size_lst.append(_episode)
else:
file_size = int(metadata.file_size)
if operator(file_size, value):
size_lst.append(metadata)
else:
return size_lst
continue
def watched_work(user, sectionID=None, ratingKey=None): def watched_work(user, sectionID=None, ratingKey=None):
""" """
Parameters Parameters
@ -389,6 +449,7 @@ if __name__ == '__main__':
opts = parser.parse_args() opts = parser.parse_args()
# todo find: watched by list of users[x], unwatched based on time[x], based on size, most transcoded, star rating # todo find: watched by list of users[x], unwatched based on time[x], based on size, most transcoded, star rating
# todo find: all selectors should be able to search by user, library, and/or time
# todo actions: delete[x], move?, zip and move?, notify, optimize # todo actions: delete[x], move?, zip and move?, notify, optimize
# todo deletion toggle and optimize is dependent on plexapi PRs 433 and 426 respectively # todo deletion toggle and optimize is dependent on plexapi PRs 433 and 426 respectively
# todo logging and notification # todo logging and notification
@ -397,6 +458,7 @@ if __name__ == '__main__':
all_sections = [] all_sections = []
watched_lst = [] watched_lst = []
unwatched_lst = [] unwatched_lst = []
size_lst = []
user_lst = [] user_lst = []
if opts.date: if opts.date:
@ -447,7 +509,7 @@ if __name__ == '__main__':
item.title, added_at, sizeof_fmt(size), item.file)) item.title, added_at, sizeof_fmt(size), item.file))
total_size = sum(sizes) total_size = sum(sizes)
print("Total size: {}".format(sizeof_fmt(total_size))) 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)
@ -483,3 +545,39 @@ if __name__ == '__main__':
for watched in watched_by_all: for watched in watched_by_all:
metadata = user_lst[0].watch[watched] metadata = user_lst[0].watch[watched]
print(u" {}".format(metadata.full_title)) print(u" {}".format(metadata.full_title))
if opts.select in ["size", "rating"]:
if opts.selectValue:
operator, value = opts.selectValue
if operator not in OPERATORS.keys():
print("Operator not found")
exit()
else:
print("No value provided.")
exit()
op = OPERATORS.get(operator)
if opts.select == "size":
if value[-2:] in UNTIS.keys():
size = parseSize(value)
if libraries:
for _library in libraries:
print("Checking library: '{}' items {}{} in size...".format(_library.title, operator, value))
size_lst += size_work(sectionID=_library.key, operator=op, value=size, episodes=opts.episodes)
if opts.action == "show":
sizes = []
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 ''
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:
print("Size must end with one of these notations: {}".format(", ".join(UNTIS.keys())))
pass
elif opts.select == "rating":
pass