Example #1
0
def addline(env, args, kwargs):
    """[LINE,...] {file:filename}@Adds all LINEs to file filename. Note that newlines must be included."""
    try:
        _file = kwargs["file"]
        if _file[0] not in ["/", "~"]:
            _file = os.path.join(env.directory, _file)
        for line in args:
            open(kwargs["file"], "a").write(line + "\n")
        return
    except KeyError:
        raise ErgonomicaError(
            "[ergo: ArgumentError]: No file set for addline.")
Example #2
0
def rm(env, args, kwargs):
    """[FILE,...]@Remove FILEs (works for directories as well)."""
    for x in args:
        path = os.path.expanduser(x)
        if os.path.exists(path):
            if os.path.isdir(path):
                shutil.rmtree(path)
            else:
                os.remove(path)
        else:
            raise ErgonomicaError("[ergo: NoSuchFileOrDirectoryError]: '%s'." %
                                  (path))
Example #3
0
def mkdir(env, args, kwargs):
    """[DIR,...]@Make DIRs."""
    for directory in args:
        try:
            os.mkdir(os.path.expanduser(directory))
        except OSError:
            if errno.EEXIST:
                if kwargs.get("overwrite") == 'true':
                    shutil.rmtree(os.path.expanduser(directory))
                    os.mkdir(os.path.expanduser(directory))
                else:
                    raise ErgonomicaError(
                        '[ergo: DirectoryExist]')  # TODO issue #42
Example #4
0
def cow(env, args, kwargs):
    """STRING@Make a cow say STRING."""
    if len(args) == 1:
        string = args[0]
        s = " " + "_" * (len(string) + 2) + "\n"
        s += "< %s >\n" % string
        s += " " + "-" * (len(string) + 2)
        s += """
        \\   ^__^
         \\  (oo)\\_______
            (__)\\        )\\/\\
                ||----w |
                ||     ||"""
        return s
    else:
        raise ErgonomicaError(
            "[ergo: Wrong number of arguments for 'cow' command.")
Example #5
0
def get_code_blocks(string):
    lines = string.split("\n")
    blocks = []

    for line in lines:
        if line == "":
            pass
        elif line[0] != " ":
            blocks.append(line)
        else:
            if (not line.startswith("   ")) and (line.startswith(" ")):
                raise ErgonomicaError(
                    "[ergo: SyntaxError]: Incorrect indentation on line '%s'."
                    % line)
            else:
                blocks[-1] += "\n" + line[3:]

    return blocks
Example #6
0
def cd(env, args, kwargs):
    """[DIR]@Changes to directory DIR. If none specified, changes to ~."""
    try:
        if args == []:
            os.chdir(os.path.expanduser("~"))

        elif args[0][0] in ["~", "/"]:
            os.chdir(os.path.expanduser(args[0]))

        else:
            os.chdir(os.path.join(env.directory, args[0]))

        env.directory = os.getcwd()
    except OSError:
        _, error, _ = sys.exc_info()

        raise ErgonomicaError(
            "[ergo: NoSuchDirectoryError] No such directory '%s'. Perhaps it's a file?"
            % (re.findall(r"'(.*?)'", str(error))[0]))
Example #7
0
def main(argc):
    """rm: Remove files and directories.

    Usage:
       rm FILE
    """

    _file = argc.args['FILE']
    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):
        if os.path.isdir(path):
            shutil.rmtree(path)
        else:
            os.remove(path)
    else:
        raise ErgonomicaError("[ergo: NoSuchFileOrDirectoryError]: '%s'." %
                              (path))
Example #8
0
def find(env, args, kwargs):
    """[DIR] {name:PATTERN}@Finds a file with name matching PATTERN. If no DIR specified, chooses current directory."""
    try:
        pattern = kwargs["name"]
    except KeyError:
        pattern = "*"
    try:
        path = args[0]
    except IndexError:
        path = env.directory

    if not os.path.isdir(path):
        raise ErgonomicaError("[ergo: NoSuchDirectoryError]: No such directory '%s'." % (path))

    result = []
    for root, dirs, files in os.walk(path):
        for dir in dirs:
            if fnmatch.fnmatch(os.path.join(root, dir), pattern):
                result.append(os.path.join(root, dir))
        for name in files:
            if fnmatch.fnmatch(name, pattern):
                result.append(os.path.join(root, name))
    return [env.theme["files"] + x for x in list(set(result))]
Example #9
0
def size(env, args, kwargs):
    """[FILE,...] {unit:UNIT}@Prints the size of each file. If unit specified, displays size in that unit (B, kB, MB,...)."""
    out = []
    size_factor = 1
    if "unit" in kwargs:
        unit = kwargs["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 args:
        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
Example #10
0
def ergo_help(env, args, kwargs):
    """[COMMAND,...]@Display all ergonomica commands. If COMMANDs specified, returns the docstrings and arguments for them."""
    out = ""
    if args == []:
        return globalization_query("help_welcome_message", env.LANG)
    for arg in args:

        if arg == "syntax":
            out += """In Ergonomica, commands are of the form

            command arg1 arg2,... {kwarg1:val1,kwarg2:val2,...}

For example, finding all files in the root directory that match the regular expression 'e.*o':

            find / {name:e.*o}

Note that you can call a command by the first three letters of its name. For example, instead of

            edit important_code.py

you can type

           edi important_code.py

If a command is not defined in Ergonomica, ergonomica will fallback to BASH (but with Ergonomica syntax). Arguments are the same. If a flag requires a value (like -f file), there will be a kwarg with that flag that takes that value. If it does not require a value, simply supply 't' or 'true' for the value. For example, the command

            git commit --interactive -m "Making the world a better place"

The Ergonomica equivalent for this command would be
            
            git commit {-interactive:t,m:"Making the world a better place"}

            or

            git commit {-interactive:true,m:"Making the world a better place"}

To "pipe" in Ergonomica, one uses the '->' symbol. Commands may be put together as a chain

            command1 -> command2 -> command3

The last command in the chain will have its output printed. Each command outputs "args", and certain operators (defined later) allow for piping of kwargs. To make a command accept the arguments from the last command, one uses --arg as one of the arguments. For example, to list all files and remove them, one would run

            ls -> rm --arg

(analagous to)

            rm file1.txt file2.mp3,...

To accept kwargs, one uses --kw.
To process pipes of arguments, there are "operators", denoted by parenthases, e.g.,

            (filter) x.endswith(".py")

The available operators are:
(map) python_expression: applies a python expression to each argument. For example,

            ls -> (map) x + ' is on my computer.'
            # adds ' is on my computer' to each directory listing

(filter) python_expression: returns all arguments such that python_expression is true. For example,

            ifconfig -> (match) .*broadcast.*
            # shows lines that contain "broadcast" in ifconfig (ip address on wifi cards)

(match) regular_expression: returns all arguments that match regexp regular_expression. For example,

           ls -> (match) .*\.py
           # display all .py files
            
(reverse): reverses all arguments
(splice): splice arguments from last and current pipes. For example,
       
           echo a b -> echo c d -> (splice)
           # returns a c b d

(split): splits all arguments by spaces and flattens list

           echo "hello world" -> (splice)
           # returns hello world

(kw): sets each first argument to the value of the second in kwargs. For example,

          echo a 2 b 3 -> (kw) -> set --kw
          # sets a to 2 and b to 3\n\n"""

        elif arg == "commands":
            pruned_verbs = {}
            for item in env.verbs:
                if item not in pruned_verbs:
                    pruned_verbs[item] = env.verbs[item]
            for item in pruned_verbs:
                docstring = env.verbs[item].__doc__.split("@")
                out += "%-36s |  %29s\n" % (item + " " + docstring[0],
                                            docstring[1])

        elif arg in env.verbs:
            docstring = env.verbs[arg].__doc__.split("@")
            out += "%-26s |  %29s\n" % (arg + " " + docstring[0], docstring[1])
        else:
            print("arg is", arg)
            raise ErgonomicaError(
                "[ergo: HelpError]: No such help directive '%s'." % (arg))
    return out + "\nVisit https://github.com/ergonomica/ergonomica/wiki for more documentation."
Example #11
0
def run_operator(block, pipe):
    operator = get_operator(block)

    # (map) -- map an operator to a list of operands
    if operator == "map":
        try:
            func = eval("lambda x: " + block.replace("(map)", ""))
        except Exception as error:
            raise ErgonomicaError(
                "[ergo: OperatorError]: Error in parsing command for operator 'map'."
                + str(error))
        try:
            out = list(pool.map(func, pipe.getstack_args(-1)))
        except TypeError:
            if pipe.getstack_args(-1) is None:
                raise ErgonomicaError(
                    "[ergo: OperatorError]: Error in parsing command for operator 'map'."
                )
        except Exception as error:
            raise ErgonomicaError("[ergo: OperatorError]: " + (str(error)))
            #raise error
        return out
        #return pipe.args[-1]

    # (filter) -- return all arguments that match the specified function
    elif operator == "filter":
        try:
            func = eval("lambda x: " + block.replace("(filter)", ""))
        except SyntaxError:
            raise ErgonomicaError(
                "[ergo: OperatorError]: SyntaxError in operator 'filter'.")
        pipe.lastlast_args = pipe.getstack_args(-1)
        try:
            out = pool_filter(func, pipe.getstack_args(-1))
        except TypeError as error:
            if pipe.getstack_args(-1) is None:
                raise ErgonomicaError(
                    "[ergo: OperatorError]: No arguments provided to operator 'filter'."
                )
            raise error
        return out

    # (match) -- return all arguments that match the specified regexp
    elif operator == "match":
        exp = block.replace("(match)", "").strip()
        pool_filter(lambda x: re.findall(exp, x.strip()),
                    pipe.getstack_args(-1))

    # (reverse) -- reverse the order of all arguments
    elif operator == "reverse":
        return pipe.getstack_args(-1)[::-1]

    # (splice) -- splice the last and 2nd last argument lists together
    elif operator == "splice":
        return list(
            filter(
                None,
                sum(
                    izip_longest(pipe.getstack_args(-2),
                                 pipe.getstack_args(-1)), ())))

    # (split) -- split input strings by spaces
    elif operator == "split":
        return [
            item for sublist in [x.split() for x in pipe.getstack_args(-1)]
            for item in sublist
        ]

    # (kw) -- map the last and 2nd last argument lists into a dictionary
    elif operator == "kw":
        pipe.setstack_kwargs({
            pipe.getstack_args(-1)[i]: pipe.getstack_args(-1)[i + 1]
            for i in range(len(pipe.getstack_args(-1)) - 1)
        })
        return pipe.getstack_kwargs(-1)
    else:
        return False