Created
January 7, 2018 05:40
-
-
Save tevino/3bf787d4a1b951a0249901f1c3da25a9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import os | |
import sys | |
import HTMLParser | |
from json import loads | |
from urllib2 import urlopen | |
from urllib import urlretrieve | |
from threading import Thread | |
from mutagen.mp3 import MP3 | |
from mutagen.id3 import ID3, APIC, error | |
from mutagen.easyid3 import EasyID3 | |
folder = 'Xiami' | |
if not os.path.exists(folder): | |
os.mkdir(folder) | |
h = HTMLParser.HTMLParser() | |
progress = {} | |
class CoverSetter(Thread): | |
def __init__(self, cover_url, filename, **kwargs): | |
self.cover_url = cover_url | |
self.cover_ext = cover_url.split('.')[-1].lower() | |
self.filename = filename | |
for k, v in kwargs.iteritems(): | |
setattr(self, k, v) | |
return super(CoverSetter, self).__init__() | |
def run(self): | |
self.cover = urlopen(self.cover_url).read() | |
self.set_cover() | |
def set_cover(self): | |
f = MP3(self.filename, ID3=ID3) | |
# add ID3 tag if not | |
try: | |
f.add_tags() | |
except error: | |
pass | |
f.tags.add( | |
APIC( | |
encoding=3, # 3 is for utf-8 | |
mime='image/' + self.cover_ext, # image/jpeg or image/png | |
type=3, # 3 is for the cover image | |
desc=u'Cover', | |
data=self.cover | |
) | |
) | |
f.save() | |
f = EasyID3(self.filename) | |
f['title'] = self.title | |
f['artist'] = self.artist | |
f['album'] = self.album | |
f.save() | |
progress[self.filename] = True # flag as finished | |
class Downloader(Thread): | |
def __init__(self, url, cover_url, filename, **kwargs): | |
self.url = url | |
self.filename = filename | |
self.cover_url = cover_url | |
self.kwargs = kwargs | |
return super(Downloader, self).__init__() | |
def run(self): | |
urlretrieve(self.url, self.filename, self.on_report) | |
def on_report(self, blocks, bs, total): | |
p = float(blocks * bs) / total | |
progress[self.filename] = p | |
print('%s/%s' % (sum(progress.values()), len(progress))) | |
if p >= 1: | |
td = CoverSetter(self.cover_url, self.filename, **self.kwargs) | |
td.start() | |
td.join() | |
def cleanup(): | |
print('cleaning up...') | |
for k, v in progress.items(): | |
if v is not True: | |
print('remove %s' % k) | |
os.remove(k) | |
if __name__ == '__main__': | |
try: | |
uid = sys.argv[1] | |
except IndexError: | |
uid = None | |
while not uid: | |
uid = raw_input('Xiami uid:') | |
rv = urlopen('http://api.xiami.com/app/android/lib-songs?uid=' + uid).read() | |
downloaders = [] | |
for s in loads(rv)['songs']: | |
title = s['name'] | |
album = s['title'] | |
artist = s['artist_name'] | |
cover_url = s['album_logo'] | |
url = s['location'] | |
ext = '.' + s['listen_file'].split('.')[-1] | |
filename = h.unescape('%(title)s - %(album)s - %(artist)s' % locals()) | |
filename = filename.strip('-') + ext | |
downloaders.append(Downloader( | |
url, | |
cover_url, | |
os.path.join(folder, filename), | |
title=title, | |
album=album, | |
artist=artist)) | |
try: | |
for d in downloaders: | |
d.start() | |
d.join() | |
finally: | |
cleanup() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
From: Fri Jun 13 16:51:59 2014 +0800