3333from .clustering_helper import (
3434 _get_stratified_song_subset ,
3535 get_job_result_safely ,
36- _perform_single_clustering_iteration
36+ _perform_single_clustering_iteration ,
37+ _shuffle_playlist_songs ,
38+ _assign_playlist_chunks ,
39+ _try_ai_name_playlist ,
3740)
3841# Import post-processing functions from dedicated module
3942from .clustering_postprocessing import (
@@ -910,37 +913,29 @@ def _name_and_prepare_playlists(best_result, ai_provider, ollama_url, ollama_mod
910913 Returns a dictionary mapping final playlist names to lists of song tuples (id, title, author).
911914 """
912915 final_playlists = {}
913- centroids = best_result .get ("playlist_centroids" , {})
914916 named_playlists = best_result .get ("named_playlists" , {})
915917 max_songs = best_result .get ("parameters" , {}).get ("max_songs_per_cluster" , MAX_SONGS_PER_CLUSTER )
916918
917919 for original_name , songs in named_playlists .items ():
918920 if not songs :
919921 continue
920922
921- final_name = original_name
922- if ai_provider in ["OLLAMA" , "OPENAI" , "GEMINI" , "MISTRAL" ]:
923+ if ai_provider in ("OLLAMA" , "OPENAI" , "GEMINI" , "MISTRAL" ):
923924 try :
924-
925- ai_config = {
926- 'provider' : ai_provider ,
927- 'ollama_url' : ollama_url , 'ollama_model' : ollama_model ,
928- 'openai_url' : openai_url , 'openai_model' : openai_model , 'openai_key' : openai_key ,
929- 'gemini_key' : gemini_key , 'gemini_model' : gemini_model ,
930- 'mistral_key' : mistral_key , 'mistral_model' : mistral_model ,
931- }
932- ai_name = get_ai_playlist_name (
933- creative_prompt_template ,
934- [{'title' : s_title , 'author' : s_author } for _ , s_title , s_author in songs ],
935- centroids .get (original_name , {}),
936- ai_config ,
925+ final_name = _try_ai_name_playlist (
926+ original_name , songs ,
927+ best_result .get ("playlist_centroids" , {}),
928+ ai_provider ,
929+ ollama_url , ollama_model ,
930+ openai_url , openai_model , openai_key ,
931+ gemini_key , gemini_model ,
932+ mistral_key , mistral_model ,
937933 )
938- if ai_name and "Error" not in ai_name :
939- final_name = ai_name .strip ().replace ("\n " , " " )
940- else :
941- logger .warning (f"AI naming failed for '{ original_name } ': { ai_name } . Using original name." )
942934 except Exception as e :
943935 logger .warning (f"AI naming failed for '{ original_name } ': { e } . Using original name." )
936+ final_name = original_name
937+ else :
938+ final_name = original_name
944939
945940 # Ensure unique names
946941 temp_name = final_name
@@ -950,34 +945,9 @@ def _name_and_prepare_playlists(best_result, ai_provider, ollama_url, ollama_mod
950945 temp_name = f"{ final_name } ({ suffix } )"
951946 final_name = temp_name
952947
953- # Add suffix and handle chunking
954- base_name_with_suffix = f"{ final_name } _automatic"
955-
956- # The 'songs' variable is already the list of tuples: [(item_id, title, author), ...]
957- # *** FINAL SAFETY SHUFFLE: Ensure songs are randomized in final playlists ***
958- final_songs = songs .copy ()
959- n = len (final_songs )
960-
961- if n > 1 :
962- # FISHER-YATES MANUAL SHUFFLE - GUARANTEED TO RANDOMIZE
963- current_time_seed = int (time .time () * 1000000 ) % 1000000
964-
965- for i in range (n - 1 , 0 , - 1 ):
966- j = (random .randint (0 , i ) + current_time_seed + i * 7 ) % (i + 1 )
967- final_songs [i ], final_songs [j ] = final_songs [j ], final_songs [i ]
968- current_time_seed = (current_time_seed * 1103515245 + 12345 ) % (2 ** 31 )
969-
970- logger .info (f"FINAL FISHER-YATES SHUFFLE applied to '{ base_name_with_suffix } ': { len (final_songs )} songs" )
971- logger .info (f"FINAL ORDER: First song = '{ final_songs [0 ][1 ]} ', Last song = '{ final_songs [- 1 ][1 ]} '" )
972- else :
973- logger .info (f"FINAL: '{ base_name_with_suffix } ' has only { n } songs - no shuffling needed" )
974-
975- if max_songs > 0 and len (final_songs ) > max_songs :
976- chunks = [final_songs [i :i + max_songs ] for i in range (0 , len (final_songs ), max_songs )]
977- for idx , chunk in enumerate (chunks , 1 ):
978- final_playlists [f"{ base_name_with_suffix } ({ idx } )" ] = chunk # Store the chunk of tuples
979- else :
980- final_playlists [base_name_with_suffix ] = final_songs # Store the list of tuples
948+ base_name = f"{ final_name } _automatic"
949+ shuffled = _shuffle_playlist_songs (songs , base_name )
950+ _assign_playlist_chunks (shuffled , max_songs , base_name , final_playlists )
981951
982952 return final_playlists
983953
0 commit comments