Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix #244] Fix incompatibilities with python3 #273

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 68 additions & 67 deletions octoprint_telegram/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import absolute_import

from PIL import Image
from subprocess import Popen, PIPE
import threading, requests, re, time, datetime, StringIO, json, random, logging, traceback, io, collections, os, flask,base64,PIL, pkg_resources,subprocess,zipfile,glob #,resource
import threading, requests, re, time, datetime, io, json, random, logging, traceback, io, collections, os, flask,base64,PIL, pkg_resources,subprocess,zipfile,glob #,resource
import octoprint.plugin, octoprint.util, octoprint.filemanager
from flask_babel import gettext
from flask_login import current_user
Expand Down Expand Up @@ -260,22 +260,22 @@ def handleDocumentMessage(self, message, chat_id, from_id):
def handleTextMessage(self, message, chat_id, from_id):
# We got a chat message.
# handle special messages from groups (/commad@BotName)
command = str(message['message']['text'].split('@')[0].encode('utf-8'))
command = str(message['message']['text'].split('@')[0])
parameter = ""
# TODO: Do we need this anymore?
# reply_to_messages will be send on value inputs (eg notification height)
# but also on android when pushing a button. Then we have to switch command and parameter.
#if "reply_to_message" in message['message'] and "text" in message['message']['reply_to_message']:
#command = message['message']['reply_to_message']['text']
#parameter = message['message']['text']
#if command.encode('utf-8') not in [str(k.encode('utf-8')) for k in self.main.tcmd.commandDict.keys()]:
#if command not in [str(k) for k in self.main.tcmd.commandDict.keys()]:
#command = message['message']['text']
#parameter = message['message']['reply_to_message']['text']
# if command is with parameter, get the parameter
if any((k+"_") in command for k,v in self.main.tcmd.commandDict.iteritems() if 'param' in v):
if any((k+"_") in command for k,v in self.main.tcmd.commandDict.items() if 'param' in v):
parameter = '_'.join(command.split('_')[1:])
command = command.split('_')[0]
self._logger.info("Got a command: '" + str(command.encode('utf-8')) + "' with parameter: '" + str(parameter.encode('utf-8')) + "' in chat " + str(message['message']['chat']['id']))
self._logger.info("Got a command: '" + str(command) + "' with parameter: '" + str(parameter) + "' in chat " + str(message['message']['chat']['id']))
# is command known?
if command not in self.main.tcmd.commandDict:
# we dont know the command so skip the message
Expand Down Expand Up @@ -455,33 +455,33 @@ def __init__(self,version):
self.newChat = {}
# use of emojis see below at method gEmo()
self.emojis = {
'octo': u'\U0001F419', #octopus
'mistake': u'\U0001F616',
'notify': u'\U0001F514',
'shutdown' : u'\U0001F4A4',
'shutup': u'\U0001F64A',
'noNotify': u'\U0001F515',
'notallowed': u'\U0001F62C',
'rocket': u'\U0001F680',
'save': u'\U0001F4BE',
'heart': u'\U00002764',
'info': u'\U00002139',
'settings': u'\U0001F4DD',
'clock': u'\U000023F0',
'height': u'\U00002B06',
'question': u'\U00002753',
'warning': u'\U000026A0',
'enter': u'\U0000270F',
'upload': u'\U0001F4E5',
'check': u'\U00002705',
'lamp': u'\U0001F4A1',
'movie': u'\U0001F3AC',
'finish': u'\U0001F3C1',
'cam': u'\U0001F3A6',
'hooray': u'\U0001F389',
'error': u'\U000026D4',
'play': u'\U000025B6',
'stop': u'\U000025FC'
'octo': '\U0001F419', #octopus
'mistake': '\U0001F616',
'notify': '\U0001F514',
'shutdown' : '\U0001F4A4',
'shutup': '\U0001F64A',
'noNotify': '\U0001F515',
'notallowed': '\U0001F62C',
'rocket': '\U0001F680',
'save': '\U0001F4BE',
'heart': '\U00002764',
'info': '\U00002139',
'settings': '\U0001F4DD',
'clock': '\U000023F0',
'height': '\U00002B06',
'question': '\U00002753',
'warning': '\U000026A0',
'enter': '\U0000270F',
'upload': '\U0001F4E5',
'check': '\U00002705',
'lamp': '\U0001F4A1',
'movie': '\U0001F3AC',
'finish': '\U0001F3C1',
'cam': '\U0001F3A6',
'hooray': '\U0001F389',
'error': '\U000026D4',
'play': '\U000025B6',
'stop': '\U000025FC'
}
self.emojis.update(telegramEmojiDict)
# all emojis will be get via this method to disable them globaly by the corrosponding setting
Expand Down Expand Up @@ -578,8 +578,8 @@ def on_after_startup(self):
'new': True,
'type': '',
'allow_users': False,
'commands': {k: False for k,v in self.tcmd.commandDict.iteritems()},
'notifications': {k: False for k,v in telegramMsgDict.iteritems()}
'commands': {k: False for k,v in self.tcmd.commandDict.items()},
'notifications': {k: False for k,v in telegramMsgDict.items()}
}
self.chats = self._settings.get(["chats"])
self.start_listening()
Expand Down Expand Up @@ -612,7 +612,7 @@ def on_startup(self, host, port):
#self.main.tcmd.port = port
except Exception as ex:
self._logger.error("Exception on_startup: "+ str(ex) )


