Merge pull request #1 from yoshiyoshyosh/fixed_from_updates

fix removed functions and matching, add --no-unzip
This commit is contained in:
7x11x13
2023-11-17 16:02:11 -05:00
committed by GitHub
2 changed files with 36 additions and 32 deletions
+2 -1
View File
@@ -18,7 +18,7 @@ pip install git+https://github.com/7x11x13/free-bandcamp-downloader
``` ```
Usage: Usage:
bcdl-free (-a <URL> | -l <URL>)[--force][-d | --dir <dir>][-e | --email <email>] bcdl-free (-a <URL> | -l <URL>)[--force][--no-unzip][-d | --dir <dir>][-e | --email <email>]
[-z | --zipcode <zipcode>][-c | --country <country>][-f | --format <format>] [-z | --zipcode <zipcode>][-c | --country <country>][-f | --format <format>]
bcdl-free setdefault [-d | --dir <dir>][-e | --email <email>][-z | --zipcode <zipcode>] bcdl-free setdefault [-d | --dir <dir>][-e | --email <email>][-z | --zipcode <zipcode>]
[-c | --country <country>][-f | --format <format>] [-c | --country <country>][-f | --format <format>]
@@ -32,6 +32,7 @@ Options:
-a <URL> Download the album at URL -a <URL> Download the album at URL
-l <URL> Download all free albums of the label at URL -l <URL> Download all free albums of the label at URL
--force Download even if album has been downloaded before --force Download even if album has been downloaded before
--no-unzip Don't unzip downloaded albums
setdefault Set default options setdefault Set default options
defaults List the default options defaults List the default options
clear Clear download history clear Clear download history
+34 -31
View File
@@ -1,6 +1,6 @@
"""Download free albums and tracks from Bandcamp """Download free albums and tracks from Bandcamp
Usage: Usage:
bcdl-free (-a <URL> | -l <URL>)[--force][-d | --dir <dir>][-e | --email <email>] bcdl-free (-a <URL> | -l <URL>)[--force][--no-unzip][-d | --dir <dir>][-e | --email <email>]
[-z | --zipcode <zipcode>][-c | --country <country>][-f | --format <format>] [-z | --zipcode <zipcode>][-c | --country <country>][-f | --format <format>]
bcdl-free setdefault [-d | --dir <dir>][-e | --email <email>][-z | --zipcode <zipcode>] bcdl-free setdefault [-d | --dir <dir>][-e | --email <email>][-z | --zipcode <zipcode>]
[-c | --country <country>][-f | --format <format>] [-c | --country <country>][-f | --format <format>]
@@ -14,6 +14,7 @@ Options:
-a <URL> Download the album at URL -a <URL> Download the album at URL
-l <URL> Download all free albums of the label at URL -l <URL> Download all free albums of the label at URL
--force Download even if album has been downloaded before --force Download even if album has been downloaded before
--no-unzip Don't unzip downloaded albums
setdefault Set default options setdefault Set default options
defaults List the default options defaults List the default options
clear Clear download history clear Clear download history
@@ -83,8 +84,8 @@ xpath = {
'country': '//select[@id="fan_email_country"]', 'country': '//select[@id="fan_email_country"]',
'zipcode': '//input[@id="fan_email_postalcode"]', 'zipcode': '//input[@id="fan_email_postalcode"]',
'preparing': '//span[@class="preparing-title"]', 'preparing': '//span[@class="preparing-title"]',
'formats': '//div[@class="item-format button"]', 'formats': '//select[@id="format-type"]',
'download': '//a[@class="item-button"]', 'download': '//div[@class="download-format-tmp"]/a[1]',
'albums': '//a[./p[@class="title"]]', 'albums': '//a[./p[@class="title"]]',
'album-link': '//div[@class="download-artwork"]/a', 'album-link': '//div[@class="download-artwork"]/a',
'album-tags': '//div[contains(@class, "tralbum-tags-nu")]', 'album-tags': '//div[contains(@class, "tralbum-tags-nu")]',
@@ -93,14 +94,14 @@ xpath = {
} }
formats = { formats = {
'FLAC': 'FLAC', 'FLAC': 'flac',
'V0MP3': 'MP3 V0', 'V0MP3': 'mp3-v0',
'320MP3': 'MP3 320', '320MP3': 'mp3-320',
'AAC': 'AAC', 'AAC': 'aac-hi',
'Ogg': 'Ogg Vorbis', 'Ogg': 'vorbis',
'ALAC': 'ALAC', 'ALAC': 'alac',
'WAV': 'WAV', 'WAV': 'wav',
'AIFF': 'AIFF' 'AIFF': 'aiff-lossless'
} }
@@ -119,7 +120,7 @@ def get_driver():
options = Options() options = Options()
options.add_argument('--headless') options.add_argument('--headless')
driver = webdriver.Firefox( driver = webdriver.Firefox(
firefox_options=options, service_log_path=os.devnull) options=options, service_log_path=os.devnull)
driver.implicitly_wait(10) driver.implicitly_wait(10)
return driver return driver
@@ -132,18 +133,18 @@ def init_downloaded():
def download_file(driver, album_data=None): def download_file(driver, album_data=None):
logger.info('On download page') logger.info('On download page')
page_url = driver.find_element_by_xpath( page_url = driver.find_element("xpath",
xpath['album-link']).get_attribute('href') xpath['album-link']).get_attribute('href')
page_url = urlsplit(page_url).geturl() page_url = 'https://' + BASE_URL + urlsplit(page_url).path
if album_data is None: if album_data is None:
album_data = mail_album_data[page_url] album_data = mail_album_data[page_url]
driver.find_element_by_xpath(xpath['formats']).click() driver.find_element("xpath", xpath['formats']).click()
wait() wait()
driver.find_element_by_xpath( driver.find_element("xpath",
f'//*[text() = "{formats[options["format"]]}"]').click() f'//option[@value="{formats[options["format"]]}"]').click()
logger.info(f'Set format to {formats[options["format"]]}') logger.info(f'Set format to {formats[options["format"]]}')
wait() wait()
button = driver.find_element_by_xpath(xpath['download']) button = driver.find_element("xpath", xpath['download'])
WebDriverWait(driver, 60).until(EC.visibility_of(button)) WebDriverWait(driver, 60).until(EC.visibility_of(button))
url = button.get_attribute('href') url = button.get_attribute('href')
response = urllib.request.urlopen(url) response = urllib.request.urlopen(url)
@@ -163,12 +164,12 @@ def download_file(driver, album_data=None):
logger.info(f'Downloading {name}, {size / length * 100: .1f}%') logger.info(f'Downloading {name}, {size / length * 100: .1f}%')
response.close() response.close()
logger.info(f'Downloaded {file_name}') logger.info(f'Downloaded {file_name}')
if file_name.endswith('zip'): if file_name.endswith('zip') and not arguments['--no-unzip']:
# Unzip archive # Unzip archive
dir_name = file_name[:-4] dir_name = file_name[:-4]
with zipfile.ZipFile(file_name, 'r') as f: with zipfile.ZipFile(file_name, 'r') as f:
f.extractall(dir_name) f.extractall(dir_name)
logger.info(f'Unzipped to {dir_name}') logger.info(f'Unzipped to {dir_name}. Use --no-unzip to prevent this')
os.remove(file_name) os.remove(file_name)
files = glob.glob(os.path.join(dir_name, "*")) files = glob.glob(os.path.join(dir_name, "*"))
else: else:
@@ -230,21 +231,21 @@ def download_album(driver, url):
'tags': None 'tags': None
} }
try: try:
s = driver.find_element_by_xpath( s = driver.find_element("xpath",
xpath['album-about']).get_attribute('innerHTML') xpath['album-about']).get_attribute('innerHTML')
s = get_text(s) s = get_text(s)
album_data['about'] = s album_data['about'] = s
except Exception as e: except Exception as e:
logger.info(f"Could not get album about - {e.__class__}: {e}") logger.info(f"Could not get album about - {e.__class__}: {e}")
try: try:
s = driver.find_element_by_xpath( s = driver.find_element("xpath",
xpath['album-credits']).get_attribute('innerHTML') xpath['album-credits']).get_attribute('innerHTML')
s = get_text(s) s = get_text(s)
album_data['credits'] = s album_data['credits'] = s
except Exception as e: except Exception as e:
logger.info(f"Could not get album credits - {e.__class__}: {e}") logger.info(f"Could not get album credits - {e.__class__}: {e}")
try: try:
s = driver.find_element_by_xpath( s = driver.find_element("xpath",
xpath['album-tags']).get_attribute('innerHTML') xpath['album-tags']).get_attribute('innerHTML')
tags = {a.text for a in BeautifulSoup( tags = {a.text for a in BeautifulSoup(
s, features='html.parser', parse_only=SoupStrainer('a'))} s, features='html.parser', parse_only=SoupStrainer('a'))}
@@ -254,7 +255,7 @@ def download_album(driver, url):
logger.info(f"Album data: {album_data}") logger.info(f"Album data: {album_data}")
button = driver.find_element_by_xpath(xpath['buy']) button = driver.find_element("xpath", xpath['buy'])
if button.text == 'Free Download': if button.text == 'Free Download':
logger.info(f'{url} is Free Download') logger.info(f'{url} is Free Download')
button.click() button.click()
@@ -265,16 +266,16 @@ def download_album(driver, url):
logger.info(f'{url} is not Free Download') logger.info(f'{url} is not Free Download')
button.click() button.click()
wait() wait()
price_input = driver.find_element_by_xpath(xpath['price']) price_input = driver.find_element("xpath", xpath['price'])
price_input.click() price_input.click()
price_input.send_keys('0') price_input.send_keys('0')
wait() wait()
try: try:
driver.find_element_by_xpath(xpath['download-nyp']).click() driver.find_element("xpath", xpath['download-nyp']).click()
except: except:
logger.error(f'{url} is not free') logger.error(f'{url} is not free')
return f'{url} is not free' return f'{url} is not free'
checkout = driver.find_element_by_xpath(xpath['checkout']) checkout = driver.find_element("xpath", xpath['checkout'])
if checkout.text == 'Download Now': if checkout.text == 'Download Now':
checkout.click() checkout.click()
wait() wait()
@@ -283,13 +284,13 @@ def download_album(driver, url):
init_email() init_email()
logger.info(f'{url} requires email') logger.info(f'{url} requires email')
# fill out info # fill out info
driver.find_element_by_xpath( driver.find_element("xpath",
xpath['email']).send_keys(options['email']) xpath['email']).send_keys(options['email'])
wait() wait()
driver.find_element_by_xpath( driver.find_element("xpath",
xpath['zipcode']).send_keys(options['zipcode']) xpath['zipcode']).send_keys(options['zipcode'])
wait() wait()
Select(driver.find_element_by_xpath( Select(driver.find_element("xpath",
xpath['country'])).select_by_visible_text(options['country']) xpath['country'])).select_by_visible_text(options['country'])
wait() wait()
checkout.click() checkout.click()
@@ -309,8 +310,10 @@ def download_albums(driver, urls):
def download_label(driver, url): def download_label(driver, url):
driver.get(url) driver.get(url)
global BASE_URL
BASE_URL = urlsplit(url).netloc
links = [] links = []
for album in driver.find_elements_by_xpath(xpath['albums']): for album in driver.find_elements("xpath", xpath['albums']):
links.append(album.get_attribute('href')) links.append(album.get_attribute('href'))
download_albums(driver, links) download_albums(driver, links)