diff --git a/make_folders.py b/make_folders.py index 2af0416..191b0fc 100755 --- a/make_folders.py +++ b/make_folders.py @@ -85,72 +85,62 @@ def search_google_images_and_save(x: str, audio): audio.save(x) found_image = False + # Try album art search first if (check_tag(audio, x, "TALB","album")): - # search for artist and album if x.endswith(".flac"): songpath = join(".",str(audio["artist"]),str(audio["album"])) else: - # Use TPE2 if available, otherwise fallback to TPE1 artist_folder = str(audio.get("TPE2", audio.get("TPE1", "Unknown Artist"))) songpath = join(".", artist_folder, str(audio["TALB"])) if "\x00" in songpath: - # having null bytes in os.replace will throw an error songpath = songpath.replace("\x00",", ") make_folder(songpath) os.replace(join(".",x),join(songpath,x)) - google_keyword = "" if x.endswith(".flac"): - google_keyword = str(audio.get("artist", "Unknown Artist")) + " " + str(audio.get("album", "Unknown Album")) + " album" + artist_val = str(audio.get("artist", "Unknown Artist")) + album_val = str(audio.get("album", "Unknown Album")) else: artist_val = str(audio.get("TPE2", audio.get("TPE1", "Unknown Artist"))) album_val = str(audio.get("TALB", "Unknown Album")) - google_keyword = artist_val + " " + album_val + " album" + google_keyword = artist_val + " " + album_val + " album" logging.info("Moved file! Now searching for album art... keyword is " + google_keyword) google_Crawler = GoogleImageCrawler(storage = {'root_dir': songpath}) try: - google_Crawler.crawl(keyword = google_keyword, max_num = 1) + result = google_Crawler.crawl(keyword = google_keyword, max_num = 1) found_image = True - except: - logging.info("could not find Google result by album, searching by track and artist") - if (found_image): - logging.info("changing name of cover art file...") - logging.info(songpath) - for f in listdir(songpath): - logging.info(f) - if (isfile(join(songpath,f)) and f.split(".")[-1].lower() in ["jpg","png"]): - os.replace(join(songpath,f),join(songpath,"Cover." + f.split(".")[-1].lower())) - logging.info("Done!") - #TODO search for song name and artist if album not found on google images - # else: - # songpath = join(".",str(audio["TPE1"]),str(audio["TIT2"])) - # make_folder(songpath) - # os.replace(join(".",x),join(songpath,x)) - # logging.info("Moved file! Now searching for album art... keyword is " + str(audio["TPE1"]) + " " + str(audio["TIT2"])) - # google_Crawler = GoogleImageCrawler(storage = {'root_dir': songpath}) - - + except Exception as e: + logging.info(f"could not find Google result by album, searching by track and artist: {e}") + # Fallback: if no image found, try searching by song and artist + if not found_image or not any(f.split('.')[-1].lower() in ["jpg","png"] for f in listdir(songpath)): + song_keyword = artist_val + " " + str(audio.get("TIT2", "")) + logging.info("Fallback: searching for song art... keyword is " + song_keyword) + try: + google_Crawler.crawl(keyword = song_keyword, max_num = 1) + found_image = True + except Exception as e: + logging.info(f"could not find Google result by song: {e}") + # Rename cover art file if found + for f in listdir(songpath): + if (isfile(join(songpath,f)) and f.split(".")[-1].lower() in ["jpg","png"]): + os.replace(join(songpath,f),join(songpath,"Cover." + f.split(".")[-1].lower())) + logging.info("Done!") else: # search for song name and artist - # search for artist and album - # use TPE2 (album artist), because we want to find the album - songpath = join(".",str(audio["TPE2"]),str(audio["TIT2"])) + songpath = join(".",str(audio.get("TPE2", "Unknown Artist")),str(audio.get("TIT2", "Unknown Title"))) make_folder(songpath) os.replace(join(".",x),join(songpath,x)) - logging.info("Moved file! Now searching for album art... keyword is " + str(audio["TPE2"]) + " " + str(audio["TIT2"])) + song_keyword = str(audio.get("TPE2", "Unknown Artist")) + " " + str(audio.get("TIT2", "Unknown Title")) + logging.info("Moved file! Now searching for album art... keyword is " + song_keyword) google_Crawler = GoogleImageCrawler(storage = {'root_dir': songpath}) try: - google_Crawler.crawl(keyword = str(audio["TPE2"]) + " " + str(audio["TIT2"]), max_num = 1) + google_Crawler.crawl(keyword = song_keyword, max_num = 1) found_image = True - except: - logging.info("could not find Google result by track and artist") - if (found_image): - logging.info("changing name of cover art file...") - logging.info(songpath) - for f in listdir(songpath): - logging.info(f) - if (isfile(join(songpath,f)) and f.split(".")[-1].lower() in ["jpg","png"]): - os.replace(join(songpath,f),join(songpath,"Cover." + f.split(".")[-1].lower())) - logging.info("Done!") + except Exception as e: + logging.info(f"could not find Google result by track and artist: {e}") + for f in listdir(songpath): + if (isfile(join(songpath,f)) and f.split(".")[-1].lower() in ["jpg","png"]): + os.replace(join(songpath,f),join(songpath,"Cover." + f.split(".")[-1].lower())) + logging.info("Done!") # TIT2 = title, # TPE1 = artist, @@ -236,25 +226,21 @@ def check_title_songname(x: str, audio): logging.info("Detected ' - Topic - ' in name, removing 'Topic'.") # Rebuild items without 'Topic' items = [items[0]] + items[2:] - if (len(items) > 2): - logging.info("song title has more than 1 part after the -: " + str(items)) - if (items[1].count(".mp3") >= 1): - logging.info("setting TIT2 tag to: " + str(items[1].strip().rstrip().rsplit(".")[0])) # get second part of title and remove the file extension - audio["TIT2"] = TIT2(encoding=3,text=str(items[1].strip().rstrip().rsplit(".")[0])) - elif (items[1].count(".flac") >= 1): - logging.info("setting title tag to " + str(items[1].strip().rstrip().rsplit(".")[0])) # get second part of title and remove the file extension - audio["title"] = str(items[1].strip().rstrip().rsplit(".")[0]) - else: - logging.info("title: " + str(items[1].strip().rstrip())) # get second part of title and remove the file extension - audio["TIT2"] = TIT2(encoding=3,text=str(items[1].strip().rstrip())) - audio["title"] = TIT2(encoding=3,text=str(items[1].strip().rstrip())) + # Set artist and title tags robustly + if len(items) == 2: + artist, title = items[0].strip(), items[1].strip() + elif len(items) > 2: + artist, title = items[0].strip(), items[1].strip() else: - logging.info("song title has only 1 part after the -: " + items[1]) - if ("TIT2" not in audio.keys()): - song_title = items[1].strip().rstrip() - logging.info("TIT2 tag not found, creating it. Using song title: " + song_title) - audio["TIT2"] = TIT2(encoding=3,text=song_title) - audio["title"] = TIT2(encoding=3,text=song_title) + artist, title = x.strip(), x.strip() + # Set both TPE1 (song artist) and TPE2 (album artist) + audio["TPE1"] = TPE1(encoding=3, text=artist) + audio["TPE2"] = TPE2(encoding=3, text=artist) + audio["artist"] = artist + # Set title tags + audio["TIT2"] = TIT2(encoding=3, text=title) + audio["title"] = title + logging.info(f"Set artist: {artist}, title: {title}") else: logging.info("no - found in title, setting full name as title: " + x) if ("TIT2" not in audio.keys()): @@ -295,15 +281,16 @@ def check_for_multiple_artists(audio, filename: str, name: str): def check_artist_songname(x: str, audio): items = x.split(" - ") logging.info("Checking artist by name. items: " + str(items)) - if (len(items) > 2): - check_for_multiple_artists(audio, x, items[0].strip()) - - else: # no multiple artists in name - logging.info("Setting artist tags TPE1 and TPE2 to " + str(items[0].strip().rstrip())) - - audio["TPE1"] = TPE1(encoding=3,text=str(items[0].strip().rstrip())) - audio["TPE2"] = TPE2(encoding=3,text=str(items[0].strip().rstrip())) - audio["artist"] = audio["TPE1"] + # Remove 'Topic' if present + if len(items) > 2 and items[1].strip().lower() == "topic": + logging.info("Detected ' - Topic - ' in name, removing 'Topic'.") + items = [items[0]] + items[2:] + artist = items[0].strip() + # Set both TPE1 (song artist) and TPE2 (album artist) + audio["TPE1"] = TPE1(encoding=3, text=artist) + audio["TPE2"] = TPE2(encoding=3, text=artist) + audio["artist"] = artist + logging.info(f"Set artist tags TPE1 and TPE2 to {artist}") def check_artist(audio, filename: str) -> bool: res = False @@ -682,6 +669,19 @@ def check_spotify_and_save(spotify, audio,x: str) -> bool: return found def main(): + # Preprocess: rename files with '- Topic -' in the name to 'artist - title' + for fname in [f for f in listdir(".") if isfile(join(".",f)) and "- Topic -" in f]: + parts = fname.rsplit("- Topic -", 1) + if len(parts) == 2: + artist = parts[0].strip().rstrip("- ") + title = parts[1].rsplit('.', 1)[0].strip() + ext = fname.rsplit('.', 1)[-1] + new_name = f"{artist} - {title}.{ext}" + if not os.path.exists(new_name): + logging.info(f"Renaming file '{fname}' to '{new_name}'") + os.rename(fname, new_name) + else: + logging.warning(f"Target filename '{new_name}' already exists. Skipping rename for '{fname}'") # for spotipy to be able to log in, the environment variables SPOTIPY_CLIENT_ID and SPOTIPY_CLIENT_SECRET have to be set # these can be obtained from the spotify developer dashboard