def on_shutdown(self):
self.on_event("PrinterShutdown",{})
Expand Down Expand Up @@ -679,14 +679,14 @@ def on_settings_migrate(self, target, current=None):
'new': False,
'type': '',
'allow_users': False,
'commands': {k: False for k,v in tcmd.commandDict.iteritems()},
'notifications': {k: False for k,v in telegramMsgDict.iteritems()}
'commands': {k: False for k,v in tcmd.commandDict.items()},
'notifications': {k: False for k,v in telegramMsgDict.items()}
}

##########
### migrate from old plugin Versions < 1.3 (old versions had no settings version check)
##########
chats = {k: v for k, v in self._settings.get(['chats']).iteritems() if k != 'zBOTTOMOFCHATS'}
chats = {k: v for k, v in self._settings.get(['chats']).items() if k != 'zBOTTOMOFCHATS'}
self._logger.debug("LOADED CHATS: " + str(chats))
self._settings.set(['chats'], {})
if current is None or current < 1:
Expand All @@ -697,9 +697,9 @@ def on_settings_migrate(self, target, current=None):
for setting in newUsrDict:
if setting not in chats[chat]:
if setting == "commands":
chats[chat]['commands'] = {k: False for k,v in tcmd.commandDict.iteritems() if 'bind_none' not in v}
chats[chat]['commands'] = {k: False for k,v in tcmd.commandDict.items() if 'bind_none' not in v}
elif setting == "notifications":
chats[chat]['notifications'] = {k: False for k,v in telegramMsgDict.iteritems()}
chats[chat]['notifications'] = {k: False for k,v in telegramMsgDict.items()}
else:
chats[chat][setting] = False
########## Is there a chat from old single user plugin version?
Expand Down Expand Up @@ -969,18 +969,18 @@ def on_api_get(self, request):
self._logger.debug("Updated chat - " + str(request.args['id']))
elif 'bindings' in request.args:
bind_text = {}
for key in {k: v for k, v in telegramMsgDict.iteritems() if 'bind_msg' in v }:
for key in {k: v for k, v in telegramMsgDict.items() if 'bind_msg' in v }:
if telegramMsgDict[key]['bind_msg'] in bind_text:
bind_text[telegramMsgDict[key]['bind_msg']].append(key)
else:
bind_text[telegramMsgDict[key]['bind_msg']] = [key]
return json.dumps({
'bind_cmd':[k for k, v in self.tcmd.commandDict.iteritems() if 'bind_none' not in v ],
'bind_msg':[k for k, v in telegramMsgDict.iteritems() if 'bind_msg' not in v ],
'bind_cmd':[k for k, v in self.tcmd.commandDict.items() if 'bind_none' not in v ],
'bind_msg':[k for k, v in telegramMsgDict.items() if 'bind_msg' not in v ],
'bind_text':bind_text,
'no_setting':[k for k, v in telegramMsgDict.iteritems() if 'no_setting' in v ]})
'no_setting':[k for k, v in telegramMsgDict.items() if 'no_setting' in v ]})

