예제 #1
0
파일: walk_dir.py 프로젝트: havocesp/colr
def walk_dir_animated(path, maxdircnt=1000):
    """ Walk a directory, printing status updates along the way. """
    p = AnimatedProgress(
        'Walking {}...'.format(path),
        frames=Frames.dots_orbit.as_rainbow(),
        show_time=True,
    )
    rootcnt = 0
    print('\nStarting animated progress.')
    with p:
        for root, dirs, files in os.walk(path):
            rootcnt += 1
            if rootcnt % 50 == 0:
                p.text = 'Walking {}...'.format(C(root, 'cyan'))
            if rootcnt > maxdircnt:
                # Stop is called because we are printing before the
                # AnimatedProgress is finished running.
                p.stop()
                print('\nFinished walking {} directories.'.format(
                    C(maxdircnt, 'blue', style='bright')))
                break
        else:
            # AnimatedProgress still running, `stop` it before printing.
            p.stop()
            print_err('\nNever made it to {} directories ({}).'.format(
                C(maxdircnt, 'blue', style='bright'),
                C(rootcnt, 'red', style='bright'),
            ))
    print('\nFinished with animated progress.')
    return 0
예제 #2
0
def write_sitemap(
        rootdir, filepath='sitemap.xml',
        domain=None, include='.html', exclude=None):
    if not rootdir:
        rootdir = os.getcwd()
    mapstr = get_sitemap(
        rootdir,
        domain=domain,
        include=include,
        exclude=exclude,
    )
    if not mapstr:
        print_err('\nNo site map to write!')
        return 1
    if not filepath:
        print(mapstr)
        return 0

    try:
        with open(filepath, 'w') as f:
            f.write(mapstr)
    except EnvironmentError as ex:
        print_err(f'Unable to write sitemap: {ex.filename}\n{ex}')
        return 1
    print(C(': ').join('Wrote sitemap', C(filepath, 'blue')))
    return 0
예제 #3
0
def format_file_name(s):
    """ Format a file name for printing. """
    return str(C('').join(
        '\n',
        C(s, 'blue', style='bright'),
        ':',
    ))
예제 #4
0
def print_err(*args, **kwargs):
    """ Print a message to stderr by default. """
    if kwargs.get('file', None) is None:
        kwargs['file'] = sys.stderr
    nothing = object()
    value = nothing
    with suppress(KeyError):
        value = kwargs.pop('value')
    error = nothing
    with suppress(KeyError):
        error = kwargs.pop('error')

    msg = kwargs.get('sep', ' ').join(
        str(a) if isinstance(a, C) else str(C(a, 'red'))
        for a in args
    )
    if (value is nothing) and (error is nothing):
        print(msg, **kwargs)
        return None
    # Label/value pair.
    if value is not nothing:
        msg = C(': ').join(msg, C(value, 'blue'))
    if error is not nothing:
        msg = C('\n  ').join(msg, C(error, 'red', style='bright'))
    print(msg, **kwargs)
    return None
예제 #5
0
def partlist_compare_fmt(lista, listb):
    """ Show two parts lists side by side, highlighting any differences.
        Returns a formatted str if the lists differ, otherwise returns
        an empty str ('').
    """
    if lista == listb:
        return ''
    lena, lenb = len(lista), len(listb)
    maxwidth = 80
    halfwidth = maxwidth // 2
    lines = []
    for i in range(max(lena, lenb)):
        try:
            itema = lista[i]
        except IndexError:
            itema = NotSet
        try:
            itemb = listb[i]
        except IndexError:
            itemb = NotSet
        symbol = '==' if itema == itemb else '!='
        colora = 'red' if itema is NotSet else 'cyan'
        colorb = 'red' if itemb is NotSet or itemb != itema else 'cyan'
        lines.append(
            str(
                C('\n').join(
                    '   {}'.format(C(itema, colora).ljust(halfwidth)),
                    '{} {}'.format(symbol, C(itemb, colorb)),
                )))

    return '\n'.join(lines)
예제 #6
0
 def __colr__(self):
     return C(': ').join(
         C('Large file', 'red'),
         C(' ').join(
             C('{} bytes'.format(self.size), 'blue').join('(', ')'),
             C(self.filepath, 'cyan'),
         ))
