def build_problem_pdf(problem): prepare_problem(problem) builddir = config.tmpdir / problem.id util.copy_and_substitute( config.tools_root / 'latex/problem.tex', builddir / 'problem.tex', { 'problemlabel': problem.label, 'problemyamlname': problem.config['name'], 'problemauthor': problem.config.get('author'), 'timelimit': get_tl(problem.config), 'problemdir': builddir, }) ensure_symlink(builddir / 'bapc.cls', config.tools_root / 'latex/bapc.cls') for i in range(3): ok, err, out = util.exec_command( PDFLATEX + ['-output-directory', builddir, builddir / 'problem.tex'], 0, False, cwd=builddir, stdout=subprocess.PIPE) if ok is not True: print(f'{_c.red}Failure compiling pdf:{_c.reset}\n{out}') return False # link the output pdf output_pdf = problem.path / 'problem.pdf' ensure_symlink(output_pdf, builddir / 'problem.pdf', True) print(f'{_c.green}Pdf written to {output_pdf}{_c.reset}') return True
def run_scons(variables=[]): packages_dir = os.path.join(util.get_home_dir(), 'packages') # Give the priority to the packages installed by apio os.environ['PATH'] = os.pathsep.join([ os.path.join(packages_dir, 'toolchain-icestorm', 'bin'), os.environ['PATH'] ]) util.exec_command( [ os.path.normpath( sys.executable), # TODO: find python2 if executed with python3 os.path.join(packages_dir, 'tool-scons', 'script', 'scons'), '-Q' ] + variables, stdout=util.AsyncPipe(on_run_out), stderr=util.AsyncPipe(on_run_err))
def execNetstatCmd(self, *args): """Execute ps command with positional params args and return result as list of lines. @param *args: Positional params for netstat command. @return: List of output lines """ out = util.exec_command([netstatCmd,] + list(args)) return out.splitlines()
def custom_output_validator(testcase, outfile, settings, output_validators): flags = [] if settings.space_change_sensitive: flags += ['space_change_sensitive'] if settings.case_sensitive: flags += ['case_sensitive'] run_all_validators = hasattr(settings, 'all_validators') and settings.all_validators ok = None err = None out = None for output_validator in output_validators: header = output_validator[0] + ': ' if len( output_validators) > 1 else '' with open(outfile, 'r') as outf: judgepath = config.tmpdir / 'judge' judgepath.mkdir(parents=True, exist_ok=True) judgemessage = judgepath / 'judgemessage.txt' judgeerror = judgepath / 'judgeerror.txt' val_ok, err, out = util.exec_command(output_validator[1] + [ testcase.with_suffix('.in'), testcase.with_suffix('.ans'), judgepath ] + flags, expect=config.RTV_AC, stdin=outf) if err is None: err = '' if judgemessage.is_file(): err += judgemessage.read_text() judgemessage.unlink() if judgeerror.is_file(): # Remove any std output because it will usually only contain the err = judgeerror.read_text() judgeerror.unlink() if err: err = header + err if ok == None: ok = val_ok if run_all_validators and val_ok != ok: ok = 'INCONSISTENT_VALIDATORS' err = 'INCONSISTENT VALIDATORS: ' + err return (ok, err, out) if val_ok is True: continue if not run_all_validators: break if ok == config.RTV_WA: ok = False return (ok, err, out)
def execNetstatCmd(self, *args): """Execute ps command with positional params args and return result as list of lines. @param *args: Positional params for netstat command. @return: List of output lines """ out = util.exec_command([ netstatCmd, ] + list(args)) return out.splitlines()
def verify(self, sha1=None): _dlsize = getsize(self._destination) if _dlsize != self.get_size(): raise FDSizeMismatch(_dlsize, self._fname, self.get_size()) if not sha1: return dlsha1 = None try: result = util.exec_command(["sha1sum", self._destination]) dlsha1 = result['out'] except (OSError, ValueError): try: result = util.exec_command( ["shasum", "-a", "1", self._destination]) dlsha1 = result['out'] except (OSError, ValueError): pass if dlsha1: dlsha1 = dlsha1[1:41] if dlsha1.startswith("\\") else dlsha1[:40] if sha1 != dlsha1: raise FDSHASumMismatch(dlsha1, self._fname, sha1)
def build_latex_pdf(builddir, tex_path, problem_path=None): env = make_environment() if shutil.which('latexmk') == None: fatal('latexmk not found!') latexmk_command = [ 'latexmk', '-cd', '-g', '-pdf', '-pdflatex=pdflatex -interaction=nonstopmode -halt-on-error', ] if config.args.watch: latexmk_command.append("-pvc") if getattr(config.args, '1'): latexmk_command.extend(['-e', '$max_repeat=1']) latexmk_command.extend([f'-output-directory={builddir}', tex_path]) ret = util.exec_command( latexmk_command, expect=0, crop=False, cwd=builddir, stdout=subprocess.PIPE, env=env, timeout=None, ) if ret.ok is not True: error(f'Failure compiling pdf:') print(ret.out, file=sys.stderr) error(f'return code {ret.ok}') error(f'duration {ret.duration}') return False # link the output pdf output_pdf = Path(tex_path.name).with_suffix('.pdf') dest_path = output_pdf if problem_path is None else problem_path / output_pdf ensure_symlink(dest_path, builddir / output_pdf, True) log(f'Pdf written to {dest_path}') return True
def getHostOffset(self, host): """Get NTP Stats and offset of remote host relative to localhost by querying NTP Server on remote host. @param host: Remote Host IP. @return: Dictionary of NTP stats converted to seconds. """ info_dict = {} output = util.exec_command([ntpdateCmd, '-u', '-q', host]) for line in output.splitlines(): mobj = re.match('server.*,\s*stratum\s+(\d),.*' 'offset\s+([\d\.-]+),.*delay\s+([\d\.]+)\s*$', line) if mobj: info_dict['stratum'] = int(mobj.group(1)) info_dict['delay'] = float(mobj.group(3)) info_dict['offset'] = float(mobj.group(2)) return info_dict return info_dict
def getHostOffset(self, host): """Get NTP Stats and offset of remote host relative to localhost by querying NTP Server on remote host. @param host: Remote Host IP. @return: Dictionary of NTP stats converted to seconds. """ info_dict = {} output = util.exec_command([ntpdateCmd, '-u', '-q', host]) for line in output.splitlines(): mobj = re.match( 'server.*,\s*stratum\s+(\d),.*' 'offset\s+([\d\.-]+),.*delay\s+([\d\.]+)\s*$', line) if mobj: info_dict['stratum'] = int(mobj.group(1)) info_dict['delay'] = float(mobj.group(3)) info_dict['offset'] = float(mobj.group(2)) return info_dict return info_dict
def getStats(self): """Runs varnishstats command to get stats from Varnish Cache. @return: Dictionary of stats. """ info_dict = {} args = [varnishstatCmd, "-1"] if self._instance is not None: args.extend(["-n", self._instance]) output = util.exec_command(args) if self._descDict is None: self._descDict = {} for line in output.splitlines(): mobj = re.match("(\S+)\s+(\d+)\s+(\d+\.\d+|\.)\s+(\S.*\S)\s*$", line) if mobj: fname = mobj.group(1).replace(".", "_") info_dict[fname] = util.parse_value(mobj.group(2)) self._descDict[fname] = mobj.group(4) return info_dict
def getPeerStats(self): """Get NTP Peer Stats for localhost by querying local NTP Server. @return: Dictionary of NTP stats converted to seconds. """ info_dict = {} output = util.exec_command([ntpqCmd, '-n', '-c', 'peers']) for line in output.splitlines(): mobj = re.match('\*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+', line) if mobj: info_dict['ip'] = mobj.group(1) cols = line.split() info_dict['stratum'] = int(cols[2]) info_dict['delay'] = float(cols[7]) / 1000.0 info_dict['offset'] = float(cols[8]) / 1000.0 info_dict['jitter'] = float(cols[9]) / 1000.0 return info_dict else: raise Exception("Execution of command failed: %s" % ntpqCmd) return info_dict
def getStats(self): """Runs varnishstats command to get stats from Varnish Cache. @return: Dictionary of stats. """ info_dict = {} args = [varnishstatCmd, '-1'] if self._instance is not None: args.extend(['-n', self._instance]) output = util.exec_command(args) if self._descDict is None: self._descDict = {} for line in output.splitlines(): mobj = re.match('(\S+)\s+(\d+)\s+(\d+\.\d+|\.)\s+(\S.*\S)\s*$', line) if mobj: info_dict[mobj.group(1)] = util.parse_value(mobj.group(2)) self._descDict[mobj.group(1)] = mobj.group(4) return info_dict return info_dict
def getHostOffsets(self, hosts): """Get NTP Stats and offset of multiple remote hosts relative to localhost by querying NTP Servers on remote hosts. @param host: List of Remote Host IPs. @return: Dictionary of NTP stats converted to seconds. """ info_dict = {} output = util.exec_command([ntpdateCmd, '-u', '-q'] + list(hosts)) for line in output.splitlines(): mobj = re.match('server\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}),' '\s*stratum\s+(\d),.*offset\s+([\d\.-]+),' '.*delay\s+([\d\.]+)\s*$', line) if mobj: host_dict = {} host = mobj.group(1) host_dict['stratum'] = int(mobj.group(2)) host_dict['delay'] = float(mobj.group(4)) host_dict['offset'] = float(mobj.group(3)) info_dict[host] = host_dict return info_dict
def getPRIstats(self, iface): """Return RDSI Operational Stats for interface. @param iface: Interface name. (Ex. w1g1) @return: Nested dictionary of statistics for interface. """ info_dict = {} output = util.exec_command([wanpipemonCmd, '-i', iface, '-c', 'Ta']) for line in output.splitlines(): mobj = re.match('^\s*(Line Code Violation|Far End Block Errors|' 'CRC4 Errors|FAS Errors)\s*:\s*(\d+)\s*$', line, re.IGNORECASE) if mobj: info_dict[mobj.group(1).lower().replace(' ', '')] = int(mobj.group(2)) continue mobj = re.match('^\s*(Rx Level)\s*:\s*>{0,1}\s*([-\d\.]+)db\s*', line, re.IGNORECASE) if mobj: info_dict[mobj.group(1).lower().replace(' ', '')] = float(mobj.group(2)) continue return info_dict
def getHostOffsets(self, hosts): """Get NTP Stats and offset of multiple remote hosts relative to localhost by querying NTP Servers on remote hosts. @param host: List of Remote Host IPs. @return: Dictionary of NTP stats converted to seconds. """ info_dict = {} output = util.exec_command([ntpdateCmd, '-u', '-q'] + list(hosts)) for line in output.splitlines(): mobj = re.match( 'server\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}),' '\s*stratum\s+(\d),.*offset\s+([\d\.-]+),' '.*delay\s+([\d\.]+)\s*$', line) if mobj: host_dict = {} host = mobj.group(1) host_dict['stratum'] = int(mobj.group(2)) host_dict['delay'] = float(mobj.group(4)) host_dict['offset'] = float(mobj.group(3)) info_dict[host] = host_dict return info_dict
def getPRIstats(self, iface): """Return RDSI Operational Stats for interface. @param iface: Interface name. (Ex. w1g1) @return: Nested dictionary of statistics for interface. """ info_dict = {} output = util.exec_command([wanpipemonCmd, '-i', iface, '-c', 'Ta']) for line in output.splitlines(): mobj = re.match( '^\s*(Line Code Violation|Far End Block Errors|' 'CRC4 Errors|FAS Errors)\s*:\s*(\d+)\s*$', line, re.IGNORECASE) if mobj: info_dict[mobj.group(1).lower().replace(' ', '')] = int( mobj.group(2)) continue mobj = re.match('^\s*(Rx Level)\s*:\s*>{0,1}\s*([-\d\.]+)db\s*', line, re.IGNORECASE) if mobj: info_dict[mobj.group(1).lower().replace(' ', '')] = float( mobj.group(2)) continue return info_dict
def build_problem_pdf(problem): prepare_problem(problem) builddir = problem.tmpdir util.copy_and_substitute( config.tools_root / 'latex/problem.tex', builddir / 'problem.tex', { 'problemlabel': problem.label, 'problemyamlname': problem.settings.name.replace('_', ' '), 'problemauthor': problem.settings.author, 'timelimit': problem.settings.timelimit, 'problemdir': problem.path.absolute().as_posix(), 'builddir': problem.tmpdir.as_posix(), }) env = get_environment() for i in range(3): ret = util.exec_command( PDFLATEX + ['-output-directory', builddir, builddir / 'problem.tex'], 0, False, cwd=builddir, stdout=subprocess.PIPE, env=env, ) if ret.ok is not True: print(f'{Fore.RED}Failure compiling pdf:{Style.RESET_ALL}\n{ret.out}') return False # link the output pdf output_pdf = problem.path / 'problem.pdf' ensure_symlink(output_pdf, builddir / 'problem.pdf', True) print(f'{Fore.GREEN}Pdf written to {output_pdf}{Style.RESET_ALL}') return True
def build_contest_pdf(contest, problems, solutions=False, web=False): builddir = config.tmpdir / contest builddir.mkdir(parents=True, exist_ok=True) build_type = 'solution' if solutions else 'problem' main_file = 'solutions' if solutions else 'contest' main_file += '-web.tex' if web else '.tex' if solutions: ensure_symlink(builddir / 'solutions-base.tex', config.tools_root / 'latex/solutions-base.tex') ensure_symlink(builddir / 'bapc.cls', config.tools_root / 'latex/bapc.cls') ensure_symlink(builddir / 'images', config.tools_root / 'latex/images') ensure_symlink(builddir / main_file, config.tools_root / 'latex' / main_file) config_data = util.read_yaml(Path('contest.yaml')) config_data['testsession'] = '\\testsession' if config_data.get( 'testsession') else '' util.copy_and_substitute(config.tools_root / 'latex/contest-data.tex', builddir / 'contest_data.tex', config_data) ensure_symlink(builddir / 'logo.pdf', find_logo()) problems_data = '' # Link the solve stats directory if it exists. solve_stats = Path('solve_stats') if solve_stats.exists(): ensure_symlink(builddir / 'solve_stats', solve_stats) # include a header slide in the solutions PDF headertex = Path('solution_header.tex') if headertex.exists(): ensure_symlink(builddir / 'solution_header.tex', headertex) if solutions and headertex.exists(): problems_data += f'\\input{{{headertex}}}\n' per_problem_data = (config.tools_root / 'latex' / f'contest-{build_type}.tex').read_text() # Some logic to prevent duplicate problem IDs. for problem in problems: prepare_problem(problem) id_ok = True problems_data += util.substitute( per_problem_data, { 'problemlabel': problem.label, 'problemyamlname': problem.config['name'], 'problemauthor': problem.config.get('author'), 'timelimit': get_tl(problem.config), 'problemdir': config.tmpdir / problem.id, }) # include a statistics slide in the solutions PDF footer_tex = Path('solution_footer.tex') if footer_tex.exists(): ensure_symlink(builddir / 'solution_footer.tex', footer_tex) if solutions and footer_tex.exists(): problems_data += f'\\input{{{footer_tex}}}\n' (builddir / f'contest-{build_type}s.tex').write_text(problems_data) for i in range(3): ok, err, out = util.exec_command(PDFLATEX + [ '-output-directory', builddir, (builddir / main_file).with_suffix('.tex') ], 0, False, cwd=builddir, stdout=subprocess.PIPE) if ok is not True: print(f'{_c.red}Failure compiling pdf:{_c.reset}\n{out}') return False # link the output pdf output_pdf = Path(main_file).with_suffix('.pdf') ensure_symlink(output_pdf, builddir / output_pdf, True) print(f'{_c.green}Pdf written to {output_pdf}{_c.reset}') return True
def build_contest_pdf(contest, problems, tmpdir, solutions=False, web=False): builddir = tmpdir / contest builddir.mkdir(parents=True, exist_ok=True) build_type = 'solution' if solutions else 'problem' main_file = 'solutions' if solutions else 'contest' main_file += '-web.tex' if web else '.tex' config_data = util.read_yaml(Path('contest.yaml')) config_data['testsession'] = '\\testsession' if config_data.get('testsession') else '' config_data['logofile'] = find_logo().as_posix() util.copy_and_substitute(config.tools_root / 'latex/contest-data.tex', builddir / 'contest_data.tex', config_data) problems_data = '' if solutions: # Link the solve stats directory if it exists. solve_stats = Path('solve_stats') # include a header slide in the solutions PDF headertex = Path('solution_header.tex') if headertex.exists(): problems_data += f'\\input{{{headertex}}}\n' per_problem_data = (config.tools_root / 'latex' / f'contest-{build_type}.tex').read_text() # Some logic to prevent duplicate problem IDs. for problem in problems: if build_type == 'problem': prepare_problem(problem) problems_data += util.substitute( per_problem_data, { 'problemlabel': problem.label, 'problemyamlname': problem.settings.name.replace('_', ' '), 'problemauthor': problem.settings.author, 'timelimit': problem.settings.timelimit, 'problemdir': problem.path.absolute().as_posix(), 'builddir': problem.tmpdir.as_posix(), }) if solutions: # include a statistics slide in the solutions PDF footer_tex = Path('solution_footer.tex') if footer_tex.exists(): problems_data += f'\\input{{{footer_tex}}}\n' (builddir / f'contest-{build_type}s.tex').write_text(problems_data) env = get_environment() for i in range(3): ret = util.exec_command( PDFLATEX + ['-output-directory', builddir, config.tools_root / 'latex' / main_file], 0, False, cwd=builddir, stdout=subprocess.PIPE, env=env, ) if ret.ok is not True: print(f'{Fore.RED}Failure compiling pdf:{Style.RESET_ALL}\n{ret.out}') return False # link the output pdf output_pdf = Path(main_file).with_suffix('.pdf') ensure_symlink(output_pdf, builddir / output_pdf, True) print(f'{Fore.GREEN}Pdf written to {output_pdf}{Style.RESET_ALL}') return True