diff --git a/scdl/scdl.py b/scdl/scdl.py index 72956a3..19a9323 100755 --- a/scdl/scdl.py +++ b/scdl/scdl.py @@ -6,33 +6,35 @@ Usage: scdl -l [-a | -f | -t | -p][-c][-o ]\ [--hidewarnings][--debug | --error][--path ][--addtofile][--onlymp3] -[--hide-progress] +[--hide-progress][--min-size ][--max-size ] scdl me (-s | -a | -f | -t | -p)[-c][-o ]\ [--hidewarnings][--debug | --error][--path ][--addtofile][--onlymp3] -[--hide-progress] +[--hide-progress][--min-size ][--max-size ] scdl -h | --help scdl --version Options: - -h --help Show this screen - --version Show version - me Use the user profile from the auth_token - -l [url] URL can be track/playlist/user - -s Download the stream of a user (token needed) - -a Download all tracks of a user (including repost) - -t Download all uploads of a user - -f Download all favorites of a user - -p Download all playlists of a user - -c Continue if a music already exist - -o [offset] Begin with a custom offset - --path [path] Use a custom path for this time - --hidewarnings Hide Warnings. (use with precaution) - --addtofile Add the artist name to the filename if it isn't in the filename already - --onlymp3 Download only the mp3 file even if the track is Downloadable - --error Only print debug information (Error/Warning) - --debug Print every information and - --hide-progress Hide the wget progress bar + -h --help Show this screen + --version Show version + me Use the user profile from the auth_token + -l [url] URL can be track/playlist/user + -s Download the stream of a user (token needed) + -a Download all tracks of a user (including repost) + -t Download all uploads of a user + -f Download all favorites of a user + -p Download all playlists of a user + -c Continue if a music already exist + -o [offset] Begin with a custom offset + --path [path] Use a custom path for this time + --min-size [min-size] Skip tracks smaller than size (k/m/g) + --max-size [max-size] Skip tracks larger than size (k/m/g) + --hidewarnings Hide Warnings. (use with precaution) + --addtofile Add the artist name to the filename if it isn't in the filename already + --onlymp3 Download only the mp3 file even if the track is Downloadable + --error Only print debug information (Error/Warning) + --debug Print every information and + --hide-progress Hide the wget progress bar """ import logging @@ -116,6 +118,30 @@ def main(): sys.exit() logger.debug('offset: %d', offset) + if arguments['--min-size'] is not None: + try: + arguments['--min-size'] = utils.size_in_bytes( + arguments['--min-size'] + ) + except: + logger.exception( + 'Min size should be an integer with a possible unit suffix' + ) + sys.exit() + logger.debug('min-size: %d', arguments['--min-size']) + + if arguments['--max-size'] is not None: + try: + arguments['--max-size'] = utils.size_in_bytes( + arguments['--max-size'] + ) + except: + logger.error( + 'Max size should be an integer with a possible unit suffix' + ) + sys.exit() + logger.debug('max-size: %d', arguments['--max-size']) + if arguments['--hidewarnings']: warnings.filterwarnings('ignore') @@ -382,8 +408,21 @@ def download_track(track, playlist_name=None, playlist_file=None): logger.debug(url) r = requests.get(url, stream=True) temp = tempfile.NamedTemporaryFile(delete=False) + + total_length = int(r.headers.get('content-length')) + + min_size = arguments.get('--min-size') + max_size = arguments.get('--max-size') + + if min_size is not None and total_length < min_size: + logging.info('{0} not large enough, skipping'.format(title)) + return + + if max_size is not None and total_length > max_size: + logging.info('{0} too large, skipping'.format(title)) + return + with temp as f: - total_length = int(r.headers.get('content-length')) for chunk in progress.bar( r.iter_content(chunk_size=1024), expected_size=(total_length/1024) + 1, diff --git a/scdl/utils.py b/scdl/utils.py index e638211..e561272 100644 --- a/scdl/utils.py +++ b/scdl/utils.py @@ -6,6 +6,7 @@ https://github.com/davidfischer-ch/pytoolbox/blob/master/pytoolbox/logging.py """ import logging +import re from termcolor import colored __all__ = ('ColorizeFilter', ) @@ -25,3 +26,48 @@ class ColorizeFilter(logging.Filter): if color: record.msg = colored(record.msg, color) return True + + +def size_in_bytes(insize): + """ + Returns the size in bytes from strings such as '5 mb' into 5242880. + + >>> size_in_bytes('1m') + 1048576 + >>> size_in_bytes('1.5m') + 1572864 + >>> size_in_bytes('2g') + 2147483648 + >>> size_in_bytes(None) + Traceback (most recent call last): + raise ValueError('no string specified') + ValueError: no string specified + >>> size_in_bytes('') + Traceback (most recent call last): + raise ValueError('no string specified') + ValueError: no string specified + """ + if insize is None or insize.strip() == '': + raise ValueError('no string specified') + + units = { + 'k': 1024, + 'm': 1024 ** 2, + 'g': 1024 ** 3, + 't': 1024 ** 4, + 'p': 1024 ** 5, + } + match = re.search('^\s*([0-9\.]+)\s*([kmgtp])?', insize, re.I) + + if match is None: + raise ValueError('match not found') + + size, unit = match.groups() + + if size: + size = float(size) + + if unit: + size = size * units[unit.lower().strip()] + + return int(size)