forked from evolve700/PlexPlaylistExport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplex2m3u.py
executable file
·132 lines (112 loc) · 4.83 KB
/
plex2m3u.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"""
Plex Playlist Export Script
This script connects to a Plex Media Server and allows users to export audio playlists
to M3U files. The playlists can be customized to include album and artist information
and are moved to a specified target directory. Non-ASCII characters can be converted
to ASCII if desired.
This script is based on the original work by evolve700, which is available at:
https://github.com/evolve700/PlexPlaylistExport/tree/main
The original code is licensed under the GPL-3.0 license.
"""
import os
import argparse
import shutil
import requests
from plexapi.server import PlexServer
from unidecode import unidecode
from config import (
HOST, TOKEN, PLEX_MUSIC_ROOT, REPLACE_WITH_DIR, ASCIIFY,
WRITE_ALBUM, WRITE_ALBUM_ARTIST, TARGET_DIR
)
from unidecode import unidecode
def do_asciify(input_string):
"""Converts a string to its ASCII representation."""
if input_string is None:
return None
return unidecode(input_string)
def list_playlists():
"""Retrieve all audio playlists available on the Plex server."""
try:
print("Connecting to Plex...", end="")
plex = PlexServer(HOST, TOKEN)
print(" done.")
playlists = [p.title for p in plex.playlists() if p.playlistType == "audio"]
return playlists
except Exception as e:
print(f"Failed to connect or retrieve playlists. Error: {e}")
return []
def export_playlist(playlist_name):
"""Export a selected playlist as an M3U file."""
try:
print(f"Exporting playlist: '{playlist_name}'...", end=" ")
plex = PlexServer(HOST, TOKEN)
playlist = plex.playlist(playlist_name)
song_count = len(playlist.items())
playlist_title = do_asciify(playlist.title) if ASCIIFY else playlist.title
extension = "m3u"
encoding = "ascii" if ASCIIFY else "utf-8"
file_path = f"{playlist_title}.{extension}"
with open(file_path, 'w', encoding=encoding) as m3u:
m3u.write("#EXTM3U\n")
m3u.write(f"#PLAYLIST:{playlist_title}\n\n")
for item in playlist.items():
seconds = int(item.duration / 1000)
title = do_asciify(item.title) if ASCIIFY else item.title
album = do_asciify(item.parentTitle) if ASCIIFY else item.parentTitle
artist = do_asciify(item.grandparentTitle) if ASCIIFY else item.grandparentTitle
if WRITE_ALBUM:
m3u.write(f"#EXTALB:{album}\n")
if WRITE_ALBUM_ARTIST:
m3u.write(f"#EXTART:{artist}\n")
for part in item.media[0].parts:
m3u.write(f"#EXTINF:{seconds},{artist} - {title}\n")
m3u.write(f"{part.file.replace(PLEX_MUSIC_ROOT, REPLACE_WITH_DIR)}\n\n")
destination = os.path.join(TARGET_DIR, file_path)
if os.path.exists(destination):
os.remove(destination) # Remove the existing file
shutil.move(file_path, TARGET_DIR)
print(f"done. {song_count} songs exported and moved to '{TARGET_DIR}'.")
except Exception as e:
print(f"Failed to export playlist '{playlist_name}'. Error: {e}")
def export_all_playlists():
"""Export all audio playlists as M3U files, excluding 'All Music'."""
try:
print("\nExporting all playlists...", end=" ")
plex = PlexServer(HOST, TOKEN)
playlists = [p for p in plex.playlists() if p.playlistType == "audio" and p.title != "All Music"]
if not playlists:
print("No audio playlists found.")
return
for playlist in playlists:
export_playlist(playlist.title)
print("All playlists (excluding 'All Music') exported.")
except Exception as e:
print(f"Failed to export all playlists. Error: {e}")
def main():
playlists = list_playlists()
if not playlists:
return
print("\nAvailable Playlists:")
for idx, title in enumerate(playlists, start=1):
print(f"{idx}. {title}")
print("\nOptions:")
print("0. Export all playlists (CAUTION: depending on playlist size and amount, could be very slow)")
while True:
try:
choice = input("\nEnter the number of the playlist to export (or type 'x' to exit): ")
if choice.lower() == "x":
print("Exiting...")
break
if choice == "0":
export_all_playlists()
break
if not choice.isdigit() or int(choice) < 1 or int(choice) > len(playlists):
print("Invalid choice. Please enter a valid number.")
continue
selected_playlist = playlists[int(choice) - 1]
export_playlist(selected_playlist)
except KeyboardInterrupt:
print("\nExiting...")
break
if __name__ == "__main__":
main()