Skip to content

Instantly share code, notes, and snippets.

@tribela
Last active November 7, 2015 07:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tribela/ac362489bb263594fb25 to your computer and use it in GitHub Desktop.
Save tribela/ac362489bb263594fb25 to your computer and use it in GitHub Desktop.
bandcamp album downloader
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