Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / history_cli.py @ 34e4cf61

History | View | Annotate | Download (6.2 kB)

1 73e0914d Stavros Sachtouris
#!/usr/bin/env python
2 73e0914d Stavros Sachtouris
3 73e0914d Stavros Sachtouris
# Copyright 2012 GRNET S.A. All rights reserved.
4 73e0914d Stavros Sachtouris
#
5 73e0914d Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
6 73e0914d Stavros Sachtouris
# without modification, are permitted provided that the following
7 73e0914d Stavros Sachtouris
# conditions are met:
8 73e0914d Stavros Sachtouris
#
9 73e0914d Stavros Sachtouris
#   1. Redistributions of source code must retain the above
10 73e0914d Stavros Sachtouris
#      copyright notice, this list of conditions and the following
11 73e0914d Stavros Sachtouris
#      disclaimer.
12 73e0914d Stavros Sachtouris
#
13 73e0914d Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
14 73e0914d Stavros Sachtouris
#      copyright notice, this list of conditions and the following
15 73e0914d Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
16 73e0914d Stavros Sachtouris
#      provided with the distribution.
17 73e0914d Stavros Sachtouris
#
18 73e0914d Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 73e0914d Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 73e0914d Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 73e0914d Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 73e0914d Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 73e0914d Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 73e0914d Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 73e0914d Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 73e0914d Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 73e0914d Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 73e0914d Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 73e0914d Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
30 73e0914d Stavros Sachtouris
#
31 73e0914d Stavros Sachtouris
# The views and conclusions contained in the software and
32 73e0914d Stavros Sachtouris
# documentation are those of the authors and should not be
33 73e0914d Stavros Sachtouris
# interpreted as representing official policies, either expressed
34 73e0914d Stavros Sachtouris
# or implied, of GRNET S.A.
35 73e0914d Stavros Sachtouris
36 d486baec Stavros Sachtouris
from kamaki.cli.command_tree import CommandTree
37 234954d1 Stavros Sachtouris
from kamaki.cli.argument import IntArgument, ValueArgument
38 fce93ff6 Stavros Sachtouris
from kamaki.cli.argument import ArgumentParseManager
39 73e0914d Stavros Sachtouris
from kamaki.cli.history import History
40 73e0914d Stavros Sachtouris
from kamaki.cli import command
41 03fd7ddb Stavros Sachtouris
from kamaki.cli.commands import _command_init
42 b6a99832 Stavros Sachtouris
from kamaki.cli import exec_cmd, print_error_message
43 ee9f8245 Stavros Sachtouris
from kamaki.cli.errors import CLIError, CLISyntaxError, raiseCLIError
44 fce93ff6 Stavros Sachtouris
from kamaki.cli.utils import split_input
45 fce93ff6 Stavros Sachtouris
from kamaki.clients import ClientError
46 73e0914d Stavros Sachtouris
47 234954d1 Stavros Sachtouris
48 d486baec Stavros Sachtouris
history_cmds = CommandTree('history', 'Command history')
49 db950b10 Stavros Sachtouris
_commands = [history_cmds]
50 234954d1 Stavros Sachtouris
51 234954d1 Stavros Sachtouris
52 00ef4ab6 Stavros Sachtouris
def _get_num_list(num_str):
53 00ef4ab6 Stavros Sachtouris
    if num_str.startswith('-'):
54 00ef4ab6 Stavros Sachtouris
        num1, sep, num2 = num_str[1:].partition('-')
55 00ef4ab6 Stavros Sachtouris
        num1 = '-%s' % num1
56 00ef4ab6 Stavros Sachtouris
    else:
57 00ef4ab6 Stavros Sachtouris
        num1, sep, num2 = num_str.partition('-')
58 00ef4ab6 Stavros Sachtouris
    (num1, num2) = (num1.strip(), num2.strip())
59 00ef4ab6 Stavros Sachtouris
    try:
60 00ef4ab6 Stavros Sachtouris
        num1 = (-int(num1[1:])) if num1.startswith('-') else int(num1)
61 00ef4ab6 Stavros Sachtouris
    except ValueError as e:
62 00ef4ab6 Stavros Sachtouris
        raiseCLIError(e, 'Invalid id %s' % num1)
63 00ef4ab6 Stavros Sachtouris
    if sep:
64 00ef4ab6 Stavros Sachtouris
        try:
65 00ef4ab6 Stavros Sachtouris
            num2 = (-int(num2[1:])) if num2.startswith('-') else int(num2)
66 519d8639 Stavros Sachtouris
            num2 += 1 if num2 > 0 else 0
67 00ef4ab6 Stavros Sachtouris
        except ValueError as e:
68 00ef4ab6 Stavros Sachtouris
            raiseCLIError(e, 'Invalid id %s' % num2)
69 00ef4ab6 Stavros Sachtouris
    else:
70 00ef4ab6 Stavros Sachtouris
        num2 = (1 + num1) if num1 else 0
71 00ef4ab6 Stavros Sachtouris
    return [i for i in range(num1, num2)]
72 00ef4ab6 Stavros Sachtouris
73 00ef4ab6 Stavros Sachtouris
74 5eae854d Stavros Sachtouris
class _init_history(_command_init):
75 234954d1 Stavros Sachtouris
    def main(self):
76 234954d1 Stavros Sachtouris
        self.history = History(self.config.get('history', 'file'))
77 234954d1 Stavros Sachtouris
78 73e0914d Stavros Sachtouris
79 d486baec Stavros Sachtouris
@command(history_cmds)
80 d53062bd Stavros Sachtouris
class history_show(_init_history):
81 00ef4ab6 Stavros Sachtouris
    """Show history [[-]commandid1[-[-]commandid2] ..."""
82 234954d1 Stavros Sachtouris
83 234954d1 Stavros Sachtouris
    def __init__(self, arguments={}):
84 d53062bd Stavros Sachtouris
        super(self.__class__, self).__init__(arguments)
85 234954d1 Stavros Sachtouris
        self.arguments['limit'] =\
86 234954d1 Stavros Sachtouris
            IntArgument('number of lines to show', '-n', default=0)
87 234954d1 Stavros Sachtouris
        self.arguments['match'] =\
88 234954d1 Stavros Sachtouris
            ValueArgument('show lines that match all given terms', '--match')
89 73e0914d Stavros Sachtouris
90 00ef4ab6 Stavros Sachtouris
    def main(self, *cmd_ids):
91 d53062bd Stavros Sachtouris
        super(self.__class__, self).main()
92 234954d1 Stavros Sachtouris
        ret = self.history.get(match_terms=self.get_argument('match'),
93 234954d1 Stavros Sachtouris
            limit=self.get_argument('limit'))
94 00ef4ab6 Stavros Sachtouris
95 00ef4ab6 Stavros Sachtouris
        if not cmd_ids:
96 00ef4ab6 Stavros Sachtouris
            print(''.join(ret))
97 00ef4ab6 Stavros Sachtouris
            return
98 00ef4ab6 Stavros Sachtouris
99 00ef4ab6 Stavros Sachtouris
        num_list = []
100 00ef4ab6 Stavros Sachtouris
        for num_str in cmd_ids:
101 00ef4ab6 Stavros Sachtouris
            num_list += _get_num_list(num_str)
102 00ef4ab6 Stavros Sachtouris
103 00ef4ab6 Stavros Sachtouris
        for cmd_id in num_list:
104 660a0dad Stavros Sachtouris
            try:
105 519d8639 Stavros Sachtouris
                cur_id = int(cmd_id)
106 519d8639 Stavros Sachtouris
                if cur_id:
107 519d8639 Stavros Sachtouris
                    print(ret[cur_id - (1 if cur_id > 0 else 0)][:-1])
108 660a0dad Stavros Sachtouris
            except IndexError as e2:
109 660a0dad Stavros Sachtouris
                raiseCLIError(e2, 'Command id out of 1-%s range' % len(ret))
110 73e0914d Stavros Sachtouris
111 73e0914d Stavros Sachtouris
112 d486baec Stavros Sachtouris
@command(history_cmds)
113 73e0914d Stavros Sachtouris
class history_clean(_init_history):
114 234954d1 Stavros Sachtouris
    """Clean up history"""
115 73e0914d Stavros Sachtouris
116 234954d1 Stavros Sachtouris
    def main(self):
117 d53062bd Stavros Sachtouris
        super(self.__class__, self).main()
118 234954d1 Stavros Sachtouris
        self.history.clean()
119 304c90b5 Stavros Sachtouris
120 33b3595a Stavros Sachtouris
121 304c90b5 Stavros Sachtouris
@command(history_cmds)
122 519d8639 Stavros Sachtouris
class history_run(_init_history):
123 68ab0942 Stavros Sachtouris
    """Run previously executed command(s)
124 68ab0942 Stavros Sachtouris
    run <order id> for a command with <order id>
125 68ab0942 Stavros Sachtouris
    run <from>-<to> for a set of commands, where <from> and <to> are order ids
126 68ab0942 Stavros Sachtouris
    Get order ids for commands by using history show
127 68ab0942 Stavros Sachtouris
    """
128 304c90b5 Stavros Sachtouris
129 33b3595a Stavros Sachtouris
    _cmd_tree = None
130 33b3595a Stavros Sachtouris
131 33b3595a Stavros Sachtouris
    def __init__(self, arguments={}, cmd_tree=None):
132 33b3595a Stavros Sachtouris
        super(self.__class__, self).__init__(arguments)
133 33b3595a Stavros Sachtouris
        self._cmd_tree = cmd_tree
134 33b3595a Stavros Sachtouris
135 fce93ff6 Stavros Sachtouris
    def _run_from_line(self, line):
136 fce93ff6 Stavros Sachtouris
        terms = split_input(line)
137 fce93ff6 Stavros Sachtouris
        cmd, args = self._cmd_tree.find_best_match(terms)
138 fce93ff6 Stavros Sachtouris
        if not cmd.is_command:
139 fce93ff6 Stavros Sachtouris
            return
140 fce93ff6 Stavros Sachtouris
        try:
141 fce93ff6 Stavros Sachtouris
            instance = cmd.get_class()(self.arguments)
142 fce93ff6 Stavros Sachtouris
            instance.config = self.config
143 fce93ff6 Stavros Sachtouris
            prs = ArgumentParseManager(cmd.path.split(),
144 fce93ff6 Stavros Sachtouris
                dict(instance.arguments))
145 fce93ff6 Stavros Sachtouris
            prs.syntax = '%s %s' % (cmd.path.replace('_', ' '),
146 fce93ff6 Stavros Sachtouris
                cmd.get_class().syntax)
147 fce93ff6 Stavros Sachtouris
            prs.parse(args)
148 b6a99832 Stavros Sachtouris
            exec_cmd(instance, prs.unparsed, prs.parser.print_help)
149 fce93ff6 Stavros Sachtouris
        except (CLIError, ClientError) as err:
150 b6a99832 Stavros Sachtouris
            print_error_message(err)
151 fce93ff6 Stavros Sachtouris
        except Exception as e:
152 fce93ff6 Stavros Sachtouris
            print('Execution of [ %s ] failed' % line)
153 fce93ff6 Stavros Sachtouris
            print('\t%s' % e)
154 fce93ff6 Stavros Sachtouris
155 f2e2663e Stavros Sachtouris
    def _get_cmd_ids(self, cmd_ids):
156 ee9f8245 Stavros Sachtouris
        if not cmd_ids:
157 ee9f8245 Stavros Sachtouris
            raise CLISyntaxError('Usage: <id1> [id2] ... [id3-id4] ...',
158 ee9f8245 Stavros Sachtouris
                details=' where id* are for commands in history')
159 f2e2663e Stavros Sachtouris
        cmd_id_list = []
160 f2e2663e Stavros Sachtouris
        for cmd_str in cmd_ids:
161 00ef4ab6 Stavros Sachtouris
            cmd_id_list += _get_num_list(cmd_str)
162 f2e2663e Stavros Sachtouris
        return cmd_id_list
163 f2e2663e Stavros Sachtouris
164 f2e2663e Stavros Sachtouris
    def main(self, *command_ids):
165 304c90b5 Stavros Sachtouris
        super(self.__class__, self).main()
166 f2e2663e Stavros Sachtouris
        cmd_list = self._get_cmd_ids(command_ids)
167 f2e2663e Stavros Sachtouris
        for cmd_id in cmd_list:
168 f2e2663e Stavros Sachtouris
            r = self.history.retrieve(cmd_id)
169 00ef4ab6 Stavros Sachtouris
            try:
170 00ef4ab6 Stavros Sachtouris
                print('< %s >' % r[:-1])
171 00ef4ab6 Stavros Sachtouris
            except (TypeError, KeyError):
172 519d8639 Stavros Sachtouris
                continue
173 f2e2663e Stavros Sachtouris
            if self._cmd_tree:
174 f2e2663e Stavros Sachtouris
                r = r[len('kamaki '):-1] if r.startswith('kamaki ') else r[:-1]
175 f2e2663e Stavros Sachtouris
                self._run_from_line(r)