Open knichel opened 11 years ago
I think I'm going to do a quick overhaul on this script while on the train =)
I'll definitely include this feature, but probably in the form of multiple input files, so you could do something like $ script.py my-dir/*
.
My implementation simply took the folder as the input and anything in the folder is used.
On Fri, Oct 11, 2013 at 3:07 PM, Simon Weber notifications@github.comwrote:
I think I'm going to do a quick overhaul on this script while on the train =)
I'll definitely include this feature, but probably in the form of multiple input files, so you could do something like $ script.py my-dir/*.
— Reply to this email directly or view it on GitHubhttps://github.com/simon-weber/Google-Music-Playlist-Importer/issues/4#issuecomment-26163384 .
Michael Knichel
I have started working with this again after having to step away for a while. I am now trying to get the single import to work and I keep getting 0 matches. Can you look to see where I might have an inssue?
"""Python script to import local playlists to Google Music."""
import re
import sys
import codecs
from getpass import getpass
import chardet
import gmusicapi.gmtools.tools as gm_tools
from gmusicapi import Mobileclient
def init(max_attempts=3):
"""Makes an instance of the api and attempts to login with it.
Returns the api after at most max_attempts.
:param max_attempts:
"""
api = Mobileclient()
logged_in = False
attempts = 0
print "Log in to Google Music."
while not logged_in and attempts < max_attempts:
email = raw_input("Email: ")
password = getpass()
logged_in = api.login(email, password)
attempts += 1
return api
def guess_encoding(filename):
"""Returns a tuple of (guessed encoding, confidence).
:param filename:
"""
res = chardet.detect(open(filename).read())
return (res['encoding'], res['confidence'])
def main():
if not len(sys.argv) == 2:
print "usage:", sys.argv[0], "<playlist file>"
sys.exit(0)
#The three md_ lists define the format of the playlist and how matching
should be done against the library.
#They must all have the same number of elements.
#Where this pattern matches, a query will be formed from the captures.
#My example matches against a playlist file with lines like:
# /home/simon/music/library/The Cat Empire/Live on Earth/The Car
Song.mp3
#Make sure it won't match lines that don't contain song info!
#File4=file:///backup/MUSIC/Asia/Asia/One Step Closer.mp3
md_pattern = r"^File{[0-9]+}=file:///backup/MUSIC/(.*)/(.*)/(.*)\..*$"
#Identify what metadata each capture represents.
#These need to be valid fields in the GM json - see protocol_info in
the api repo.
md_cap_types = ('artist', 'album', 'title')
#The lower-better priority of the capture types above.
#In this example, I order title first, then artist, then album.
md_cap_pr = (2,3,1)
#Build queries from the playlist.
playlist_fname = sys.argv[1]
pl_encoding, confidence = guess_encoding(playlist_fname)
queries = None
with codecs.open(playlist_fname, encoding=pl_encoding, mode='r') as f:
queries = gm_tools.build_queries_from(f,
re.compile(md_pattern),
md_cap_types,
md_cap_pr,
pl_encoding)
api = init()
if not api.is_authenticated():
print "Failed to log in."
sys.exit(0)
print "Loading library from Google Music..."
library = api.get_all_songs()
print "Matching songs..."
matcher = gm_tools.SongMatcher(library)
matched_songs = matcher.match(queries)
res = raw_input("Output matches to file or terminal? (f/t): ")
if res == "t":
print matcher.build_log()
elif res == "f":
res = raw_input("Filename to write to: ")
with open(res, mode='w') as f:
f.write(matcher.build_log())
print "File written."
go = raw_input("Create playlist from these matches? (y/n): ")
if go == "y":
name = raw_input("playlist name: ")
p_id = api.create_playlist(name)['id']
print "Made playlist", name
res = api.add_songs_to_playlist(p_id,
map(gm_tools.filter_song_md, matched_songs))
print "Added songs."
if __name__ == '__main__':
main()
playlist file:
[playlist]
X-GNOME-Title=Asia
NumberOfEntries=9
File1=file:///backup/MUSIC/Asia/Asia/Cuttin' It Fine.mp3
Title1=Cutting It Fine
File2=file:///backup/MUSIC/Asia/Asia/Heat of the Moment.mp3
Title2=Heat of the Moment
File3=file:///backup/MUSIC/Asia/Asia/Here Comes The Feeling.mp3
Title3=Here Comes The Feeling
File4=file:///backup/MUSIC/Asia/Asia/One Step Closer.mp3
Title4=One Step Closer
File5=file:///backup/MUSIC/Asia/Asia/Only Time Will Tell.mp3
Title5=Only Time Will Tell
File6=file:///backup/MUSIC/Asia/Asia/Sole Survivor.mp3
Title6=Sole Survivor
File7=file:///backup/MUSIC/Asia/Asia/Time Again.mp3
Title7=Time Again
File8=file:///backup/MUSIC/Asia/Asia/Wildest Dreams.mp3
Title8=Wildest Dreams
File9=file:///backup/MUSIC/Asia/Asia/Without You.mp3
Title9=Without You
Here is the output in terminal (I have embedded my login credentials to the code I am running):
Log in to Google Music.
Loading library from Google Music...
Matching songs...
Output matches to file or terminal? (f/t): t
### Starting match of 0 queries ###
Create playlist from these matches? (y/n): n
get_all_songs is broken at the moment: https://github.com/simon-weber/Unofficial-Google-Music-API/issues/221.
I'll check this out once it's working again.
I have been working on modifying the script to accept a directory of playlist files. If I make a playlist and run it through the original script, it works. If I copy it to a second file with a different name and run it through my version it works and imports both playlists. However if I I export 2 separate playlists, it works on the first but fails on the second with this error right after the print "Matching Songs..." Traceback (most recent call last): File "test_gm_playlists_importer.py", line 145, in
main()
File "test_gm_playlists_importer.py", line 115, in main
matched_songs = matcher.match(queries)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/gmtools/tools.py", line 393, in match
res = self.query_library(query, tie_breaker, auto=auto)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/gmtools/tools.py", line 311, in query_library
next_results = self.query_library(query, tie_breaker, current_mods, auto)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/gmtools/tools.py", line 311, in query_library
next_results = self.query_library(query, tie_breaker, current_mods, auto)
File "/usr/local/lib/python2.7/dist-packages/gmusicapi/gmtools/tools.py", line 309, in query_library
raise self.TieBroken(tie_breaker(query, results))
TypeError: 'staticmethod' object is not callable
My code is as follows