Wrote out method song in ripper

This commit is contained in:
Kepoor Hampond 2017-03-04 23:33:27 -08:00
parent cfdec19136
commit be13b60ba6
3 changed files with 184 additions and 132 deletions

View file

@ -1,11 +1,19 @@
# MP3 Metadata editing
from mutagen.mp3 import MP3, EasyMP3
from mutagen.easyid3 import EasyID3
from mutagen.id3 import ID3, APIC
from mutagen.id3 import * # There's A LOT of stuff to import, forgive me.
# System
import sys
# Info finding
from urllib.parse import quote_plus, quote
from urllib.request import urlopen, Request
if sys.version_info[0] >= 3:
from urllib.parse import quote_plus, quote
from urllib.request import urlopen, Request
elif sys.version_info[0] < 3:
from urllib import quote_plus, quote
from urllib import urlopen
from urllib2 import Request
# Info parsing
import json
@ -13,135 +21,49 @@ from re import match
from bs4 import BeautifulSoup
# Local utils
from .utils import *
import utils
# Powered by...
import spotipy
class Metadata:
def __init__(self, location, song, artist):
def __init__(self, location):
self.spotify = spotipy.Spotify()
self.song = song
self.artist = artist
self.location = location
self.info = self.search_google()
self.mp3 = MP3(self.location, ID3=EasyID3)
def get_attr(self, attr):
try:
return self.mp3[attr][0]
except Exception:
return False
def add_title(self):
self.mp3['title'] = self.song
self.mp3.save()
return True
def add_artist(self):
self.mp3['artist'] = self.artist
self.mp3.save()
return True
def add_album(self, album=None):
try:
if not album:
for i, j in enumerate(self.info):
if "Album:" in j:
album = (self.info[i + 1])
self.mp3['album'] = album
self.mp3.save()
return True
except Exception:
self.mp3['album'] = self.song
self.mp3.save()
return False
def add_release_date(self, release_date=None):
try:
if not release_date:
for i, j in enumerate(self.info):
if "Released:" in j:
date = (self.info[i + 1])
self.mp3['date'] = date
self.mp3.save()
return True
except UnboundLocalError:
return False
def add_track_number(self, track_number):
self.mp3['tracknumber'] = str(track_number)
self.mp3.save()
return True
def get_album_art(self, artist, album, id=None):
spotify = spotipy.Spotify()
if id:
album = spotify.album(id)
return album["images"][0]["url"]
results = spotify.search(q=artist + " " + album, type='album')
items = results['albums']['items']
if len(items) > 0:
album = items[0]['images'][0]['url']
return album
#self.mp3 = MP3(self.location, ID3=EasyID3)
self.mp3 = EasyID3(self.location)
def add_tag(self, tag, data):
# For valid tags: `EasyID3.valid_keys.keys()`
audio[tag] = data
audio.save()
def add_album_art(self, image_url):
mp3 = EasyMP3(self.location, ID3=ID3)
try:
mp3.add_tags()
except Exception as e:
pass
if not image_url:
image_url = self.get_album_art(self.artist, self.mp3["album"][0])
try:
mp3.tags.add(
APIC(
encoding = 3,
mime = 'image/png',
type = 3,
desc = 'cover',
data = urlopen(image_url).read()
)
mp3.tags.add(
APIC(
encoding = 3,
mime = 'image/png',
type = 3,
desc = 'cover',
data = urlopen(image_url).read()
)
mp3.save()
return image_url
except Exception:
return False
def search_google(self, search_terms=""):
def visible(element):
if element.parent.name in ['style', 'script', '[document]', 'head', 'title']:
return False
elif match('<!--.*-->', str(element)):
return False
return True
search_terms = "%s %s %s" % (self.song, self.artist, search_terms)
url = 'http://www.google.com/search?q=' + quote_plus(search_terms)
hdr = {
'User-Agent':'Mozilla/5.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
}
texts = BeautifulSoup(urlopen(Request(url, \
headers=hdr)).read(), 'html.parser').findAll(text=True)
return list(filter(visible, texts))
)
mp3.save()
def find_album(song, artist):
tracks = self.spotify.search(q=song, type="track")
for track in tracks:
if utils.blank_include(track["name"], song):
if utils.blank_include(track["artists"][0]["name"], artist):
return track["album"], track
def parse_genre(genres):
if genres != []:
genres.reverse()
genres = list(map(lambda x: x.replace("-", " "), genres))
genres.sort(key=lambda x: len(x.split()))
print (genres)
return genres[0]
else:
return ""

View file

@ -6,6 +6,7 @@ from spotipy.oauth2 import SpotifyClientCredentials
# System
import sys
import os
import glob
# Parsing
from bs4 import BeautifulSoup
@ -21,6 +22,7 @@ else:
# Local utilities
import utils
from metadata import *
class Ripper:
def __init__(self, args={}):
@ -36,10 +38,10 @@ class Ripper:
def find_yt_url(self, song=None, artist=None, additional_search="lyrics"):
try:
if not song: song = self.args["song"]
if not song: song = self.args["song_title"]
if not artist: artist = self.args["artist"]
except ValueError:
raise ValueError("Must have specify `song` and/or `artist` in either init with `args` or with method arguments.")
raise ValueError("Must specify song_title/artist in `args` with init, or in method arguments.")
search_terms = song + " " + artist + " " + additional_search
query_string = urlencode({"search_query" : (search_terms)})
@ -85,10 +87,10 @@ class Ripper:
def spotify_list(self, type=None, title=None, username=None):
try:
if not type: type = self.args["type"]
if not title: title = self.args["title"]
if not title: title = self.args["list_title"]
if not username: username = self.args["username"]
except ValueError:
raise ValueError("Must specify type/title/username in `args` with init, or in method arguements.")
raise ValueError("Must specify type/title/username in `args` with init, or in method arguments.")
if type == "album":
search = title
@ -128,6 +130,8 @@ class Ripper:
for track in the_list["tracks"]:
if type == "playlist":
file_prefix = str(len(tracks)) + " - "
elif type == "album":
file_prefix = str(track["track_number"]) + " - "
data = {
"name": track["name"],
@ -137,7 +141,7 @@ class Ripper:
"track_number": track["track_number"],
"disc_number": track["disc_number"],
"compilation": compilation,
"file_prefix": file_prefix,
"file_prefix": file_prefix,
}
tracks.append(data)
@ -161,4 +165,77 @@ class Ripper:
locations.append(loc)
os.remove(".irs-download-log")
return locations
return locations
def song(song=None, artist=None, data={}):
try:
if not song: song = self.args["song_title"]
if not artist: artist = self.args["artist"]
except ValueError:
raise ValueError("Must specify song_title/artist in `args` with init, or in method arguments.")
if data == {}: data = False
video_url, video_title = self.find_yt_url(song, artist)
print ('Downloading "%s" by "%s"' % (song, artist))
file_prefix = ""
if data != False:
file_prefix = data["file_prefix"]
file_name = file_prefix + utils.blank(song, False) + ".mp3"
ydl_opts = {
'format': 'bestaudio/best',
#'quiet': True,
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
'logger': utils.MyLogger(),
'progress_hooks': [utils.my_hook],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([video_url])
for file in glob.glob("./*%s*" % video_title.split("/watch?v=")[-1]):
os.rename(file, file_name)
if data == False:
if "album" not in self.args:
album, track = find_album_and_track(song, artist)
else:
album = self.args["album"]
if album != None:
genre = album["artists"][0]["genres"]
album_name = ""
if album:
if utils.check_garbage_phrases(["remastered", "explicit"], album.name, "")
album_name = album["name"].split(" (")[0]
else:
album_name = album["name"]
genre = parse_genre(genre)
# Ease of Variables (copyright) (patent pending) (git yer filthy hands off)
#
# *5 Minutes Later*
# Depecrated. It won't be the next big thing. :(
m = Metadata(file_name)
m.add_tag( "title", song)
m.add_tag( "artist", artist)
m.add_tag( "comment", "Downloaded from: %s\n Video Title: %s" % (video_url, video_title))
if album:
m.add_tag("album", album_name)
m.add_tag("genre", genre)
m.add_tag("compilation", compilation)
m.add_tag("tracknumber", track["track_number"])
m.add_tag("discnumber", track["disc_number"])
m.add_album_art( album["images"][0]["url"])

View file

@ -1,3 +1,27 @@
#==========================
# Youtube-DL Logs and Hooks
#==========================
class MyLogger(object):
def debug(self, msg):
pass
def warning(self, msg):
pass
def error(self, msg):
print(msg)
def my_hook(d):
if d['status'] == 'finished':
print('Done downloading, now converting ...')
#=================================
# String Manipulation and Checking
#=================================
def check_garbage_phrases(phrases, string, title):
for phrase in phrases:
if phrase in blank(string):
@ -28,10 +52,15 @@ def individual_word_match(match_against, match):
if match_ag == word:
matched.append(word)
return (float(matched.uniq.size) / float(match_against.size))
#=========================================
# Download Log Reading/Updating/Formatting
#=========================================
def format_download_log_line(track, download_status="not downloaded"):
return " @@ ".join([t["name"], t["artist"], t["album"]["id"], \
t["genre"], t["track_number"], t["disc_number"], t["compilation"], \
t["genre"], t["track_number"], t["disc_number"], str(t["compilation"]), \
t["prefix"], download_status]) + "\n"
def format_download_log_data(data):
@ -40,6 +69,23 @@ def format_download_log_data(data):
lines.append(format_download_log_line(track))
return lines
def read_download_log(spotify):
data = []
with open(".irs-download-log", "r") as file:
for line in file:
line = line.split(" @@ ")
data.append({
"name": line[0],
"artist": line[1],
"album": spotify.album(line[2]),
"genre": line[3],
"track_number": line[4],
"disc_number": line[5],
"compilation": bool(line[6]),
"file_prefix": line[7],
})
return data
def update_download_log_line_status(track, status="downloaded"):
line_to_find = format_download_log_line(track)
with open(".irs-download-log", "r") as input_file, \
@ -49,4 +95,11 @@ def update_download_log_line_status(track, status="downloaded"):
output_file.write(format_download_log_line(track, status))
else:
output_file.write(line)
#============================================
# And Now, For Something Completely Different
#============================================
def ease_of_variables(the_name, data):
eval(the_name + " = " + data) # Forgive me my lord, for I have sinned