p3lib 1.1.75__py3-none-any.whl → 1.1.77__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
p3lib/boot_manager.py CHANGED
@@ -3,6 +3,7 @@
3
3
  import os
4
4
  import sys
5
5
  import platform
6
+ import getpass
6
7
 
7
8
  from subprocess import check_call, DEVNULL, STDOUT, Popen, PIPE
8
9
  from datetime import datetime
@@ -35,10 +36,10 @@ class BootManager(object):
35
36
  else:
36
37
  raise Exception("{} is an unsupported OS.".format(self._osName) )
37
38
 
38
- def add(self, user, argString=None, enableSyslog=False):
39
+ def add(self, user=None, argString=None, enableSyslog=False):
39
40
  """@brief Add an executable file to the processes started at boot time.
40
41
  @param exeFile The file/program to be executed. This should be an absolute path.
41
- @param user The user that will run the executable file.
42
+ @param user The user that will run the executable file. If left as None then the current user will be used.
42
43
  @param argString The argument string that the program is to be launched with.
43
44
  @param enableSyslog If True enable stdout and stderr to be sent to syslog."""
44
45
  if self._platformBootManager:
@@ -63,9 +64,41 @@ class BootManager(object):
63
64
  class LinuxBootManager(object):
64
65
  """@brief Responsible for adding/removing Linux services using systemd."""
65
66
 
66
- LOG_PATH="/var/log"
67
- SERVICE_FOLDER = "/etc/systemd/system/"
68
- SYSTEM_CTL = "/bin/systemctl"
67
+ LOG_PATH ="/var/log"
68
+ ROOT_SERVICE_FOLDER = "/etc/systemd/system/"
69
+ SYSTEM_CTL_1 = "/bin/systemctl"
70
+ SYSTEM_CTL_2 = "/usr/bin/systemctl"
71
+
72
+ @staticmethod
73
+ def GetSystemCTLBin():
74
+ """@brief Get the location of the systemctl binary file on this system.
75
+ @return The systemctl bin file."""
76
+ binFile = None
77
+ if os.path.isfile(LinuxBootManager.SYSTEM_CTL_1):
78
+ binFile = LinuxBootManager.SYSTEM_CTL_1
79
+ elif os.path.isfile(LinuxBootManager.SYSTEM_CTL_2):
80
+ binFile = LinuxBootManager.SYSTEM_CTL_2
81
+ else:
82
+ raise Exception("Failed to find the location of the systemctl bin file on this machine.")
83
+ return binFile
84
+
85
+ @staticmethod
86
+ def GetServiceFolder(rootUser):
87
+ """"@brief Get the service folder to use.
88
+ @param rootUser False if non root user.
89
+ @return The folder that should hold the systemctl service files."""
90
+ serviceFolder = None
91
+ if rootUser:
92
+ serviceFolder = LinuxBootManager.ROOT_SERVICE_FOLDER
93
+ else:
94
+ homeFolder = os.path.expanduser('~')
95
+ serviceFolder = os.path.join(homeFolder, '.config/systemd/user/')
96
+ if not os.path.isdir(serviceFolder):
97
+ os.makedirs(serviceFolder)
98
+
99
+ if not os.path.isdir(serviceFolder):
100
+ raise Exception(f"{serviceFolder} folder not found.")
101
+ return serviceFolder
69
102
 
70
103
  def __init__(self, uio, allowRootUser):
71
104
  """@brief Constructor
@@ -74,12 +107,20 @@ class LinuxBootManager(object):
74
107
  self._uio = uio
75
108
  self._logFile = None
76
109
  self._allowRootUser=allowRootUser
77
-
78
- if os.geteuid() != 0:
79
- self._fatalError("Please run this command with root level access.")
80
-
81
110
  self._info("OS: {}".format(platform.system()) )
82
-
111
+ self._rootMode = False # If True run as root, else False.
112
+ self._systemCtlBin = LinuxBootManager.GetSystemCTLBin()
113
+ if os.geteuid() == 0:
114
+ if not allowRootUser:
115
+ self._fatalError(self.__class__.__name__ + f": You are running as root user but allowRootUser={allowRootUser}.")
116
+ else:
117
+ self._rootMode = True
118
+ if not self._rootMode:
119
+ self._cmdLinePrefix = self._systemCtlBin + " --user"
120
+ else:
121
+ self._cmdLinePrefix = self._systemCtlBin
122
+ self._username = getpass.getuser()
123
+ self._serviceFolder = LinuxBootManager.GetServiceFolder(self._rootMode)
83
124
  self._appName = None
84
125
 
85
126
  def _getInstallledStartupScript(self):
@@ -188,7 +229,9 @@ class LinuxBootManager(object):
188
229
  self._fatalError("{} file not found.".format(absApp) )
189
230
 
190
231
  appName = appName.replace(".py", "")
191
- self._logFile = os.path.join(LinuxBootManager.LOG_PATH, appName)
232
+ if self._rootMode:
233
+ # We can only save to /var/log/ is we are root user.
234
+ self._logFile = os.path.join(LinuxBootManager.LOG_PATH, appName)
192
235
 
193
236
  return (appName, absApp)
194
237
 
@@ -197,7 +240,7 @@ class LinuxBootManager(object):
197
240
  @param appName The name of the app to execute.
198
241
  @return The absolute path to the service file """
