Last active
November 7, 2015 07:59
-
-
Save tribela/ac362489bb263594fb25 to your computer and use it in GitHub Desktop.
bandcamp album downloader
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
import Queue | |
import json | |
import os | |
import re | |
import sys | |
import threading | |
import urllib2 | |
from contextlib import closing | |
URL_FORMAT = 'http://{0}.bandcamp.com/{1}/{2}' | |
PATTERN = re.compile(r'\s*trackinfo\s*:\s*(\[.*\]),') | |
THREAD_NUM = 8 | |
def downloader(queue): | |
while not queue.empty(): | |
filename, url = queue.get() | |
try: | |
with closing(urllib2.urlopen(url)) as stream: | |
with open(filename, 'w') as fp: | |
fp.write(stream.read()) | |
print(u'Done: {0}'.format(filename)) | |
except: | |
print(u'Cannot download {0}: {1}'.format(filename, url)) | |
finally: | |
queue.task_done() | |
def download_album(artist, album): | |
queue = Queue.Queue() | |
threads = [threading.Thread(target=downloader, args=(queue,)) | |
for _ in range(THREAD_NUM)] | |
try: | |
url = URL_FORMAT.format(artist, 'album', album) | |
with closing(urllib2.urlopen(url)) as fp: | |
content = fp.read() | |
dir_name = u'{0}/{1}'.format(artist, album) | |
except urllib2.HTTPError: | |
url = URL_FORMAT.format(artist, 'track', album) | |
with closing(urllib2.urlopen(url)) as fp: | |
content = fp.read() | |
dir_name = artist | |
print(url) | |
json_data = PATTERN.search(content).group(1) | |
data = json.loads(json_data) | |
if not os.path.exists(artist): | |
os.mkdir(artist) | |
if not os.path.exists(dir_name): | |
os.mkdir(dir_name) | |
for index, song in enumerate(data): | |
title = song['title'] | |
url = song['file']['mp3-128'] | |
if url.startswith('//'): | |
url = 'http:' + url | |
filename = u'{0}/{1:02d}-{2}.mp3'.format(dir_name, index + 1, title) | |
queue.put((filename, url)) | |
print(u'{0}: {1}'.format(filename, url)) | |
for thread in threads: | |
thread.setDaemon(True) | |
thread.start() | |
queue.join() | |
for thread in threads: | |
thread.join() | |
if __name__ == '__main__': | |
download_album(sys.argv[1], sys.argv[2]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment