Last active 1522694835

Google Music player in the terminal woopwoop | Individual song playback implemented, album support coming soon?

gmusicplay.py Raw
1#!/usr/bin/env python3
2from gmusicapi import Mobileclient
3import os
4from json import load
5import sys
6
7def mkdir_p(path):
8 import errno
9 try:
10 os.makedirs(path)
11 except OSError as exc:
12 if exc.errno == errno.EEXIST and os.path.isdir(path):
13 pass
14 else:
15 raise
16
17mkdir_p(os.path.expanduser("~/.config"))
18with open(os.path.expanduser("~/.config/gmusic.json")) as f:
19 CONFIG = load(f)
20
21client = Mobileclient()
22client.login(*CONFIG)
23
24def search(term, results=10):
25 results = client.search(term, max_results=results)
26 return {"album": [client.get_album_info(x["album"]["albumId"]) for x in results["album_hits"]],
27 "artist": [client.get_artist_info(x["artist"]["artistId"], max_rel_artist=0) for x in results["artist_hits"]],
28 "playlist": [client.get_shared_playlist_contents(x["playlist"]["shareToken"]) for x in results["playlist_hits"]],
29 "podcast": [client.get_podcast_series_info(x["series"]["seriesId"]) for x in results["podcast_hits"]],
30 "song": [x["track"] for x in results["song_hits"]],
31 "video": [x.get("youtube_video", None) for x in results["video_hits"]],
32 }
33
34def get_stream(results, selection):
35 section, _, n = selection.partition("#")
36 if not section in results:
37 raise ValueError("Invalid section name")
38 n = int(n)
39 if n+1 > len(results[section]):
40 raise ValueError("Invalid number")
41 result = results[section][n]
42 if section == "song":
43 return client.get_stream_url(result.get("storeId") or result.get("id"))
44 else:
45 raise NotImplemented
46
47get_stream.supported = ["song"]
48
49def main():
50 from argparse import ArgumentParser
51 parser = ArgumentParser()
52 parser.add_argument("term", nargs="+")
53 parser.add_argument("-n", help="number of results returned", type=int, default=10)
54 args = parser.parse_args()
55 results = search(args.term, results=args.n)
56 for section in results:
57 if section in get_stream.supported:
58 print("\n".join("{}#{}: {}".format(section, n, i["title"]) for n,i in enumerate(results[section]) if type(i) is dict and i.get("title")), file=sys.stderr)
59 print("Selection (section#number): ", end="", file=sys.stderr)
60 print(get_stream(results, input()))
61 return 0
62
63if __name__ == "__main__":
64 sys.exit(main())
65