-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
153 lines (127 loc) · 6.07 KB
/
main.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
"""Copyright (C) 2023 anonymous
This program is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not,
see <https://www.gnu.org/licenses/>."""
# TODO backup Playlist.JSON before editing
import pathlib
import time
import logging
import sys
import json
import eyed3
logger = logging.getLogger(__name__)
# Set logging level
logger.setLevel(logging.INFO) # remove newline at end of line
formatter = logging.Formatter("%(message)s ")
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(formatter)
logger.addHandler(stdout_handler)
# Initialize m3u_path as Path() -> while loop works
m3u_path = pathlib.Path()
# wait till a valid Path to .m3u playlist was supplied
while m3u_path.is_file() is False:
m3u_path = pathlib.Path(input('enter valid file path to m3u Playlist:\n'))
# Format of playlists in the Harmonoid Playlist.JSON file
# playlistDictHarmonoid = [{'name': None,
# 'id': None,
# 'tracks': [
# {
# "uri": None,
# "trackName": None,
# "albumName": None,
# "trackNumber": 1,
# "discNumber": 1,
# "albumLength": 1,
# "albumArtistName": "Deichkind",
# "trackArtistNames": ["Deichkind"],
# "timeAdded": int(time.time()),
# "duration": 0,
# "bitrate": 0,
# }],
# }]
# m3u specification:
# https://en.wikipedia.org/wiki/M3U
with open(m3u_path) as f:
tracks = []
playlistTitle = ' '
for i, line in enumerate(f):
line = line.replace('\n', '') # remove newline at end of line
if '#PLAYLIST' in line:
playlistTitle = line.replace('#PLAYLIST:', '') # set title of playlist
if '#' in line: # '#' indicates that the line is a comment or additional unnecessary info -> skip line
continue
if '/' in line: # '/' indicates that the line is a Path to a song
path = pathlib.Path(line)
audiofile = eyed3.load(path.absolute()) # open the file with eyed3 to read its metadata
albumArtist = audiofile.tag.album_artist
artists = audiofile.tag.artist
if artists is None: # if artist doesn't exist use album_artist instead
artists = albumArtist
trackName = audiofile.tag.title
albumName = audiofile.tag.album
for tag in [albumArtist, artists, trackName, albumName]:
# if one of the tags is missing skip because it will break the playlist otherwise
if tag is None:
continue
tracks.append({
"uri": path.absolute().as_uri(),
"trackName": trackName,
"albumName": albumName,
"trackNumber": 1,
"discNumber": 1,
"albumLength": 1,
"albumArtistName": albumArtist,
"trackArtistNames": artists,
"timeAdded": int(time.time()),
"duration": 0,
"bitrate": 0
})
logger.debug(tracks)
# If there was no title in .m3u file set it to the name of the .m3u file
if playlistTitle == '':
playlistTitle = m3u_path.name[0:m3u_path.name.rfind('.m3u')]
logger.info(f"Title of Playlist: '{playlistTitle}'")
playlistDictHarmonoid = {'name': playlistTitle,
'id': 3,
'tracks': tracks, }
# print(playlistDictHarmonoid)
# print(json.dumps(playlistDictHarmonoid, indent=4))
harmonoidPlaylist_path = pathlib.Path.joinpath(pathlib.Path.home(), '.Harmonoid', 'Playlists.JSON')
answer = str.lower(input(f"Is this the path to your Harmonoid Playlists.JSON file?\n'{harmonoidPlaylist_path}'\n["
f"yes/no]?\n"))
while answer != 'yes' and answer != 'y' and answer != 'no' and answer != 'n':
logger.debug(f'answer: {answer}')
if harmonoidPlaylist_path.is_file() is False:
print(f"{harmonoidPlaylist_path} is not a file.\nexiting now")
exit(1)
answer = str.lower(input('[yes/no]?\n'))
if answer == 'no' or answer == 'n':
harmonoidPlaylist_path = pathlib.Path(input('enter valid Path to your Harmonoid Playlists.JSON file:\n'))
while harmonoidPlaylist_path.is_file() is False:
harmonoidPlaylist_path = pathlib.Path(input('enter valid Path to your Harmonoid Playlists.JSON file:\n'))
# determine the count of playlists to insert the .m3u playlist at the end
with open(harmonoidPlaylist_path) as f:
data = json.load(f)
r = -2
for line in data['playlists']:
i = line.get('id', None)
if i > r:
r = i
logger.debug(f"largest Playlist id: {r}")
playlistDictHarmonoid = {'name': m3u_path.name[0:m3u_path.name.rfind('.m3u')],
'id': r + 1,
'tracks': tracks, }
oldPlaylist = data['playlists']
newPlaylist = oldPlaylist.copy()
newPlaylist.append(playlistDictHarmonoid) # fixme
playlistNewHarmonoid = {"playlists": newPlaylist}
# print(json.dumps(playlistNewHarmonoid, indent=4))
logger.debug(json.dumps(playlistNewHarmonoid, indent=4))
# write the updated Playlist.JSON file
with open(harmonoidPlaylist_path, 'w') as f:
f.write(json.dumps(playlistNewHarmonoid, indent=4))
print(f'Added playlist to Harmonoid.\nRestart Harmonoid to play it.')