p3lib 1.1.108__py2.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/__init__.py +0 -0
- p3lib/ate.py +108 -0
- p3lib/bokeh_auth.py +363 -0
- p3lib/bokeh_gui.py +845 -0
- p3lib/boot_manager.py +420 -0
- p3lib/conduit.py +145 -0
- p3lib/database_if.py +289 -0
- p3lib/file_io.py +154 -0
- p3lib/gnome_desktop_app.py +146 -0
- p3lib/helper.py +420 -0
- p3lib/json_networking.py +239 -0
- p3lib/login.html +98 -0
- p3lib/mqtt_rpc.py +240 -0
- p3lib/netif.py +226 -0
- p3lib/netplotly.py +223 -0
- p3lib/ngt.py +841 -0
- p3lib/pconfig.py +874 -0
- p3lib/ssh.py +935 -0
- p3lib/table_plot.py +675 -0
- p3lib/uio.py +574 -0
- p3lib-1.1.108.dist-info/LICENSE +21 -0
- p3lib-1.1.108.dist-info/METADATA +34 -0
- p3lib-1.1.108.dist-info/RECORD +24 -0
- p3lib-1.1.108.dist-info/WHEEL +4 -0
p3lib/netplotly.py
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
import os
|
4
|
+
import plotly
|
5
|
+
import tarfile
|
6
|
+
import tempfile
|
7
|
+
import shutil
|
8
|
+
|
9
|
+
from pathlib import Path
|
10
|
+
try:
|
11
|
+
from .ssh import SSH
|
12
|
+
from .helper import getHomePath
|
13
|
+
except:
|
14
|
+
#We get here if running netplotly_demo.py as it sits in the same folder
|
15
|
+
#as netplotly.py
|
16
|
+
from ssh import SSH
|
17
|
+
from helper import getHomePath
|
18
|
+
|
19
|
+
class NetPlotly(object):
|
20
|
+
"""@brief Manage plotly graphs on a webserver and allow them to be transferred over a network via ssh.
|
21
|
+
Plots are saved to a local folder. The local folder maybe served via a web server.
|
22
|
+
The contents of the local folder maybe transferred to a remote machine via ssh.
|
23
|
+
The contents of the remote folder maybe served via a web server.
|
24
|
+
|
25
|
+
The local and remote folders will contain an index.html file. This displays a table of
|
26
|
+
all the available plots. Each plot name in the table maybe clicked which will display
|
27
|
+
the plotly plot."""
|
28
|
+
INDEX_HTML_FILE = "netplotly_index.html"
|
29
|
+
DEFAULT_LOCAL_ROOT = "~/.netplotly"
|
30
|
+
ASSETS_FOLDER = "assets"
|
31
|
+
PLOT_LIST_FILE = "plot_list.txt"
|
32
|
+
|
33
|
+
@staticmethod
|
34
|
+
def GetTarBallFile():
|
35
|
+
"""@brief Get the tarball file path
|
36
|
+
@return The abs file path"""
|
37
|
+
return os.path.join( tempfile.gettempdir(), "netplotly.tgz" )
|
38
|
+
|
39
|
+
def __init__(self, localRoot=DEFAULT_LOCAL_ROOT, serverRoot=DEFAULT_LOCAL_ROOT, host=None, username=None, password=None, port=22, uio=None):
|
40
|
+
"""@brief Constructor
|
41
|
+
@param localRoot The local folder to store the plots in.
|
42
|
+
A web server may serve files directly from here or they maybe
|
43
|
+
uploaded (via ssh) to a webserver using the API's provided
|
44
|
+
by this class.
|
45
|
+
@param serverRoot The folder to store html files in on the server.
|
46
|
+
@param host The address of the ssh server to upload files to.
|
47
|
+
@param username The SSH server username
|
48
|
+
@param password The SSH server password. Not required if auto login via public
|
49
|
+
key is enabled for the ssh server.
|
50
|
+
@param port The ssh server port (default=22).
|
51
|
+
@param uio A UIO instance for displaying messages to the user."""
|
52
|
+
self._localRoot = localRoot
|
53
|
+
self._serverRoot = serverRoot
|
54
|
+
self._host = host
|
55
|
+
self._username = username
|
56
|
+
self._password = password
|
57
|
+
self._port = port
|
58
|
+
self._uio = uio
|
59
|
+
self._ssh = None
|
60
|
+
|
61
|
+
self._updateLocalRoot()
|
62
|
+
|
63
|
+
def _updateLocalRoot(self):
|
64
|
+
"""@brief Set the local _rootp attr"""
|
65
|
+
if self._localRoot.startswith("~"):
|
66
|
+
self._localRoot = getHomePath() + self._localRoot.replace("~", "")
|
67
|
+
|
68
|
+
def info(self, msg):
|
69
|
+
"""@brief Display an info level message if we have been provided with a uio object"""
|
70
|
+
if self._uio:
|
71
|
+
self._uio.info(msg)
|
72
|
+
|
73
|
+
def _getPlotListFile(self):
|
74
|
+
"""@return The plot list file"""
|
75
|
+
return os.path.join(self._localRoot, NetPlotly.PLOT_LIST_FILE)
|
76
|
+
|
77
|
+
def _updatePlotList(self, plotTitle):
|
78
|
+
"""@brief Update the plot title log file. This file is read by the javascript to
|
79
|
+
present a table of available plots to the user. The PLOT_LIST_FILE
|
80
|
+
simply contains a number of lines each lines text is the name of the plot.
|
81
|
+
@param plotTitle The plot title
|
82
|
+
@return None"""
|
83
|
+
alreadyAdded = False
|
84
|
+
plotListFile = self._getPlotListFile()
|
85
|
+
if os.path.isfile(plotListFile):
|
86
|
+
fd = open(plotListFile, 'r')
|
87
|
+
lines = fd.readlines()
|
88
|
+
fd.close()
|
89
|
+
for line in lines:
|
90
|
+
line=line.rstrip("\n")
|
91
|
+
if line == plotTitle:
|
92
|
+
alreadyAdded=True
|
93
|
+
if not alreadyAdded:
|
94
|
+
fd = open(plotListFile, 'a')
|
95
|
+
fd.write("{}\n".format(plotTitle))
|
96
|
+
fd.close()
|
97
|
+
|
98
|
+
def _removePlotList(self, plotTitle):
|
99
|
+
"""@brief Remove a file from the plot list.
|
100
|
+
@param plotTitle The plot title
|
101
|
+
@return None"""
|
102
|
+
plotListFile = self._getPlotListFile()
|
103
|
+
newLines = []
|
104
|
+
if os.path.isfile(plotListFile):
|
105
|
+
fd = open(plotListFile, 'r')
|
106
|
+
lines = fd.readlines()
|
107
|
+
fd.close()
|
108
|
+
|
109
|
+
for line in lines:
|
110
|
+
if not line.startswith(plotTitle):
|
111
|
+
newLines.append(line)
|
112
|
+
|
113
|
+
fd = open(plotListFile, 'w')
|
114
|
+
for l in newLines:
|
115
|
+
fd.write(l)
|
116
|
+
|
117
|
+
fd.close()
|
118
|
+
|
119
|
+
def save(self, fig, htmlFile=None, autoOpen=False):
|
120
|
+
"""@brief Save a plotly figure to an html file in the local home folder.
|
121
|
+
@param fig The plotly figure
|
122
|
+
@param htmlFile The name of the htmlfile to save. If not provided the name of the plot
|
123
|
+
with the .html suffix is used as the filename.
|
124
|
+
@param autoOpen If True then a browser window is launched to show the plot"""
|
125
|
+
#don't allow index.html as this is usd for the table of plots
|
126
|
+
if htmlFile == NetPlotly.INDEX_HTML_FILE:
|
127
|
+
raise Exception("save(): {} is a reserved html file name.".format(NetPlotly.INDEX_HTML_FILE))
|
128
|
+
|
129
|
+
#If no html file provided then use the name of the plot
|
130
|
+
if not htmlFile:
|
131
|
+
htmlFile = "{}.html".format( fig["layout"]["title"]["text"] )
|
132
|
+
|
133
|
+
if not os.path.isdir(self._localRoot):
|
134
|
+
os.makedirs(self._localRoot)
|
135
|
+
self.info("Created {}".format(self._localRoot))
|
136
|
+
|
137
|
+
plotName = htmlFile.replace(".html", "")
|
138
|
+
self._updatePlotList(plotName)
|
139
|
+
|
140
|
+
fileToSave = os.path.join(self._localRoot, htmlFile)
|
141
|
+
plotly.offline.plot(fig, filename=fileToSave, auto_open = autoOpen)
|
142
|
+
self.info("Saved {}".format(fileToSave))
|
143
|
+
|
144
|
+
def _createTarBall(self, opFile, srcFolder):
|
145
|
+
self.info("Creating {} from {}".format(opFile, srcFolder))
|
146
|
+
with tarfile.open(opFile, "w:gz") as tar:
|
147
|
+
tar.add(srcFolder, arcname=os.path.basename(srcFolder))
|
148
|
+
|
149
|
+
def connect(self):
|
150
|
+
"""@brief connect to the server vis ssh"""
|
151
|
+
if not self._host:
|
152
|
+
raise Exception("No SSH server defined to connect to")
|
153
|
+
|
154
|
+
if not self._ssh:
|
155
|
+
self.info("Connecting to {}:{} as {}".format(self._host, self._port, self._username))
|
156
|
+
self._ssh = SSH(self._host, username=self._username, password=self._password, port=self._port)
|
157
|
+
self._ssh.connect(connectSFTPSession=True)
|
158
|
+
self.info("Connected")
|
159
|
+
|
160
|
+
def disconnect(self):
|
161
|
+
"""@brief Close the connection to the server."""
|
162
|
+
if self._ssh:
|
163
|
+
self._ssh.close()
|
164
|
+
self._ssh = None
|
165
|
+
self.info("Closed server connection")
|
166
|
+
|
167
|
+
def upload(self, purge=False):
|
168
|
+
"""@brief Upload the plot to the server.
|
169
|
+
@param purge If True (default is False) then all html files are removed from the server before uploading
|
170
|
+
from the local path. If True the caller must be careful to set serverRoot (in Constructor)
|
171
|
+
as all files in this location are purged before files are uploaded."""
|
172
|
+
if self._host and self._username:
|
173
|
+
tarBallFile = NetPlotly.GetTarBallFile()
|
174
|
+
self._createTarBall(tarBallFile, self._localRoot)
|
175
|
+
self.connect()
|
176
|
+
|
177
|
+
if purge:
|
178
|
+
#Remove all the files in the server folder
|
179
|
+
cmd = "rm -f {}/*".format(self._serverRoot)
|
180
|
+
self._ssh.runCmd(cmd)
|
181
|
+
|
182
|
+
self.info("Uploading {} to {}:{}".format(tarBallFile, self._host, self._port))
|
183
|
+
self._ssh.putFile(tarBallFile, tarBallFile)
|
184
|
+
|
185
|
+
self.info("Decompressing {} into {} on the server.".format(tarBallFile, self._serverRoot))
|
186
|
+
rPath = Path(self._serverRoot)
|
187
|
+
cmd = "tar zxvf {} -C {}".format(tarBallFile, rPath.parent)
|
188
|
+
self._ssh.runCmd(cmd)
|
189
|
+
|
190
|
+
self.disconnect()
|
191
|
+
|
192
|
+
def getPlotNameList(self):
|
193
|
+
"""@brief Get a list of the names of all the plots currently stored in the local root folder.
|
194
|
+
@return a list of plot names."""
|
195
|
+
plotList = []
|
196
|
+
plotListFile = self._getPlotListFile()
|
197
|
+
if os.path.isfile(plotListFile):
|
198
|
+
fd = open(plotListFile, 'r')
|
199
|
+
plotList = fd.read().splitlines()
|
200
|
+
fd.close()
|
201
|
+
|
202
|
+
return plotList
|
203
|
+
|
204
|
+
def getPlotFileList(self):
|
205
|
+
"""@brief Get a list of the plot file names of all the plots currently stored in the local root folder.
|
206
|
+
@return a list of plot file names."""
|
207
|
+
plotList = self.getPlotNameList()
|
208
|
+
plotFileList = ["{}.html".format(plotName) for plotName in plotList]
|
209
|
+
return plotFileList
|
210
|
+
|
211
|
+
def remove(self, plotName):
|
212
|
+
"""@brief Remove a plot by it's name from the plot list.
|
213
|
+
@return None"""
|
214
|
+
fileToRemove = os.path.join(self._localRoot, "{}.html".format(plotName))
|
215
|
+
if os.path.isfile(fileToRemove):
|
216
|
+
os.remove(fileToRemove)
|
217
|
+
self._removePlotList(plotName)
|
218
|
+
|
219
|
+
def removeLocalRoot(self):
|
220
|
+
"""@brief Remove all plots from the list of plots. Be sure you have _localRoot set
|
221
|
+
correctly before calling this method.
|
222
|
+
@return None"""
|
223
|
+
shutil.rmtree(self._localRoot)
|