parse-playlist (3845B)
1 #!/usr/bin/env python3 2 3 import os 4 import re 5 import sys 6 from pathlib import Path 7 8 def parse_playlist(playlist_path): 9 """ 10 Parse M3U/M3U8 playlist file to extract artist and song information. 11 Outputs in format: Artist Name - Song Name 12 """ 13 songs = [] 14 15 # Enhanced patterns for music files 16 patterns = [ 17 # Artist - Song.mp3 18 r'^(?P<artist>.+?)\s*-\s*(?P<song>.+?)\.[^.]+$', 19 # Song by Artist.mp3 20 r'^(?P<song>.+?)\s+by\s+(?P<artist>.+?)\.[^.]+$', 21 # Artist_-_Song.mp3 or Artist_-_Song.m4a etc 22 r'^(?P<artist>.+?)_-_(?P<song>.+?)\.[^.]+$', 23 # ArtistName--SongName.mp3 24 r'^(?P<artist>.+?)--(?P<song>.+?)\.[^.]+$' 25 ] 26 27 try: 28 with open(playlist_path, 'r', encoding='utf-8') as f: 29 current_title = None 30 31 for line in f: 32 line = line.strip() 33 34 # Handle extended M3U directives 35 if line.startswith('#EXTINF:'): 36 # Try to extract title from EXTINF line 37 parts = line.split(',', 1) 38 if len(parts) > 1: 39 current_title = parts[1] 40 continue 41 elif line.startswith('#'): 42 continue 43 elif not line: 44 continue 45 46 # Get just the filename without the path and extension 47 filename = os.path.basename(line) 48 name_without_ext = os.path.splitext(filename)[0] 49 50 # First try to use EXTINF title if available 51 if current_title: 52 if ' - ' in current_title: 53 artist, song = current_title.split(' - ', 1) 54 songs.append({ 55 'artist': artist.strip(), 56 'song': song.strip() 57 }) 58 current_title = None 59 continue 60 61 # If no EXTINF or couldn't parse it, try filename patterns 62 song_info = None 63 64 # Try each pattern until we find a match 65 for pattern in patterns: 66 match = re.match(pattern, filename) 67 if match: 68 song_info = { 69 'artist': match.group('artist').strip(), 70 'song': match.group('song').strip() 71 } 72 break 73 74 # If no pattern matched, try to split on the first hyphen if it exists 75 if not song_info and ' - ' in name_without_ext: 76 parts = name_without_ext.split(' - ', 1) 77 if len(parts) == 2: 78 song_info = { 79 'artist': parts[0].strip(), 80 'song': parts[1].strip() 81 } 82 83 # If still no match, use the whole filename as the song name 84 if not song_info: 85 song_info = { 86 'artist': 'Unknown', 87 'song': name_without_ext.strip() 88 } 89 90 songs.append(song_info) 91 92 return songs 93 94 except Exception as e: 95 print(f"Error reading playlist: {e}") 96 return [] 97 98 def main(): 99 # Check if playlist file was provided as argument 100 if len(sys.argv) != 2: 101 print("Usage: parse-playlist playlist_file.m3u8") 102 return 103 104 playlist_path = sys.argv[1] 105 106 if not os.path.exists(playlist_path): 107 print(f"Playlist file '{playlist_path}' not found.") 108 return 109 110 songs = parse_playlist(playlist_path) 111 112 # Print in requested format 113 for song in songs: 114 print(f"{song['artist']} - {song['song']}") 115 116 if __name__ == "__main__": 117 main()