MythTV  master
sendProfile.py
Go to the documentation of this file.
1 #!/usr/bin/python3
2 # -*- coding: utf-8 -*-
3 
4 # smolt - Fedora hardware profiler
5 #
6 # Copyright (C) 2007 Mike McGrath
7 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
8 #
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
22 
23 from __future__ import print_function
24 from builtins import str
25 from builtins import input
26 import sys
27 import time
28 import os
29 import getpass
30 
31 
33  _code_location = '/usr/share/smolt/client'
34  if sys.path[-1] == _code_location:
35  return
36  sys.path.append(_code_location)
37 
38 
41  from i18n import _
42  import smolt
43 
44  from optparse import OptionParser
45  parser = OptionParser(version = smolt.clientVersion)
46 
47  parser.add_option('-d', '--debug',
48  dest = 'DEBUG',
49  default = False,
50  action = 'store_true',
51  help = _('enable debug information'))
52  parser.add_option('--config',
53  dest = 'the_only_config_file',
54  default = None,
55  metavar = 'file.cfg',
56  help = _('specify the location of the (only) config file to use'))
57  parser.add_option('-s', '--server',
58  dest = 'smoonURL',
59  default = smolt.smoonURL,
60  metavar = 'smoonURL',
61  help = _('specify the URL of the server (default "%default")'))
62  parser.add_option('--username',
63  dest = 'userName',
64  default = None,
65  metavar = 'userName',
66  help = _('(optional) Fedora Account System registration'))
67  parser.add_option('--password',
68  dest = 'password',
69  default = None,
70  metavar = 'password',
71  help = _('password, will prompt if not specified'))
72  parser.add_option('-p', '--printOnly',
73  dest = 'printOnly',
74  default = False,
75  action = 'store_true',
76  help = _('print information only, do not send'))
77  parser.add_option('-a', '--autoSend',
78  dest = 'autoSend',
79  default = False,
80  action = 'store_true',
81  help = _('don\'t prompt to send, just send'))
82  parser.add_option('-r', '--retry',
83  dest = 'retry',
84  default = False,
85  action = 'store_true',
86  help = _('continue to send until success'))
87  parser.add_option('-u', '--useragent', '--user_agent',
88  dest = 'user_agent',
89  default = smolt.user_agent,
90  metavar = 'USERAGENT',
91  help = _('specify HTTP user agent (default "%default")'))
92  parser.add_option('-t', '--timeout',
93  dest = 'timeout',
94  type = 'float',
95  default = smolt.timeout,
96  help = _('specify HTTP timeout in seconds (default %default seconds)'))
97  parser.add_option('-c', '--checkin',
98  dest = 'cron_mode',
99  default = False,
100  action = 'store_true',
101  help = _('do an automated checkin as when run from cron (implies --autoSend)'))
102  parser.add_option('-S', '--scanOnly',
103  dest = 'send_profile',
104  default = True,
105  action = 'store_false',
106  help = _('only scan this machine for known hardware errata, do not send profile.'))
107  parser.add_option('--submitOnly',
108  dest = 'scan_remote',
109  default = True,
110  action = 'store_false',
111  help = _('do not scan this machine for know hardware errata, only submit profile.'))
112  parser.add_option('--uuidFile',
113  dest = 'uuidFile',
114  default = smolt.hw_uuid_file,
115  help = _('specify which uuid to use, useful for debugging and testing mostly.'))
116  #parser.add_option('-b', '--bodhi',
117  # dest = 'bodhi',
118  # default = False,
119  # action = 'store_true',
120  # help = _('Submit this profile to Bodhi as well, for Fedora Developmnent'))
121  parser.add_option('-n', '--newPublicUUID',
122  dest = 'new_pub',
123  default = False,
124  action = 'store_true',
125  help = _('Request a new public UUID'))
126  parser.add_option('--http-proxy',
127  dest = 'httpproxy',
128  default = None,
129  help = _('HTTP proxy'))
130 
131  (opts, args) = parser.parse_args()
132 
133  if opts.cron_mode:
134  # Smolt is set to run
135  opts.autoSend = True
136 
137  return opts, args
138 
139 
142  from i18n import _
143  from smolt import to_ascii
144 
145  def inner_indent(text):
146  return ('\n' + 5 * ' ').join(text.split('\n'))
147 
148  excerpts = {
149  'label_intro':_('Smolt has collected four types of information:'),
150  'label_question':_('Do you want to ..'),
151  'label_question_view':_('(v)iew details on collected information?'),
152  'label_question_send':_('(s)end this information to the Smolt server?'),
153  'label_question_quit':_('(q)uit Smolt?'),
154  'label_general':_('General'),
155  'label_devices':_('Devices'),
156  'label_fs_related':_('File system-related'),
157  'label_distro_specific':_('Distribution-specific'),
158 
159  'general':inner_indent(to_ascii(profile.get_general_info_excerpt())),
160  'devices':inner_indent(to_ascii(profile.get_devices_info_excerpt())),
161  'file_system':inner_indent(to_ascii(profile.get_file_system_info_excerpt())),
162  'distro':inner_indent(to_ascii(profile.get_distro_info_excerpt())),
163  }
164  return excerpts
165 
166 
167 def dump_excerpts(excerpts):
168  print("""\
169 =====================================================
170 %(label_intro)s
171 
172 %(label_general)s
173  %(general)s
174 
175 %(label_devices)s
176  %(devices)s
177 
178 %(label_fs_related)s
179  %(file_system)s
180 
181 %(label_distro_specific)s
182  %(distro)s
183 
184 =====================================================
185 %(label_question)s
186 %(label_question_view)s
187 %(label_question_send)s
188 %(label_question_quit)s
189 """ % excerpts)
190 
191 
193  import subprocess
194  from tempfile import NamedTemporaryFile
195 
197  from i18n import _
198  from smolt import error
199 
200  excerpts = make_display_excerpts(profile)
201 
202  submit = False
203  while not submit:
204  dump_excerpts(excerpts)
205 
206  try:
207  choice = input(_('Your choice (s)end (v)iew (q)uit: ')).strip()
208  except KeyboardInterrupt:
209  error(_('Exiting...'))
210  sys.exit(4)
211  if choice in (_('s|y|yes')).split('|'):
212  submit = True
213  print('\n\n')
214  elif choice in (_('q|n|no')).split('|'):
215  sys.exit(0)
216  elif choice in (_('v')).split('|'):
217  f = NamedTemporaryFile(suffix=b'')
218  for line in profile.getProfile():
219  try:
220  f.write(bytes(line + '\n', 'latin1'))
221  except UnicodeEncodeError:
222  pass
223  f.flush()
224  os.chmod(f.name, 0o400)
225  try:
226  pager_command = os.environ['PAGER']
227  except KeyError:
228  if os.path.exists('/usr/bin/less'):
229  pager_command = '/usr/bin/less'
230  elif os.path.exists('/bin/less'):
231  pager_command = '/bin/less'
232  else:
233  #fallback to more , could use /bin/more but might as well let the path sort it out.
234  pager_command = 'more'
235  try:
236  subprocess.call([pager_command, f.name])
237  except NameError:
238  os.system(' '.join([pager_command, f.name]))
239  f.close()
240  print('\n\n')
241  else:
242  error(_('Exiting...'))
243  sys.exit(4)
244 
245 
246 def do_send_profile(uuiddb, uuid, profile, opts, proxies):
247  (error_code, pub_uuid, admin) = profile.send(uuiddb, uuid, user_agent=opts.user_agent,
248  smoonURL=opts.smoonURL,
249  timeout=opts.timeout,
250  proxies=proxies,
251  batch=opts.cron_mode)
252  return (error_code, pub_uuid, admin)
253 
254 
255 def send_profile(uuiddb, uuid, profile, opts, proxies):
257  from i18n import _
258  from smolt import error
259 
260  if opts.retry:
261  while 1:
262  (error_code, pub_uuid, admin) = do_send_profile(uuiddb, uuid, profile, opts, proxies)
263  if not error_code:
264  break
265  error(_('Retry Enabled - Retrying'))
266  time.sleep(30)
267  else:
268  (error_code, pub_uuid, admin) = do_send_profile(uuiddb, uuid, profile, opts, proxies)
269  if error_code:
270  print(_('Could not send - Exiting'))
271  sys.exit(1)
272 
273  return (error_code, pub_uuid, admin)
274 
275 
276 def mention_profile_web_view(opts, pub_uuid, admin):
278  import smolt
279  from i18n import _
280 
281  pubUrl = smolt.get_profile_link(opts.smoonURL, pub_uuid)
282  print()
283  print(_('To share your profile: \n\t%s (public)') % pubUrl)
284  if not smolt.secure:
285  print(_('\tAdmin Password: %s') % admin)
286 
287 
288 def get_proxies(opts):
289  if opts.httpproxy == None:
290  proxies = dict()
291  else:
292  proxies = {'http':opts.httpproxy}
293  return proxies
294 
295 
296 def read_profile(gate, uuid):
298  from i18n import _
299  import smolt
300 
301  try:
302  profile = smolt.create_profile(gate, uuid)
303  except smolt.UUIDError as e:
304  sys.stderr.write(_('%s\n' % e))
305  sys.exit(9)
306  return profile
307 
308 
311  from i18n import _
312 
313  if not opts.password:
314  password = getpass.getpass('\n' + _('Password:') + ' ')
315  else:
316  password = opts.password
317 
318  if profile.register(userName=opts.userName, password=password, user_agent=opts.user_agent, smoonURL=opts.smoonURL, timeout=opts.timeout):
319  print(_('Registration Failed, Try again'))
320 
321 
322 def do_scan_remote(profile, opts, gate):
324  from scan import scan, rating
325 
326  scan(profile, opts.smoonURL, gate)
327  try:
328  rating(profile, opts.smoonURL, gate)
329  except ValueError:
330  print("Could not get rating!")
331 
332 
335  from i18n import _
336  print()
337  print(_('No Public UUID found! Please re-run with -n to generate a new public uuid'))
338 
339 
340 def main_request_new_public_uuid(uuiddb, uuid, profile, opts):
342  from i18n import _
343  from smolt import error, ServerError
344 
345  try:
346  pub_uuid = profile.regenerate_pub_uuid(uuiddb, uuid, user_agent=opts.user_agent,
347  smoonURL=opts.smoonURL,
348  timeout=opts.timeout)
349  except ServerError as e:
350  error(_('Error contacting server: %s') % str(e))
351  sys.exit(1)
352 
353  print(_('Success! Your new public UUID is: %s' % pub_uuid))
354  sys.exit(0)
355 
356 
357 def main_scan_only(profile, opts, gate):
358  do_scan_remote(profile, opts, gate)
359  sys.exit(0)
360 
361 
362 def main_print_only(profile):
363  for line in profile.getProfile():
364  if not line.startswith('#'):
365  print(line)
366  sys.exit(0)
367 
368 
369 def main_send_profile(uuiddb, uuid, profile, opts, gate):
370  proxies = get_proxies(opts)
371 
372  if not opts.autoSend:
374 
375  (error_code, pub_uuid, admin) = send_profile(uuiddb, uuid, profile, opts, proxies)
376 
377  if opts.userName:
379 
380  if opts.scan_remote and not opts.cron_mode:
381  do_scan_remote(profile, opts, gate)
382 
383  if pub_uuid:
384  mention_profile_web_view(opts, pub_uuid, admin)
385  elif not opts.cron_mode:
387 
388 
389 def main():
391  from i18n import _
392  import smolt
393  from gate import create_default_gate, create_gate_from_file
394  from uuiddb import create_default_uuiddb
395 
396  (opts, args) = command_line()
397 
398  if opts.the_only_config_file is None:
399  gate = create_default_gate()
400  else:
401  gate = create_gate_from_file(opts.the_only_config_file)
402 
403  smolt.DEBUG = opts.DEBUG
404  smolt.hw_uuid_file = opts.uuidFile
405 
406  profile = read_profile(gate, smolt.read_uuid())
407 
408  if opts.new_pub:
409  uuiddb = create_default_uuiddb()
410  uuid = smolt.read_uuid()
411  main_request_new_public_uuid(uuiddb, uuid, profile, opts)
412  elif not opts.send_profile:
413  main_scan_only(profile, opts, gate)
414  elif opts.printOnly and not opts.autoSend:
415  main_print_only(profile)
416  else:
417  uuiddb = create_default_uuiddb()
418  uuid = smolt.read_uuid()
419  main_send_profile(uuiddb, uuid, profile, opts, gate)
420 
421 
422 if __name__ == '__main__':
423  main()
def mention_profile_web_view(opts, pub_uuid, admin)
Definition: sendProfile.py:276
def create_default_gate()
Definition: gate.py:83
static void print(const QList< uint > &raw_minimas, const QList< uint > &raw_maximas, const QList< float > &minimas, const QList< float > &maximas)
def scan(profile, smoonURL, gate)
Definition: scan.py:57
def do_send_profile(uuiddb, uuid, profile, opts, proxies)
Definition: sendProfile.py:246
static void error(const char *str,...)
Definition: vbi.c:42
def make_display_excerpts(profile)
Definition: sendProfile.py:140
def rating(profile, smoonURL, gate)
Definition: scan.py:39
def to_ascii(o, current_encoding='utf-8')
Definition: smolt.py:205
def send_profile(uuiddb, uuid, profile, opts, proxies)
Definition: sendProfile.py:255
def create_default_uuiddb()
Definition: uuiddb.py:69
def create_gate_from_file(filename)
Definition: gate.py:87
def main_scan_only(profile, opts, gate)
Definition: sendProfile.py:357
def do_scan_remote(profile, opts, gate)
Definition: sendProfile.py:322
def main_request_new_public_uuid(uuiddb, uuid, profile, opts)
Definition: sendProfile.py:340
def present_and_require_confirmation(profile)
Definition: sendProfile.py:192
def read_profile(gate, uuid)
Definition: sendProfile.py:296
def main_send_profile(uuiddb, uuid, profile, opts, gate)
Definition: sendProfile.py:369
def register_with_fedora_account_system(opts, profile)
Definition: sendProfile.py:309