p3lib 1.1.122__tar.gz → 1.1.124__tar.gz

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.
Files changed (25) hide show
  1. {p3lib-1.1.122 → p3lib-1.1.124}/PKG-INFO +1 -1
  2. {p3lib-1.1.122 → p3lib-1.1.124}/pyproject.toml +1 -1
  3. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/helper.py +25 -88
  4. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/ngt.py +52 -40
  5. {p3lib-1.1.122 → p3lib-1.1.124}/LICENSE +0 -0
  6. {p3lib-1.1.122 → p3lib-1.1.124}/README.md +0 -0
  7. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/__init__.py +0 -0
  8. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/ate.py +0 -0
  9. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/bokeh_auth.py +0 -0
  10. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/bokeh_gui.py +0 -0
  11. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/boot_manager.py +0 -0
  12. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/conduit.py +0 -0
  13. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/database_if.py +0 -0
  14. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/file_io.py +0 -0
  15. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/gnome_desktop_app.py +0 -0
  16. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/json_networking.py +0 -0
  17. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/login.html +0 -0
  18. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/mqtt_rpc.py +0 -0
  19. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/netif.py +0 -0
  20. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/netplotly.py +0 -0
  21. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/pconfig.py +0 -0
  22. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/ssh.py +0 -0
  23. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/table_plot.py +0 -0
  24. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/uio.py +0 -0
  25. {p3lib-1.1.122 → p3lib-1.1.124}/src/p3lib/windows_app.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: p3lib
3
- Version: 1.1.122
3
+ Version: 1.1.124
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
  License: MIT
6
6
  Author: Paul Austen
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "p3lib"
3
- version = "1.1.122"
3
+ version = "1.1.124"
4
4
  description = "A group of python modules for networking, plotting data, config storage, automating boot scripts, ssh access and user input output."
5
5
  authors = ["Paul Austen <pjaos@gmail.com>"]
6
6
  license = "MIT License"
@@ -9,7 +9,6 @@ import platform
9
9
  import json
10
10
  import traceback
11
11
  import socket
12
- import inspect
13
12
 
14
13
  def initArgs(parser, lastCmdLineArg=None, checkHostArg=True):
15
14
  """This method is responsible for
@@ -389,8 +388,7 @@ def getAbsFile(filename):
389
388
  @param filename The name of the icon file.
390
389
  @return The abs path of the file or None if not found."""
391
390
  file_found = None
392
- startup_path = os.getenv("PWD", os.getcwd())
393
- abs_filename = os.path.join(startup_path, filename)
391
+ abs_filename = os.path.abspath(filename)
394
392
  if os.path.isfile(abs_filename):
395
393
  file_found = abs_filename
396
394
 
@@ -412,18 +410,18 @@ def getAbsFile(filename):
412
410
  else:
413
411
  # Try all the site packages folders we know about.
414
412
  for path in sys.path:
415
- if 'site-packages' in path:
416
- site_packages_path = path
417
- abs_filename = os.path.join(site_packages_path, filename)
413
+ if os.path.isdir(path):
414
+ abs_filename = os.path.join(path, filename)
418
415
  if os.path.isfile(abs_filename):
419
416
  file_found = abs_filename
420
-
421
417
  else:
422
- path3 = os.path.join(site_packages_path, 'assets')
423
- abs_filename = os.path.join(path3, filename)
418
+ path2 = os.path.join(path, 'assets')
419
+ abs_filename = os.path.join(path2, filename)
424
420
  if os.path.isfile(abs_filename):
425
421
  file_found = abs_filename
426
422
  break
423
+ if file_found:
424
+ break
427
425
 
428
426
  return file_found
429
427
 
@@ -433,84 +431,23 @@ def getProgramVersion():
433
431
  """@return The program/package version. This comes from the pyproject.toml file.
434
432
  If this file is not found an exception is thrown. """
435
433
  poetryConfigFile = getAbsFile(PYPROJECT_FILE)
436
- programVersion = None
437
- with open(poetryConfigFile, 'r') as fd:
438
- lines = fd.readlines()
439
- for line in lines:
440
- line=line.strip("\r\n")
441
- if line.startswith('version'):
442
- elems = line.split("=")
443
- if len(elems) == 2:
444
- programVersion = elems[1].strip('" ')
445
- break
446
- if programVersion is None:
447
- raise Exception(f"Failed to extract program version from '{line}' line of {poetryConfigFile} file.")
434
+ if poetryConfigFile:
435
+ programVersion = None
436
+ with open(poetryConfigFile, 'r') as fd:
437
+ lines = fd.readlines()
438
+ for line in lines:
439
+ line=line.strip("\r\n")
440
+ if line.startswith('version'):
441
+ elems = line.split("=")
442
+ if len(elems) == 2:
443
+ programVersion = elems[1].strip('" ')
444
+ break
445
+ if programVersion is None:
446
+ raise Exception(f"Failed to extract program version from '{line}' line of {poetryConfigFile} file.")
447
+ else:
448
+ # In the event we can't find the PYPROJECT_FILE file return an invalid verion (hopefully)
449
+ # to indicate this. This can happen if the pyproject.toml file is not included or can't be
450
+ # found.
451
+ return -999.99
448
452
  return programVersion
