Use disposable email to download emailed links

This commit is contained in:
7x11x13
2021-04-28 11:40:49 -04:00
parent 9461fccb7b
commit ff69fc50d4
3 changed files with 49 additions and 12 deletions
+4 -3
View File
@@ -1,6 +1,6 @@
# free-bandcamp-downloader # free-bandcamp-downloader
Download free and $0 minimum albums and tracks from Bandcamp Download free and $0 minimum name-your-price albums and tracks from Bandcamp (including ones that are sent to email)
## Installation ## Installation
@@ -15,7 +15,8 @@ py -m pip install git+https://github.com/7x11x13/free-bandcamp-downloader
## Usage ## Usage
```Usage: ```
Usage:
bcdl-free (-a <URL> | -l <URL>)[--force][-d | --dir <dir>][-e | --email <email>] bcdl-free (-a <URL> | -l <URL>)[--force][-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>]
@@ -36,7 +37,7 @@ Options:
-d --dir <dir> Set download directory -d --dir <dir> Set download directory
-c --country <country> Set country -c --country <country> Set country
-z --zipcode <zipcode> Set zipcode -z --zipcode <zipcode> Set zipcode
-e --email <email> Set email -e --email <email> Set email (set to 'auto' to automatically download from a disposable email)
-f --format <format> Set format -f --format <format> Set format
Formats: Formats:
- FLAC - FLAC
+1 -1
View File
@@ -22,7 +22,7 @@ default_config = \
f"""[free-bandcamp-downloader] f"""[free-bandcamp-downloader]
country = United States country = United States
zipcode = 00000 zipcode = 00000
email = email = auto
format = FLAC format = FLAC
dir = . dir = .
download_history_file = {download_history_file}""" download_history_file = {download_history_file}"""
+44 -8
View File
@@ -20,7 +20,7 @@ Options:
-d --dir <dir> Set download directory -d --dir <dir> Set download directory
-c --country <country> Set country -c --country <country> Set country
-z --zipcode <zipcode> Set zipcode -z --zipcode <zipcode> Set zipcode
-e --email <email> Set email -e --email <email> Set email (set to 'auto' to automatically download from a disposable email)
-f --format <format> Set format -f --format <format> Set format
Formats: Formats:
- FLAC - FLAC
@@ -33,7 +33,7 @@ Formats:
- AIFF - AIFF
""" """
import atexit, time, sys, urllib.request, os import atexit, time, sys, urllib.request, os, re
from docopt import docopt from docopt import docopt
from guerrillamail import GuerrillaMailSession from guerrillamail import GuerrillaMailSession
from selenium import webdriver from selenium import webdriver
@@ -47,6 +47,8 @@ from free_bandcamp_downloader import __version__, config, logger
# Global variables # Global variables
arguments = None arguments = None
driver = None driver = None
mail_session = None
expected_emails = 0
downloaded = set() downloaded = set()
options = { options = {
'country': None, 'country': None,
@@ -57,6 +59,9 @@ options = {
} }
# Constants # Constants
link_regex = re.compile('<a href="(?P<url>http[^"]*)">')
xpath = { xpath = {
'buy': '//*[@class="ft compound-button main-button"]/button[@class="download-link buy-link"]', 'buy': '//*[@class="ft compound-button main-button"]/button[@class="download-link buy-link"]',
'price': '//input[@id="userPrice"]', 'price': '//input[@id="userPrice"]',
@@ -85,6 +90,12 @@ formats = {
def wait(): def wait():
time.sleep(1) time.sleep(1)
def init_email():
global mail_session
if not mail_session and (not options['email'] or options['email'] == 'auto'):
mail_session = GuerrillaMailSession()
options['email'] = mail_session.get_session_state()['email_address']
def init_driver(): def init_driver():
global driver global driver
if not driver: if not driver:
@@ -99,7 +110,7 @@ def init_downloaded():
for line in f: for line in f:
downloaded.add(line.strip()) downloaded.add(line.strip())
def download_file(page_url): def download_file(page_url=None):
logger.info('On download page') logger.info('On download page')
driver.find_element_by_xpath(xpath['formats']).click() driver.find_element_by_xpath(xpath['formats']).click()
wait() wait()
@@ -125,9 +136,10 @@ def download_file(page_url):
response.close() response.close()
logger.info(f'Downloaded {os.path.join(options["dir"], name)}') logger.info(f'Downloaded {os.path.join(options["dir"], name)}')
# successfully downloaded file, add to download history # successfully downloaded file, add to download history
downloaded.add(page_url) if page_url:
with open(config.get('download_history_file'), 'a') as f: downloaded.add(page_url)
f.write(f'{page_url}\n') with open(config.get('download_history_file'), 'a') as f:
f.write(f'{page_url}\n')
def download_album(url): def download_album(url):
if url in downloaded and not arguments['--force']: if url in downloaded and not arguments['--force']:
@@ -162,6 +174,7 @@ def download_album(url):
wait() wait()
return download_file(url) return download_file(url)
else: else:
init_email()
logger.info('Album requires email') logger.info('Album requires email')
# fill out info # fill out info
driver.find_element_by_xpath(xpath['email']).send_keys(options['email']) driver.find_element_by_xpath(xpath['email']).send_keys(options['email'])
@@ -172,6 +185,12 @@ def download_album(url):
wait() wait()
checkout.click() checkout.click()
logger.info(f'Download link sent to {options["email"]}') logger.info(f'Download link sent to {options["email"]}')
global expected_emails
expected_emails += 1
downloaded.add(url)
with open(config.get('download_history_file'), 'a') as f:
f.write(f'{url}\n')
except Exception as e: except Exception as e:
return e return e
@@ -192,7 +211,6 @@ def main():
global arguments global arguments
arguments = docopt(__doc__, version=__version__) arguments = docopt(__doc__, version=__version__)
if arguments['-a'] or arguments['-l']: if arguments['-a'] or arguments['-l']:
init_downloaded()
# set options # set options
for option in options: for option in options:
arg = f'--{option}' arg = f'--{option}'
@@ -206,6 +224,7 @@ def main():
if options['format'] not in formats: if options['format'] not in formats:
logger.error(f'{options["format"]} is not a valid format. See "bcdl-free -h" for valid formats') logger.error(f'{options["format"]} is not a valid format. See "bcdl-free -h" for valid formats')
sys.exit(1) sys.exit(1)
init_downloaded()
if arguments['-a']: if arguments['-a']:
err = download_album(arguments['-a']) err = download_album(arguments['-a'])
if err: if err:
@@ -224,7 +243,24 @@ def main():
elif arguments['clear']: elif arguments['clear']:
with open(config.get('download_history_file'), 'w'): with open(config.get('download_history_file'), 'w'):
pass pass
# download emailed albums
checked_ids = set()
global expected_emails
logger.info(f'Waiting for {expected_emails} emails from bandcamp')
while expected_emails > 0:
time.sleep(10)
for email in mail_session.get_email_list():
if email.guid not in checked_ids:
checked_ids.add(email.guid)
if email.sender == 'noreply@bandcamp.com' and 'download' in email.subject:
logger.info(f'Received email "{email.subject}"')
email = mail_session.get_email(email.guid)
match = link_regex.search(email.body)
if match:
download_url = match.group('url')
driver.get(download_url)
download_file()
expected_emails -= 1
if __name__ == '__main__': if __name__ == '__main__':
main() main()