From 88445f508f9d5a7f4357c7e2d549b4ab35eadf4f Mon Sep 17 00:00:00 2001 From: Tristan Williams Date: Sun, 30 Mar 2025 19:02:05 -0400 Subject: Conform to PEP 8 conventions --- sortashuffle.py | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 97 insertions(+), 11 deletions(-) diff --git a/sortashuffle.py b/sortashuffle.py index ea03ff7..1bb7047 100644 --- a/sortashuffle.py +++ b/sortashuffle.py @@ -1,7 +1,9 @@ #!/usr/bin/env python3 - # sortashuffle.py -# Shuffles shows but keeps episodes in order. + +# REQUIREMENTS +# - Must be run as administrator on Windows +# - All episodes of each show must be in one folder; no season folders! # USAGE # 0. Copy this script to the playlist folder @@ -16,28 +18,87 @@ import os import random + # Must be in format "C://Dir1//Dir2" -TARGET = "" +TARGET = "" SOURCES = ["", ""] + def collect_showlist(sources): - """Returns a list of lists. - Each sub-list represents a show, and elements represent episodes.""" + """Collect show dirs and associated episodes in a nested list. + + Parameters: + sources (list of str): List of paths to scan for episodes. + Each path should represent a distinct show, with all + episodes in one flat directory. + + Returns: + list of list of str: Nested list structure where: + - each sub-list represents a show. + - elements of sub-lists represent episodes. + + Notes: + - Episode filenames are returned in arbitrary filesystem order. + - No filtering is performed. All files are included. + - Does not perform recursive directory scanning + """ return [[f for f in os.listdir(source)] for source in sources] + def calculate_weights(showlist): - """Calculate the weights for each show; # of remaining episodes""" + """Calculate the weights to be used for selecting a show at random. + + The number of episodes is used as the weight because shows with more + episodes need to be selected more often in order to maintain an even + spread of each show across the whole playlist. + + Parameters: + showlist (list of list of str): Nested list structure where: + - each sub-list represents a show. + - elements of sub-lists represent episodes. + + Returns: + list of int: List where: + - each element corresponds to a show in `showlist' + - each element represents the remaining number of episodes. + """ return [len(show) for show in showlist] + def select_show(showlist, weightlist): - """Select a show, accounting weight.""" + """Select a show at random, accounting for weight. + + Parameters: + showlist (list of list of str): Nested list structure where: + - each sub-list represents a show. + - elements of sub-lists represent episodes. + weightlist (list of int): List where: + - each element corresponds to a show in `showlist' + - each element represents the remaining number of episodes. + + Returns: + int: The list index of a show in the showlist. + """ return random.choices(range(len(showlist)), weights=weightlist, k=1)[0] + def shuffle(showlist, weightlist): - """Shuffle the playlist.""" + """Shuffle the playlist. + + Parameters: + showlist (list of list of str): Nested list structure where: + - each sub-list represents a show. + - elements of sub-lists represent episodes. + weightlist (list of int): List where: + - each element corresponds to a show in `showlist' + - each element represents the remaining number of episodes. + + Returns: + shuffled (list of str): Flat list of shuffled episodes. + """ shuffled = [] while any(showlist): selection = select_show(showlist, weightlist) @@ -45,22 +106,46 @@ def shuffle(showlist, weightlist): weightlist[selection] = len(showlist[selection]) return shuffled + def deploy_symlinks(shuffled): - """Deploy episode symlinks.""" + """Deploy episode symlinks. + + Creates a symlink for each episode in `shuffled'. + Uses the `count' in the for loop as filename to keep shuffled order. + + Parameters: + shuffled (list of str): Flat list of shuffled episodes. + + Returns: + count (int): The number of symlinks deployed. + """ count = 0 for episode in shuffled: os.symlink(episode, TARGET + "//" + str(count)) count += 1 return count + def deploy_index(shuffled): - """Deploy playlist index.""" + """Deploy playlist index. + + Create a file namned _PLAYLIST_INDEX.txt containing the shuffled + list of episodes. + + Parameters: + shuffled (list): Flat list of shuffled episodes. + + Returns: + index (str): Full path and filename of _PLAYLIST_INDEX.txt. + """ index = open(TARGET + "//" + "_PLAYLIST_INDEX.txt", 'w', encoding='utf-8') index.write("\n".join(shuffled)) index.close() return index + def main(): + """Shuffle shows but keeps episodes in order.""" SHOWLIST = collect_showlist(SOURCES) WEIGHTLIST = calculate_weights(SHOWLIST) SHUFFLED = shuffle(SHOWLIST, WEIGHTLIST) @@ -68,5 +153,6 @@ def main(): deploy_index(SHUFFLED) return 0 -if __name__=="__main__": + +if __name__ == "__main__": main() -- cgit v1.2.3