199
242
  serviceName = "{}.service".format(appName)
200
- serviceFile = os.path.join(LinuxBootManager.SERVICE_FOLDER, serviceName)
243
+ serviceFile = os.path.join(self._serviceFolder, serviceName)
201
244
  return serviceFile
202
245
 
203
246
  def add(self, user, argString=None, enableSyslog=False):
@@ -209,9 +252,9 @@ class LinuxBootManager(object):
209
252
  to non root user paths on Linux systems and the startup
210
253
  script should then be executed with the same username in
211
254
  order that the same config file is used.
255
+ If set to None then the current user is used.
212
256
  @param argString The argument string that the program is to be launched with.
213
257
  @param enableSyslog If True enable stdout and stderr to be sent to syslog."""
214
-
215
258
  appName, absApp = self._getApp()
216
259
 
217
260
  serviceFile = self._getServiceFile(appName)
@@ -253,12 +296,12 @@ class LinuxBootManager(object):
253
296
  except IOError:
254
297
  self._fatalError("Failed to create {}".format(serviceFile) )
255
298
 
256
- cmd = "{} daemon-reload".format(LinuxBootManager.SYSTEM_CTL)
299
+ cmd = "{} daemon-reload".format(self._cmdLinePrefix)
257
300
  self._runLocalCmd(cmd)
258
- cmd = "{} enable {}".format(LinuxBootManager.SYSTEM_CTL, appName)
301
+ cmd = "{} enable {}".format(self._cmdLinePrefix, appName)
259
302
  self._info("Enabled {} on restart".format(appName))
260
303
  self._runLocalCmd(cmd)
261
- cmd = "{} start {}".format(LinuxBootManager.SYSTEM_CTL, appName)
304
+ cmd = "{} start {}".format(self._cmdLinePrefix, appName)
262
305
  self._runLocalCmd(cmd)
263
306
  self._info("Started {}".format(appName))
264
307
 
@@ -270,11 +313,11 @@ class LinuxBootManager(object):
270
313
 
271
314
  serviceFile = self._getServiceFile(appName)
272
315
  if os.path.isfile(serviceFile):
273
- cmd = "{} disable {}".format(LinuxBootManager.SYSTEM_CTL, appName)
316
+ cmd = "{} disable {}".format(self._cmdLinePrefix, appName)
274
317
  self._runLocalCmd(cmd)
275
318
  self._info("Disabled {} on restart".format(appName))
276
319
 
277
- cmd = "{} stop {}".format(LinuxBootManager.SYSTEM_CTL, appName)
320
+ cmd = "{} stop {}".format(self._cmdLinePrefix, appName)
278
321
  self._runLocalCmd(cmd)
279
322
  self._info("Stopped {}".format(appName))
280
323
 
@@ -287,11 +330,11 @@ class LinuxBootManager(object):
287
330
  """@brief Get a status report.
