Mercurial > libervia-backend
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')) |