retChats = {k: v for k, v in self.chats.iteritems() if 'delMe' not in v and k != 'zBOTTOMOFCHATS'}
retChats = {k: v for k, v in self.chats.items() if 'delMe' not in v and k != 'zBOTTOMOFCHATS'}
for chat in retChats:
if os.path.isfile(self.get_plugin_data_folder()+"/img/user/pic" +chat+".jpg"):
retChats[chat]['image'] = "/plugin/telegram/img/user/pic" +chat+".jpg"
Expand Down Expand Up @@ -1011,7 +1011,7 @@ def on_api_command(self, command, data):
if strId in self.chats:
del self.chats[strId]
# do self._settings.save() here???????
return json.dumps({'chats':{k: v for k, v in self.chats.iteritems() if 'delMe' not in v and k != 'zBOTTOMOFCHATS'}, 'connection_state_str':self.connection_state_str, 'connection_ok':self.connection_ok})
return json.dumps({'chats':{k: v for k, v in self.chats.items() if 'delMe' not in v and k != 'zBOTTOMOFCHATS'}, 'connection_state_str':self.connection_state_str, 'connection_ok':self.connection_ok})

##########
### Telegram API-Functions
Expand Down Expand Up @@ -1068,7 +1068,7 @@ def _send_edit_msg(self,message="",msg_id="",chatID="", responses= None, inline=
if responses and inline:
myArr = []
for k in responses:
myArr.append(map(lambda x: {"text":x[0],"callback_data":x[1]}, k))
myArr.append([{"text":x[0],"callback_data":x[1]} for x in k])
keyboard = {'inline_keyboard':myArr}
data['reply_markup'] = json.dumps(keyboard)
self._logger.debug("SENDING UPDATE: " + str(data))
Expand Down Expand Up @@ -1103,7 +1103,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
self._logger.debug("Sending text...")
t = threading.Thread(target=self._send_msg, kwargs = args).run()
return

self._logger.info("Sending a message: " + message.replace("\n", "\\n") + " with_image=" + str(with_image) + " with_gif=" + str(with_gif) + " chatID= " + str(chatID))
data = {}
# Do we want to show web link previews?
Expand All @@ -1115,7 +1115,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
if responses:
myArr = []
for k in responses:
myArr.append(map(lambda x: {"text":x[0],"callback_data":x[1]}, k))
myArr.append([{"text":x[0],"callback_data":x[1]} for x in k])
keyboard = {'inline_keyboard':myArr}
data['reply_markup'] = json.dumps(keyboard)

Expand All @@ -1130,7 +1130,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
try:
curr = self._settings.global_get(["plugins","multicam","multicam_profiles"])
self._logger.error("multicam_profiles : "+ str(curr))
for li in curr:
for li in curr:
try:
self._logger.error("multicam profile : "+ str(li))
url = li.get("URL")
Expand All @@ -1140,15 +1140,15 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
if not sendOneInLoop:
self.send_file(chatID, ret,message)
else:
self.send_file(chatID, ret,"")
self.send_file(chatID, ret,"")
sendOneInLoop = True
except Exception as ex:
self._logger.error("Exception loop multicam URL to create gif: "+ str(ex) )
except Exception as ex:
self._logger.error("Exception occured on getting multicam options: "+ str(ex) )
else:
ret = self.create_gif_new(chatID,0,0)

if ret == "":
ret = self.create_gif_new(chatID,0,0)

Expand All @@ -1171,20 +1171,20 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
if with_image:
self._logger.debug("image data so far: " + str(image_data))

if (not image_data or 'html' in image_data) and with_image:
if (not image_data or 'html' in str(image_data)) and with_image:
message = "[ERR GET IMAGE]\n\n" + message
image_data = None

r = None

if image_data:
self._logger.debug("Sending with image.. " + str(chatID))
files = {'photo':("image.jpg", image_data)}
self._logger.debug("files so far: " + str(files))
if message is not "":
data['caption'] = message
r = requests.post(self.bot_url + "/sendPhoto", files=files, data=data)

self._logger.debug("Sending finished. " + str(r.status_code))
else:
self._logger.debug("Sending without image.. " + str(chatID))
Expand All @@ -1200,7 +1200,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
try:
curr = self._settings.global_get(["plugins","multicam","multicam_profiles"])
self._logger.debug("multicam_profiles : "+ str(curr))
for li in curr:
for li in curr:
try:
self._logger.debug("multicam profile: "+ str(li))
snapshot_url = li.get("URL")
Expand All @@ -1227,7 +1227,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
self._logger.debug("no image " + str(li.get("name")))
else:
self._logger.debug("url is the same as the one from octoprint " )

except Exception as ex:
self._logger.error("Exception loop multicam URL to create image: "+ str(ex) )
except Exception as ex:
Expand All @@ -1243,7 +1243,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None,
if 'message_id' in myJson['result']:
self.updateMessageID[chatID] = myJson['result']['message_id']


except Exception as ex:
self._logger.debug("Caught an exception in _send_msg(): " + str(ex))

Expand Down Expand Up @@ -1322,7 +1322,7 @@ def get_usrPic(self,chat_id, file_id=""):
else:
r = self.get_file(file_id)
file_name = self.get_plugin_data_folder() + "/img/user/pic" + str(chat_id) + ".jpg"
img = Image.open(StringIO.StringIO(r))
img = Image.open(io.BytesIO(r))
img = img.resize((40, 40), PIL.Image.ANTIALIAS)
img.save(file_name, format="JPEG")
self._logger.debug("Saved Photo "+ str(chat_id))
Expand All @@ -1342,9 +1342,9 @@ def test_token(self, token=None):
json = response.json()
if not 'ok' in json or not json['ok']:
if json['description']:
raise(Exception(gettext("Telegram returned error code %(error)s: %(message)s", error=json['error_code'], message=json['description'])))
raise Exception
else:
raise(Exception(gettext("Telegram returned an unspecified error.")))
raise Exception
else:
return "@" + json['result']['username']

Expand Down Expand Up @@ -1403,14 +1403,14 @@ def take_image(self,snapshot_url=""):
if data == None:
return None
if flipH or flipV or rotate:
image = Image.open(StringIO.StringIO(data))
image = Image.open(io.BytesIO(data))
if flipH:
image = image.transpose(Image.FLIP_LEFT_RIGHT)
if flipV:
image = image.transpose(Image.FLIP_TOP_BOTTOM)
if rotate:
image = image.transpose(Image.ROTATE_270)
output = StringIO.StringIO()
output = io.BytesIO()
image.save(output, format="JPEG")
data = output.getvalue()
output.close()
Expand All @@ -1430,7 +1430,7 @@ def calculate_ETA(self,printTime = 0):
else:
return ""
else:
self._logger.debug("will do timedelta on currentData['progress']['printTimeLeft']: " + str(currentData["progress"]["printTimeLeft"]) )
self._logger.debug("will do timedelta on currentData['progress']['printTimeLeft']: " + str(currentData["progress"]["printTimeLeft"]) )
finish_time = current_time + datetime.timedelta(0,currentData["progress"]["printTimeLeft"])
strtime = format_time(finish_time)
strdate = ""
Expand Down Expand Up @@ -1606,7 +1606,7 @@ def create_gif(self,chatID,nbImg = 0): #giloser 05/05/2019
try:
requests.get(self.bot_url + "/sendChatAction", params = {'chat_id': chatID, 'action': 'record_video'})
#self._file_manager.add_file(self.get_plugin_data_folder() + "/tmpgif",'Test_Telegram_%02d.jpg' % i,data,allow_overwrite=True)
image = Image.open(StringIO.StringIO(data))
image = Image.open(io.BytesIO(data))
image.thumbnail((320, 240))
frames.append(image)
#image.save('Gif_Telegram_%02d.jpg' % i, 'JPEG')
Expand Down Expand Up @@ -1670,7 +1670,7 @@ def track_action(self, action):
if not self._settings.get_boolean(["tracking_activated"]):
return
if self._settings.get(["tracking_token"]) is None:
token = "".join(random.choice("abcdef0123456789") for i in xrange(16))
token = "".join(random.choice("abcdef0123456789") for i in range(16))
self._settings.set(["tracking_token"], token)
params = {
'idsite': '3',
Expand Down Expand Up @@ -1765,6 +1765,7 @@ def __init__(self,version):


__plugin_name__ = "Telegram Notifications"
__plugin_pythoncompat__ = ">=3,<4"
__plugin_implementation__ = get_implementation_class()
__plugin_hooks__ = {
"octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information,
Expand Down
Loading