comparison sat_frontends/jp/cmd_debug.py @ 2562:26edcf3a30eb

core, setup: huge cleaning: - moved directories from src and frontends/src to sat and sat_frontends, which is the recommanded naming convention - move twisted directory to root - removed all hacks from setup.py, and added missing dependencies, it is now clean - use https URL for website in setup.py - removed "Environment :: X11 Applications :: GTK", as wix is deprecated and removed - renamed sat.sh to sat and fixed its installation - added python_requires to specify Python version needed - replaced glib2reactor which use deprecated code by gtk3reactor sat can now be installed directly from virtualenv without using --system-site-packages anymore \o/
author Goffi <goffi@goffi.org>
date Mon, 02 Apr 2018 19:44:50 +0200
parents frontends/src/jp/cmd_debug.py@0046283a285d
children 56f94936df1e
comparison
equal deleted inserted replaced
2561:bd30dc3ffe5a 2562:26edcf3a30eb
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
3
4 # jp: a SàT command line tool
5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org)
6
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
16
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
21 import base
22 from sat.core.i18n import _
23 from sat_frontends.jp.constants import Const as C
24 from sat.tools.common.ansi import ANSI as A
25 import json
26
27 __commands__ = ["Debug"]
28
29
30 class BridgeCommon(object):
31
32 def evalArgs(self):
33 if self.args.arg:
34 try:
35 return eval(u'[{}]'.format(u",".join(self.args.arg)))
36 except SyntaxError as e:
37 self.disp(u"Can't evaluate arguments: {mess}\n{text}\n{offset}^".format(
38 mess=e,
39 text=e.text.decode('utf-8'),
40 offset=u" "*(e.offset-1)
41 ), error=True)
42 self.host.quit(C.EXIT_BAD_ARG)
43 else:
44 return []
45
46
47 class Method(base.CommandBase, BridgeCommon):
48
49 def __init__(self, host):
50 base.CommandBase.__init__(self, host, 'method', help=_(u'call a bridge method'))
51 BridgeCommon.__init__(self)
52 self.need_loop=True
53
54 def add_parser_options(self):
55 self.parser.add_argument("method", type=str, help=_(u"name of the method to execute"))
56 self.parser.add_argument("arg", type=base.unicode_decoder, nargs="*", help=_(u"argument of the method"))
57
58 def method_cb(self, ret=None):
59 if ret is not None:
60 self.disp(unicode(ret))
61 self.host.quit()
62
63 def method_eb(self, failure):
64 self.disp(_(u"Error while executing {}: {}".format(self.args.method, failure)), error=True)
65 self.host.quit(C.EXIT_ERROR)
66
67 def start(self):
68 method = getattr(self.host.bridge, self.args.method)
69 args = self.evalArgs()
70 try:
71 method(*args, profile=self.profile, callback=self.method_cb, errback=self.method_eb)
72 except TypeError:
73 # maybe the method doesn't need a profile ?
74 try:
75 method(*args, callback=self.method_cb, errback=self.method_eb)
76 except TypeError:
77 self.method_eb(_(u"bad arguments"))
78
79
80 class Signal(base.CommandBase, BridgeCommon):
81
82 def __init__(self, host):
83 base.CommandBase.__init__(self, host, 'signal', help=_(u'send a fake signal from backend'))
84 BridgeCommon.__init__(self)
85
86 def add_parser_options(self):
87 self.parser.add_argument("signal", type=str, help=_(u"name of the signal to send"))
88 self.parser.add_argument("arg", type=base.unicode_decoder, nargs="*", help=_(u"argument of the signal"))
89
90 def start(self):
91 args = self.evalArgs()
92 json_args = json.dumps(args)
93 # XXX: we use self.args.profile and not self.profile
94 # because we want the raw profile_key (so plugin handle C.PROF_KEY_NONE)
95 self.host.bridge.debugFakeSignal(self.args.signal, json_args, self.args.profile)
96
97
98 class Bridge(base.CommandBase):
99 subcommands = (Method, Signal)
100
101 def __init__(self, host):
102 super(Bridge, self).__init__(host, 'bridge', use_profile=False, help=_('bridge s(t)imulation'))
103
104
105 class Monitor(base.CommandBase):
106
107 def __init__(self, host):
108 super(Monitor, self).__init__(host,
109 'monitor',
110 use_verbose=True,
111 use_profile=False,
112 use_output=C.OUTPUT_XML,
113 help=_('monitor XML stream'))
114 self.need_loop = True
115
116 def add_parser_options(self):
117 self.parser.add_argument("-d", "--direction", choices=('in', 'out', 'both'), default='both', help=_(u"stream direction filter"))
118
119 def printXML(self, direction, xml_data, profile):
120 if self.args.direction == 'in' and direction != 'IN':
121 return
122 if self.args.direction == 'out' and direction != 'OUT':
123 return
124 verbosity = self.host.verbosity
125 if not xml_data.strip():
126 if verbosity <= 2:
127 return
128 whiteping = True
129 else:
130 whiteping = False
131
132 if verbosity:
133 profile_disp = u' ({})'.format(profile) if verbosity>1 else u''
134 if direction == 'IN':
135 self.disp(A.color(A.BOLD, A.FG_YELLOW, '<<<===== IN ====', A.FG_WHITE, profile_disp))
136 else:
137 self.disp(A.color(A.BOLD, A.FG_CYAN, '==== OUT ====>>>', A.FG_WHITE, profile_disp))
138 if whiteping:
139 self.disp('[WHITESPACE PING]')
140 else:
141 try:
142 self.output(xml_data)
143 except Exception:
144 # initial stream is not valid XML,
145 # in this case we print directly to data
146 # FIXME: we should test directly lxml.etree.XMLSyntaxError
147 # but importing lxml directly here is not clean
148 # should be wrapped in a custom Exception
149 self.disp(xml_data)
150 self.disp(u'')
151
152 def start(self):
153 self.host.bridge.register_signal('xmlLog', self.printXML, 'plugin')
154
155
156 class Debug(base.CommandBase):
157 subcommands = (Bridge, Monitor)
158
159 def __init__(self, host):
160 super(Debug, self).__init__(host, 'debug', use_profile=False, help=_('debugging tools'))