449
453
 
450
- def get_assets_folders():
451
- """@return A list of all the assets folders found."""
452
- searchFolders = []
453
- assetsFolders = []
454
- calling_file = None
455
- # Get the full path to the python file that called this get_assets_folders() function.
456
- frame = inspect.stack()[1]
457
- module = inspect.getmodule(frame[0])
458
- if module and hasattr(module, '__file__'):
459
- calling_file = os.path.abspath(module.__file__)
460
-
461
- if calling_file:
462
- startup_path = os.path.dirname(calling_file)
463
- searchFolders.append( os.path.join(startup_path, 'assets') )
464
- pp1 = os.path.join(startup_path, '..')
465
- searchFolders.append( os.path.join(pp1, 'assets') )
466
- pp2 = os.path.join(pp1, '..')
467
- searchFolders.append( os.path.join(pp2, 'assets') )
468
- # Try all the site packages folders we know about.
469
- for path in sys.path:
470
- if 'site-packages' in path:
471
- site_packages_path = path
472
- searchFolders.append( os.path.join(site_packages_path, 'assets') )
473
-
474
- for folder in searchFolders:
475
- absPath = os.path.abspath(folder)
476
- if os.path.isdir(absPath):
477
- assetsFolders.append(absPath)
478
-
479
- return assetsFolders
480
-
481
-
482
- def get_assets_folder(raise_error=True):
483
- """@brief Get the assests folder.
484
- @param raise_error If True then raise an error if the assets folder is not found.
485
- @return The abs assets folder path string."""
486
- searchFolders = []
487
- assetsFolder = None
488
- calling_file = None
489
- # Get the full path to the python file that called this get_assets_folder() function.
490
- frame = inspect.stack()[1]
491
- module = inspect.getmodule(frame[0])
492
- if module and hasattr(module, '__file__'):
493
- calling_file = os.path.abspath(module.__file__)
494
-
495
- if calling_file:
496
- startup_path = os.path.dirname(calling_file)
497
- searchFolders.append( os.path.join(startup_path, 'assets') )
498
- pp1 = os.path.join(startup_path, '..')
499
- searchFolders.append( os.path.join(pp1, 'assets') )
500
- pp2 = os.path.join(pp1, '..')
501
- searchFolders.append( os.path.join(pp2, 'assets') )
502
- # Try all the site packages folders we know about.
503
- for path in sys.path:
504
- if 'site-packages' in path:
505
- site_packages_path = path
506
- searchFolders.append( os.path.join(site_packages_path, 'assets') )
507
-
508
- for folder in searchFolders:
509
- absPath = os.path.abspath(folder)
510
- if os.path.isdir(absPath):
511
- assetsFolder = absPath
512
-
513
- if raise_error and assetsFolder is None:
514
- raise Exception('Failed to find assets folder.')
515
-
516
- return assetsFolder
@@ -379,7 +379,13 @@ class TabbedNiceGui(object):
379
379
  if isinstance(rxMessage, dict):
380
380
  self._processRXDict(rxMessage)
381
381
 