예제 #7
0
 def __colr__(self):
     """ Format this TigerPart as a Colr when passed directly to Colr().
     """
     just_default = 3
     just = {
         'length': 7,
         'part': 5,
         'no': 10,
     }
     justtype_default = '>'
     justtype = {
         'part': '<',
         'no': '<',
     }
     missing_default = C('None', 'dimgrey').join('<', '>', fore='dimgrey')
     missing = {
         'completed': '0',
     }
     pcs = []
     for key in self.header:
         keylow = key.lower()
         val = getattr(self, keylow, None)
         if not val:
             val = missing.get(keylow, missing_default)
         if keylow == 'length':
             val = '{:0.2f}'.format(float(val))
         pcs.append(
             '{k}: {v:{justtype}{just}}'.format(
                 k=C(key, 'blue'),
                 v=C(val, 'cyan'),
                 justtype=justtype.get(keylow, justtype_default),
                 just=just.get(keylow, just_default),
             )
         )
     return C(' ').join(pcs)
예제 #8
0
def list_tests(package='test', full=False, patterns=None):
    """ List all discoverable tests. """
    test_info = filter_test_info(
        patterns,
        load_test_info(package=package),
    )
    for modulename, cases in test_info.items():
        modulefmt = C(modulename, 'blue', style='bright')
        casenames = {type(c).__name__: c for c in cases}
        if not full:
            print(modulefmt(':'))
        for casename in sorted(casenames):
            methodnames = cases[casenames[casename]]
            casefmt = C(casename, 'cyan')
            if not full:
                print('  {}'.format(casefmt))
            for methodname in sorted(methodnames):
                methodfmt = C(methodname, 'green')
                if full:
                    print(C('.').join(modulefmt, casefmt, methodfmt))
                else:
                    print('    {}'.format(methodfmt))
            if full and (not methodnames):
                # Methods were filtered out.
                print(C('.').join(modulefmt, casefmt))
        if full and (not casenames):
            # Methods and cases were filtered out.
            print(modulefmt)

    return 0
예제 #9
0
def debug(*args, **kwargs):
    """ Print a message only if DEBUG is truthy. """
    if not (DEBUG and args):
        return None

    # Include parent class name when given.
    parent = kwargs.get('parent', None)
    with suppress(KeyError):
        kwargs.pop('parent')

    # Go back more than once when given.
    backlevel = kwargs.get('back', 1)
    with suppress(KeyError):
        kwargs.pop('back')

    frame = inspect.currentframe()
    # Go back a number of frames (usually 1).
    while backlevel > 0:
        frame = frame.f_back
        backlevel -= 1
    fname = os.path.split(frame.f_code.co_filename)[-1]
    lineno = frame.f_lineno
    if parent:
        func = '{}.{}'.format(parent.__class__.__name__, frame.f_code.co_name)
    else:
        func = frame.f_code.co_name

    lineinfo = '{}:{} {}: '.format(
        C(fname, 'yellow'), C(str(lineno).ljust(4), 'blue'),
        C().join(C(func, 'magenta'), '()').ljust(20))
    # Patch args to stay compatible with print().
    pargs = list(C(a, 'green').str() for a in args)
    pargs[0] = ''.join((lineinfo, pargs[0]))
    print_err(*pargs, **kwargs)
예제 #10
0
def search_requirements(
        pattern, filename=DEFAULT_FILE, ignorecase=True):
    """ Search requirements lines for a text/regex pattern, and print
        results as they are found.
        Returns the number of results found.
    """
    reqs = Requirementz.from_file(filename=filename)
    try:
        found = Requirementz(
            requirements=reqs.search(pattern, ignorecase=ignorecase)
        )
    except re.error as ex:
        print_err('\nInvalid regex pattern', value=pattern, error=ex)
        return 1
    total = len(found)
    if not total:
        print_err('\nNo entries found with', value=pattern)
        return 1

    print('\n'.join(found.iter_str(color=True, align=True)))
    print(C(' ').join(
        C('\nFound', 'cyan'),
        colr_num(total, style='bright'),
        C('{}.'.format('entry' if total == 1 else 'entries'), 'cyan'),
    ))
    return 0
예제 #11
0
def list_duplicates(filename=DEFAULT_FILE):
    """ Print any duplicate package names found in the file.
        Returns the number of duplicates found.
    """
    dupes = Requirementz.from_file(filename=filename).duplicates()
    dupelen = len(dupes)
    if not dupelen:
        print(C('No duplicate requirements found.', 'cyan'))
        return 0

    print(
        C(' ').join(
            C('Found', 'cyan'),
            colr_num(dupelen),
            C(
                '{} with duplicate entries:'.format(
                    'requirement' if dupelen == 1 else 'requirements',
                ),
                'cyan',
            )
        )
    )
    for req, dupcount in dupes.items():
        print('{name:>30} has {num} {plural}'.format(
            name=colr_name(req.name),
            num=colr_num(dupcount, style='bright'),
            plural='duplicate' if dupcount == 1 else 'duplicates'
        ))
    return sum(dupes.values())
예제 #12
0
 def __str__(self):
     # Amount to indent version info, plus 2 for ': '.
     verindent = ' ' * (self.basename_rjust + 2)
     # Width, not counting indent, allowed for relative paths.
     filenamewidth = (TERMWIDTH + len(verindent)) - self.basename_rjust
     verstrlines = []
     for fi in self.versions:
         pathfmt = C(fi.relpath, 'cyan')
         minfile = self.get_min_file(fi.relpath)
         if minfile:
             pathfmt = C(' ').join(
                 pathfmt,
                 C('{} {}'.format(
                     C('and', 'cyan'),
                     C(minfile, 'green'),
                 )).join('(', ')', style='bright')
             )
         verstrlines.append(str(pathfmt))
     verstr = FormatBlock(
         '\n'.join(verstrlines)
     ).format(
         prepend=verindent,
         newlines=True,
         strip_first=True,
         width=filenamewidth,
     )
     return '{bname:>{bnamerjust}}: {verstr}'.format(
         bname=self.basename,
         bnamerjust=self.basename_rjust,
         verstr=verstr
     )
예제 #13
0
def rainbow_text(text,
                 spread=2,
                 freq=0.1,
                 offset=0,
                 bg=False,
                 fg=(255, 255, 255),
                 style=[],
                 rand=False):
    res = ''
    if rand:
        offset = random.randint(0, 10) * 10

    for (l, (r, g, b)) in _rainbow_rgb_chars(text,
                                             spread=spread,
                                             freq=freq,
                                             offset=offset):
        if bg:
            char = C().b_rgb(r, g, b).rgb(fg[0], fg[1], fg[2], l)
            for sty in style:
                char = color(char, style=sty)
            res += char
        else:
            char = C().rgb(r, g, b, l)
            for sty in style:
                char = color(char, style=sty)
            res += char

    return res
예제 #14
0
def rewrite_files(filepaths,
                  pat,
                  repl,
                  view_first=False,
                  silent_empty=False,
                  diff=False):
    """ Rewrite multiple files, replacing `pat` matches with `repl` str.
    """
    skipped = 0
    totalchanges = 0
    confirm_opts = {'silent': silent_empty, 'diff': diff}
    for filepath in filepaths:
        infile = parse_file_arg(filepath, mode='r', viewmode=view_first)
        if infile is None:
            return 1
        rf = ReplaceFile(infile, pat, repl)
        if view_first and (not rf.confirm_lines(**confirm_opts)):
            skipped += 1
            continue
        totalchanges += rf.replace_cnt
        rf.rewrite()
        print(format_file_changes(rf))

    statuspcs = [
        C(': ').join('Files', CNum(len(filepaths))),
        C(': ').join('Changes', CNum(totalchanges)),
    ]
    if skipped:
        statuspcs.append(C(': ').join('Skipped', CNum(skipped)))
    print('\n{}'.format(C(', ').join(statuspcs)))
    return 0 if totalchanges else 1
예제 #15
0
def format_accepted_values(headername):
    """ Return a comma-separated list of acceptable values for a header,
        or the 'any' string if it was used.
    """
    if HEADERS[headername]['accepted'] is ANY:
        return C(ANY, 'yellow')
    return C(', ').join(
        C(val, 'yellow') for val in HEADERS[headername]['accepted'])
예제 #16
0
 def proces_image(self, image):
     colors = self.get_colors(image)
     seperator = '================================'
     print(C().b_rgb(0, 0, 0).rgb(255, 255, 255, seperator))
     print(C().b_rgb(0, 0, 0).rgb(255, 255, 255, image))
     print(C().b_rgb(0, 0, 0).rgb(255, 255, 255, seperator))
     for c in colors:
         self.show_colors(c[1])
예제 #17
0
def format_lbl(lbl, val, rjust=0, indent=0):
    """ Format a label/value pair string. """
    return C('').join(
        ' ' * indent,
        C(': ').join(
            C(str(lbl).rjust(rjust), 'cyan'),
            C(val, 'blue', style='bright'),
        ))
예제 #18
0
 def __str__(self):
     if self.msg:
         try:
             lbl, val = self.msg.split(':')
         except ValueError:
             return 'Invalid argument, {}'.format(self.msg)
         msg = C('Invalid argument, {}'.format(lbl), 'red', style='bright')
         return str(C(':').join(msg, C(val, 'blue', style='bright')))
     return 'Invalid argument!'
예제 #19
0
def list_labelconfig():
    """ Print label config to the console and return an exit status. """
    labels = label_config_get(use_display_order=True)
    for name, lblinfo in labels:
        print('{}:'.format(C(name, 'blue', style='bright')))
        for k, v in lblinfo.items():
            print('    {:>8}: {}'.format(
                C(k, 'blue'),
                C(v, 'cyan'),
            ))
    return 0
예제 #20
0
def print_test_names(names):
    """ Print formatted test names. """
    print(
        C(':').join(
            C('Parsed test names', 'cyan'),
            C(len(names), 'blue', style='bright'),
        ))
    for name in names:
        print(C(name, 'blue'))

    return 0 if names else 1
예제 #21
0
def status(label=None, msg=None):
    """ Print a status message if running in the console, and log it also. """
    if msg:
        line = C(': ').join(
            C(label, 'blue'),
            C(msg, 'cyan'),
        )
    else:
        line = C(label, 'cyan')
    if sys.stdout.isatty():
        print(line)
    logger.info(fix_log_msg(line.stripped(), level=1))
예제 #22
0
def write_tiger_file(
        mozfile, outdir, archive_dir=None, extra_data=False,
        error_cb=None, success_cb=None):
    """ Write a .tiger file from a MozaikFile.
        Without callbacks given, it returns an exit status (0 or 1).
        With callbacks it returns `error_cb(mozfile, msg)` or
        `success_cb(mozfile, tigerpath)`

    """
    tigerpath = os.path.join(outdir, mozfile.filepath)
    use_err_cb = callable(error_cb)
    use_success_cb = callable(success_cb)

    if os.path.exists(tigerpath):
        debug_err('Tiger file already exists: {}'.format(tigerpath))
        tigerpath = increment_file_path(tigerpath)
        debug_err('Made new tiger file path: {}'.format(tigerpath))
    try:
        with open(tigerpath, 'w') as f:
            f.write(create_xml(mozfile, extra_data=extra_data))
    except EnvironmentError as ex:
        msg = 'Cannot write tiger file: {}\n{}'.format(
            tigerpath,
            ex,
        )
        print_err(msg)
        return error_cb(mozfile, msg) if use_err_cb else 1
    partlen = len(mozfile.parts)
    plural = 'part' if partlen == 1 else 'parts'
    msg = C(' ').join(
        C('Created', 'blue'),
        C(partlen, 'blue', style='bright'),
        C(plural, 'blue'),
        C('parts in', 'blue'),
    )
    status(msg, tigerpath)
    if archive_dir in (None, '', '-'):
        # No archiving was requested/set.
        debug('No archiving {}.'.format(
            'requested' if archive_dir == '-' else 'set up',
        ))
        return success_cb(mozfile, tigerpath) if use_success_cb else 0
    if outdir in (None, '-'):
        debug('Archiving disabled due to output style.')
        return success_cb(mozfile, tigerpath) if use_success_cb else 0

    archived = archive_file(
        mozfile.parent_file,
        archive_dir,
        created_files=[tigerpath]
    )
    exitstatus = 0 if archived else 1
    return success_cb(mozfile, tigerpath) if use_success_cb else exitstatus
예제 #23
0
def preview_file(filepath):
    """ Preview a Mozaik file as a Tiger file. """
    try:
        check_file(filepath)
    except LargeFileError as ex:
        msg = '\n'.join((
            str(C(ex)),
            '',
            str(C('Continue anyway?', 'cyan')),
        ))
        if not confirm(msg):
            return 1
    return TigerFiles.from_file(filepath, split_parts=True).print()
예제 #24
0
def list_packages(location=False):
    """ List all installed packages. """
    # Sort by name first.
    pkgs = sorted(PKGS)
    if location:
        # Sort by location, but the name sort is kept.
        pkgs = sorted(pkgs, key=lambda p: PKGS[p].location)
    for pname in pkgs:
        p = PKGS[pname]
        print('{:<30} v. {:<12} {}'.format(
            colr_name(p.project_name),
            C(pkg_installed_version(pname), fore='cyan'),
            C(p.location, fore='green'),
        ))
