Skip to content

Commit f309f37

Browse files
authored
Merge pull request #342 from giloser/master
Version 1.6.4
2 parents 5b3a54a + d4e2585 commit f309f37

File tree

7 files changed

+275
-66
lines changed

7 files changed

+275
-66
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
This plugin integrates Telegram Messenger with Octoprint. It sends messages (with photos if available) on print start, end and failure. Also it sends messages during the print at configurable intervals. That way you don't have to remember to regularly have a look at the printing process.
77
Also, you can control Octoprint via messages (settings, start a print and much more). Send `/status` to get the current printer status or `/abort` to abort the current print. Send `/help` for a list of all recognized commands. You may also use this bot in groups.
88

9-
**Latest release: [1.6.3](https://github.com/fabianonline/OctoPrint-Telegram/releases)**
9+
**Latest release: [1.6.4](https://github.com/fabianonline/OctoPrint-Telegram/releases)**
1010

1111
<!-- omit in toc -->
1212
## Contents

octoprint_telegram/__init__.py

Lines changed: 104 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def __init__(self, main):
4545
def run(self):
4646
self._logger.debug("Try first connect.")
4747
self.tryFirstContact()
48-
# repeat fetching and processing messages unitil thread stopped
48+
# repeat fetching and processing messages until thread stopped
4949
self._logger.debug("Listener is running.")
5050
try:
5151
while not self.do_stop:
@@ -208,7 +208,7 @@ def handleDocumentMessage(self, message, chat_id, from_id):
208208
#stream = octoprint.filemanager.util.StreamWrapper(target_filename, bytes_reader_class(data))
209209
#self.main._file_manager.add_folder(self.get_plugin_data_folder() , "tmpzip", ignore_existing=True)
210210
zip_filename = self.main.get_plugin_data_folder()+"/tmpzip/" +file_name
211-
with open(zip_filename, 'w') as f:
211+
with open(zip_filename, 'wb') as f:
212212
f.write(data)
213213
#self.main._file_manager.add_file(octoprint.filemanager.FileDestinations.LOCAL, target_filename, stream, allow_overwrite=True)
214214
except Exception as ex:
@@ -269,7 +269,7 @@ def handleDocumentMessage(self, message, chat_id, from_id):
269269
os.remove(zip_filename)
270270
else:
271271
path = self.main.get_plugin_data_folder()+"/tmpzip/" +file_name
272-
with open(path, 'w') as f:
272+
with open(path, 'wb') as f:
273273
f.write(data)
274274
file_wrapper = octoprint.filemanager.util.DiskFileWrapper(target_filename, path)
275275
added_file = self.main._file_manager.add_file(octoprint.filemanager.FileDestinations.LOCAL,file_wrapper.filename,file_wrapper,allow_overwrite=True)
@@ -1002,7 +1002,8 @@ def get_api_commands(self):
10021002
return dict(
10031003
testToken=["token"],
10041004
testEvent=["event"],
1005-
delChat=["ID"]
1005+
delChat=["ID"],
1006+
setCommandList=["force"]
10061007
)
10071008

10081009
def on_api_get(self, request):
@@ -1064,6 +1065,16 @@ def on_api_command(self, command, data):
10641065
return json.dumps({'ok': True, 'error_msg': None })
10651066
except Exception as ex:
10661067
return json.dumps({'ok': False, 'username': None, 'error_msg': str(ex)})
1068+
elif command=="setCommandList":
1069+
self._logger.debug("Set default command for bot")
1070+
try:
1071+
self.setMyCommands(True)
1072+
self._logger.debug("Set default command for bot done will return ok")
1073+
return json.dumps({'ok': True, 'setMyCommands_state_str': gettext("SetMyCommands done",), 'error_msg': None})
1074+
except Exception as ex:
1075+
return json.dumps({'ok': False, 'setMyCommands_state_str': gettext("Error: %(error)s", error=ex), 'error_msg': str(ex)})
1076+
1077+
10671078
##########
10681079
### Telegram API-Functions
10691080
##########
@@ -1141,7 +1152,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
11411152
self._logger.debug("start _send_msg")
11421153

11431154
try:
1144-
if with_image or with_gif:
1155+
if (with_image or with_gif):
11451156
premethod = self._settings.get(["PreImgMethod"])
11461157
self._logger.debug("PreImgMethod {}".format(premethod))
11471158
precommand = self._settings.get(["PreImgCommand"])
@@ -1197,53 +1208,57 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
11971208
data['disable_notification'] = silent
11981209
if with_gif: #giloser 05/05/19
11991210
try:
1200-
self._logger.info("Will try to create a gif ")
12011211
sendOneInLoop = False
1202-
#requests.get(self.main.bot_url + "/sendChatAction", params = {'chat_id': chat_id, 'action': 'upload_document'})
1203-
if self._plugin_manager.get_plugin("multicam",True) and self._settings.get(["multicam"]):
1204-
try:
1205-
curr = self._settings.global_get(["plugins","multicam","multicam_profiles"])
1206-
self._logger.debug("multicam_profiles : "+ str(curr))
1207-
ListGif = []
1208-
for li in curr:
1209-
try:
1210-
self._logger.debug("multicam profile : "+ str(li))
1211-
url = li.get("URL")
1212-
self._logger.debug("multicam URL : "+ str(url))
1213-
ret = self.create_gif_new(chatID,0,li)
1214-
if ret != "":
1215-
ListGif.append(ret)
1216-
#if not sendOneInLoop:
1217-
# self.send_file(chatID, ret,message)
1218-
#else:
1219-
# self.send_file(chatID, ret,"")
1220-
#sendOneInLoop = True
1221-
except Exception as ex:
1222-
self._logger.exception("Exception loop multicam URL to create gif: "+ str(ex) )
1223-
ret = ListGif[-1]
1224-
self._logger.debug("ListGif: "+str(ListGif))
1225-
for x in ListGif:
1226-
try:
1227-
if x != ret:
1228-
self._logger.debug("send_file whithout message: "+str(x))
1229-
self.send_file(chatID, x,"")
1230-
except Exception as ex:
1231-
self._logger.exception("Exception loop multicam URL to send gif: "+ str(ex) )
1232-
1233-
except Exception as ex:
1234-
self._logger.exception("Exception occured on getting multicam options: "+ str(ex) )
1212+
if kwargs['event'] == "MovieDone":
1213+
ret = kwargs['movie']
12351214
else:
1236-
ret = self.create_gif_new(chatID,0,0)
1215+
self._logger.info("Will try to create a gif ")
1216+
1217+
#requests.get(self.main.bot_url + "/sendChatAction", params = {'chat_id': chat_id, 'action': 'upload_document'})
1218+
if self._plugin_manager.get_plugin("multicam",True) and self._settings.get(["multicam"]):
1219+
try:
1220+
curr = self._settings.global_get(["plugins","multicam","multicam_profiles"])
1221+
self._logger.debug("multicam_profiles : "+ str(curr))
1222+
ListGif = []
1223+
for li in curr:
1224+
try:
1225+
self._logger.debug("multicam profile : "+ str(li))
1226+
url = li.get("URL")
1227+
self._logger.debug("multicam URL : "+ str(url))
1228+
ret = self.create_gif_new(chatID,0,li)
1229+
if ret != "":
1230+
ListGif.append(ret)
1231+
#if not sendOneInLoop:
1232+
# self.send_file(chatID, ret,message)
1233+
#else:
1234+
# self.send_file(chatID, ret,"")
1235+
#sendOneInLoop = True
1236+
except Exception as ex:
1237+
self._logger.exception("Exception loop multicam URL to create gif: "+ str(ex) )
1238+
ret = ListGif[-1]
1239+
self._logger.debug("ListGif: "+str(ListGif))
1240+
for x in ListGif:
1241+
try:
1242+
if x != ret:
1243+
self._logger.debug("send_file whithout message: "+str(x))
1244+
self.send_file(chatID, x,"")
1245+
except Exception as ex:
1246+
self._logger.exception("Exception loop multicam URL to send gif: "+ str(ex) )
1247+
1248+
except Exception as ex:
1249+
self._logger.exception("Exception occured on getting multicam options: "+ str(ex) )
1250+
else:
1251+
ret = self.create_gif_new(chatID,0,0)
12371252

1238-
if ret == "":
1239-
ret = self.create_gif_new(chatID,0,0)
1253+
if ret == "":
1254+
ret = self.create_gif_new(chatID,0,0)
12401255

12411256
if ret != "" and not sendOneInLoop:
12421257
self._logger.debug("send_file whith message: "+str(ret))
12431258
self.send_file(chatID, ret,message)
1244-
#ret = self.create_gif_new(chatID,0,0)
1245-
#if ret != "":
1246-
# self.send_file(chatID, ret,message)
1259+
#ret = self.create_gif_new(chatID,0,0)
1260+
#if ret != "":
1261+
# self.send_file(chatID, ret,message)
12471262
except Exception as ex:
12481263
self._logger.info("Caught an exception trying send gif: " + str(ex))
12491264
self.send_msg(self.gEmo('dizzy face') + " Problem creating gif, please check log file", chatID=chatID)#and make sure you have installed libav-tools or ffmpeg with command : `sudo apt-get install libav-tools`",chatID=chat_id)
@@ -1523,6 +1538,45 @@ def test_token(self, token=None):
15231538
else:
15241539
return "@" + json['result']['username']
15251540

1541+
1542+
# sets bot own list of commands
1543+
def setMyCommands(self, force=False):
1544+
if not self.send_messages:
1545+
return
1546+
try:
1547+
shallRun=force
1548+
if not force:
1549+
# check if a list of commands was already set
1550+
resp = requests.get(self.bot_url + "/getMyCommands").json()
1551+
self._logger.debug("getMyCommands returned " + str(resp))
1552+
shallRun=(len(resp['result']) == 0)
1553+
if shallRun:
1554+
commands = []
1555+
commands.append({"command":"status","description":"Displays the current status including a capture from the camera"})
1556+
commands.append({"command":"togglepause","description":"Pauses/Resumes current print"})
1557+
commands.append({"command":"files","description":"Lists all the files available for printing"})
1558+
commands.append({"command":"print","description":"Lets you start a print (confirmation required)"})
1559+
commands.append({"command":"tune","description":"Sets feed and flow rate, control temperatures"})
1560+
commands.append({"command":"ctrl","description":"Activates self defined controls from Octoprint"})
1561+
commands.append({"command":"con","description":"Connects or disconnects the printer"})
1562+
commands.append({"command":"sys","description":"Executes Octoprint system commands"})
1563+
commands.append({"command":"abort","description":"Aborts the currently running print (confirmation required)"})
1564+
commands.append({"command":"off","description":"Turn off the printer"})
1565+
commands.append({"command":"on","description":"Turn on the printer"})
1566+
commands.append({"command":"settings","description":"Displays notification settings and lets change them"})
1567+
commands.append({"command":"upload","description":"Stores a file into the Octoprint library"})
1568+
commands.append({"command":"filament","description":"Shows filament spools and lets you change it (requires Filament Manager Plugin)"})
1569+
commands.append({"command":"user","description":"Gets user info"})
1570+
commands.append({"command":"gcode","description":"call gCode commande with /gcode_XXX where XXX is the gcode command"})
1571+
commands.append({"command":"gif","description":"Sends a gif from the current video"})
1572+
commands.append({"command":"supergif","description":"Sends a bigger gif from the current video"})
1573+
commands.append({"command":"shutup","description":"Disables automatic notifications until the next print ends"})
1574+
commands.append({"command":"dontshutup","description":"Makes the bot talk again (opposite of `/shutup`)"})
1575+
commands.append({"command":"help","description":"Shows this help message"})
1576+
resp = requests.post(self.bot_url + "/setMyCommands", data={'commands':json.dumps(commands)}).json()
1577+
self._logger.debug("setMyCommands returned " + str(resp))
1578+
except Exception as ex:
1579+
pass
15261580
##########
15271581
### Helper methods
15281582
##########
@@ -1618,8 +1672,9 @@ def calculate_ETA(self,printTime = 0):
16181672
currentData = self._printer.get_current_data()
16191673
current_time = datetime.datetime.today()
16201674
if not currentData["progress"]["printTimeLeft"]:
1621-
if printTime == 0:
1675+
if printTime == 0 or str(printTime)=="11:11:00":
16221676
return "" # maybe put something like "nothing to print" in here
1677+
self._logger.debug("printTime=" + str(printTime))
16231678
finish_time = current_time + datetime.timedelta(0, printTime)
16241679
else:
16251680
finish_time = current_time + datetime.timedelta(0, currentData["progress"]["printTimeLeft"])
@@ -1880,7 +1935,6 @@ def hook_gcode_sent(self, comm_instance, phase, cmd, cmd_type, gcode, *args, **k
18801935
if gcode and cmd[:4] == "M600":
18811936
self._logger.info("M600 registered")
18821937
try:
1883-
#self.on_event("plugin_pause_for_user_event_notify", {})
18841938
self.on_event("gCode_M600", {})
18851939
except Exception as ex:
18861940
self._logger.error("exception on event M600: " + str(ex))
@@ -1891,7 +1945,9 @@ def recv_callback(self, comm_instance, line, *args, **kwargs):
18911945
if not self.triggered:
18921946
self.on_event("plugin_pause_for_user_event_notify", {})
18931947
self.triggered = True
1894-
# Other text, we may fire another event if we encounter "paused for user" again
1948+
elif "echo:UserNotif" in line:
1949+
self.on_event("UserNotif", {"UserNotif":line[15:]})
1950+
# Other text, we may fire another event if we encounter "paused for user" again
18951951
else:
18961952
self.triggered = False
18971953

octoprint_telegram/static/js/telegram.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ $(function() {
4040
self.isloading = ko.observable(false);
4141
self.errored = ko.observable(false);
4242
self.token_state_str = ko.observable("Unknown");
43+
self.setCommandList_state_str = ko.observable("");
4344
self.editChatDialog = undefined;
4445
self.varInfoDialog = undefined;
4546
self.emoInfoDialog = undefined;
@@ -405,6 +406,41 @@ $(function() {
405406
}
406407

407408
}
409+
410+
self.setCommandResponse = function(response) {
411+
self.setCommandList_state_str(response.setMyCommands_state_str);
412+
self.errored(!response.ok);
413+
if(!response.ok){
414+
$('#CmdteleErrored').removeClass("text-warning");
415+
$('#CmdteleErrored').addClass("text-error");
416+
}
417+
else{
418+
$('#CmdteleErrored').removeClass("text-warning");
419+
$('#CmdteleErrored').addClass("text-success");
420+
}
421+
422+
}
423+
424+
self.setCommandList = function(data, event) {
425+
console.log("StartSetCommandList");
426+
$('#CmdteleErrored').addClass("text-warning");
427+
$('#CmdteleErrored').removeClass("text-danger");
428+
$('#CmdteleErrored').removeClass("text-sucess");
429+
self.setCommandList_state_str("Please wait ...")
430+
var callback = function() {
431+
$.ajax({
432+
url: API_BASEURL + "plugin/telegram",
433+
type: "POST",
434+
dataType: "json",
435+
data: JSON.stringify({ "command": "setCommandList", "force": 'True'}),
436+
contentType: "application/json",
437+
success: self.setCommandResponse
438+
});
439+
};
440+
showConfirmationDialog('Do you really want to set default commands ', function (e) {
441+
callback();
442+
});
443+
}
408444

409445
self.fromResponse = function(response) {
410446
if(response === undefined) return;

0 commit comments

Comments
 (0)