|
@@ -1,6 +1,7 @@
|
1
|
1
|
#!/usr/bin/env python3
|
2
|
2
|
|
3
|
3
|
# OctoTray Linux Qt System Tray OctoPrint client
|
|
4
|
+#
|
4
|
5
|
# depends on:
|
5
|
6
|
# - python-pyqt5
|
6
|
7
|
# - curl
|
|
@@ -26,7 +27,7 @@ class OctoTray():
|
26
|
27
|
iconName = "octotray_icon.png"
|
27
|
28
|
|
28
|
29
|
# 0=host, 1=key
|
29
|
|
- # (2=method, 3=menu, 4=on-action, 5=off-action, 6=web-action)
|
|
30
|
+ # (2=method, 3=menu, 4...=actions)
|
30
|
31
|
printers = [
|
31
|
32
|
[ "PRINTER_HOST_HERE", "PRINTER_API_KEY_HERE" ]
|
32
|
33
|
]
|
|
@@ -66,6 +67,11 @@ class OctoTray():
|
66
|
67
|
p.append(action)
|
67
|
68
|
menu.addAction(action)
|
68
|
69
|
|
|
70
|
+ action = QAction("Get Status")
|
|
71
|
+ action.triggered.connect(lambda chk, x=p: self.printerStatusAction(x))
|
|
72
|
+ p.append(action)
|
|
73
|
+ menu.addAction(action)
|
|
74
|
+
|
69
|
75
|
action = QAction("Open Web UI")
|
70
|
76
|
action.triggered.connect(lambda chk, x=p: self.printerWebAction(x))
|
71
|
77
|
p.append(action)
|
|
@@ -99,6 +105,30 @@ class OctoTray():
|
99
|
105
|
def openBrowser(self, url):
|
100
|
106
|
os.system("xdg-open http://" + url)
|
101
|
107
|
|
|
108
|
+ def showDialog(self, title, text1, text2, question, warning):
|
|
109
|
+ msg = QMessageBox()
|
|
110
|
+
|
|
111
|
+ if warning:
|
|
112
|
+ msg.setIcon(QMessageBox.Warning)
|
|
113
|
+ else:
|
|
114
|
+ msg.setIcon(QMessageBox.Information)
|
|
115
|
+
|
|
116
|
+ msg.setWindowTitle(title)
|
|
117
|
+ msg.setText(text1)
|
|
118
|
+
|
|
119
|
+ if text2 is not None:
|
|
120
|
+ msg.setInformativeText(text2)
|
|
121
|
+
|
|
122
|
+ if question:
|
|
123
|
+ msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
|
|
124
|
+ else:
|
|
125
|
+ msg.setStandardButtons(QMessageBox.Ok)
|
|
126
|
+
|
|
127
|
+ retval = msg.exec_()
|
|
128
|
+ if retval == QMessageBox.Yes:
|
|
129
|
+ return True
|
|
130
|
+ return False
|
|
131
|
+
|
102
|
132
|
def sendRequest(self, host, headers, path, content = None):
|
103
|
133
|
cmdline = 'curl -s'
|
104
|
134
|
for h in headers:
|
|
@@ -121,7 +151,7 @@ class OctoTray():
|
121
|
151
|
headers = [ "X-Api-Key: " + key ]
|
122
|
152
|
return self.sendRequest(host, headers, path)
|
123
|
153
|
|
124
|
|
- def getStatus(self, host, key):
|
|
154
|
+ def getState(self, host, key):
|
125
|
155
|
r = self.sendGetRequest(host, key, "job")
|
126
|
156
|
try:
|
127
|
157
|
rd = json.loads(r)
|
|
@@ -131,6 +161,16 @@ class OctoTray():
|
131
|
161
|
pass
|
132
|
162
|
return "Unknown"
|
133
|
163
|
|
|
164
|
+ def getProgress(self, host, key):
|
|
165
|
+ r = self.sendGetRequest(host, key, "job")
|
|
166
|
+ try:
|
|
167
|
+ rd = json.loads(r)
|
|
168
|
+ if "progress" in rd:
|
|
169
|
+ return rd["progress"]
|
|
170
|
+ except json.JSONDecodeError:
|
|
171
|
+ pass
|
|
172
|
+ return "Unknown"
|
|
173
|
+
|
134
|
174
|
def getName(self, host, key):
|
135
|
175
|
r = self.sendGetRequest(host, key, "printerprofiles")
|
136
|
176
|
try:
|
|
@@ -191,9 +231,9 @@ class OctoTray():
|
191
|
231
|
self.setPrinter(item[0], item[1], item[2], True)
|
192
|
232
|
|
193
|
233
|
def printerOffAction(self, item):
|
194
|
|
- state = self.getStatus(item[0], item[1])
|
|
234
|
+ state = self.getState(item[0], item[1])
|
195
|
235
|
if state in self.statesWithWarning:
|
196
|
|
- if self.showdialog() == True:
|
|
236
|
+ if self.showDialog("OctoTray Warning", "The printer seems to be running currently!", "Do you really want to turn it off?", True, True) == True:
|
197
|
237
|
self.setPrinter(item[0], item[1], item[2], False)
|
198
|
238
|
else:
|
199
|
239
|
self.setPrinter(item[0], item[1], item[2], False)
|
|
@@ -201,19 +241,20 @@ class OctoTray():
|
201
|
241
|
def printerWebAction(self, item):
|
202
|
242
|
self.openBrowser(item[0])
|
203
|
243
|
|
204
|
|
- def showdialog(self):
|
205
|
|
- msg = QMessageBox()
|
206
|
|
- msg.setIcon(QMessageBox.Warning)
|
207
|
|
-
|
208
|
|
- msg.setWindowTitle("OctoTray Warning")
|
209
|
|
- msg.setText("The printer seems to be running currently!")
|
210
|
|
- msg.setInformativeText("Do you really want to turn it off?")
|
211
|
|
- msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
|
212
|
|
-
|
213
|
|
- retval = msg.exec_()
|
214
|
|
- if retval == QMessageBox.Yes:
|
215
|
|
- return True
|
216
|
|
- return False
|
|
244
|
+ def printerStatusAction(self, item):
|
|
245
|
+ progress = self.getProgress(item[0], item[1])
|
|
246
|
+ s = ""
|
|
247
|
+ warning = False
|
|
248
|
+ if ("completion" in progress) and ("printTime" in progress) and ("printTimeLeft" in progress) and (progress["completion"] != None) and (progress["printTime"] != None) and (progress["printTimeLeft"] != None):
|
|
249
|
+ s = "%.1f%% Completion\n" % progress["completion"]
|
|
250
|
+ s += "Printing since " + time.strftime("%H:%M:%S", time.gmtime(progress["printTime"])) + "\n"
|
|
251
|
+ s += time.strftime("%H:%M:%S", time.gmtime(progress["printTimeLeft"])) + " left\n"
|
|
252
|
+ elif ("completion" in progress) and ("printTime" in progress) and ("printTimeLeft" in progress):
|
|
253
|
+ s = "No job is currently running"
|
|
254
|
+ else:
|
|
255
|
+ s = "Could not read printer status!"
|
|
256
|
+ warning = True
|
|
257
|
+ self.showDialog("OctoTray Status", s, None, False, warning)
|
217
|
258
|
|
218
|
259
|
if __name__ == "__main__":
|
219
|
260
|
tray = OctoTray()
|