Downloads songs into songs/ directory to use with geneated videos. Returns: None
()
| 63 | |
| 64 | |
| 65 | def fetch_songs() -> None: |
| 66 | """ |
| 67 | Downloads songs into songs/ directory to use with geneated videos. |
| 68 | |
| 69 | Returns: |
| 70 | None |
| 71 | """ |
| 72 | try: |
| 73 | info(f" => Fetching songs...") |
| 74 | |
| 75 | files_dir = os.path.join(ROOT_DIR, "Songs") |
| 76 | if not os.path.exists(files_dir): |
| 77 | os.mkdir(files_dir) |
| 78 | if get_verbose(): |
| 79 | info(f" => Created directory: {files_dir}") |
| 80 | else: |
| 81 | existing_audio_files = [ |
| 82 | name |
| 83 | for name in os.listdir(files_dir) |
| 84 | if os.path.isfile(os.path.join(files_dir, name)) |
| 85 | and name.lower().endswith((".mp3", ".wav", ".m4a", ".aac", ".ogg")) |
| 86 | ] |
| 87 | if len(existing_audio_files) > 0: |
| 88 | return |
| 89 | |
| 90 | configured_url = get_zip_url().strip() |
| 91 | download_urls = [configured_url] if configured_url else [] |
| 92 | download_urls.extend(DEFAULT_SONG_ARCHIVE_URLS) |
| 93 | |
| 94 | archive_path = os.path.join(files_dir, "songs.zip") |
| 95 | downloaded = False |
| 96 | |
| 97 | for download_url in download_urls: |
| 98 | try: |
| 99 | response = requests.get(download_url, timeout=60) |
| 100 | response.raise_for_status() |
| 101 | |
| 102 | with open(archive_path, "wb") as file: |
| 103 | file.write(response.content) |
| 104 | |
| 105 | SAFE_EXTENSIONS = (".mp3", ".wav", ".m4a", ".aac", ".ogg", ".flac") |
| 106 | with zipfile.ZipFile(archive_path, "r") as zf: |
| 107 | for member in zf.namelist(): |
| 108 | basename = os.path.basename(member) |
| 109 | if not basename or not basename.lower().endswith(SAFE_EXTENSIONS): |
| 110 | warning(f"Skipping non-audio file in archive: {member}") |
| 111 | continue |
| 112 | if ".." in member or member.startswith("/"): |
| 113 | warning(f"Skipping suspicious path in archive: {member}") |
| 114 | continue |
| 115 | zf.extract(member, files_dir) |
| 116 | |
| 117 | downloaded = True |
| 118 | break |
| 119 | except Exception as err: |
| 120 | warning(f"Failed to fetch songs from {download_url}: {err}") |
| 121 | |
| 122 | if not downloaded: |
no test coverage detected