summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackson Taylor <jackson@jacksontaylor.xyz>2022-08-06 16:19:53 -0400
committerJackson Taylor <jackson@jacksontaylor.xyz>2022-08-06 16:19:53 -0400
commit71bcf9ffd22d4afd83b2d626bac76db30d8a7073 (patch)
treedf6b59b54ff84e47bcad69443a28c276159c2cfe
parentffd09bf58a7e08e7f216257995435dbb6396b4cf (diff)
Use generic metadata dict
This replaces the need to read the json file each time, or do weird stuff for the file name.
-rwxr-xr-xjamos161
1 files changed, 91 insertions, 70 deletions
diff --git a/jamos b/jamos
index 587577c..9c666e2 100755
--- a/jamos
+++ b/jamos
@@ -9,6 +9,7 @@ from pathlib import Path
import sys
import youtube_dl
+
def cleanup_metadata_files(music_directory):
files = glob.glob(os.path.join(music_directory, '*.json'))
@@ -41,10 +42,22 @@ def get_all_files(directory):
def get_command_line_options():
- parser = argparse.ArgumentParser(description="Download songs from YouTube Music")
- parser.add_argument("url", metavar="string", type=str, help="Playlist or Song URL to download")
- parser.add_argument("-c", "--cookies", metavar="string", type=str, help="Cookie file to use.")
- parser.add_argument("-o", "--output", metavar="string", type=str, help="Output directory to use")
+ parser = argparse.ArgumentParser(
+ description="Download songs from YouTube Music")
+ parser.add_argument("url",
+ metavar="string",
+ type=str,
+ help="Playlist or Song URL to download")
+ parser.add_argument("-c",
+ "--cookies",
+ metavar="string",
+ type=str,
+ help="Cookie file to use.")
+ parser.add_argument("-o",
+ "--output",
+ metavar="string",
+ type=str,
+ help="Output directory to use")
return parser.parse_args()
@@ -66,26 +79,15 @@ def get_video_urls_in_playlist(playlist_url, ytdl):
def move_file(file, metadata, output_directory):
- # TODO: Pass a jamos specific metadata object/dict
- # Then we can do this validation all at once
-
- artist = 'unknownartist'
- album = 'unknownalbum'
- title = 'unknownsong'
-
- if ('artist' in metadata.keys()) and (metadata['artist'] is not None):
- if len(metadata['artist'].split(',')) > 1:
- # If there are multiple artists, pick the first one
- # NOTE: This may break if the artist has a comma in their name
- artist = metadata['artist'].split(',')[0].replace(' ', '_').lower()
- else:
- artist = metadata['artist'].replace(' ', '_').lower()
-
- if ('album' in metadata.keys()) and (metadata['album'] is not None):
- album = metadata['album'].replace(' ', '_').replace(',', '').replace("'", "").replace('"', "").lower()
-
- if ('title' in metadata.keys()) and (metadata['title'] is not None):
- title = metadata['title'].replace(' ', '_').replace('/', '').lower()
+ artist = metadata['artist'].replace(
+ '-', ' ').replace(' ', '_').replace("'", "").replace(
+ "&", "and").lower()
+ album = metadata['album'].replace(
+ '-', ' ').replace(' ', '_').replace("'", "").replace(
+ "&", "and").lower()
+ title = metadata['title'].replace(
+ '-', ' ').replace(' ', '_').replace("'", "").replace(
+ "&", "and").lower()
final_directory = os.path.join(
output_directory,
@@ -99,62 +101,78 @@ def move_file(file, metadata, output_directory):
# TODO: Research better file formats over mp3?
os.rename(
file,
- os.path.join(final_directory, artist + '_' + title + '.mp3'))
+ os.path.join(final_directory, '{}_{}_{}.mp3'.format(artist,
+ album,
+ title)))
+
+
+def write_metadata_to_song_file(filename, metadata):
+ file = music_tag.load_file(filename)
+ file['name'] = metadata['title']
+ file['artist'] = metadata['artist']
+ file['album'] = metadata['album']
+ file['year'] = metadata['year']
-def write_metadata_to_song_file(file, metadata):
- f = music_tag.load_file(file)
+ file.save()
- artist = 'unknownartist'
- album = 'unknownalbum'
- title = 'unknownsong'
- year = 9999
- if ('artist' in metadata.keys()) and (metadata['artist'] is not None):
- if len(metadata['artist'].split(',')) > 1:
- # If there are multiple artists, pick the first one
- # NOTE: This will break if the artist has a comma in their name
- artist = metadata['artist'].split(',')[0].replace(' ', '_').lower()
- else:
- artist = metadata['artist'].replace(' ', '_').lower()
+def get_song_metadata_from_json(json, counter):
+ metadata = {
+ 'title': 'unknownsong',
+ 'artist': 'unknownartist',
+ 'album': 'unknownalbum',
+ 'year': 1999,
+ 'jamos_filename': 'jamos_unknwon_file_number_{}.mp3'.format(counter),
+ }
- artist = artist.replace('&', 'and')
+ try:
+ if ('artist' in json.keys()) and (json['artist'] is not None):
+ metadata['artist'] = json['artist']
+ if len(metadata['artist'].split(',')) > 1:
+ # If there are multiple artists, pick the first one
+ # NOTE: This will break if the artist has a comma in their name
+ metadata['artist'] = metadata['artist'].split(',')[0]
+
+ if ('album' in json.keys()) and (json['album'] is not None):
+ metadata['album'] = json['album']
- if ('album' in metadata.keys()) and (metadata['album'] is not None):
- album = metadata['album'].replace(' ', '_').lower()
+ if ('title' in json.keys()) and (json['title'] is not None):
+ metadata['title'] = json['title']
- if ('title' in metadata.keys()) and (metadata['title'] is not None):
- title = metadata['title'].replace(' ', '_').lower()
+ if ('release_date' in json.keys()):
+ metadata['year'] = format_youtube_date(json['release_date'])
- if ('release_date' in metadata.keys()):
- year = format_youtube_date(metadata['release_date'])
+ artist_for_filename = metadata['artist'].replace(' ', '_').lower()
+ title_for_filename = metadata['title'].replace(' ', '_').lower()
+ metadata['jamos_filename'] = '{}_{}.mp3'.format(artist_for_filename,
+ title_for_filename)
- f['name'] = title
- f['artist'] = artist
- f['album'] = album
- f['year'] = year
+ except Exception as ex:
+ print(ex)
- f.save()
+ return metadata
def create_downloader(music_directory, cookies):
audio_options = {
- 'format': 'mp3/bestaudio/best',
- 'cookiefile': cookies,
- 'outtmpl': music_directory + '%(title)s.%(ext)s',
- 'postprocessors': [
- {
- 'key': 'FFmpegExtractAudio',
- 'preferredcodec': 'mp3',
- 'preferredquality': '192',
- },
- {'key': 'FFmpegMetadata'},
- ],
- 'writeinfojson': True
- }
+ 'format': 'mp3/bestaudio/best',
+ 'cookiefile': cookies,
+ 'outtmpl': music_directory + '%(title)s.%(ext)s',
+ 'postprocessors': [
+ {
+ 'key': 'FFmpegExtractAudio',
+ 'preferredcodec': 'mp3',
+ 'preferredquality': '192',
+ },
+ {'key': 'FFmpegMetadata'},
+ ],
+ 'writeinfojson': True
+ }
return youtube_dl.YoutubeDL(audio_options)
+
def save_urls_from_playlist_to_file(filename, urls):
try:
f = open(filename, "w")
@@ -165,6 +183,7 @@ def save_urls_from_playlist_to_file(filename, urls):
print(e)
raise e
+
if __name__ == "__main__":
args = get_command_line_options()
@@ -174,15 +193,16 @@ if __name__ == "__main__":
music_directory = args.output or "~/Music"
cookies = args.cookies or "~/cookies.txt"
- # From some testing, if your playlist is public, you don't have to use a cookie file.
- # Youtube-dl doesn't break or throw if the file doesn't exist.
+ # From some testing, if your playlist is public, you don't have to use a
+ # cookie file. Youtube-dl doesn't break or throw if the file doesn't exist.
ytdl = create_downloader(music_directory, cookies)
# TODO: Save urls to file so we can start in the
# middle of the playlist if needed
urls = get_video_urls_in_playlist(playlist_url, ytdl)
- save_urls_from_playlist_to_file("~/jamos_urls.txt", urls)
+ save_urls_from_playlist_to_file(os.path.join(music_directory,
+ "jamos_urls.txt"), urls)
for url in urls:
try:
@@ -193,16 +213,17 @@ if __name__ == "__main__":
files = get_all_files(music_directory)
+ counter = 1
for f in files:
try:
- json_data = None
with open(f.replace('.mp3', '.info.json')) as json_file:
json_data = json.load(json_file)
- write_metadata_to_song_file(f, json_data)
- move_file(f, json_data, music_directory)
+ metadata = get_song_metadata_from_json(json_data, counter)
+ write_metadata_to_song_file(f, metadata)
+ move_file(f, metadata, music_directory)
+ counter += 1
except Exception as e:
# just gonna print this and move on to the next file.
print(e)
cleanup_metadata_files(music_directory)
-