From 8d20962afc78736ab26de518d0c5889871880be2 Mon Sep 17 00:00:00 2001
From: Salt <rehashedsalt@cock.li>
Date: Fri, 13 Mar 2020 06:08:28 -0500
Subject: [PATCH] Working on a playlist importer

---
 badwitch.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 69 insertions(+), 2 deletions(-)

diff --git a/badwitch.py b/badwitch.py
index b950e8b..ab479d8 100755
--- a/badwitch.py
+++ b/badwitch.py
@@ -22,6 +22,7 @@ import json
 import logging
 import math
 import pathlib
+import re
 import types
 import sys
 import youtube_dl
@@ -256,7 +257,7 @@ class BadWitch:
         self.argparser.add_argument('-d', '--debug', action='store_true',
                 help='Show even more status messages')
         self.argparser.add_argument('action', metavar='action', nargs='?',
-                choices=['download', 'edit', 'gui', 'list'],
+                choices=['download', 'edit', 'playlist', 'gui', 'list'],
                 help='Action to perform on the library')
         # Set up appdirs
         self.dirs = AppDirs('badwitch', 'rehashedsalt')
@@ -285,6 +286,9 @@ class BadWitch:
         elif self.args.action == 'edit':
             self.prompt(lib)
             return
+        elif self.args.action == 'playlist':
+            self.playlist(lib)
+            return
         elif self.args.action == 'list':
             for album, albumcontent in lib.albums.items():
                 print(album)
@@ -299,8 +303,71 @@ class BadWitch:
             print('Nothing to do')
             return
 
+    def playlist(self, lib):
+        in_playlist = input('YouTube Playlist URL: ')
+        playlist = {}
+        metadata = {}
+        artist = ''
+        album = ''
+        # Get our video URLs
+        with youtube_dl.YoutubeDL({'outtmpl': '%(id)s%(ext)s', 'quiet':True,}) as ydl:
+            print('Extracting information...')
+            result = ydl.extract_info(in_playlist, download=False)
+            if 'entries' in result:
+                entries = result['entries']
+                for i, item in enumerate(entries):
+                    playlist[i] = {
+                            'title': entries[i]['title'],
+                            'source': entries[i]['webpage_url']
+                            }
+                    # Song tags like these are per-song, so we have to detect them here
+                    if 'artist' in item:
+                        if artist != '' and artist != entries[i]['artist']:
+                            print('Detected multiple artists')
+                            artist = 'Various Artists'
+                        elif artist != entries[i]['artist']:
+                            print('Detected artist ' + entries[i]['artist'])
+                            artist = entries[i]['artist']
+                    if 'album' in item and album == '':
+                        print('Detected album title ' + entries[i]['album'])
+                        album = entries[i]['album']
+                    if 'release_date' in item and 'release_date' not in metadata and entries[i]['release_date'] is not None:
+                        print('Detected release date ' + entries[i]['release_date'])
+                        metadata['release_date'] = entries[i]['release_date']
+                # If YouTube's song tags didn't work, just grab metadata from the playlist
+                if album == '':
+                    album = result['title']
+                if artist == '':
+                    artist = result['uploader']
+        for field in ['genre', 'publisher', 'release_date']:
+            if field in metadata:
+                continue
+            in_value = input('Metadata: ' + field + ' = ')
+            if in_value is not '': metadata[field] = in_value
+        # Remove artist prefixes because that happens a lot
+        artistregex = re.compile(r'^' + re.escape(artist) + r'[ ]*[-:;~]*[ ]*', re.IGNORECASE)
+        for song, songcontent in playlist.items():
+            songcontent['title'] = artistregex.sub('', songcontent['title'])
+        # Build up an album
+        playlistalbum = {}
+        playlistalbum['meta'] = metadata
+        for song, songcontent in playlist.items():
+            playlistalbum[songcontent['title']] = {
+                'track': song,
+                'artist': artist,
+                'source': songcontent['source']
+                }
+        lib.albums[album] = playlistalbum
+        lib.validate()
+        lib.save()
+        print('Successfully added "' + album + '" by ' + artist)
+        for song, songcontent in lib.albums[album].items():
+            if song == 'meta':
+                continue
+            print(str(songcontent['track']) + ': ' + song + ' (' + songcontent['source'] + ')')
+
     def prompt(self, lib):
-        print('Bad Witch interactive $ibrary editor')
+        print('Bad Witch interactive library editor')
         print('^C to abort, ^D to finish changes')
         print('Loaded library ' + lib.file)
         try: