Пример #1
0
def setSubst(sheet, cols, rows):
    if not rows:
        warning('no %s selected' % sheet.rowtype)
        return
    modified = 'column' if len(cols) == 1 else 'columns'
    rex = vd.input("transform %s by regex: " % modified, type="regex-subst")
    setValuesFromRegex(cols, rows, rex)
Пример #2
0
def copyCells(sheet, col, rows):
    vd.clipcells = [col.getDisplayValue(r) for r in rows]
    if not rows:
        warning('no %s selected; clipboard emptied' % sheet.rowtype)
        return
    status('copied %d %s.%s to clipboard' %
           (len(rows), sheet.rowtype, col.name))
Пример #3
0
def gen_identify_duplicates(sheet):
    """
    Takes a sheet, and returns a generator yielding a tuple for each row
    encountered. The tuple's structure is `(row_object, is_dupe)`, where
    is_dupe is True/False.

    See note in Usage section above regarding how duplicates are determined.
    """

    keyCols = sheet.keyCols

    cols_to_check = None
    if len(keyCols) == 0:
        warning("No key cols specified. Using all columns.")
        cols_to_check = sheet.visibleCols
    else:
        cols_to_check = sheet.keyCols

    seen = set()
    for r in Progress(sheet.rows):
        vals = tuple(col.getValue(r) for col in cols_to_check)
        is_dupe = vals in seen
        if not is_dupe:
            seen.add(vals)
        yield (r, is_dupe)
Пример #4
0
def confirm(vd, prompt, exc=EscapeException):
    yn = vd.input(prompt, value='no', record=False)[:1]
    if not yn or yn not in 'Yy':
        msg = 'disconfirmed: ' + prompt
        if exc:
            raise exc(msg)
        warning(msg)
        return False
    return True
Пример #5
0
    def reload(self):
        mapping = self.source

        self.columns = []
        self.rows = []

        self.key_type = str
        self.size = len(mapping)

        if self.size == 0:
            return

        if isinstance(mapping, list):
            first = mapping[0]
            if isinstance(first, dict):
                colgetter = lambda x: x.keys()
            elif isinstance(first, list):
                colgetter = lambda x: list(range(len(x)))
            else:
                mapping = dict(enumerate(mapping))
                self.key_type = int
                self.size = len(mapping)

        if isinstance(mapping, dict):
            self.is_keyvalue = True
            if self.size:
                max_key_len = max(map(len, map(str, mapping.keys())))
                key_width = min(50, max(max_key_len + 2, 6))
            else:
                key_width = None

            self.addColumn(
                ColumnItem("key", width=key_width, type=self.key_type))
            self.addColumn(ColumnItem("value"))
            self.setKeys(self.columns[:1])

            for k, v in mapping.items():
                self.addRow({"key": k, "value": v})

        elif isinstance(mapping, list):
            self.is_keyvalue = False
            indices = []
            for item in mapping:
                try:
                    cols = colgetter(item)
                    for col in cols:
                        if col not in indices:
                            self.addColumn(ColumnItem(col))
                            indices.append(col)

                    self.addRow(item)

                except Exception as e:
                    warning(
                        "Can't dive on lists with heterogenous item types.")
                    return False
Пример #6
0
    def dive(self):
        if self.is_keyvalue:
            cell = self.cursorRow["value"]
            name = joinSheetnames(self.name, self.cursorRow["key"])

            if isinstance(cell, (list, dict)):
                vs = self.__class__(name, source=cell)
            else:
                warning("Nothing to dive into.")
                return
        else:
            name = joinSheetnames(self.name, "row")
            vs = self.__class__(name, source=self.cursorRow)

        success = vs.reload()
        if success == False:
            return

        vd.push(vs)
Пример #7
0
def openurl_s3(p, filetype):
    '''
    Open a sheet for an S3 path. S3 directories (prefixes) require special handling,
    but files (objects) can use standard VisiData "open" functions.
    '''
    from s3fs import S3FileSystem

    # Non-obvious behavior here: For the default case, we don't want to send
    # a custom endpoint to s3fs. However, using None as a default trips up
    # VisiData's type detection for the endpoint option. So we use an empty
    # string as the default instead, and convert back to None here.
    endpoint = options.vds3_endpoint or None
    version_aware = options.vds3_version_aware

    # We can reuse an existing S3FileSystem as long as no relevant options
    # have changed since it was created.
    if (not S3Path.fs or S3Path.fs.version_aware != version_aware
            or S3Path.fs.client_kwargs.get('endpoint_url', '') != endpoint):
        S3Path.fs = S3FileSystem(client_kwargs={'endpoint_url': endpoint},
                                 version_aware=version_aware)

    p = S3Path(p.given)

    if not p.is_file():
        return S3DirSheet(p.name, source=p)

    if not filetype:
        filetype = p.ext or 'txt'

    openfunc = getGlobals().get('open_' + filetype.lower())
    if not openfunc:
        warning(f'no loader found for {filetype} files, falling back to txt')
        filetype = 'txt'
        openfunc = open_txt

    vs = openfunc(p)
    status(f'opening {p.given} as {filetype}')
    return vs
Пример #8
0
def chooseMany(choices):
    'Return list of `choices` elements (if list) or values (if dict).'
    if isinstance(choices, dict):
        prompt = '/'.join(choices.keys())
        chosen = []
        for c in vd.input(prompt + ': ',
                          completer=CompleteKey(choices)).split():
            poss = [choices[p] for p in choices if str(p).startswith(c)]
            if not poss:
                warning('invalid choice "%s"' % c)
            else:
                chosen.extend(poss)
    else:
        prompt = '/'.join(str(x) for x in choices)
        chosen = []
        for c in vd.input(prompt + ': ',
                          completer=CompleteKey(choices)).split():
            poss = [p for p in choices if str(p).startswith(c)]
            if not poss:
                warning('invalid choice "%s"' % c)
            else:
                chosen.extend(poss)
    return chosen
Пример #9
0
def copyRows(sheet, rows):
    vd.cliprows = list((sheet, i, r) for i, r in enumerate(rows))
    if not rows:
        warning('no %s selected; clipboard emptied' % sheet.rowtype)
    else:
        status('copied %d %s to clipboard' % (len(rows), sheet.rowtype))
Пример #10
0
 def wrapper(*args, **kwargs):
     # ideally would include a stacktrace
     visidata.warning(f'{func.__name__} deprecated since v{ver}')
     return func(*args, **kwargs)