382
- def initGUI(self, tabNameList, tabMethodInitList, reload=True, address="0.0.0.0", port=DEFAULT_SERVER_PORT, pageTitle="NiceGUI"):
382
+ def initGUI(self,
383
+ tabNameList,
384
+ tabMethodInitList,
385
+ reload=True,
386
+ address="0.0.0.0",
387
+ port=DEFAULT_SERVER_PORT,
388
+ pageTitle="NiceGUI"):
383
389
  """@brief Init the tabbed GUI.
384
390
  @param tabNameList A list of the names of each tab to be created.
385
391
  @param tabMethodInitList A list of the methods to be called to init each of the above tabs.
@@ -387,47 +393,53 @@ class TabbedNiceGui(object):
387
393
  @param reload If reload is set False then changes to python files will not cause the server to be restarted.
388
394
  @param address The address to bind the server to.
389
395
  @param The TCP port to bind the server to.
390
- @param pageTitle The page title that appears in the browser."""
391
- # A bit of defensive programming.
392
- if len(tabNameList) != len(tabMethodInitList):
393
- raise Exception(f"initGUI: BUG: tabNameList ({len(tabNameList)}) and tabMethodInitList ({len(tabMethodInitList)}) are not the same length.")
394
- tabObjList = []
395
- with ui.row():
396
- with ui.tabs().classes('w-full') as tabs:
397
- for tabName in tabNameList:
398
- tabObj = ui.tab(tabName)
399
- tabObjList.append(tabObj)
400
-
401
- with ui.tab_panels(tabs, value=tabObjList[0]).classes('w-full'):
402
- for tabObj in tabObjList:
403
- with ui.tab_panel(tabObj):
404
- tabIndex = tabObjList.index(tabObj)
405
- tabMethodInitList[tabIndex]()
406
-
407
- guiLogLevel = "warning"
408
- if self._debugEnabled:
409
- guiLogLevel = "debug"
410
-
411
- ui.label("Message Log")
412
- self._progress = ui.slider(min=0,max=TabbedNiceGui.MAX_PROGRESS_VALUE,step=1)
413
- self._progress.set_visibility(False)
414
- self._progress.min = 0
415
- # Don't allow user to adjust progress bar thumb
416
- self._progress.disable()
417
- self._log = ui.log(max_lines=2000).classes('my-log')
418
- self._log.set_visibility(True)
396
+ @param pageTitle The page title that appears in the browser.
397
+ @param maxLogLines The maximum number of lines to be displayed in the log. Be aware setting this higher will cause the browser to use more memory."""
398
+ with ui.column().classes('h-screen w-screen p4'):
399
+ # A bit of defensive programming.
400
+ if len(tabNameList) != len(tabMethodInitList):
401
+ raise Exception(f"initGUI: BUG: tabNameList ({len(tabNameList)}) and tabMethodInitList ({len(tabMethodInitList)}) are not the same length.")
402
+ tabObjList = []
403
+ with ui.row():
404
+ with ui.tabs().classes('w-full') as tabs:
405
+ for tabName in tabNameList:
406
+ tabObj = ui.tab(tabName)
407
+ tabObjList.append(tabObj)
408
+
409
+ with ui.tab_panels(tabs, value=tabObjList[0]).classes('w-full'):
410
+ for tabObj in tabObjList:
411
+ with ui.tab_panel(tabObj):
412
+ tabIndex = tabObjList.index(tabObj)
413
+ tabMethodInitList[tabIndex]()
414
+
415
+ guiLogLevel = "warning"
416
+ if self._debugEnabled:
417
+ guiLogLevel = "debug"
418
+
419
+ ui.label("Message Log")
420
+ self._progress = ui.slider(min=0,max=TabbedNiceGui.MAX_PROGRESS_VALUE,step=1)
421
+ self._progress.set_visibility(False)
422
+ self._progress.min = 0
423
+ # Don't allow user to adjust progress bar thumb
424
+ self._progress.disable()
425
+ # Setup the log area to fill the available space in the page vertically and horizontally
426
+ # The 32px is to make space for the vertical scrollbar within the page or it will be
427
+ # shifted out of sight to the right.
428
+ # Previously used self._log = ui.log(max_lines=2000) but the ui.log() does not currently limit data in the log.
429
+ self._log = ui.log().classes('my-log grow w-full max-w-[calc(100%-32px)] overflow-auto box-border')
430
+ self._log.set_visibility(True)
419
431
 
420
- with ui.row():
421
- ui.button('Clear Log', on_click=self._clearLog)
422
- ui.button('Log Message Count', on_click=self._showLogMsgCount)
423
- ui.button('Quit', on_click=self.close)
432
+ with ui.row():
433
+ ui.button('Clear Log', on_click=self._clearLog)
434
+ ui.button('Log Message Count', on_click=self._showLogMsgCount)
435
+ ui.button('Quit', on_click=self.close)
424
436
 
425
- with ui.row():
426
- ui.label(f"Software Version: {self._programVersion}")
437
+ with ui.row():
438
+ ui.label(f"Software Version: {self._programVersion}")
427
439
 
428
- ui.timer(interval=TabbedNiceGui.GUI_TIMER_SECONDS, callback=self.guiTimerCallback)
429
- ui.timer(interval=TabbedNiceGui.PROGRESS_TIMER_SECONDS, callback=self.progressTimerCallback)
430
- ui.run(host=address, port=port, title=pageTitle, dark=True, uvicorn_logging_level=guiLogLevel, reload=reload)
440
+ ui.timer(interval=TabbedNiceGui.GUI_TIMER_SECONDS, callback=self.guiTimerCallback)
441
+ ui.timer(interval=TabbedNiceGui.PROGRESS_TIMER_SECONDS, callback=self.progressTimerCallback)
442
+ ui.run(host=address, port=port, title=pageTitle, dark=True, uvicorn_logging_level=guiLogLevel, reload=reload)
431
443
 
432
444
  def progressTimerCallback(self):
433
445
  """@brief Time to update the progress bar. We run the timer all the time because there appears to be a
@@ -947,4 +959,4 @@ class local_file_picker(ui.dialog):
947
959
  selected=selected[1:]
948
960
  selected = self.drives_toggle.value + selected
949
961
 
950
- self.submit([selected])
962
+ self.submit([selected])
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes