Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / history.py @ b8220825

History | View | Annotate | Download (4.6 kB)

1 5e383dd4 Stavros Sachtouris
# Copyright 2012-2014 GRNET S.A. All rights reserved.
2 73e0914d Stavros Sachtouris
#
3 73e0914d Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 73e0914d Stavros Sachtouris
# without modification, are permitted provided that the following
5 73e0914d Stavros Sachtouris
# conditions are met:
6 73e0914d Stavros Sachtouris
#
7 73e0914d Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 73e0914d Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 73e0914d Stavros Sachtouris
#      disclaimer.
10 73e0914d Stavros Sachtouris
#
11 73e0914d Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 73e0914d Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 73e0914d Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 73e0914d Stavros Sachtouris
#      provided with the distribution.
15 73e0914d Stavros Sachtouris
#
16 73e0914d Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 73e0914d Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 73e0914d Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 73e0914d Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 73e0914d Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 73e0914d Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 73e0914d Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 73e0914d Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 73e0914d Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 73e0914d Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 73e0914d Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 73e0914d Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 73e0914d Stavros Sachtouris
#
29 73e0914d Stavros Sachtouris
# The views and conclusions contained in the software and
30 73e0914d Stavros Sachtouris
# documentation are those of the authors and should not be
31 73e0914d Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 73e0914d Stavros Sachtouris
# or implied, of GRNET S.A.
33 73e0914d Stavros Sachtouris
34 c49188b7 Stavros Sachtouris
import codecs
35 50a32c37 Stavros Sachtouris
from logging import getLogger
36 50a32c37 Stavros Sachtouris
37 50a32c37 Stavros Sachtouris
38 50a32c37 Stavros Sachtouris
log = getLogger(__name__)
39 c49188b7 Stavros Sachtouris
40 fd5db045 Stavros Sachtouris
41 73e0914d Stavros Sachtouris
class History(object):
42 a313f923 Stavros Sachtouris
    ignore_commands = ['config set', ]
43 a313f923 Stavros Sachtouris
44 ddc97a10 Stavros Sachtouris
    def __init__(self, filepath, token=None):
45 fd5db045 Stavros Sachtouris
        self.filepath = filepath
46 2d1f5058 Stavros Sachtouris
        self.token = token
47 5e383dd4 Stavros Sachtouris
        self._limit = 0
48 5e383dd4 Stavros Sachtouris
        self.counter = 0
49 edaf3ba6 Stavros Sachtouris
50 a44a9d97 Stavros Sachtouris
    def __getitem__(self, cmd_ids):
51 a44a9d97 Stavros Sachtouris
        with codecs.open(self.filepath, mode='r', encoding='utf-8') as f:
52 edaf3ba6 Stavros Sachtouris
            try:
53 50a32c37 Stavros Sachtouris
                lines = f.readlines()
54 50a32c37 Stavros Sachtouris
                self.counter, cmd_list = int(lines[0]), lines[1:]
55 a44a9d97 Stavros Sachtouris
                return cmd_list[cmd_ids]
56 edaf3ba6 Stavros Sachtouris
            except IndexError:
57 edaf3ba6 Stavros Sachtouris
                return None
58 73e0914d Stavros Sachtouris
59 5e383dd4 Stavros Sachtouris
    @property
60 5e383dd4 Stavros Sachtouris
    def limit(self):
61 5e383dd4 Stavros Sachtouris
        return self._limit
62 5e383dd4 Stavros Sachtouris
63 5e383dd4 Stavros Sachtouris
    @limit.setter
64 5e383dd4 Stavros Sachtouris
    def limit(self, new_limit):
65 5e383dd4 Stavros Sachtouris
        new_limit = int(new_limit)
66 5e383dd4 Stavros Sachtouris
        if new_limit < 0:
67 5e383dd4 Stavros Sachtouris
            raise ValueError('Invalid history limit (%s)' % new_limit)
68 5e383dd4 Stavros Sachtouris
        old_limit, self._limit = self._limit, new_limit
69 50a32c37 Stavros Sachtouris
        if self._limit and ((not old_limit) or (self._limit <= old_limit)):
70 5e383dd4 Stavros Sachtouris
            with codecs.open(self.filepath, mode='r', encoding='utf-8') as f:
71 5e383dd4 Stavros Sachtouris
                lines = f.readlines()
72 50a32c37 Stavros Sachtouris
                self.counter = int(lines[0])
73 5e383dd4 Stavros Sachtouris
                old_len = len(lines[1:])
74 50a32c37 Stavros Sachtouris
            if old_len > new_limit:
75 50a32c37 Stavros Sachtouris
                self.counter += old_len - new_limit
76 50a32c37 Stavros Sachtouris
                with codecs.open(
77 50a32c37 Stavros Sachtouris
                        self.filepath, mode='w', encoding='utf-8') as f:
78 5e383dd4 Stavros Sachtouris
                    f.write('%s\n' % self.counter)
79 50a32c37 Stavros Sachtouris
                    f.write(''.join(lines[old_len - new_limit + 1:]))
80 5e383dd4 Stavros Sachtouris
                    f.flush()
81 5e383dd4 Stavros Sachtouris
82 fd5db045 Stavros Sachtouris
    @classmethod
83 fd5db045 Stavros Sachtouris
    def _match(self, line, match_terms):
84 a44a9d97 Stavros Sachtouris
        if match_terms:
85 a44a9d97 Stavros Sachtouris
            return all(term in line for term in match_terms.split())
86 fd5db045 Stavros Sachtouris
        return True
87 73e0914d Stavros Sachtouris
88 fd5db045 Stavros Sachtouris
    def get(self, match_terms=None, limit=0):
89 ddc97a10 Stavros Sachtouris
        """DEPRECATED since 0.14"""
90 24903c7d Stavros Sachtouris
        limit = int(limit or 0)
91 a44a9d97 Stavros Sachtouris
        r = ['%s.\t%s' % (i + 1, line) for i, line in enumerate(self[:]) if (
92 a44a9d97 Stavros Sachtouris
                self._match(line, match_terms))]
93 a44a9d97 Stavros Sachtouris
        return r[- limit:]
94 73e0914d Stavros Sachtouris
95 fd5db045 Stavros Sachtouris
    def add(self, line):
96 50a32c37 Stavros Sachtouris
        line = '%s' % line or ''
97 a313f923 Stavros Sachtouris
        bline = [w.lower() for w in line.split() if not w.startswith('-')]
98 a313f923 Stavros Sachtouris
        for cmd in self.ignore_commands:
99 a313f923 Stavros Sachtouris
            cmds = [w.lower() for w in cmd.split()]
100 a313f923 Stavros Sachtouris
            if cmds == bline[1:len(cmds) + 1]:
101 a313f923 Stavros Sachtouris
                log.debug('History ignored a command of type "%s"' % cmd)
102 a313f923 Stavros Sachtouris
                return
103 2d1f5058 Stavros Sachtouris
        line = line.replace(self.token, '...') if self.token else line
104 50a32c37 Stavros Sachtouris
        try:
105 50a32c37 Stavros Sachtouris
            with codecs.open(self.filepath, mode='a+', encoding='utf-8') as f:
106 50a32c37 Stavros Sachtouris
                f.write(line + '\n')
107 50a32c37 Stavros Sachtouris
                f.flush()
108 50a32c37 Stavros Sachtouris
            self.limit = self.limit
109 50a32c37 Stavros Sachtouris
        except Exception as e:
110 50a32c37 Stavros Sachtouris
            log.debug('Add history failed for "%s" (%s)' % (line, e))
111 73e0914d Stavros Sachtouris
112 edaf3ba6 Stavros Sachtouris
    def empty(self):
113 a44a9d97 Stavros Sachtouris
        with open(self.filepath, 'w') as f:
114 5e383dd4 Stavros Sachtouris
            f.write('0\n')
115 a44a9d97 Stavros Sachtouris
            f.flush()
116 5e383dd4 Stavros Sachtouris
        self.counter = 0
117 75a0ea7d Stavros Sachtouris
118 edaf3ba6 Stavros Sachtouris
    def clean(self):
119 a44a9d97 Stavros Sachtouris
        """DEPRECATED since version 0.14"""
120 edaf3ba6 Stavros Sachtouris
        return self.empty()
121 75a0ea7d Stavros Sachtouris
122 edaf3ba6 Stavros Sachtouris
    def retrieve(self, cmd_id):
123 a44a9d97 Stavros Sachtouris
        if not cmd_id:
124 a44a9d97 Stavros Sachtouris
            return None
125 a44a9d97 Stavros Sachtouris
        cmd_id = int(cmd_id)
126 a44a9d97 Stavros Sachtouris
        return self[cmd_id - (1 if cmd_id > 0 else 0)]