diff --git a/README.md b/README.md index 28d3082..f5ed05f 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ pip install git+https://github.com/7x11x13/free-bandcamp-downloader ``` Usage: - bcdl-free (-a | -l )[--force][-d | --dir ][-e | --email ] + bcdl-free (-a | -l )[--force][--no-unzip][-d | --dir ][-e | --email ] [-z | --zipcode ][-c | --country ][-f | --format ] bcdl-free setdefault [-d | --dir ][-e | --email ][-z | --zipcode ] [-c | --country ][-f | --format ] @@ -32,6 +32,7 @@ Options: -a Download the album at URL -l Download all free albums of the label at URL --force Download even if album has been downloaded before + --no-unzip Don't unzip downloaded albums setdefault Set default options defaults List the default options clear Clear download history diff --git a/free_bandcamp_downloader/main.py b/free_bandcamp_downloader/main.py index ca0275a..fa17d94 100644 --- a/free_bandcamp_downloader/main.py +++ b/free_bandcamp_downloader/main.py @@ -1,6 +1,6 @@ """Download free albums and tracks from Bandcamp Usage: - bcdl-free (-a | -l )[--force][-d | --dir ][-e | --email ] + bcdl-free (-a | -l )[--force][--no-unzip][-d | --dir ][-e | --email ] [-z | --zipcode ][-c | --country ][-f | --format ] bcdl-free setdefault [-d | --dir ][-e | --email ][-z | --zipcode ] [-c | --country ][-f | --format ] @@ -14,6 +14,7 @@ Options: -a Download the album at URL -l Download all free albums of the label at URL --force Download even if album has been downloaded before + --no-unzip Don't unzip downloaded albums setdefault Set default options defaults List the default options clear Clear download history @@ -83,8 +84,8 @@ xpath = { 'country': '//select[@id="fan_email_country"]', 'zipcode': '//input[@id="fan_email_postalcode"]', 'preparing': '//span[@class="preparing-title"]', - 'formats': '//div[@class="item-format button"]', - 'download': '//a[@class="item-button"]', + 'formats': '//select[@id="format-type"]', + 'download': '//div[@class="download-format-tmp"]/a[1]', 'albums': '//a[./p[@class="title"]]', 'album-link': '//div[@class="download-artwork"]/a', 'album-tags': '//div[contains(@class, "tralbum-tags-nu")]', @@ -93,14 +94,14 @@ xpath = { } formats = { - 'FLAC': 'FLAC', - 'V0MP3': 'MP3 V0', - '320MP3': 'MP3 320', - 'AAC': 'AAC', - 'Ogg': 'Ogg Vorbis', - 'ALAC': 'ALAC', - 'WAV': 'WAV', - 'AIFF': 'AIFF' + 'FLAC': 'flac', + 'V0MP3': 'mp3-v0', + '320MP3': 'mp3-320', + 'AAC': 'aac-hi', + 'Ogg': 'vorbis', + 'ALAC': 'alac', + 'WAV': 'wav', + 'AIFF': 'aiff-lossless' } @@ -119,7 +120,7 @@ def get_driver(): options = Options() options.add_argument('--headless') driver = webdriver.Firefox( - firefox_options=options, service_log_path=os.devnull) + options=options, service_log_path=os.devnull) driver.implicitly_wait(10) return driver @@ -132,18 +133,18 @@ def init_downloaded(): def download_file(driver, album_data=None): logger.info('On download page') - page_url = driver.find_element_by_xpath( + page_url = driver.find_element("xpath", 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: album_data = mail_album_data[page_url] - driver.find_element_by_xpath(xpath['formats']).click() + driver.find_element("xpath", xpath['formats']).click() wait() - driver.find_element_by_xpath( - f'//*[text() = "{formats[options["format"]]}"]').click() + driver.find_element("xpath", + f'//option[@value="{formats[options["format"]]}"]').click() logger.info(f'Set format to {formats[options["format"]]}') wait() - button = driver.find_element_by_xpath(xpath['download']) + button = driver.find_element("xpath", xpath['download']) WebDriverWait(driver, 60).until(EC.visibility_of(button)) url = button.get_attribute('href') 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}%') response.close() logger.info(f'Downloaded {file_name}') - if file_name.endswith('zip'): + if file_name.endswith('zip') and not arguments['--no-unzip']: # Unzip archive dir_name = file_name[:-4] with zipfile.ZipFile(file_name, 'r') as f: 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) files = glob.glob(os.path.join(dir_name, "*")) else: @@ -230,21 +231,21 @@ def download_album(driver, url): 'tags': None } try: - s = driver.find_element_by_xpath( + s = driver.find_element("xpath", xpath['album-about']).get_attribute('innerHTML') s = get_text(s) album_data['about'] = s except Exception as e: logger.info(f"Could not get album about - {e.__class__}: {e}") try: - s = driver.find_element_by_xpath( + s = driver.find_element("xpath", xpath['album-credits']).get_attribute('innerHTML') s = get_text(s) album_data['credits'] = s except Exception as e: logger.info(f"Could not get album credits - {e.__class__}: {e}") try: - s = driver.find_element_by_xpath( + s = driver.find_element("xpath", xpath['album-tags']).get_attribute('innerHTML') tags = {a.text for a in BeautifulSoup( s, features='html.parser', parse_only=SoupStrainer('a'))} @@ -254,7 +255,7 @@ def download_album(driver, url): 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': logger.info(f'{url} is Free Download') button.click() @@ -265,16 +266,16 @@ def download_album(driver, url): logger.info(f'{url} is not Free Download') button.click() wait() - price_input = driver.find_element_by_xpath(xpath['price']) + price_input = driver.find_element("xpath", xpath['price']) price_input.click() price_input.send_keys('0') wait() try: - driver.find_element_by_xpath(xpath['download-nyp']).click() + driver.find_element("xpath", xpath['download-nyp']).click() except: logger.error(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': checkout.click() wait() @@ -283,13 +284,13 @@ def download_album(driver, url): init_email() logger.info(f'{url} requires email') # fill out info - driver.find_element_by_xpath( + driver.find_element("xpath", xpath['email']).send_keys(options['email']) wait() - driver.find_element_by_xpath( + driver.find_element("xpath", xpath['zipcode']).send_keys(options['zipcode']) wait() - Select(driver.find_element_by_xpath( + Select(driver.find_element("xpath", xpath['country'])).select_by_visible_text(options['country']) wait() checkout.click() @@ -309,8 +310,10 @@ def download_albums(driver, urls): def download_label(driver, url): driver.get(url) + global BASE_URL + BASE_URL = urlsplit(url).netloc 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')) download_albums(driver, links)