Fix conflicts

This commit is contained in:
ritiek
2018-01-12 15:56:09 +05:30
parent b2f3c43d0f
commit 8c76bd8ea3
7 changed files with 77 additions and 31 deletions

View File

@@ -7,12 +7,13 @@
- Can also download a song by entering its artist and song name (in case if you don't have the Spotify's HTTP link for some song). - Can also download a song by entering its artist and song name (in case if you don't have the Spotify's HTTP link for some song).
- Automatically fixes song's meta-tags which include: - Automatically applies metadata to the downloaded song which include:
- Title - Title
- Artist - Artist
- Album - Album
- Album art - Album art
- Lyrics (if found on http://lyrics.wikia.com)
- Album artist - Album artist
- Genre - Genre
- Track number - Track number

View File

@@ -13,7 +13,7 @@ def log_leveller(log_level_str):
return loggin_level return loggin_level
def get_arguments(to_group=False, raw_args=None): def get_arguments(to_group=True, raw_args=None):
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='Download and convert songs from Spotify, Youtube etc.', description='Download and convert songs from Spotify, Youtube etc.',
formatter_class=argparse.ArgumentDefaultsHelpFormatter) formatter_class=argparse.ArgumentDefaultsHelpFormatter)
@@ -56,6 +56,10 @@ def get_arguments(to_group=False, raw_args=None):
parser.add_argument( parser.add_argument(
'-o', '--output-ext', default='.mp3', '-o', '--output-ext', default='.mp3',
help='prefered output extension .mp3 or .m4a (AAC)') help='prefered output extension .mp3 or .m4a (AAC)')
parser.add_argument(
'-dm', '--download-only-metadata', default=False,
help='download songs for which metadata is found',
action='store_true')
parser.add_argument( parser.add_argument(
'-d', '--dry-run', default=False, '-d', '--dry-run', default=False,
help='Show only track title and YouTube URL', help='Show only track title and YouTube URL',

View File

@@ -1,5 +1,5 @@
from mutagen.easyid3 import EasyID3 from mutagen.easyid3 import EasyID3
from mutagen.id3 import ID3, APIC from mutagen.id3 import ID3, TORY, TYER, TPUB, APIC, USLT, COMM
from mutagen.mp4 import MP4, MP4Cover from mutagen.mp4 import MP4, MP4Cover
from core.const import log from core.const import log
@@ -45,6 +45,9 @@ class EmbedMetadata:
music_file = self.music_file music_file = self.music_file
meta_tags = self.meta_tags meta_tags = self.meta_tags
# EasyID3 is fun to use ;) # EasyID3 is fun to use ;)
# For supported easyid3 tags:
# https://github.com/quodlibet/mutagen/blob/master/mutagen/easyid3.py
# Check out somewhere at end of above linked file
audiofile = EasyID3(music_file) audiofile = EasyID3(music_file)
audiofile['artist'] = meta_tags['artists'][0]['name'] audiofile['artist'] = meta_tags['artists'][0]['name']
audiofile['albumartist'] = meta_tags['artists'][0]['name'] audiofile['albumartist'] = meta_tags['artists'][0]['name']
@@ -61,7 +64,7 @@ class EmbedMetadata:
audiofile['arranger'] = meta_tags['artists'][0]['name'] audiofile['arranger'] = meta_tags['artists'][0]['name']
audiofile['performer'] = meta_tags['artists'][0]['name'] audiofile['performer'] = meta_tags['artists'][0]['name']
audiofile['website'] = meta_tags['external_urls']['spotify'] audiofile['website'] = meta_tags['external_urls']['spotify']
audiofile['length'] = str(meta_tags['duration_ms'] / 1000) audiofile['length'] = str(meta_tags['duration_ms'] / 1000.0)
if meta_tags['publisher']: if meta_tags['publisher']:
audiofile['encodedby'] = meta_tags['publisher'] audiofile['encodedby'] = meta_tags['publisher']
if meta_tags['genre']: if meta_tags['genre']:
@@ -71,14 +74,26 @@ class EmbedMetadata:
if meta_tags['external_ids']['isrc']: if meta_tags['external_ids']['isrc']:
audiofile['isrc'] = meta_tags['external_ids']['isrc'] audiofile['isrc'] = meta_tags['external_ids']['isrc']
audiofile.save(v2_version=3) audiofile.save(v2_version=3)
# For supported id3 tags:
# https://github.com/quodlibet/mutagen/blob/master/mutagen/id3/_frames.py
# Each class represents an id3 tag
audiofile = ID3(music_file) audiofile = ID3(music_file)
year, *_ = meta_tags['release_date'].split('-')
audiofile['TORY'] = TORY(encoding=3, text=year)
audiofile['TYER'] = TYER(encoding=3, text=year)
audiofile['TPUB'] = TPUB(encoding=3, text=meta_tags['publisher'])
audiofile['COMM'] = COMM(encoding=3, text=meta_tags['external_urls']['spotify'])
if meta_tags['lyrics']:
audiofile['USLT'] = USLT(encoding=3, desc=u'Lyrics', text=meta_tags['lyrics'])
try: try:
albumart = urllib.request.urlopen(meta_tags['album']['images'][0]['url']) albumart = urllib.request.urlopen(meta_tags['album']['images'][0]['url'])
audiofile["APIC"] = APIC(encoding=3, mime='image/jpeg', type=3, audiofile['APIC'] = APIC(encoding=3, mime='image/jpeg', type=3,
desc=u'Cover', data=albumart.read()) desc=u'Cover', data=albumart.read())
albumart.close() albumart.close()
except IndexError: except IndexError:
pass pass
audiofile.save(v2_version=3) audiofile.save(v2_version=3)
return True return True
@@ -88,22 +103,24 @@ class EmbedMetadata:
meta_tags = self.meta_tags meta_tags = self.meta_tags
# Apple has specific tags - see mutagen docs - # Apple has specific tags - see mutagen docs -
# http://mutagen.readthedocs.io/en/latest/api/mp4.html # http://mutagen.readthedocs.io/en/latest/api/mp4.html
tags = {'album': '\xa9alb', tags = { 'album' : '\xa9alb',
'artist': '\xa9ART', 'artist' : '\xa9ART',
'date': '\xa9day', 'date' : '\xa9day',
'title': '\xa9nam', 'title' : '\xa9nam',
'originaldate': 'purd', 'year' : '\xa9day',
'comment': '\xa9cmt', 'originaldate' : 'purd',
'group': '\xa9grp', 'comment' : '\xa9cmt',
'writer': '\xa9wrt', 'group' : '\xa9grp',
'genre': '\xa9gen', 'writer' : '\xa9wrt',
'tracknumber': 'trkn', 'genre' : '\xa9gen',
'albumartist': 'aART', 'tracknumber' : 'trkn',
'disknumber': 'disk', 'albumartist' : 'aART',
'cpil': 'cpil', 'disknumber' : 'disk',
'albumart': 'covr', 'cpil' : 'cpil',
'copyright': 'cprt', 'albumart' : 'covr',
'tempo': 'tmpo'} 'copyright' : 'cprt',
'tempo' : 'tmpo',
'lyrics' : '\xa9lyr' }
audiofile = MP4(music_file) audiofile = MP4(music_file)
audiofile[tags['artist']] = meta_tags['artists'][0]['name'] audiofile[tags['artist']] = meta_tags['artists'][0]['name']
@@ -114,11 +131,16 @@ class EmbedMetadata:
meta_tags['total_tracks'])] meta_tags['total_tracks'])]
audiofile[tags['disknumber']] = [(meta_tags['disc_number'], 0)] audiofile[tags['disknumber']] = [(meta_tags['disc_number'], 0)]
audiofile[tags['date']] = meta_tags['release_date'] audiofile[tags['date']] = meta_tags['release_date']
year, *_ = meta_tags['release_date'].split('-')
audiofile[tags['year']] = year
audiofile[tags['originaldate']] = meta_tags['release_date'] audiofile[tags['originaldate']] = meta_tags['release_date']
audiofile[tags['comment']] = meta_tags['external_urls']['spotify']
if meta_tags['genre']: if meta_tags['genre']:
audiofile[tags['genre']] = meta_tags['genre'] audiofile[tags['genre']] = meta_tags['genre']
if meta_tags['copyright']: if meta_tags['copyright']:
audiofile[tags['copyright']] = meta_tags['copyright'] audiofile[tags['copyright']] = meta_tags['copyright']
if meta_tags['lyrics']:
audiofile[tags['lyrics']] = meta_tags['lyrics']
try: try:
albumart = urllib.request.urlopen(meta_tags['album']['images'][0]['url']) albumart = urllib.request.urlopen(meta_tags['album']['images'][0]['url'])
audiofile[tags['albumart']] = [MP4Cover( audiofile[tags['albumart']] = [MP4Cover(

View File

@@ -1,11 +1,13 @@
import spotipy import spotipy
import spotipy.oauth2 as oauth2 import spotipy.oauth2 as oauth2
import lyricwikia
from titlecase import titlecase from titlecase import titlecase
import pprint
from core import internals from core import internals
from core.const import log from core.const import log
import pprint
def generate_token(): def generate_token():
""" Generate the token. Please respect these credentials :) """ """ Generate the token. Please respect these credentials :) """
@@ -52,6 +54,19 @@ def generate_metadata(raw_song):
meta_tags[u'publisher'] = album['label'] meta_tags[u'publisher'] = album['label']
meta_tags[u'total_tracks'] = album['tracks']['total'] meta_tags[u'total_tracks'] = album['tracks']['total']
log.debug('Fetching lyrics')
try:
meta_tags['lyrics'] = lyricwikia.get_lyrics(
meta_tags['artists'][0]['name'],
meta_tags['name'])
except lyricwikia.LyricsNotFound:
meta_tags['lyrics'] = None
# remove unused clutter when debug meta_tags
del meta_tags['available_markets']
del meta_tags['album']['available_markets']
log.debug(pprint.pformat(meta_tags)) log.debug(pprint.pformat(meta_tags))
return meta_tags return meta_tags

View File

@@ -71,15 +71,15 @@ def generate_youtube_url(raw_song, meta_tags, tries_remaining=5):
else: else:
song = internals.generate_songname(meta_tags) song = internals.generate_songname(meta_tags)
query['q'] = song query['q'] = song
log.debug('Query: {0}'.format(query)) log.debug('query: {0}'.format(query))
data = pafy.call_gdata('search', query) data = pafy.call_gdata('search', query)
query2 = {'part': 'contentDetails,snippet,statistics', query_results = {'part': 'contentDetails,snippet,statistics',
'maxResults': 50, 'maxResults': 50,
'id': ','.join(i['id']['videoId'] for i in data['items'])} 'id': ','.join(i['id']['videoId'] for i in data['items'])}
log.debug('Query2: {0}'.format(query2)) log.debug('query_results: {0}'.format(query_results))
vdata = pafy.call_gdata('videos', query2) vdata = pafy.call_gdata('videos', query_results)
videos = [] videos = []
for x in vdata['items']: for x in vdata['items']:
@@ -94,8 +94,6 @@ def generate_youtube_url(raw_song, meta_tags, tries_remaining=5):
if not videos: if not videos:
return None return None
log.debug(pprint.pformat(videos))
if const.args.manual: if const.args.manual:
log.info(song) log.info(song)
log.info('0. Skip downloading this song.\n') log.info('0. Skip downloading this song.\n')

View File

@@ -6,3 +6,4 @@ mutagen >= 1.37
unicode-slugify >= 0.1.3 unicode-slugify >= 0.1.3
titlecase >= 0.10.0 titlecase >= 0.10.0
logzero >= 1.3.1 logzero >= 1.3.1
lyricwikia >= 0.1.8

View File

@@ -137,7 +137,12 @@ def grab_single(raw_song, number=None):
meta_tags = spotify_tools.generate_metadata(raw_song) meta_tags = spotify_tools.generate_metadata(raw_song)
content = youtube_tools.go_pafy(raw_song, meta_tags) content = youtube_tools.go_pafy(raw_song, meta_tags)
if not content: if const.args.download_only_metadata:
if meta_tags is None:
log.info('Found No metadata. Skipping the download')
return
if content is None:
log.debug('Found no matching video') log.debug('Found no matching video')
return return
@@ -215,8 +220,8 @@ if __name__ == '__main__':
elif const.args.username: elif const.args.username:
spotify_tools.feed_playlist(username=const.args.username) spotify_tools.feed_playlist(username=const.args.username)
# Actually we don't necessarily need this, but yeah... # actually we don't necessarily need this, but yeah...
# Explicit is better than implicit! # explicit is better than implicit!
sys.exit(0) sys.exit(0)
except KeyboardInterrupt as e: except KeyboardInterrupt as e: