comparison sat_frontends/jp/cmd_info.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_info.py@0046283a285d
children 947c4c4c5c53
comparison
equal deleted inserted replaced
2561:bd30dc3ffe5a 2562:26edcf3a30eb
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
3
4 # jp: a SAT 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 import base
21 from sat.core.i18n import _
22 from sat.tools.common.ansi import ANSI as A
23 from sat_frontends.jp.constants import Const as C
24 from sat_frontends.jp import common
25
26 __commands__ = ["Info"]
27
28
29 class Disco(base.CommandBase):
30
31 def __init__(self, host):
32 extra_outputs = {'default': self.default_output}
33 super(Disco, self).__init__(host, 'disco', use_output='complex', extra_outputs=extra_outputs, help=_('service discovery'))
34 self.need_loop=True
35
36 def add_parser_options(self):
37 self.parser.add_argument(u"jid", type=base.unicode_decoder, help=_(u"entity to discover"))
38 self.parser.add_argument(u"-t", u"--type", type=str, choices=('infos', 'items', 'both'), default='both', help=_(u"type of data to discover"))
39 self.parser.add_argument(u"-n", u"--node", type=base.unicode_decoder, default=u'', help=_(u"node to use"))
40 self.parser.add_argument(u"-C", u"--no-cache", dest='use_cache', action="store_false", help=_(u"ignore cache"))
41
42 def start(self):
43 self.get_infos = self.args.type in ('infos', 'both')
44 self.get_items = self.args.type in ('items', 'both')
45 jids = self.host.check_jids([self.args.jid])
46 jid = jids[0]
47 if not self.get_infos:
48 self.gotInfos(None, jid)
49 else:
50 self.host.bridge.discoInfos(jid, node=self.args.node, use_cache=self.args.use_cache, profile_key=self.host.profile, callback=lambda infos: self.gotInfos(infos, jid), errback=self.error)
51
52 def error(self, failure):
53 print (_("Error while doing discovery [%s]") % failure)
54 self.host.quit(1)
55
56 def gotInfos(self, infos, jid):
57 if not self.get_items:
58 self.gotItems(infos, None)
59 else:
60 self.host.bridge.discoItems(jid, node=self.args.node, use_cache=self.args.use_cache, profile_key=self.host.profile, callback=lambda items: self.gotItems(infos, items), errback=self.error)
61
62 def gotItems(self, infos, items):
63 data = {}
64
65 if self.get_infos:
66 features, identities, extensions = infos
67 features.sort()
68 identities.sort(key=lambda identity: identity[2])
69 data.update({
70 u'features': features,
71 u'identities': identities,
72 u'extensions': extensions})
73
74 if self.get_items:
75 items.sort(key=lambda item: item[2])
76 data[u'items'] = items
77
78 self.output(data)
79 self.host.quit()
80
81 def default_output(self, data):
82 features = data.get(u'features', [])
83 identities = data.get(u'identities', [])
84 extensions = data.get(u'extensions', {})
85 items = data.get(u'items', [])
86
87 identities_table = common.Table(self.host,
88 identities,
89 headers=(_(u'category'),
90 _(u'type'),
91 _(u'name')),
92 use_buffer=True)
93
94 extensions_tpl = []
95 extensions_types = extensions.keys()
96 extensions_types.sort()
97 for type_ in extensions_types:
98 fields = []
99 for field in extensions[type_]:
100 field_lines = []
101 data, values = field
102 data_keys = data.keys()
103 data_keys.sort()
104 for key in data_keys:
105 field_lines.append(A.color(u'\t', C.A_SUBHEADER, key, data[key]))
106 for value in values:
107 field_lines.append(A.color(u'\t', A.BOLD, value))
108 fields.append(u'\n'.join(field_lines))
109 extensions_tpl.append(u'{type_}\n{fields}'.format(type_=type_,
110 fields='\n\n'.join(fields)))
111
112 items_table = common.Table(self.host,
113 items,
114 headers=(_(u'entity'),
115 _(u'node'),
116 _(u'name')),
117 use_buffer=True)
118
119 template = []
120 if features:
121 template.append(A.color(C.A_HEADER, _(u"Features")) + u"\n\n{features}")
122 if identities:
123 template.append(A.color(C.A_HEADER, _(u"Identities")) + u"\n\n{identities}")
124 if extensions:
125 template.append(A.color(C.A_HEADER, _(u"Extensions")) + u"\n\n{extensions}")
126 if items:
127 template.append(A.color(C.A_HEADER, _(u"Items")) + u"\n\n{items}")
128
129 print u"\n\n".join(template).format(features = u'\n'.join(features),
130 identities = identities_table.display().string,
131 extensions = u'\n'.join(extensions_tpl),
132 items = items_table.display().string,
133 )
134
135
136 class Version(base.CommandBase):
137
138 def __init__(self, host):
139 super(Version, self).__init__(host, 'version', help=_('software version'))
140 self.need_loop=True
141
142 def add_parser_options(self):
143 self.parser.add_argument("jid", type=str, help=_("Entity to request"))
144
145 def start(self):
146 jids = self.host.check_jids([self.args.jid])
147 jid = jids[0]
148 self.host.bridge.getSoftwareVersion(jid, self.host.profile, callback=self.gotVersion, errback=self.error)
149
150 def error(self, failure):
151 print (_("Error while trying to get version [%s]") % failure)
152 self.host.quit(1)
153
154 def gotVersion(self, data):
155 infos = []
156 name, version, os = data
157 if name:
158 infos.append(_("Client name: %s") % name)
159 if version:
160 infos.append(_("Client version: %s") % version)
161 if os:
162 infos.append(_("Operating System: %s") % os)
163
164 print "\n".join(infos)
165 self.host.quit()
166
167
168 class Session(base.CommandBase):
169
170 def __init__(self, host):
171 super(Session, self).__init__(host, 'session', use_output='dict', help=_('running session'))
172 self.need_loop=True
173
174 def add_parser_options(self):
175 pass
176
177 def start(self):
178 self.host.bridge.sessionInfosGet(self.host.profile, callback=self._sessionInfoGetCb, errback=self._sessionInfoGetEb)
179
180 def _sessionInfoGetCb(self, data):
181 self.output(data)
182 self.host.quit()
183
184 def _sessionInfoGetEb(self, error_data):
185 self.disp(_(u'Error getting session infos: {}').format(error_data), error=True)
186 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
187
188
189 class Info(base.CommandBase):
190 subcommands = (Disco, Version, Session)
191
192 def __init__(self, host):
193 super(Info, self).__init__(host, 'info', use_profile=False, help=_('Get various pieces of information on entities'))