Clean up menu system UX

This commit is contained in:
Brian Lee 2025-01-26 08:34:07 -08:00
parent ff6e2e4968
commit 3b514c46a9
2 changed files with 114 additions and 57 deletions

View File

@ -46,45 +46,59 @@ def saberlist() -> None:
Generate a playlist of songs using a specified strategy. Generate a playlist of songs using a specified strategy.
Avoids reusing the same song+difficulty in a playlist based on history. Avoids reusing the same song+difficulty in a playlist based on history.
""" """
strategy = get_strategy() args = parse_args_subcommands()
strategy = args.subcommand
# If the user requested a reset, do that before anything else
if getattr(args, 'reset', False):
reset_history(strategy)
sys.exit(0)
# Then call the strategy-based logic
if strategy == 'scoresaber_oldscores': if strategy == 'scoresaber_oldscores':
playlist_data, playlist_title = playlist_strategy_scoresaber_oldscores(ScoreSaberAPI(cache_expiry_days=CACHE_EXPIRY_DAYS)) playlist_data, playlist_title = playlist_strategy_scoresaber_oldscores(
ScoreSaberAPI(cache_expiry_days=CACHE_EXPIRY_DAYS)
)
playlist_builder = PlaylistBuilder() playlist_builder = PlaylistBuilder()
elif strategy == 'beatleader_oldscores': elif strategy == 'beatleader_oldscores':
playlist_data, playlist_title = playlist_strategy_beatleader_oldscores(BeatLeaderAPI(cache_expiry_days=CACHE_EXPIRY_DAYS)) playlist_data, playlist_title = playlist_strategy_beatleader_oldscores(
BeatLeaderAPI(cache_expiry_days=CACHE_EXPIRY_DAYS)
)
playlist_builder = PlaylistBuilder() playlist_builder = PlaylistBuilder()
elif strategy == 'beatsaver_acc':
playlist_data, playlist_title = playlist_strategy_beatsaver_acc()
playlist_builder = PlaylistBuilder(covers_dir='./covers/beatsavers')
elif strategy == 'beatleader_lowest_pp':
playlist_data, playlist_title = playlist_strategy_beatleader_lowest_pp(BeatLeaderAPI(cache_expiry_days=CACHE_EXPIRY_DAYS))
playlist_builder = PlaylistBuilder(covers_dir='./covers/pajamas')
elif strategy == 'scoresaber_lowest_pp':
playlist_data, playlist_title = playlist_strategy_scoresaber_lowest_pp(ScoreSaberAPI(cache_expiry_days=CACHE_EXPIRY_DAYS))
playlist_builder = PlaylistBuilder(covers_dir='./covers/scoresaber')
elif strategy == 'beatleader_lowest_acc':
playlist_data, playlist_title = playlist_strategy_beatleader_lowest_acc(BeatLeaderAPI(cache_expiry_days=CACHE_EXPIRY_DAYS))
playlist_builder = PlaylistBuilder(covers_dir='./covers/kaiju')
elif strategy == 'beatleader_accuracy_gaps': elif strategy == 'beatleader_accuracy_gaps':
playlist_data, playlist_title = playlist_strategy_beatleader_accuracy_gaps(SimpleBeatLeaderAPI(cache_expiry_days=CACHE_EXPIRY_DAYS)) playlist_data, playlist_title = playlist_strategy_beatleader_accuracy_gaps(
SimpleBeatLeaderAPI(cache_expiry_days=CACHE_EXPIRY_DAYS)
)
playlist_builder = PlaylistBuilder(covers_dir='./covers/pajamas') playlist_builder = PlaylistBuilder(covers_dir='./covers/pajamas')
elif strategy == 'beatleader_accuracy_gaps_star_range': elif strategy == 'beatleader_accuracy_gaps_star_range':
input_star_level = input("Enter star level (Default: 6)") or 6 playlist_data, playlist_title = playlist_strategy_beatleader_accuracy_gaps_star_range(
playlist_data, playlist_title = playlist_strategy_beatleader_accuracy_gaps_star_range(SimpleBeatLeaderAPI(cache_expiry_days=CACHE_EXPIRY_DAYS), star_level=float(input_star_level)) SimpleBeatLeaderAPI(cache_expiry_days=CACHE_EXPIRY_DAYS),
star_level=args.star_level
)
playlist_builder = PlaylistBuilder(covers_dir='./covers/pajamas') playlist_builder = PlaylistBuilder(covers_dir='./covers/pajamas')
elif strategy == 'scoresaber_accuracy_gaps': elif strategy == 'scoresaber_accuracy_gaps':
playlist_data, playlist_title = playlist_strategy_scoresaber_accuracy_gaps(ScoreSaberAPI(cache_expiry_days=CACHE_EXPIRY_DAYS)) playlist_data, playlist_title = playlist_strategy_scoresaber_accuracy_gaps(
ScoreSaberAPI(cache_expiry_days=CACHE_EXPIRY_DAYS)
)
playlist_builder = PlaylistBuilder(covers_dir='./covers/scoresaber') playlist_builder = PlaylistBuilder(covers_dir='./covers/scoresaber')
elif strategy == 'beatsaver_curated': elif strategy == 'beatsaver_curated':
playlist_data, playlist_title = playlist_strategy_beatsaver_curated(SimpleBeatSaverAPI()) playlist_data, playlist_title = playlist_strategy_beatsaver_curated(SimpleBeatSaverAPI())
playlist_builder = PlaylistBuilder(covers_dir='./covers/curated') playlist_builder = PlaylistBuilder(covers_dir='./covers/curated')
elif strategy == 'beatsaver_mappers': elif strategy == 'beatsaver_mappers':
playlist_data, playlist_title = playlist_strategy_beatsaver_mappers(SimpleBeatSaverAPI()) playlist_data, playlist_title = playlist_strategy_beatsaver_mappers(SimpleBeatSaverAPI())
playlist_builder = PlaylistBuilder(covers_dir='./covers/pajamas') playlist_builder = PlaylistBuilder(covers_dir='./covers/pajamas')
elif strategy == 'blank_playlist': elif strategy == 'blank_playlist':
playlist_data, playlist_title = [], input("Enter playlist title: ") playlist_data = []
playlist_title = input("Enter playlist title: ")
playlist_builder = PlaylistBuilder(covers_dir='./covers/pajamas') playlist_builder = PlaylistBuilder(covers_dir='./covers/pajamas')
else: else:
logging.error(f"Unknown strategy '{strategy}'") logging.error(f"Unknown strategy '{strategy}'")
return return
@ -99,41 +113,82 @@ def saberlist() -> None:
playlist_author="SaberList Tool" playlist_author="SaberList Tool"
) )
def get_strategy(): def parse_args_subcommands():
parser = argparse.ArgumentParser(description="Generate Beat Saber playlists") """
parser.add_argument("-s", "--strategy", Parse sub-commands for each strategy instead of using a single `-s/--strategy`.
choices=[ """
"scoresaber_oldscores", parser = argparse.ArgumentParser(
"beatleader_oldscores", description="Generate Beat Saber playlists"
# "beatsaver_acc", )
# "beatleader_lowest_pp",
# "scoresaber_lowest_pp", subparsers = parser.add_subparsers(
# "beatleader_lowest_acc", title="Available Strategies",
"beatleader_accuracy_gaps", dest="subcommand",
"beatleader_accuracy_gaps_star_range", help="Choose which sub-command (strategy) to run"
"scoresaber_accuracy_gaps", )
"beatsaver_curated",
"beatsaver_mappers", # 1) -------- scoresaber_oldscores --------
"blank_playlist" parser_ss_old = subparsers.add_parser("scoresaber_oldscores",
], help="Generate a playlist using ScoreSaber old-scores strategy")
help="Specify the playlist generation strategy") parser_ss_old.add_argument("-r", "--reset",
parser.add_argument("-r", "--reset", action="store_true",
action="store_true", help="Reset the history for scoresaber_oldscores")
help="Reset the history for the specified strategy")
# 2) -------- beatleader_oldscores --------
parser_bl_old = subparsers.add_parser("beatleader_oldscores",
help="Generate a playlist using BeatLeader old-scores strategy")
parser_bl_old.add_argument("-r", "--reset",
action="store_true",
help="Reset the history for beatleader_oldscores")
# 3) -------- beatleader_accuracy_gaps --------
parser_bl_acc_gaps = subparsers.add_parser("beatleader_accuracy_gaps",
help="Generate a playlist using BeatLeader accuracy gaps strategy")
parser_bl_acc_gaps.add_argument("-r", "--reset",
action="store_true",
help="Reset the history for beatleader_accuracy_gaps")
# 4) -------- beatleader_accuracy_gaps_star_range --------
parser_bl_acc_stars = subparsers.add_parser("beatleader_accuracy_gaps_star_range",
help="Generate a playlist for accuracy gaps within a star range (BeatLeader)")
parser_bl_acc_stars.add_argument("-r", "--reset",
action="store_true",
help="Reset the history for beatleader_accuracy_gaps_star_range")
parser_bl_acc_stars.add_argument("--star-level",
type=float,
help="Star level to filter on")
# 5) -------- scoresaber_accuracy_gaps --------
parser_ss_acc_gaps = subparsers.add_parser("scoresaber_accuracy_gaps",
help="Generate a playlist using ScoreSaber accuracy gap strategy")
parser_ss_acc_gaps.add_argument("-r", "--reset",
action="store_true",
help="Reset the history for scoresaber_accuracy_gaps")
# 6) -------- beatsaver_curated --------
parser_bs_curated = subparsers.add_parser("beatsaver_curated",
help="Generate a curated BeatSaver playlist")
parser_bs_curated.add_argument("-r", "--reset",
action="store_true",
help="Reset the history for beatsaver_curated")
# 7) -------- beatsaver_mappers --------
parser_bs_mappers = subparsers.add_parser("beatsaver_mappers",
help="Generate a playlist for specified BeatSaver mappers")
parser_bs_mappers.add_argument("-r", "--reset",
action="store_true",
help="Reset the history for beatsaver_mappers")
# 8) -------- blank_playlist --------
parser_blank = subparsers.add_parser("blank_playlist",
help="Generate a blank playlist (no songs, just a descriptor)")
parser_blank.add_argument("-r", "--reset",
action="store_true",
help="Reset the history for blank_playlist (usually unnecessary)")
# If no arguments passed, print help
if len(sys.argv) == 1: if len(sys.argv) == 1:
parser.print_help() parser.print_help(sys.stderr)
sys.exit(1) sys.exit(1)
args = parser.parse_args() return parser.parse_args()
if args.reset:
if not args.strategy:
parser.error("--reset requires --strategy to be specified")
reset_history(args.strategy)
sys.exit(0)
if not args.strategy:
parser.error("--strategy is required unless --reset is used")
return args.strategy

View File

@ -417,7 +417,9 @@ def playlist_strategy_beatleader_accuracy_gaps_star_range(
history.setdefault('beatleader_accuracy_gaps_star_range', {}) history.setdefault('beatleader_accuracy_gaps_star_range', {})
history.setdefault('playlist_counts', {}) history.setdefault('playlist_counts', {})
# Validate star_level if not star_level:
input_star_level = input("Enter star level (Default: 6): ") or 6
star_level = float(input_star_level)
if not isinstance(star_level, (int, float)) or star_level < 0: if not isinstance(star_level, (int, float)) or star_level < 0:
logging.error("Invalid star_level provided. It must be a non-negative number.") logging.error("Invalid star_level provided. It must be a non-negative number.")
return [], "" return [], ""