def launch_file(self, filename): args = self.args query, release = file_to_query(filename) if args.query: query = args.query if args.release: release = string_set(args.release) if args.verbose: echo('Using query "{query}" and release "{release}"'.format( release=' '.join(release), query=query )) search_results = search(query) if not search_results: echo('No result') return if self.args.batch and len(search_results) > 1: raise Error('More than one result, aborting') episode = self.select(search_results) return episode and self.episode(episode, args.language, release)
def launch_file(self, filename): args = self.args query, release = file_to_query(filename) if args.query: query = args.query if args.release: release = string_set(args.release) if args.verbose: echo('Using query "{query}" and release "{release}"'.format( release=' '.join(release), query=query)) search_results = search(query) if not search_results: echo('No result') return if self.args.batch and len(search_results) > 1: raise Error('More than one result, aborting') episode = self.select(search_results) return episode and self.episode(episode, args.language, release)
def launch(self): use_multidownload = bool(get_current_user()) and \ len(self.args.file) > 1 if use_multidownload: echo('Using multi-download') Version.multidownload(*zip(*self.iter_files())) else: for (version, output_file) in self.iter_files(): version.download(output_file)
def select(self, choices): if not choices: raise Error("Internal error: no choices!") chosen_index = None skipping = False if len(choices) == 1 or self.batch: chosen_index = 1 else: just = len(str(len(choices))) index = 1 for choice in choices: echo(" {} : {}".format(str(index).rjust(just), choice)) index += 1 echo(" S : Skip") while True: answer = input('[1] > ') if not answer: chosen_index = 1 elif answer.lower() == "s": skipping = True else: try: chosen_index = int(answer) except ValueError: pass if skipping or (chosen_index and 1 <= chosen_index <= len(choices)): break else: echo("Bad response") if skipping: echo("Skipping") return None result = choices[chosen_index - 1] echo(result) return result
def select(self, choices): if not choices: raise Error("Internal error: no choices!") chosen_index = None skipping = False if len(choices) == 1 or self.batch: chosen_index = 1 else: just = len(str(len(choices))) index = 1 for choice in choices: echo(" {} : {}".format(str(index).rjust(just), choice)) index += 1 echo(" S : Skip") while True: answer = input('[1] > ') if not answer: chosen_index = 1 elif answer.lower() == "s": skipping = True else: try: chosen_index = int(answer) except ValueError: pass if skipping or (chosen_index and 1 <= chosen_index <= len(choices)): break else: echo("Bad response") if skipping: echo("Skipping") return None result = choices[chosen_index - 1] echo("{}".format(result)) return result
def launch(self): use_multidownload = bool(get_current_user()) and \ len(self.args.file) > 1 files = list(self.iter_files()) if not files: echo('Nothing to download') elif use_multidownload: echo('Using multi-download') Version.multidownload(files) else: for (version, output_file) in files: version.download(output_file)
def confirm(self, question, default=None): responses = 'yn' if default is None else 'Yn' if default else 'yN' question += ' [{}] > '.format(responses) if self.batch: return True while True: answer = input(question).lower() if answer in ('y', 'n'): return answer == 'y' elif answer == '' and default is not None: return default else: echo('Bad answer')
def get_file_alias(filename): directory, basename = os.path.split(filename) filelist_path = os.path.join(directory, 'filelist') if os.path.isfile(filelist_path): basename = remove_extension(basename) try: tree = ET.parse(filelist_path) except Exception as e: echo('Warning: unable to parse {}: {}'.format(filelist_path, e)) else: for record in tree.findall('.//record'): if remove_extension(record.get('to')) == basename: return record.get('from') return filename
def should_ignore_file(self, filename): ignore = False echo('Target SRT file:', filename) if os.path.isfile(filename): echo('File exists.', end=' ') if self.args.ignore or (not self.args.overwrite and not self.confirm('Overwrite?', True)): echo('Ignoring.') ignore = True else: echo('Overwriting.') return ignore
def select(self, choices): if not choices: raise Error("Internal error: no choices!") if len(choices) == 1 or self.batch: result = 1 else: just = len(str(len(choices))) index = 1 for choice in choices: echo(str(index).rjust(just), ':', choice) index += 1 while True: answer = input('[1] > ') if not answer: result = 1 else: try: result = int(answer) except ValueError: result = None if result and 1 <= result <= len(choices): break else: echo("Bad response") result = choices[result - 1] echo(result) return result
def iter_files(self): for file_arg in self.args.file: try: if not self.args.lang_suffix: output_file = remove_extension(file_arg) + '.srt' if self.should_ignore_file(output_file): continue version = self.launch_file(file_arg) if version: if self.args.lang_suffix: output_file = "{}.{}.srt".format( remove_extension(file_arg), version.iso639_language, ) if self.should_ignore_file(output_file): continue yield version, output_file echo() except Error as e: echo('Error:', e)
def iter_files(self): for file_arg in self.args.file: try: if not self.args.lang_suffix: output_file = remove_extension(file_arg) + '.srt' if self.should_ignore_file(output_file): continue version = self.launch_file(file_arg) if version: if self.args.lang_suffix: output_file = "{}.{}.srt".format( remove_extension(file_arg), version.iso639_language, ) if self.should_ignore_file(output_file): continue yield version, output_file echo() except Error as e: echo('Error: {}'.format(e))
def should_ignore_file(self, filename): ignore = False echo('Target SRT file: {}'.format(filename)) if os.path.isfile(filename): if self.args.ignore or (not self.args.overwrite and not self.confirm('Overwrite?', True)): echo('File exists. Ignoring.') ignore = True else: echo('File exists. Overwriting.') return ignore
def launch(self): self.args.session = None self.args.save_session() echo('Logged out')
def launch_file(self, filename): echo('-' * 30) args = self.args filename = remove_extension(filename) + '.srt' echo('Target SRT file:', filename) ignore = False if os.path.isfile(filename): echo('File exists.', end=' ') if args.ignore or (not args.overwrite and not self.confirm('Overwrite?', True)): echo('Ignoring.') ignore = True else: echo('Overwriting.') if not ignore: query, release = file_to_query(filename) if args.query: query = args.query if args.release: release = string_set(args.release) if args.verbose: echo('Using query "{query}" and release "{release}"'.format( release=' '.join(release), query=query )) search_results = search(query) if search_results: if self.args.batch and len(search_results) > 1: raise Error('More than one result, aborting') episode = self.select(search_results) todownload = self.episode(episode, args.language, release) todownload.download(filename) else: echo('No result') echo()
def launch(self): for file in self.args.file: try: self.launch_file(file) except Error as e: echo('Error:', e)
def main(): import textwrap import pkg_resources import sys version = pkg_resources.require('addic7ed-cli')[0].version epilog = ''' Authentification: You can login with your addic7ed.com identifiers to increase your daily download quota: * Anonymous users are limited to 15 downloads per 24 hours on their IP address * Registered users are limited to 40 * VIPs get 80 downloads (please consider donating) Configuration file: You can store frequently used options in a configuration file. Create a file at ~/.config/addic7ed (Linux, OSX) or %APPDATA%/config (Windows), and it will be parsed using the Python ConfigParser (see example below). It can contain three sections: * [flags], to set a flag (verbose, hearing-impaired, overwrite, ignore, batch or brute-batch, see :code:`addic7ed search --help` for informations about those flags) * [languages], to list prefered languages * [session], the session to use for authentification (this is automatically populated when using :code:`addic7ed login`) Example: [flags] hearing-impaired = no batch [languages] french english [session] abcdef Video organizer: video-organizer format is supported. If a "filelist" file is next to an episode, it will use it to extract its real name and forge the good query. See https://github.com/JoelSjogren/video-organizer for further informations. ''' namespace = Arguments() namespace.read_defaults() parser = ArgumentParser( description='Downloads SRT files from addic7ed.com.', epilog=textwrap.dedent(epilog), formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-V', '--version', action='version', version='%%(prog)s version %s' % version) parser.add_argument('-v', '--verbose', action='store_true', help='Print some debugging informations.') parser.configure_subparser(help='Command to run. If no command is given, ' 'the default is "search".', dest='command') parser.add_subparser('search', help='Search for a subtitle and download it') parser.add_argument('file', nargs='+', help='Subtitle file name. The extension will be ' 'replaced by .srt, so an existing video file name ' 'can be given.') parser.add_argument('-q', '--query', help='Custom query. (default: based on the filename)') parser.add_argument('-r', '--release', help='Custom release. (default: based on the ' 'filename)') parser.add_argument('-l', '--language', action='append', default=[], help='Prefer a language. (could be specified more ' 'than one time for fallbacks)') parser.add_argument('-H', '--hearing-impaired', action='store_true', help='Prefer hearing impaired version.', default=namespace.hearing_impaired) parser.add_argument('--no-hearing-impaired', dest='hearing_impaired', action='store_false') parser.add_argument('-o', '--overwrite', action='store_true', help='Always overwrite the SRT if it exists.', default=namespace.overwrite) parser.add_argument('--no-overwrite', dest='overwrite', action='store_false') parser.add_argument('-i', '--ignore', action='store_true', help='Never overwrite the SRT if it exists.', default=namespace.ignore) parser.add_argument('--no-ignore', dest='ignore', action='store_false') parser.add_argument('-b', '--batch', action='store_true', help='Do not ask anything, get the best matching ' 'subtitle. Cancel if the search returns more than one ' 'result.', default=namespace.batch) parser.add_argument('--no-batch', dest='batch', action='store_false') parser.add_argument('-bb', '--brute-batch', action='store_true', help='Do not ask anything, get the best matching ' 'subtitle. Use the first result of the search.', default=namespace.brute_batch) parser.add_argument('--no-brute-batch', dest='brute_batch', action='store_false') parser.add_argument('--lang-suffix', action='store_true', help='Append the lang to the output subtitle ' 'filename.', default=namespace.lang_suffix) parser.add_argument('--no-lang-suffix', dest='lang_suffix', action='store_false') parser.add_subparser('login', help='Login on addic7ed.com. This is not required.') parser.add_subparser('logout', help='Logout from addic7ed.com.') args = sys.argv[1:] if args and args[0] not in parser.first_candidates: args[0:0] = ('search', ) parser.parse_args(args=args, namespace=namespace) if not namespace.command: parser.print_usage() exit(1) if namespace.verbose: echo('Using configuration file {}'.format( namespace.configuration_path)) if namespace.session: set_session(namespace.session) user = get_current_user() if user: echo('Logged as {}'.format(user)) try: globals()[namespace.command](namespace) except Error as e: echo('Error: {}'.format(e)) exit(1) except FatalError as e: echo('Fatal error: {}'.format(e)) exit(1) except KeyboardInterrupt: echo('Aborted by user') exit(1)
def main(): import textwrap import pkg_resources import sys version = pkg_resources.require('addic7ed-cli')[0].version epilog = ''' Authentification: You can login with your addic7ed.com identifiers to increase your daily download quota: * Anonymous users are limited to 15 downloads per 24 hours on their IP address * Registered users are limited to 40 * VIPs get 80 downloads (please consider donating) Configuration file: You can store frequently used options in a configuration file. Create a file at ~/.config/addic7ed (Linux, OSX) or %APPDATA%/config (Windows), and it will be parsed using the Python ConfigParser (see example below). It can contain three sections: * [flags], to set a flag (verbose, hearing-impaired, overwrite, ignore, batch or brute-batch) * [languages], to list prefered languages * [session], the session to use for authentification Example: [flags] hearing-impaired = no batch [languages] french english [session] abcdef Video organizer: video-organizer format is supported. If a "filelist" file is next to an episode, it will use it to extract its real name and forge the good query. See https://github.com/JoelSjogren/video-organizer for further informations. ''' parser = ArgumentParser( description='Downloads SRT files from addic7ed.com.', epilog=textwrap.dedent(epilog), formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('-V', '--version', action='version', version='%%(prog)s version %s' % version) parser.add_argument('-v', '--verbose', action='store_true', help='Print some debugging informations.') parser.configure_subparser(help='Command to run. If no command is given, ' 'the default is "search".', dest='command') parser.add_subparser('search', help='Search for a subtitle and download it') parser.add_argument('file', nargs='+', help='Subtitle file name. The extension will be ' 'replaced by .srt, so an existing video file name ' 'can be given.') parser.add_argument('-q', '--query', help='Custom query. (default: based on the filename)') parser.add_argument('-r', '--release', help='Custom release. (default: based on the ' 'filename)') parser.add_argument('-l', '--language', action='append', default=[], help='Prefer a language. (could be specified more ' 'than one time for fallbacks)') parser.add_argument('-H', '--hearing-impaired', action='store_true', help='Prefer hearing impaired version.') parser.add_argument('--no-hearing-impaired', dest='hearing_impaired', action='store_false') parser.add_argument('-o', '--overwrite', action='store_true', help='Always overwrite the SRT if it exists.') parser.add_argument('-i', '--ignore', action='store_true', help='Never overwrite the SRT if it exists.') parser.add_argument('-b', '--batch', action='store_true', help='Do not ask anything, get the best matching ' 'subtitle. Cancel if the search returns more than one ' 'result.') parser.add_argument('-bb', '--brute-batch', action='store_true', help='Do not ask anything, get the best matching ' 'subtitle. Use the first result of the search.') parser.add_subparser('login', help='Login on addic7ed.com. This is not required.') parser.add_subparser('logout', help='Logout from addic7ed.com.') args = sys.argv[1:] if args and args[0] not in parser.first_candidates: args[0:0] = ('search',) namespace = Arguments() namespace.read_defaults() parser.parse_args(args=args, namespace=namespace) if not namespace.command: parser.print_usage() exit(1) if namespace.session: set_session(namespace.session) user = get_current_user() if user: echo('Logged as', user) try: globals()[namespace.command](namespace) except Error as e: echo('Error:', e) exit(1) except FatalError as e: echo('Fatal error:', e) exit(1) except KeyboardInterrupt: echo('Aborted by user') exit(1)
def launch_file(self, filename): echo('-' * 30) args = self.args filename = remove_extension(filename) + '.srt' echo('Target SRT file:', filename) ignore = False if os.path.isfile(filename): echo('File exists.', end=' ') if args.ignore or (not args.overwrite and not self.confirm('Overwrite?', True)): echo('Ignoring.') ignore = True else: echo('Overwriting.') if not ignore: query, release = file_to_query(filename) if args.query: query = args.query if args.release: release = string_set(args.release) if args.verbose: echo('Using query "{query}" and release "{release}"'.format( release=' '.join(release), query=query)) search_results = search(query) if search_results: if self.args.batch and len(search_results) > 1: raise Error('More than one result, aborting') episode = self.select(search_results) todownload = self.episode(episode, args.language, release) todownload.download(filename) else: echo('No result') echo()