288
331
  @return Lines of text indicating the status of a previously started process."""
289
332
  appName, _ = self._getApp()
290
- p = Popen([LinuxBootManager.SYSTEM_CTL, 'status', appName], stdin=PIPE, stdout=PIPE, stderr=PIPE)
333
+ if self._rootMode:
334
+ p = Popen([self._systemCtlBin, 'status', appName], stdin=PIPE, stdout=PIPE, stderr=PIPE)
335
+ else:
336
+ p = Popen([self._systemCtlBin, '--user', 'status', appName], stdin=PIPE, stdout=PIPE, stderr=PIPE)
291
337
  output, err = p.communicate(b"input data that is passed to subprocess' stdin")
292
338
  response = output.decode() + "\n" + err.decode()
293
339
  lines = response.split("\n")
294
340
  return lines
295
-
296
-
297
-
p3lib/ngt.py CHANGED
@@ -114,6 +114,7 @@ class TabbedNiceGui(object):
114
114
  self._progressBarStartMessage = ""
115
115
  self._progressBarExpectedMessageList = []
116
116
  self._expectedProgressBarMessageIndex = 0
117
+ self._expectedProgressBarMsgCount = 0
117
118
  self._programVersion = TabbedNiceGui.GetProgramVersion()
118
119
 
119
120
  self._logPath = None
@@ -430,26 +431,39 @@ class TabbedNiceGui(object):
430
431
  # Increment the progress bar
431
432
  self._progress.set_value( self._progress.value + self._progressStepValue )
432
433
 
433
- def _startProgress(self, durationSeconds=0, startMessage=None, expectedMsgList=[]):
434
+ def _startProgress(self, durationSeconds=0, startMessage=None, expectedMsgList=[], expectedMsgCount=0):
434
435
  """@brief Start a timer that will update the progress bar.
435
436
  The progress bar can simply update on a timer every second with durationSeconds set to the expected length
436
- of the task if startMessage is unset and startMessage = None and expectedMessageCount = 0.
437
+ of the task.
437
438
 
438
- Alternatively if durationSeconds is set and startMessage (expectedMessageCount = 0) is set to some text that
439
- we expect to receive in the log before the progress timer (as detailed above) is triggered.
439
+ If startMessage is set to a text string the progress time will not start until the log message area contains
440
+ the start message.
440
441
 
441
442
  Alternatively if expectedMsgList contains a list of strings we expect to receive then the progress bar is
442
- updated as each message is received. The messages may be the entire line of a log message or parts of a log message line.
443
+ updated as each message is received. The messages may be the entire line of a log message or parts of a
444
+ log message line.
445
+
446
+ Alternatively if expectedMsgCount is set to a value > 0 then the progress bar is updated as each message is
447
+ added to the log and reaches 100% when the number of messages added to the log file reaches the expectedMsgCount.
448
+
443
449
  @param startMessage The text of the log message we expect to receive to trigger the progress bar timer start.
444
- @param expectedMsgList A list of the expected log file messages."""
450
+ @param expectedMsgList A list of the expected log file messages.
451
+ @param expectedMsgCount A int value that defines the number of log messages we expect to receive for normal progress
452
+ completion."""
445
453
  self._progressValue = 0
446
454
  self._progressBarStartMessage = ""
447
455
  self._progressBarExpectedMessageList = []
448
456
  self._expectedProgressBarMessageIndex = 0
457
+ self._expectedProgressBarMsgCount = 0
449
458
  self._updateProgressOnTimer = False
450
459
  self._progress.set_value( self._progressValue )
460
+ # If the caller wants to the progress bar to update as the log file message count increases.
461
+ if expectedMsgCount > 0:
462
+ self._expectedProgressBarMsgCount = expectedMsgCount
463
+ self._progressStepValue = TabbedNiceGui.MAX_PROGRESS_VALUE/float(self._expectedProgressBarMsgCount)
464
+
451
465
  # If the caller wants to update the progress bar on expected messages.
452
- if len(expectedMsgList):
466
+ elif len(expectedMsgList):
453
467
  #Use the text of log messages to increment the progress bar.
454
468
  self._expectedProgressBarMessageIndex = 0
455
469
  self._progressBarExpectedMessageList = expectedMsgList
@@ -477,8 +491,13 @@ class TabbedNiceGui(object):
477
491
  def _updateProgressBar(self, msg):
478
492
  """@brief Update the progress bar if required when a log message is received. This is called as each message is added to the log.
479
493
  @param msg The log message received."""
494
+ # If we update the progress bar as each message is received until we have a log with self._expectedProgressBarMsgCount many messages.
495
+ if self._expectedProgressBarMsgCount > 0:
496
+ self._progressValue = self._progressValue + self._progressStepValue
497
+ self._progress.set_value( self._progressValue )
498
+
480
499
  # If we have a list of log messages to update the progress bar.
481
- if len(self._progressBarExpectedMessageList) > 0:
500
+ elif len(self._progressBarExpectedMessageList) > 0:
482
501
  if self._expectedProgressBarMessageIndex < len(self._progressBarExpectedMessageList):
483
502
  # Get the message we expect to receive next
484
503
  expectedMsg = self._progressBarExpectedMessageList[self._expectedProgressBarMessageIndex]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: p3lib
3
- Version: 1.1.75
3
+ Version: 1.1.77
4
4
  Summary: A group of python modules for networking, plotting data, config storage, automating boot scripts, ssh access and user input output.