예제 #25
0
    def highlighted(self,
                    line_nums=False,
                    indent=0,
                    matched=False,
                    diff=False):
        """ If matched is True, the text that matched is highlighted,
            otherwise the replacement is highlighted.
        """
        if diff:
            pcs = [
                [C('-', 'red'),
                 self._highlighted_match.rstrip()],
                [C('+', 'green'), self._highlighted.rstrip()],
            ]
            if line_nums:
                pcs = [[
                    xs[0],
                    C('').join(C(self.lineno, 'red' if i == 0 else 'green'),
                               ':'), xs[1]
                ] for i, xs in enumerate(pcs)]
            return '{}\n'.format(C('\n').join(C(' ').join(pc) for pc in pcs))

        line = self._highlighted_match if matched else self._highlighted
        if line_nums:
            s = str(C(': ').join(C(self.lineno, 'blue'), line))
        else:
            s = line
        return '{}\n'.format(''.join((' ' * indent, s.rstrip())))
예제 #26
0
    def assertPartListEqual(self, a, b, msg=None, desc=None):
        """ Like assertListEqual, but with better repr's for parts. """
        if a == b:
            return
        lena, lenb = len(a), len(b)
        diffindex = -1
        for i in range(min(lena, lenb)):
            itema = a[i]
            itemb = b[i]
            if itema != itemb:
                diffindex = i
                parta = itema
                partb = itemb
                diffmsg = 'Parts are not equal.'
                break
        else:
            # One is a subset of the other.
            diffindex = max(min(lena, lenb) - 1, 0)
            try:
                parta = a[diffindex]
            except IndexError:
                parta = None
            try:
                partb = b[diffindex]
            except IndexError:
                partb = None
            if lena > lenb:
                diffmsg = 'First list is larger.'
            elif lenb > lena:
                diffmsg = 'Second list is larger.'
            else:
                diffmsg = 'List lengths are the same.'

        lines = [
            str(C(msg or 'Lists are not equal.', 'red')),
        ]
        if desc:
            lines.append('   Description: {}'.format(C(desc, 'cyan')))
        lines.append('\n'.join((
            '      Length A: {}',
            '      Length B: {}',
        )).format(C(lena, 'blue'), C(lenb, 'blue')))

        lines.append('\n{}'.format(partlist_compare_fmt(a, b)))
        lines.append('{} First differing index: {}'.format(diffmsg, diffindex))
        lines.append('\nFirst differing part:\n{}'.format(
            part_diff(parta, partb)))
        raise AssertionError('\n'.join(lines))
예제 #27
0
 def polyfill_debug_err(*args, **kwargs):
     kwargs['level'] = kwargs.get('level', 0) + 1
     args = (
         a if isinstance(a, C) else C(a, 'red')
         for a in args
     )
     return debugprinter.debug(*args, **kwargs)
예제 #28
0
def draw_image(cols,rows,tileH,tileW,pix):
    whiteToBlack = '@%#*+=-:. '
    width,height = pix.size[0],pix.size[1]

    for y in range(cols):
        yStart = int(y*tileH)
        yEnd = int((y+1)*tileH)

        if y == cols-1:
            yEnd = height

        for x in range(rows):
            xStart = int(x*tileW)
            xEnd = int((x+1)*tileW)

            if x == rows-1:
                xEnd = width

            tile = pix.crop((xStart, yStart, xEnd, yEnd))

            lum = 255 - int(getAvgBrightness(tile))
            clr = getAvgColor(tile)

            char = whiteToBlack[int((lum*9)/255)]
            print(C().color(char,fore=(clr[0],clr[1],clr[2])),end='')
        print('')
예제 #29
0
 def format_label(cls, item, default='None'):
     """ Format a label for printing, if it hasn't been printed yet. """
     if not cls.print_labels:
         return ''
     return '{}: '.format(
         C(cls.get_label(item, default=default), 'dimgrey')
     )
 def _process_input(self, text: str):
     document = Document(text)
     sentences = document.split_to_sentences(sent_tokenize)
     for sentence in sentences:
         response = self.text_index.search(sentence, neighbours=2)
         if response is None:
             continue
         sentence = sentence.get_tokens_by_indices(
             sentence.get_alphabetic_tokens())
         sys.stdout.write(str(sentence) + '\n')
         sys.stdout.write(str(response) + '\n')
         sys.stdout.write('====================\n')
         for r, word in zip(response, sentence):
             c = max(ri[0] for ri in r)
             sys.stdout.write(
                 str(C().b_rgb(255 * min(1, 1 - (c - 0.5) / 0.5), 0,
                               0).rgb(255, 255, 255, word)))
             sys.stdout.write(' ')
         sys.stdout.write('\n')
         for r, word in zip(response, sentence):
             r.sort(key=lambda ri: -ri[0])
             sys.stdout.write(word + ': ')
             for ri in r:
                 sys.stdout.write(f'({ri[1]}: {ri[0]:0.3f}) ')
             sys.stdout.write('\n')
         sys.stdout.write('====================\n')
         sys.stdout.flush()