Example #1
0
def swap(argc):
    """swap: Swap the names/contents of two files.

    Usage:
        swap <file>FILE1 <file>FILE2
    """
    tempdir = tempfile.mkdtemp()

    # set up proper paths to files
    curdir = os.getcwd()
    file1 = os.path.join(curdir, argc.args['FILE1'])
    file2 = os.path.join(curdir, argc.args['FILE2'])

    # check existence of files
    if not (os.path.exists(file1)):
        raise ErgonomicaError("[ergo: FileError]: No such file '%s'." % file1)
    elif not (os.path.exists(file2)):
        raise ErgonomicaError("[ergo: FileError]: No such file '%s'." % file2)

    # move 1 to temp
    shutil.move(file1, tempdir)

    # move 2 to 1
    shutil.move(file2, file1)

    # move temp to 1
    shutil.move(tempdir + "/" + os.path.basename(file1), file2)

    return
Example #2
0
def shuffle(array):
    if not isinstance(array, list):
        raise ErgonomicaError("[ergo: shuffle]: TypeError: Non-list passed.")

    array2 = [x for x in array]  # copy since arrays are mutable
    random.shuffle(array2)
    return array2
Example #3
0
def uuid(argc):
    """uuid: Yields a Universal Unique ID (UUID).

    Usage:
        uuid [int | hex | words] [LENGTH]
    """
    
    if not argc.args['LENGTH']:
        length = 4
    else:
        try:
            length = int(argc.args['LENGTH'])
        except ValueError:
            raise ErgonomicaError("[ergo: uuid]: UUID length must be an int.")
            
        
    if argc.args['hex']:
        charset = '0123456789abcdef'
        return "".join([random.choice(charset) for x in range(length)])
    
    elif argc.args['words']:
        rw = RandomWords()
        return " ".join([str(x) for x in rw.random_words(count=length)])

    else:
        charset = "0123456789"
        return "".join([random.choice(charset) for x in range(length)])
Example #4
0
def randint(lower, upper=None):

    if not upper:
        lower, upper = 0, lower

    if not isinstance(lower, int):
        raise ErgonomicaError(
            "[ergo: randint]: TypeError: '{}' not an integer.".format(
                str(lower)))

    elif not isinstance(upper, int):
        raise ErgonomicaError(
            "[ergo: randint]: TypeError: '{}' not an integer.".format(
                str(upper)))

    return random.randint(lower, upper)
Example #5
0
def obj_set(arr, order=True):
    new_arr = []
    for i in arr:
        contained = False
        if not order:
            if not (isinstance(i, list) or isinstance(i, str)
                    or isinstance(i, str)):
                raise ErgonomicaError("[ergo: ~=]: Non-iterable passed.")

        for j in new_arr:
            if order:
                if i == j:
                    if contained:
                        break
                    else:
                        contained = True

            else:
                if set(i) == set(j):
                    if contained:
                        break
                    else:
                        contained = True

        if not contained:
            new_arr.append(i)

    return new_arr
Example #6
0
def rm(argc):
    """rm: Remove files and directories.

    Usage:
       rm <file/directory>[FILES...]
    """

    for _file in argc.args['FILES']:
        if _file[0] == "/":
            path = _file
        elif _file[0] == "~":
            path = os.path.expanduser(_file)
        else:
            path = os.path.join(argc.env.directory, _file)

        if os.path.exists(path) or os.path.islink(path):
            if os.path.isdir(path):
                shutil.rmtree(path)
            elif os.path.islink(path):
                os.unlink(path)
            else:
                os.remove(path)
        else:
            raise ErgonomicaError(
                "[ergo: rm]: NoSuchFileOrDirectoryError: '%s'." % (path))
Example #7
0
def flatten(arr):

    if not isinstance(arr, list):
        raise ErgonomicaError("[ergo: flatten]: Non-list passed.")

    out = []
    for i in arr:
        if isinstance(i, list):
            out += flatten(i)
        else:
            out.append(i)
    return out
Example #8
0
def edit_func(funcname):
    if not hasattr(namespace[funcname], 'body'):
        raise ErgonomicaError(
            '[ergo: edit_func]: Function passed not a valid Ergonomica function! Perhaps it\'s a builtin?'
        )
    # initialize tempfile and write current function body
    filename = tempfile.mktemp()
    open(filename, 'w').write(_ast_to_string(namespace[funcname].body))

    # start fsupdate thread
    threading.Thread(target=lambda: func_update(funcname, filename)).start()

    # return the tempfile name
    return filename