5
5
  Home-page: https://github.com/pjaos/p3lib
6
6
  Author: Paul Austen
@@ -2,7 +2,7 @@ p3lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  p3lib/ate.py,sha256=_BiqMUYNAlp4O8MkP_PAUe62Bzd8dzV4Ipv62OFS6Ok,4759
3
3
  p3lib/bokeh_auth.py,sha256=XqdCLOalHL3dkyrMPqQoVQBSziVnqlfjB9YAWhZUd_U,14769
4
4
  p3lib/bokeh_gui.py,sha256=55sajP_x9O1lE0uP3w3-T5f2oMzk7jSolLqxlEdLeLg,40245
5
- p3lib/boot_manager.py,sha256=-kbfYbFpO-ktKv_heUgYdvvIQrntfCQ7pBcPWqS3C0s,12551
5
+ p3lib/boot_manager.py,sha256=iEjdj8RkL6jYnflx-ObC_cLSNjpeFT_xZj4OaCJw95k,14752
6
6
  p3lib/conduit.py,sha256=jPkjdtyCx2I6SFqcEo8y2g7rgnZ-jNY7oCuYIETzT5Q,6046
7
7
  p3lib/database_if.py,sha256=XKu1w3zftGbj4Rh54wrWJnoCtqHkhCzJUPN2S70XIKg,11915
8
8
  p3lib/helper.py,sha256=-B63_ncfchMwXrvyVcnj9sxwGnMJ3ASmLmpoYa4tBmM,11862
@@ -10,13 +10,13 @@ p3lib/json_networking.py,sha256=6u4s1SmypjTYPnSxHP712OgQ3ZJaxOqIkgHQ1J7Qews,9738
10
10
  p3lib/mqtt_rpc.py,sha256=6LmFA1kR4HSJs9eWbOJORRHNY01L_lHWjvtE2fmY8P8,10511
11
11
  p3lib/netif.py,sha256=3QV5OGdHhELIf4MBj6mx5MNCtVeZ7JXoNEkeu4KzCaE,9796
12
12
  p3lib/netplotly.py,sha256=PMDx-w1jtRVW6Od5u_kuKbBxNpTS_Y88mMF60puMxLM,9363
13
- p3lib/ngt.py,sha256=FWiRcVrWR0tTfscz6gWDHcJXam-00OezyQNjTaFXPh4,36635
13
+ p3lib/ngt.py,sha256=rXA-6zQkfeOupZ-3Q-k3-1DvbKYIi2TCtLKgUb0waWY,37726
14
14
  p3lib/pconfig.py,sha256=_ri9w3aauHXZp8u2YLYHBVroFR_iCqaTCwj_MRa3rHo,30153
15
15
  p3lib/ssh.py,sha256=klqQ9YuqU8GwPVPHrAJeEs5PI5hgoYiXflq2kIGG3as,39509
16
16
  p3lib/table_plot.py,sha256=dRPZ9rFpwE9Dpyqrvbm5t2spVaPSHrx_B7KvfWVND3g,32166
17
17
  p3lib/uio.py,sha256=hMarPnYXnqVF23HUIeDfzREo7TMdBjrupXMY_ffuCbI,23133
18
- p3lib-1.1.75.dist-info/LICENSE,sha256=igqTy5u0kVWM1n-NUZMvAlinY6lVjAXKoag0okkS8V8,1067
19
- p3lib-1.1.75.dist-info/METADATA,sha256=aBudwqSxnGiP-3sDRkKLdiv2ZpNErMlfcbthAg3bmb8,918
20
- p3lib-1.1.75.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
21
- p3lib-1.1.75.dist-info/top_level.txt,sha256=SDCpXYh-19yCFp4Z8ZK4B-3J4NvTCJElZ42NPgcR6-U,6
22
- p3lib-1.1.75.dist-info/RECORD,,
18
+ p3lib-1.1.77.dist-info/LICENSE,sha256=igqTy5u0kVWM1n-NUZMvAlinY6lVjAXKoag0okkS8V8,1067
19
+ p3lib-1.1.77.dist-info/METADATA,sha256=_mIG4rnObGLDlsjVdyZVqVnbT2XOlrQwwoX_O_PgNvc,918
20
+ p3lib-1.1.77.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
21
+ p3lib-1.1.77.dist-info/top_level.txt,sha256=SDCpXYh-19yCFp4Z8ZK4B-3J4NvTCJElZ42NPgcR6-U,6
22
+ p3lib-1.1.77.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.1.2)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5