Example #9
0
def _slice(*args):
    if len(args) == 2:
        if not isinstance(args[0], int):
            raise ErgonomicaError(
                "[ergo: slice]: TypeError: Index '{}' not an integer.".format(
                    str(args[0])))
        try:
            return args[1][args[0]]
        except IndexError:
            raise ErgonomicaError(
                "[ergo: slice]: IndexError: Index {} out of range.".format(
                    str(args[0])))
    elif len(args) == 3:
        if not isinstance(args[0], int):
            raise ErgonomicaError(
                "[ergo: slice]: TypeError: Index '{}' not an integer.".format(
                    str(args[0])))
        if not isinstance(args[1], int):
            raise ErgonomicaError(
                "[ergo: slice]: TypeError: Index '{}' not an integer.".format(
                    str(args[1])))

        return args[2][args[0]:args[1]]
Example #10
0
def arglist(_function):
    if isinstance(_function, function):
        return _function.args
    # they don't have args attributes since they're not actual Python functions
    if isinstance(_function, types.BuiltinFunctionType):
        return []
    elif isinstance(_function, types.FunctionType):
        return inspect.getargspec(_function).args
    else:
        try:
            return inspect.getargspec(function.__call__).args
        except AttributeError:
            raise ErgonomicaError(
                "[ergo]: TypeError: '{}' is not a function.".format(
                    str(function)))
Example #11
0
    def __init__(self, argspec=(), args=(), outer=None):
        argv_read = False
        args = list(args)  # so we can pop from it

        for i in argspec:
            if i.startswith("*"):
                if argv_read:
                    raise ErgonomicaError(
                        "[ergo: SyntaxError]: Multiple argv arguments.")
                else:
                    argv_read = True
                    self.update({i[1:]: args})
            else:
                self.update({i: args.pop()})

        self.outer = outer
Example #12
0
def ls(argc):
    """
    ls: List files in a directory.

    Usage:
        ls [DIR] [-c | --count-files] [-d | --date] [-h | --hide-dotfiles]

    Options:
        -d --date           Show file creation dates.
        -h --hide-dotfiles  Ignore dotfiles.
        -c --count-files    Return the number of files in a directory.

    Examples:
        ls $
    """

    file_filter = lambda x: True

    if argc.args['--hide-dotfiles']:
        file_filter = lambda x: not x.startswith(".")

    # date processing from numerical time
    date = lambda t: str(datetime.datetime.fromtimestamp(creation_date(t))) +\
           " " if argc.args['--date'] else ""

    if not argc.args['DIR']:
        argc.args['DIR'] = "."

    if not os.path.isdir(expand_path(argc.env, argc.args['DIR'])):
        raise ErgonomicaError(
            "[ergo: ls]: [DirectoryError]: No such directory '{}'.".format(
                expand_path(argc.env, argc.args['DIR'])))

    files = [
        date(x) + x
        for x in os.listdir(expand_path(argc.env, argc.args['DIR']))
        if file_filter(x)
    ]

    if argc.args['--count-files']:
        return len(files)
    else:
        return files
Example #13
0
def color(argc):
    """color: Easily print terminal color codes.

    Usage:
        color COLOR
        color bg COLOR
    """

    if argc.args['bg']:
        module = colorama.Back
    else:
        module = colorama.Fore
    try:
        return getattr(module, argc.args['COLOR'].upper())
    except AttributeError:
        raise ErgonomicaError("[ergo: color]: No such color '{}'.".format(
            argc.args['COLOR']))

    return
Example #14
0
def size(argc):
    """size: Return the sizes of files.

    Usage:
        size [-h] FILE
        size [-h] [-u UNIT] FILE

    Options:
        -u, --unit            Specify the unit of size in which to display the file.
        -h, --human-readable  Print the size along with units (i.e., human readable)

    """

    path = os.path.expanduser(argc.args['FILE'])
    if not os.path.exists(path):
        raise ErgonomicaError("[ergo: NoSuchFileError]: No such file '%s'." % (argc.args['FILE']))
    size = file_or_dir_size(path)

    if argc.args['--unit']:
        unit = argc.args["UNIT"]
        if unit in SHORT_SIZES:
            size_factor = SHORT_SIZES.index(unit)
        elif unit in SIZES:
            size_factor = SIZES.index(unit)
        elif unit in NAME_SIZES:
            size_factor = NAME_SIZES.index(unit)

    else:
        # automatically calculate the best unit, falling
        # back to largest size if too large
        size_factor = len(SHORT_SIZES) - 1
        for i in range(len(SIZES)):
            if (1024 ** i) >= size:
                size_factor = i - 1
                break


    if argc.args['--human-readable']:
        return argc.args['FILE'] + ": " + str(size / 1024.0 ** size_factor) + " " + SIZES[size_factor]
    else:
        return (size / 1024.0 ** size_factor)
Example #15
0
def cd(argc):
    """cd: Changes the directory.

    Usage:
        cd <directory>[DIR]
    """

    if not argc.args['DIR']:
        argc.args['DIR'] = "~"

    try:
        os.chdir(expand_path(argc.env, argc.args['DIR']))

    except OSError:
        raise ErgonomicaError(
            "[ergo: cd]: [DirectoryError]: No such directory '{}'.".format(
                expand_path(argc.env, argc.args['DIR'])))

    argc.env.directory = os.getcwd()

    return None
Example #16
0
def ls(argc):
    """
    ls: List files in a directory.

    Usage:
        ls [DIR] [-c | --count-files] [-d | --date] [-a | --all]

    Options:
        -d --date           Show file creation dates.
        -a --all            Do not ignore files and directories starting with a `.` character..
        -c --count-files    Return the number of files in a directory.

    Examples:
        ls $
    """

    # date processing from numerical time
    date = lambda t: str(datetime.datetime.fromtimestamp(creation_date(t))) +\
           " " if argc.args['--date'] else ""

    if not argc.args['DIR']:
        argc.args['DIR'] = "."

    if not os.path.isdir(expand_path(argc.env, argc.args['DIR'])):
        raise ErgonomicaError(
            "[ergo: ls]: [DirectoryError]: No such directory '{}'.".format(
                expand_path(argc.env, argc.args['DIR'])))

    files = [
        date(x) + x
        for x in os.listdir(expand_path(argc.env, argc.args['DIR']))
        if argc.args['--all'] or (not (x.startswith(".") or x == "~"))
    ]

    if argc.args['--count-files']:
        return len(files)
    else:
        return files
Example #17
0
def environment(argc):
    """
       environment: Configure environment variables.

       Usage:
          environment set VARIABLE VALUE
          environment get VARIABLE
    """

    if argc.args['set']:
        vars(argc.env)[argc.args['VARIABLE']] = argc.args['VALUE']
        if argc.args['VARIABLE'] == 'path':
            os.environ['PATH'] = argc.args['VALUE']
        elif argc.args['VARIABLE'] == 'pypath':
            sys.path = argc.args['VALUE'].split(os.pathsep)

    elif argc.args['get']:
        try:
            return vars(argc.env)[argc.args['VARIABLE']]
        except KeyError:
            raise ErgonomicaError(
                '[ergo]: [environment]: No such environment variable "{}".'.
                format(argc.args['VARIABLE']))
Example #18
0
def _range(argc):
    """range: Construct a range of integers.

    Usage:
        range END
        range START END
        range START END STEP
    """

    end = float(argc.args['END'])
    try:
        if argc.args['START']:
            start = float(argc.args['START'])
            if argc.args['STEP']:
                step = float(argc.args['STEP'])
                return [x for x in frange(start, end, step)]
            else:
                return [x for x in frange(start, end, 1)]
        else:
            return [x for x in frange(0, end, 1)]

    except ValueError:
        # TODO: have this give the actual offending number
        raise ErgonomicaError("[ergo: range]: Non-number passed.")
Example #19
0
def size(argc):
    """size: Return the sizes of files.

    Usage:
        size FILE...
        size [-u UNIT] FILE...

    Options:
        -u, --unit  Specify the unit of size in which to display the file.

    """

    out = []
    size_factor = 1
    if argc.args['--unit']:
        unit = argc.args["UNIT"]
        if unit in SHORT_SIZES:
            size_factor = SHORT_SIZES.index(unit)
        elif unit in SIZES:
            size_factor = SIZES.index(unit)
        elif unit in NAME_SIZES:
            size_factor = NAME_SIZES.index(unit)

    for item in argc.args['FILE']:
        try:
            path = os.path.expanduser(item)
            if not os.path.exists(path):
                raise OSError
            size = file_or_dir_size(path)
            out.append(item + ": " + str(size / 1024**size_factor) + " " +
                       SIZES[size_factor])
        except OSError:
            raise ErgonomicaError(
                "[ergo: NoSuchFileError]: No such file '%s'." % (item))

    return out[0] if len(out) == 1 else out
Example #20
0
def eval(x, ns, at_top=False):
    global namespace, PRINT_OVERRIDE, ENV

    if at_top:
        PRINT_OVERRIDE = False

    while True:
        if x == []:
            raise ErgonomicaError("syntax-error", "Empty expression!")

        if isinstance(x, Symbol):
            try:
                return ns.find(x)[x]
            except AttributeError as error:
                raise ErgonomicaError(
                    "[ergo]: NameError: No such variable {}.".format(x))

        elif isinstance(x, str):
            return x

        elif not isinstance(x, list):
            return x

        elif x[0] == "if":
            if len(x) > 4:
                # elif statements
                i = 0
                while True:
                    if i == len(x):
                        break
                    item = x[i]
                    if item in ["if", "elif"]:
                        if eval(x[i + 1], ns):
                            exp = x[i + 2]
                            break
                        i += 3
                    elif item in ["else"]:
                        exp = x[i + 1]
                        break
            elif len(x) == 3:
                (_, conditional, then) = x
                exp = (then if eval(conditional, ns) else None)
            else:
                raise ErgonomicaError(
                    "[ergo: SyntaxError]: Wrong number of arguments for `if`. Should be: `if conditional then_expr [elif conditional then_expr] [else]`."
                )
            return eval(exp, ns)

        elif x[0] == "set":
            if len(x) == 3:
                (_, name, body) = x
                name = Symbol(name)
                ns[name] = eval(body, ns)
                return None
            else:
                raise ErgonomicaError(
                    "[ergo: SyntaxError]: Wrong number of arguments for `set`. Should be: `set symbol value`."
                )

        elif x[0] == "with":
            # with (expr) as varname (body_expression)
            if len(x) == 5:
                (_, expr, _, varname, body_expression) = x
                name = Symbol(varname)
                copied_ns = copy(ns)
                copied_ns[name] = eval(expr, ns)
                return eval(body_expression, copied_ns)
            else:
                raise Ergonomica(
                    "[ergo: SyntaxError]: Wrong number of arguments for `with`. Should be: `with (expr) as varname (body_expression)`."
                )

        elif x[0] == "global":
            (_, name, body) = x
            name = Symbol(name)
            namespace[name] = eval(body, ns)
            return None

        elif x[0] == "lambda":
            if len(x) > 2:
                argspec = x[1]
                body = x[2]
                return function(argspec, body, ns)
            else:
                raise ErgonomicaError(
                    "[ergo: SyntaxError]: Wrong number of arguments for `lambda`. Should be: lambda argspec body...."
                )

        else:
            try:
                if isinstance(eval(x[0], ns), function):
                    p = eval(x[0], ns)
                    ns = Namespace(p.args[::-1], [eval(y, ns) for y in x[1:]],
                                   p.ns)
                    x = p.body
                    continue

                # if arglist(eval(x[0], ns)) == ['argc']:
                #     return eval(x[0], ns)(ArgumentsContainer(ENV, namespace, docopt(eval(x[0], ns).__doc__, [eval(i, ns) for i in x[1:]])))
                return eval(x[0], ns)(*[eval(i, ns) for i in x[1:]])

            except Exception as e:
                if isinstance(e, ErgonomicaError):
                    if not e.args[0].startswith(
                            "[ergo]: NameError: No such variable {}.".format(
                                x[0])):
                        # then it's not actually a unknown command---it's an error from something else
                        raise
                else:
                    print("[ergo]: Error on line:")
                    print(x)
                    raise

                # presumably the command isn't found
                ENV.update_env()
                if os.path.islink("~"):
                    if os.path.realpath("~") != os.path.expanduser("~"):
                        print(
                            "[ergo]: Fatal error! There is already a symlink in this directory named `~` which does not link to your home folder! Refusing to run..."
                        )
                elif os.path.exists("~"):
                    print(
                        "[ergo]: Fatal error! There is already an item in this directory named `~` which is not a symlink to your home folder! Refusing to run..."
                    )
                else:
                    os.symlink(os.path.expanduser("~"), "~")
                try:
                    if isinstance(x[0],
                                  str) and x[0].startswith("%") or at_top:
                        PRINT_OVERRIDE = at_top
                        if x[0].startswith("%"):
                            x[0] = x[0][1:]  # trim off percent sign
                        try:
                            r = os.system(" ".join([
                                quote(y) for y in [x[0]] +
                                expand_typed_args([eval(i, ns) for i in x[1:]])
                            ]))
                            os.unlink("~")
                            return r
                        except Exception as e:
                            os.unlink("~")
                            raise e
                    else:
                        try:
                            p = subprocess.Popen(
                                [x[0]] +
                                expand_typed_args([eval(i, ns)
                                                   for i in x[1:]]),
                                stdout=subprocess.PIPE,
                                universal_newlines=True)
                            p.wait()
                            os.unlink("~")
                        except Exception as e:
                            os.unlink("~")
                            raise e
                        try:
                            cur = [
                                line[:-1].encode().decode('utf-8')
                                for line in iter(p.stdout.readline, "")
                            ]
                            if len(cur) == 1:
                                return cur[0]
                            else:
                                return cur

                        except KeyboardInterrupt as e:
                            p.terminate()
                            raise e

                # TODO: instead of checking for a FileNotFoundError, check if the command is in the user's PATH.
                except FileNotFoundError as e:
                    raise ErgonomicaError(
                        "[ergo]: Unknown command '{}'.".format(x[0]))

                except OSError as e:  # on Python2
                    raise ErgonomicaError(
                        "[ergo]: Unknown command '{}'.".format(x[0]))
Example #21
0
def eval(x, ns, at_top=False):
    global namespace, PRINT_OVERRIDE, ENV

    if at_top:
        PRINT_OVERRIDE = False

    while True:
        if x == []:
            return

        if isinstance(x, Symbol):
            try:
                return ns.find(x)[x]
            except AttributeError as error:
                raise ErgonomicaError(
                    "[ergo]: NameError: No such variable {}.".format(x))

        elif isinstance(x, str):
            return x

        elif not isinstance(x, list):
            return x

        elif x[0] == "if":
            if len(x) > 4:
                # elif statements
                i = 0
                while True:
                    if i == len(x):
                        break
                    item = x[i]
                    if item in ["if", "elif"]:
                        if eval(x[i + 1], ns):
                            exp = x[i + 2]
                            break
                        i += 3
                    elif item in ["else"]:
                        exp = x[i + 1]
                        break
            elif len(x) == 3:
                (_, conditional, then) = x
                exp = (then if eval(conditional, ns) else None)
            else:
                raise ErgonomicaError(
                    "[ergo: SyntaxError]: Wrong number of arguments for `if`. Should be: if conditional then [else]."
                )
            return eval(exp, ns)

        elif x[0] == "set":
            if len(x) == 3:
                (_, name, body) = x
                name = Symbol(name)
                ns[name] = eval(body, ns)
                return None
            else:
                raise ErgonomicaError(
                    "[ergo: SyntaxError]: Wrong number of arguments for `set`. Should be: set symbol value."
                )

        elif x[0] == "global":
            (_, name, body) = x
            name = Symbol(name)
            namespace[name] = eval(body, ns)
            return None

        elif x[0] == "lambda":
            if len(x) > 2:
                argspec = x[1]
                body = x[2]
                return function(argspec, body, ns)
            else:
                raise ErgonomicaError(
                    "[ergo: SyntaxError]: Wrong number of arguments for `lambda`. Should be: lambda argspec body...."
                )

        else:
            try:
                if isinstance(eval(x[0], ns), function):
                    p = eval(x[0], ns)
                    ns = Namespace(p.args, [eval(y, ns) for y in x[1:]], p.ns)
                    x = p.body
                    continue

                if arglist(eval(x[0], ns)) == ['argc']:
                    return eval(x[0], ns)(ArgumentsContainer(
                        ENV, namespace,
                        docopt(
                            eval(x[0], ns).__doc__,
                            [eval(i, ns) for i in x[1:]])))
                return eval(x[0], ns)(*[eval(i, ns) for i in x[1:]])
            except ErgonomicaError as e:
                if not e.args[0].startswith(
                        "[ergo]: NameError: No such variable {}.".format(
                            x[0])):
                    # then it's not actually a unknown command---it's an error from something else
                    raise e
                # presumably the command isn't found
                ENV.update_env()
                try:
                    if isinstance(x[0],
                                  str) and x[0].startswith("%") or at_top:
                        PRINT_OVERRIDE = at_top
                        if x[0].startswith("%"):
                            x[0] = x[0][1:]  # trim off percent sign
                        return os.system(" ".join([
                            quote(y) for y in [x[0]] +
                            expand_typed_args([eval(i, ns) for i in x[1:]])
                        ]))
                    else:

                        p = subprocess.Popen(
                            [x[0]] +
                            expand_typed_args([eval(i, ns) for i in x[1:]]),
                            stdout=subprocess.PIPE,
                            universal_newlines=True)
                        try:
                            cur = [
                                line[:-1]
                                for line in iter(p.stdout.readline, "")
                            ]
                            if len(cur) == 1:
                                return cur[0]
                            else:
                                return cur

                        except KeyboardInterrupt as e:
                            p.terminate()
                            raise e

                except FileNotFoundError:
                    raise ErgonomicaError(
                        "[ergo]: Unknown command '{}'.".format(x[0]))

                except OSError:  # on Python2
                    raise ErgonomicaError(
                        "[ergo]: Unknown command '{}'.".format(x[0]))