From 53d09c3da7a454422eedff0dfc62c8643fd2bc11 Mon Sep 17 00:00:00 2001 From: Sergei Zobov Date: Thu, 28 May 2020 16:11:44 +0300 Subject: [PATCH 1/7] Applied 2to3 --- octoprint_telegram/__init__.py | 127 +- octoprint_telegram/emojiDict.py | 1694 +++++++++---------- octoprint_telegram/telegramCommands.py | 84 +- octoprint_telegram/telegramNotifications.py | 4 +- 4 files changed, 955 insertions(+), 954 deletions(-) diff --git a/octoprint_telegram/__init__.py b/octoprint_telegram/__init__.py index f45e227..d3be365 100644 --- a/octoprint_telegram/__init__.py +++ b/octoprint_telegram/__init__.py @@ -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 @@ -272,7 +272,7 @@ def handleTextMessage(self, message, chat_id, from_id): #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'])) @@ -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 @@ -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() @@ -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",{}) @@ -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: @@ -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? @@ -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" @@ -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 @@ -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)) @@ -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? @@ -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) @@ -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") @@ -1140,7 +1140,7 @@ 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) ) @@ -1148,7 +1148,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None, 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) @@ -1176,7 +1176,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None, image_data = None r = None - + if image_data: self._logger.debug("Sending with image.. " + str(chatID)) files = {'photo':("image.jpg", image_data)} @@ -1184,7 +1184,7 @@ def _send_msg(self, message="", with_image=False,with_gif=False,responses=None, 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)) @@ -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") @@ -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: @@ -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)) @@ -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.StringIO(r)) img = img.resize((40, 40), PIL.Image.ANTIALIAS) img.save(file_name, format="JPEG") self._logger.debug("Saved Photo "+ str(chat_id)) @@ -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'] @@ -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.StringIO(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.StringIO() image.save(output, format="JPEG") data = output.getvalue() output.close() @@ -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 = "" @@ -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.StringIO(data)) image.thumbnail((320, 240)) frames.append(image) #image.save('Gif_Telegram_%02d.jpg' % i, 'JPEG') @@ -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', @@ -1765,6 +1765,7 @@ def __init__(self,version): __plugin_name__ = "Telegram Notifications" +__plugin_pythoncompat__ = ">=2.7,<4" __plugin_implementation__ = get_implementation_class() __plugin_hooks__ = { "octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information, diff --git a/octoprint_telegram/emojiDict.py b/octoprint_telegram/emojiDict.py index cb5a7ac..12aed83 100644 --- a/octoprint_telegram/emojiDict.py +++ b/octoprint_telegram/emojiDict.py @@ -7,851 +7,851 @@ telegramEmojiDict = { -'clock face ten oclock': u'\U0001f559', -'splashing sweat symbol': u'\U0001f4a6', -'face with open mouth and cold sweat': u'\U0001f630', -'office building': u'\U0001f3e2', -'face screaming in fear': u'\U0001f631', -'face with stuck-out tongue and winking eye': u'\U0001f61c', -'musical keyboard': u'\U0001f3b9', -'heavy check mark': u'\u2714\ufe0f', -'articulated lorry': u'\U0001f69b', -'non-potable water symbol': u'\U0001f6b1', -'smiling face with heart-shaped eyes': u'\U0001f60d', -'milky way': u'\U0001f30c', -'disappointed but relieved face': u'\U0001f625', -'smiling face with horns': u'\U0001f608', -'smiling face with open mouth and tightly-closed eyes': u'\U0001f606', -'regional indicator symbol letter k + regional indicator symbol letter r': u'\U0001f1f0\U0001f1f7', -'melon': u'\U0001f348', -'white small square': u'\u25ab\ufe0f', -'smiling face with open mouth and smiling eyes': u'\U0001f604', -'squared cjk unified ideograph-7121': u'\U0001f21a', -'woman': u'\U0001f469', -'medium white circle': u'\u26aa', -'squared cool': u'\U0001f192', -'no entry': u'\u26d4', -'mountain cableway': u'\U0001f6a0', -'mans shoe': u'\U0001f45e', -'womans sandal': u'\U0001f461', -'construction worker': u'\U0001f477', -'pig nose': u'\U0001f43d', -'ticket': u'\U0001f3ab', -'circled ideograph accept': u'\U0001f251', -'teacup without handle': u'\U0001f375', -'cat face with wry smile': u'\U0001f63c', -'dragon face': u'\U0001f432', -'suspension railway': u'\U0001f69f', -'dolphin': u'\U0001f42c', -'crocodile': u'\U0001f40a', -'medium black circle': u'\u26ab', -'curly loop': u'\u27b0', -'hundred points symbol': u'\U0001f4af', -'womans boots': u'\U0001f462', -'saxophone': u'\U0001f3b7', -'rice cracker': u'\U0001f358', -'ski and ski boot': u'\U0001f3bf', -'information source': u'\u2139\ufe0f', -'white medium square': u'\u25fb\ufe0f', -'lady beetle': u'\U0001f41e', -'triangular ruler': u'\U0001f4d0', -'bicycle': u'\U0001f6b2', -'baby angel': u'\U0001f47c', -'glowing star': u'\U0001f31f', -'crying face': u'\U0001f622', -'cactus': u'\U0001f335', -'spaghetti': u'\U0001f35d', -'fork and knife': u'\U0001f374', -'ribbon': u'\U0001f380', -'hocho': u'\U0001f52a', -'chequered flag': u'\U0001f3c1', -'cooking': u'\U0001f373', -'mobile phone with rightwards arrow at left': u'\U0001f4f2', -'busts in silhouette': u'\U0001f465', -'regional indicator symbol letter c + regional indicator symbol letter n': u'\U0001f1e8\U0001f1f3', -'womans clothes': u'\U0001f45a', -'house with garden': u'\U0001f3e1', -'womans hat': u'\U0001f452', -'waning crescent moon symbol': u'\U0001f318', -'bird': u'\U0001f426', -'squared ok': u'\U0001f197', -'digit seven + combining enclosing keycap': u'7\ufe0f\u20e3', -'copyright sign': u'\xa9\ufe0f', -'herb': u'\U0001f33f', -'monkey face': u'\U0001f435', -'surfer': u'\U0001f3c4', -'baseball': u'\u26be\ufe0f', -'shaved ice': u'\U0001f367', -'page facing up': u'\U0001f4c4', -'arrow pointing rightwards then curving upwards': u'\u2934\ufe0f', -'squared vs': u'\U0001f19a', -'boy': u'\U0001f466', -'bathtub': u'\U0001f6c1', -'metro': u'\U0001f687', -'straight ruler': u'\U0001f4cf', -'last quarter moon symbol': u'\U0001f317', -'person frowning': u'\U0001f64d', -'circled latin capital letter m': u'\u24c2\ufe0f', -'older man': u'\U0001f474', -'sake bottle and cup': u'\U0001f376', -'video game': u'\U0001f3ae', -'upwards black arrow': u'\u2b06\ufe0f', -'white up pointing backhand index': u'\U0001f446', -'angry face': u'\U0001f620', -'fishing pole and fish': u'\U0001f3a3', -'family': u'\U0001f46a', -'twisted rightwards arrows': u'\U0001f500', -'ok hand sign': u'\U0001f44c', -'clock face six oclock': u'\U0001f555', -'baby bottle': u'\U0001f37c', -'anticlockwise downwards and upwards open circle arrows': u'\U0001f504', -'heavy large circle': u'\u2b55', -'digit zero + combining enclosing keycap': u'0\ufe0f\u20e3', -'beating heart': u'\U0001f493', -'cloud': u'\u2601\ufe0f', -'clock face seven oclock': u'\U0001f556', -'japanese dolls': u'\U0001f38e', -'hospital': u'\U0001f3e5', -'fisted hand sign': u'\U0001f44a', -'digit eight + combining enclosing keycap': u'8\ufe0f\u20e3', -'poodle': u'\U0001f429', -'face massage': u'\U0001f486', -'evergreen tree': u'\U0001f332', -'keycap ten': u'\U0001f51f', -'camera': u'\U0001f4f7', -'hot beverage': u'\u2615', -'lock': u'\U0001f512', -'regional indicator symbol letter d + regional indicator symbol letter e': u'\U0001f1e9\U0001f1ea', -'anguished face': u'\U0001f627', -'horse racing': u'\U0001f3c7', -'chestnut': u'\U0001f330', -'pencil': u'\u270f\ufe0f', -'negative squared latin capital letter a': u'\U0001f170\ufe0f', -'guardsman': u'\U0001f482', -'door': u'\U0001f6aa', -'envelope': u'\u2709\ufe0f', -'south east arrow': u'\u2198\ufe0f', -'floppy disk': u'\U0001f4be', -'train': u'\U0001f686', -'rabbit': u'\U0001f407', -'baby': u'\U0001f476', -'pouch': u'\U0001f45d', -'small blue diamond': u'\U0001f539', -'libra': u'\u264e', -'sleeping symbol': u'\U0001f4a4', -'steaming bowl': u'\U0001f35c', -'black heart suit': u'\u2665\ufe0f', -'cross mark': u'\u274c', -'blue book': u'\U0001f4d8', -'satellite antenna': u'\U0001f4e1', -'jack-o-lantern': u'\U0001f383', -'cat': u'\U0001f408', -'cocktail glass': u'\U0001f378', -'heart with ribbon': u'\U0001f49d', -'extraterrestrial alien': u'\U0001f47d', -'wavy dash': u'\u3030\ufe0f', -'clock face eight-thirty': u'\U0001f563', -'pouting cat face': u'\U0001f63e', -'mens symbol': u'\U0001f6b9', -'nail polish': u'\U0001f485', -'hamburger': u'\U0001f354', -'pushpin': u'\U0001f4cc', -'tangerine': u'\U0001f34a', -'telephone receiver': u'\U0001f4de', -'crossed flags': u'\U0001f38c', -'north east arrow': u'\u2197\ufe0f', -'black rightwards arrow': u'\u27a1\ufe0f', -'station': u'\U0001f689', -'airplane': u'\u2708\ufe0f', -'dress': u'\U0001f457', -'sleeping face': u'\U0001f634', -'trident emblem': u'\U0001f531', -'sunrise over mountains': u'\U0001f304', -'scorpius': u'\u264f', -'dog face': u'\U0001f436', -'white down pointing backhand index': u'\U0001f447', -'trumpet': u'\U0001f3ba', -'disappointed face': u'\U0001f61e', -'ledger': u'\U0001f4d2', -'high-speed train with bullet nose': u'\U0001f685', -'tennis racquet and ball': u'\U0001f3be', -'file folder': u'\U0001f4c1', -'cityscape at dusk': u'\U0001f306', -'elephant': u'\U0001f418', -'flushed face': u'\U0001f633', -'no bicycles': u'\U0001f6b3', -'revolving hearts': u'\U0001f49e', -'athletic shoe': u'\U0001f45f', -'grinning cat face with smiling eyes': u'\U0001f638', -'north west arrow': u'\u2196\ufe0f', -'woman with bunny ears': u'\U0001f46f', -'briefcase': u'\U0001f4bc', -'up-pointing red triangle': u'\U0001f53a', -'izakaya lantern': u'\U0001f3ee', -'white flower': u'\U0001f4ae', -'carp streamer': u'\U0001f38f', -'white smiling face': u'\u263a\ufe0f', -'squared cjk unified ideograph-7981': u'\U0001f232', -'purple heart': u'\U0001f49c', -'notebook': u'\U0001f4d3', -'bear face': u'\U0001f43b', -'sparkles': u'\u2728', -'up down arrow': u'\u2195\ufe0f', -'first quarter moon with face': u'\U0001f31b', -'man': u'\U0001f468', -'tomato': u'\U0001f345', -'face with tears of joy': u'\U0001f602', -'registered sign': u'\xae\ufe0f', -'construction sign': u'\U0001f6a7', -'input symbol for latin small letters': u'\U0001f521', -'dragon': u'\U0001f409', -'large red circle': u'\U0001f534', -'tulip': u'\U0001f337', -'squared cjk unified ideograph-6307': u'\U0001f22f', -'wrench': u'\U0001f527', -'sailboat': u'\u26f5', -'clock face five oclock': u'\U0001f554', -'speedboat': u'\U0001f6a4', -'right-pointing magnifying glass': u'\U0001f50e', -'haircut': u'\U0001f487', -'black nib': u'\u2712\ufe0f', -'kissing face': u'\U0001f617', -'input symbol for latin capital letters': u'\U0001f520', -'persevering face': u'\U0001f623', -'digit three + combining enclosing keycap': u'3\ufe0f\u20e3', -'meat on bone': u'\U0001f356', -'speech balloon': u'\U0001f4ac', -'curry and rice': u'\U0001f35b', -'closed mailbox with lowered flag': u'\U0001f4ea', -'input symbol for numbers': u'\U0001f522', -'electric light bulb': u'\U0001f4a1', -'leftwards black arrow': u'\u2b05\ufe0f', -'imp': u'\U0001f47f', -'paperclip': u'\U0001f4ce', -'black question mark ornament': u'\u2753', -'japanese castle': u'\U0001f3ef', -'person raising both hands in celebration': u'\U0001f64c', -'south west arrow': u'\u2199\ufe0f', -'left right arrow': u'\u2194\ufe0f', -'bride with veil': u'\U0001f470', -'automated teller machine': u'\U0001f3e7', -'direct hit': u'\U0001f3af', -'cat face': u'\U0001f431', -'school': u'\U0001f3eb', -'banknote with dollar sign': u'\U0001f4b5', -'roasted sweet potato': u'\U0001f360', -'earth globe europe-africa': u'\U0001f30d', -'snake': u'\U0001f40d', -'kiss': u'\U0001f48f', -'maple leaf': u'\U0001f341', -'do not litter symbol': u'\U0001f6af', -'video camera': u'\U0001f4f9', -'headphone': u'\U0001f3a7', -'bank': u'\U0001f3e6', -'bread': u'\U0001f35e', -'grimacing face': u'\U0001f62c', -'digit five + combining enclosing keycap': u'5\ufe0f\u20e3', -'flag in hole': u'\u26f3', -'raised fist': u'\u270a', -'rice ball': u'\U0001f359', -'kissing cat face with closed eyes': u'\U0001f63d', -'trolleybus': u'\U0001f68e', -'oncoming taxi': u'\U0001f696', -'clock face three oclock': u'\U0001f552', -'alien monster': u'\U0001f47e', -'goat': u'\U0001f410', -'regional indicator symbol letter g + regional indicator symbol letter b': u'\U0001f1ec\U0001f1e7', -'circled ideograph advantage': u'\U0001f250', -'last quarter moon with face': u'\U0001f31c', -'volcano': u'\U0001f30b', -'clapper board': u'\U0001f3ac', -'expressionless face': u'\U0001f611', -'large blue diamond': u'\U0001f537', -'nut and bolt': u'\U0001f529', -'turtle': u'\U0001f422', -'tiger face': u'\U0001f42f', -'fish': u'\U0001f41f', -'pot of food': u'\U0001f372', -'thumbs down sign': u'\U0001f44e', -'clock face two-thirty': u'\U0001f55d', -'smiling face with open mouth': u'\U0001f603', -'books': u'\U0001f4da', -'light rail': u'\U0001f688', -'speaker with cancellation stroke': u'\U0001f507', -'oncoming automobile': u'\U0001f698', -'squared cjk unified ideograph-6708': u'\U0001f237\ufe0f', -'squared cjk unified ideograph-6709': u'\U0001f236', -'girl': u'\U0001f467', -'ice cream': u'\U0001f368', -'white left pointing backhand index': u'\U0001f448', -'lipstick': u'\U0001f484', -'happy person raising one hand': u'\U0001f64b', -'alarm clock': u'\u23f0', -'rightwards arrow with hook': u'\u21aa\ufe0f', -'factory': u'\U0001f3ed', -'money bag': u'\U0001f4b0', -'rabbit face': u'\U0001f430', -'sparkle': u'\u2747\ufe0f', -'fountain': u'\u26f2', -'children crossing': u'\U0001f6b8', -'delivery truck': u'\U0001f69a', -'cyclone': u'\U0001f300', -'thought balloon': u'\U0001f4ad', -'custard': u'\U0001f36e', -'clock face ten-thirty': u'\U0001f565', -'firework sparkler': u'\U0001f387', -'confounded face': u'\U0001f616', -'four leaf clover': u'\U0001f340', -'cookie': u'\U0001f36a', -'grapes': u'\U0001f347', -'heavy plus sign': u'\u2795', -'customs': u'\U0001f6c3', -'smoking symbol': u'\U0001f6ac', -'princess': u'\U0001f478', -'squared sos': u'\U0001f198', -'game die': u'\U0001f3b2', -'clockwise rightwards and leftwards open circle arrows': u'\U0001f501', -'currency exchange': u'\U0001f4b1', -'digit six + combining enclosing keycap': u'6\ufe0f\u20e3', -'face without mouth': u'\U0001f636', -'no pedestrians': u'\U0001f6b7', -'winking face': u'\U0001f609', -'face with ok gesture': u'\U0001f646', -'black spade suit': u'\u2660\ufe0f', -'bookmark': u'\U0001f516', -'mouse face': u'\U0001f42d', -'white medium small square': u'\u25fd', -'down-pointing red triangle': u'\U0001f53b', -'up-pointing small red triangle': u'\U0001f53c', -'paw prints': u'\U0001f43e', -'deciduous tree': u'\U0001f333', -'heavy dollar sign': u'\U0001f4b2', -'speaker with one sound wave': u'\U0001f509', -'ophiuchus': u'\u26ce', -'double curly loop': u'\u27bf', -'bouquet': u'\U0001f490', -'waxing crescent moon symbol': u'\U0001f312', -'downwards black arrow': u'\u2b07\ufe0f', -'clock face seven-thirty': u'\U0001f562', -'flexed biceps': u'\U0001f4aa', -'ring': u'\U0001f48d', -'steam locomotive': u'\U0001f682', -'tram car': u'\U0001f68b', -'sheep': u'\U0001f411', -'horse': u'\U0001f40e', -'monkey': u'\U0001f412', -'optical disc': u'\U0001f4bf', -'blossom': u'\U0001f33c', -'automobile': u'\U0001f697', -'dizzy face': u'\U0001f635', -'regional indicator symbol letter f + regional indicator symbol letter r': u'\U0001f1eb\U0001f1f7', -'closed umbrella': u'\U0001f302', -'fire engine': u'\U0001f692', -'horse face': u'\U0001f434', -'double exclamation mark': u'\u203c\ufe0f', -'squared free': u'\U0001f193', -'banana': u'\U0001f34c', -'banknote with pound sign': u'\U0001f4b7', -'railway car': u'\U0001f683', -'eyes': u'\U0001f440', -'cow face': u'\U0001f42e', -'globe with meridians': u'\U0001f310', -'memo': u'\U0001f4dd', -'hotel': u'\U0001f3e8', -'money with wings': u'\U0001f4b8', -'digit nine + combining enclosing keycap': u'9\ufe0f\u20e3', -'banknote with euro sign': u'\U0001f4b6', -'person bowing deeply': u'\U0001f647', -'weary face': u'\U0001f629', -'heavy division sign': u'\u2797', -'smiling face with open mouth and cold sweat': u'\U0001f605', -'television': u'\U0001f4fa', -'end with leftwards arrow above': u'\U0001f51a', -'collision symbol': u'\U0001f4a5', -'tanabata tree': u'\U0001f38b', -'french fries': u'\U0001f35f', -'black left-pointing triangle': u'\u25c0\ufe0f', -'shower': u'\U0001f6bf', -'put litter in its place symbol': u'\U0001f6ae', -'tired face': u'\U0001f62b', -'movie camera': u'\U0001f3a5', -'pile of poo': u'\U0001f4a9', -'tractor': u'\U0001f69c', -'dash symbol': u'\U0001f4a8', -'honey pot': u'\U0001f36f', -'runner': u'\U0001f3c3', -'ram': u'\U0001f40f', -'clock face four-thirty': u'\U0001f55f', -'ant': u'\U0001f41c', -'pedestrian': u'\U0001f6b6', -'rat': u'\U0001f400', -'pensive face': u'\U0001f614', -'eight spoked asterisk': u'\u2733\ufe0f', -'vertical traffic light': u'\U0001f6a6', -'japanese symbol for beginner': u'\U0001f530', -'electric torch': u'\U0001f526', -'department store': u'\U0001f3ec', -'microphone': u'\U0001f3a4', -'broken heart': u'\U0001f494', -'necktie': u'\U0001f454', -'clock face twelve-thirty': u'\U0001f567', -'hammer': u'\U0001f528', -'orange book': u'\U0001f4d9', -'basketball and hoop': u'\U0001f3c0', -'open lock': u'\U0001f513', -'water wave': u'\U0001f30a', -'monorail': u'\U0001f69d', -'palm tree': u'\U0001f334', -'police cars revolving light': u'\U0001f6a8', -'tokyo tower': u'\U0001f5fc', -'left luggage': u'\U0001f6c5', -'barber pole': u'\U0001f488', -'snowflake': u'\u2744\ufe0f', -'kiss mark': u'\U0001f48b', -'low brightness symbol': u'\U0001f505', -'squared cjk unified ideograph-7533': u'\U0001f238', -'open book': u'\U0001f4d6', -'anger symbol': u'\U0001f4a2', -'chocolate bar': u'\U0001f36b', -'ambulance': u'\U0001f691', -'guitar': u'\U0001f3b8', -'six pointed star with middle dot': u'\U0001f52f', -'eight pointed black star': u'\u2734\ufe0f', -'mouth': u'\U0001f444', -'handbag': u'\U0001f45c', -'white heavy check mark': u'\u2705', -'pager': u'\U0001f4df', -'wheelchair symbol': u'\u267f', -'playing card black joker': u'\U0001f0cf', -'green apple': u'\U0001f34f', -'love hotel': u'\U0001f3e9', -'closed book': u'\U0001f4d5', -'dog': u'\U0001f415', -'face with stuck-out tongue': u'\U0001f61b', -'clock face three-thirty': u'\U0001f55e', -'pineapple': u'\U0001f34d', -'love letter': u'\U0001f48c', -'slot machine': u'\U0001f3b0', -'squared cjk unified ideograph-6e80': u'\U0001f235', -'bomb': u'\U0001f4a3', -'minidisc': u'\U0001f4bd', -'baby chick': u'\U0001f424', -'clock face four oclock': u'\U0001f553', -'radio': u'\U0001f4fb', -'notebook with decorative cover': u'\U0001f4d4', -'panda face': u'\U0001f43c', -'chicken': u'\U0001f414', -'face with stuck-out tongue and tightly-closed eyes': u'\U0001f61d', -'bus stop': u'\U0001f68f', -'couple with heart': u'\U0001f491', -'inbox tray': u'\U0001f4e5', -'fax machine': u'\U0001f4e0', -'police officer': u'\U0001f46e', -'virgo': u'\u264d', -'clipboard': u'\U0001f4cb', -'hear-no-evil monkey': u'\U0001f649', -'gem stone': u'\U0001f48e', -'frowning face with open mouth': u'\U0001f626', -'green book': u'\U0001f4d7', -'waving hand sign': u'\U0001f44b', -'water closet': u'\U0001f6be', -'pouting face': u'\U0001f621', -'sagittarius': u'\u2650', -'envelope with downwards arrow above': u'\U0001f4e9', -'speaker with three sound waves': u'\U0001f50a', -'capricorn': u'\u2651', -'personal computer': u'\U0001f4bb', -'watch': u'\u231a', -'minibus': u'\U0001f690', -'negative squared cross mark': u'\u274e', -'baggage claim': u'\U0001f6c4', -'watermelon': u'\U0001f349', -'wedding': u'\U0001f492', -'bust in silhouette': u'\U0001f464', -'cherry blossom': u'\U0001f338', -'number sign + combining enclosing keycap': u'#\ufe0f\u20e3', -'passport control': u'\U0001f6c2', -'clock face nine-thirty': u'\U0001f564', -'heart with arrow': u'\U0001f498', -'negative squared latin capital letter b': u'\U0001f171\ufe0f', -'hourglass with flowing sand': u'\u23f3', -'squared id': u'\U0001f194', -'microscope': u'\U0001f52c', -'grinning face with smiling eyes': u'\U0001f601', -'father christmas': u'\U0001f385', -'squared new': u'\U0001f195', -'no entry sign': u'\U0001f6ab', -'crying cat face': u'\U0001f63f', -'soft ice cream': u'\U0001f366', -'clock face eleven oclock': u'\U0001f55a', -'digit four + combining enclosing keycap': u'4\ufe0f\u20e3', -'oncoming police car': u'\U0001f694', -'circus tent': u'\U0001f3aa', -'seat': u'\U0001f4ba', -'antenna with bars': u'\U0001f4f6', -'dromedary camel': u'\U0001f42a', -'flower playing cards': u'\U0001f3b4', -'vibration mode': u'\U0001f4f3', -'pisces': u'\u2653', -'calendar': u'\U0001f4c5', -'banknote with yen sign': u'\U0001f4b4', -'two women holding hands': u'\U0001f46d', -'hourglass': u'\u231b', -'hibiscus': u'\U0001f33a', -'bicyclist': u'\U0001f6b4', -'postbox': u'\U0001f4ee', -'tear-off calendar': u'\U0001f4c6', -'lock with ink pen': u'\U0001f50f', -'tropical drink': u'\U0001f379', -'artist palette': u'\U0001f3a8', -'pistol': u'\U0001f52b', -'regional indicator symbol letter i + regional indicator symbol letter t': u'\U0001f1ee\U0001f1f9', -'face with open mouth': u'\U0001f62e', -'tent': u'\u26fa', -'aquarius': u'\u2652', -'squared ng': u'\U0001f196', -'moyai': u'\U0001f5ff', -'dizzy symbol': u'\U0001f4ab', -'no one under eighteen symbol': u'\U0001f51e', -'worried face': u'\U0001f61f', -'loudly crying face': u'\U0001f62d', -'face with cold sweat': u'\U0001f613', -'clock face eleven-thirty': u'\U0001f566', -'key': u'\U0001f511', -'black sun with rays': u'\u2600\ufe0f', -'person with blond hair': u'\U0001f471', -'clock face one oclock': u'\U0001f550', -'confetti ball': u'\U0001f38a', -'see-no-evil monkey': u'\U0001f648', -'man with gua pi mao': u'\U0001f472', -'card index': u'\U0001f4c7', -'two hearts': u'\U0001f495', -'cow': u'\U0001f404', -'sparkling heart': u'\U0001f496', -'ear of maize': u'\U0001f33d', -'red apple': u'\U0001f34e', -'billiards': u'\U0001f3b1', -'restroom': u'\U0001f6bb', -'heavy multiplication x': u'\u2716\ufe0f', -'heavy exclamation mark symbol': u'\u2757', -'new moon symbol': u'\U0001f311', -'public address loudspeaker': u'\U0001f4e2', -'school satchel': u'\U0001f392', -'black medium square': u'\u25fc\ufe0f', -'shortcake': u'\U0001f370', -'night with stars': u'\U0001f303', -'blue heart': u'\U0001f499', -'cooked rice': u'\U0001f35a', -'cancer': u'\u264b', -'bell': u'\U0001f514', -'battery': u'\U0001f50b', -'jeans': u'\U0001f456', -'silhouette of japan': u'\U0001f5fe', -'leo': u'\u264c', -'squared cjk unified ideograph-55b6': u'\U0001f23a', -'neutral face': u'\U0001f610', -'dancer': u'\U0001f483', -'face with look of triumph': u'\U0001f624', -'moon viewing ceremony': u'\U0001f391', -'boar': u'\U0001f417', -'large blue circle': u'\U0001f535', -'sun behind cloud': u'\u26c5', -'bridge at night': u'\U0001f309', -'fallen leaf': u'\U0001f342', -'black diamond suit': u'\u2666\ufe0f', -'swimmer': u'\U0001f3ca', -'chart with upwards trend and yen sign': u'\U0001f4b9', -'white question mark ornament': u'\u2754', -'top hat': u'\U0001f3a9', -'oden': u'\U0001f362', -'helicopter': u'\U0001f681', -'page with curl': u'\U0001f4c3', -'snowman without snow': u'\u26c4', -'hamster face': u'\U0001f439', -'mushroom': u'\U0001f344', -'fire': u'\U0001f525', -'green heart': u'\U0001f49a', -'small orange diamond': u'\U0001f538', -'tiger': u'\U0001f405', -'arrow pointing rightwards then curving downwards': u'\u2935\ufe0f', -'foggy': u'\U0001f301', -'pine decoration': u'\U0001f38d', -'black large square': u'\u2b1b', -'confused face': u'\U0001f615', -'blowfish': u'\U0001f421', -'information desk person': u'\U0001f481', -'seedling': u'\U0001f331', -'squared cjk unified ideograph-5408': u'\U0001f234', -'pill': u'\U0001f48a', -'white square button': u'\U0001f533', -'bikini': u'\U0001f459', -'newspaper': u'\U0001f4f0', -'party popper': u'\U0001f389', -'smiling face with smiling eyes': u'\U0001f60a', -'anchor': u'\u2693', -'musical note': u'\U0001f3b5', -'hushed face': u'\U0001f62f', -'statue of liberty': u'\U0001f5fd', -'squared cjk unified ideograph-7a7a': u'\U0001f233', -'sushi': u'\U0001f363', -'purse': u'\U0001f45b', -'clock face five-thirty': u'\U0001f560', -'european castle': u'\U0001f3f0', -'rooster': u'\U0001f413', -'two men holding hands': u'\U0001f46c', -'black right-pointing triangle': u'\u25b6\ufe0f', -'violin': u'\U0001f3bb', -'rugby football': u'\U0001f3c9', -'mouse': u'\U0001f401', -'ship': u'\U0001f6a2', -'womens symbol': u'\U0001f6ba', -'balloon': u'\U0001f388', -'face with medical mask': u'\U0001f637', -'performing arts': u'\U0001f3ad', -'kimono': u'\U0001f458', -'speaker': u'\U0001f508', -'negative squared latin capital letter o': u'\U0001f17e\ufe0f', -'honeybee': u'\U0001f41d', -'digit two + combining enclosing keycap': u'2\ufe0f\u20e3', -'smiling cat face with heart-shaped eyes': u'\U0001f63b', -'snail': u'\U0001f40c', -'leopard': u'\U0001f406', -'high voltage sign': u'\u26a1', -'credit card': u'\U0001f4b3', -'koala': u'\U0001f428', -'older woman': u'\U0001f475', -'lemon': u'\U0001f34b', -'whale': u'\U0001f40b', -'chart with upwards trend': u'\U0001f4c8', -'smiling face with sunglasses': u'\U0001f60e', -'spiral shell': u'\U0001f41a', -'warning sign': u'\u26a0\ufe0f', -'squared cl': u'\U0001f191', -'running shirt with sash': u'\U0001f3bd', -'squared katakana sa': u'\U0001f202\ufe0f', -'multiple musical notes': u'\U0001f3b6', -'thumbs up sign': u'\U0001f44d', -'bento box': u'\U0001f371', -'poultry leg': u'\U0001f357', -'heavy black heart': u'\u2764\ufe0f', -'taxi': u'\U0001f695', -'smirking face': u'\U0001f60f', -'eyeglasses': u'\U0001f453', -'circled ideograph congratulation': u'\u3297\ufe0f', -'rocket': u'\U0001f680', -'man with turban': u'\U0001f473', -'man and woman holding hands': u'\U0001f46b', -'musical score': u'\U0001f3bc', -'link symbol': u'\U0001f517', -'sleepy face': u'\U0001f62a', -'heavy minus sign': u'\u2796', -'clock face nine oclock': u'\U0001f558', -'roller coaster': u'\U0001f3a2', -'speak-no-evil monkey': u'\U0001f64a', -'no mobile phones': u'\U0001f4f5', -'snowboarder': u'\U0001f3c2', -'sunflower': u'\U0001f33b', -'rose': u'\U0001f339', -'kissing face with closed eyes': u'\U0001f61a', -'incoming envelope': u'\U0001f4e8', -'cherries': u'\U0001f352', -'black down-pointing double triangle': u'\u23ec', -'cheering megaphone': u'\U0001f4e3', -'face throwing a kiss': u'\U0001f618', -'input symbol for symbols': u'\U0001f523', -'leftwards arrow with hook': u'\u21a9\ufe0f', -'high-heeled shoe': u'\U0001f460', -'aerial tramway': u'\U0001f6a1', -'chart with downwards trend': u'\U0001f4c9', -'aubergine': u'\U0001f346', -'round pushpin': u'\U0001f4cd', -'regional indicator symbol letter u + regional indicator symbol letter s': u'\U0001f1fa\U0001f1f8', -'cat face with tears of joy': u'\U0001f639', -'top with upwards arrow above': u'\U0001f51d', -'first quarter moon symbol': u'\U0001f313', -'victory hand': u'\u270c\ufe0f', -'baby symbol': u'\U0001f6bc', -'doughnut': u'\U0001f369', -'clock face six-thirty': u'\U0001f561', -'black left-pointing double triangle': u'\u23ea', -'left-pointing magnifying glass': u'\U0001f50d', -'heart decoration': u'\U0001f49f', -'soccer ball': u'\u26bd', -'raised hand': u'\u270b', -'candy': u'\U0001f36c', -'front-facing baby chick': u'\U0001f425', -'e-mail symbol': u'\U0001f4e7', -'tram': u'\U0001f68a', -'white up pointing index': u'\u261d\ufe0f', -'new moon with face': u'\U0001f31a', -'nose': u'\U0001f443', -'japanese goblin': u'\U0001f47a', -'smiling face with halo': u'\U0001f607', -'birthday cake': u'\U0001f382', -'closed lock with key': u'\U0001f510', -'trade mark sign': u'\u2122\ufe0f', -'on with exclamation mark with left right arrow above': u'\U0001f51b', -'slice of pizza': u'\U0001f355', -'church': u'\u26ea', -'crown': u'\U0001f451', -'spouting whale': u'\U0001f433', -'police car': u'\U0001f693', -'convenience store': u'\U0001f3ea', -'high brightness symbol': u'\U0001f506', -'growing heart': u'\U0001f497', -'mahjong tile red dragon': u'\U0001f004', -'sun with face': u'\U0001f31e', -'black telephone': u'\u260e\ufe0f', -'diamond shape with a dot inside': u'\U0001f4a0', -'european post office': u'\U0001f3e4', -'open mailbox with lowered flag': u'\U0001f4ed', -'high-speed train': u'\U0001f684', -'electric plug': u'\U0001f50c', -'hot springs': u'\u2668\ufe0f', -'radio button': u'\U0001f518', -'black universal recycling symbol': u'\u267b\ufe0f', -'carousel horse': u'\U0001f3a0', -'aries': u'\u2648', -'relieved face': u'\U0001f60c', -'leaf fluttering in wind': u'\U0001f343', -'bowling': u'\U0001f3b3', -'soon with rightwards arrow above': u'\U0001f51c', -'oncoming bus': u'\U0001f68d', -'full moon with face': u'\U0001f31d', -'full moon symbol': u'\U0001f315', -'black square button': u'\U0001f532', -'input symbol for latin letters': u'\U0001f524', -'house building': u'\U0001f3e0', -'weary cat face': u'\U0001f640', -'trophy': u'\U0001f3c6', -'tropical fish': u'\U0001f420', -'wrapped present': u'\U0001f381', -'white right pointing backhand index': u'\U0001f449', -'package': u'\U0001f4e6', -'potable water symbol': u'\U0001f6b0', -'mobile phone off': u'\U0001f4f4', -'negative squared ab': u'\U0001f18e', -'ox': u'\U0001f402', -'tongue': u'\U0001f445', -'open mailbox with raised flag': u'\U0001f4ec', -'octopus': u'\U0001f419', -'clinking beer mugs': u'\U0001f37b', -'ferris wheel': u'\U0001f3a1', -'black right-pointing double triangle': u'\u23e9', -'part alternation mark': u'\u303d\ufe0f', -'crystal ball': u'\U0001f52e', -'lollipop': u'\U0001f36d', -'black up-pointing double triangle': u'\u23eb', -'back with leftwards arrow above': u'\U0001f519', -'white exclamation mark ornament': u'\u2755', -'clock face eight oclock': u'\U0001f557', -'clockwise downwards and upwards open circle arrows': u'\U0001f503', -'sunset over buildings': u'\U0001f307', -'bath': u'\U0001f6c0', -'no smoking symbol': u'\U0001f6ad', -'dango': u'\U0001f361', -'mountain railway': u'\U0001f69e', -'mobile phone': u'\U0001f4f1', -'syringe': u'\U0001f489', -'earth globe americas': u'\U0001f30e', -'postal horn': u'\U0001f4ef', -'exclamation question mark': u'\u2049\ufe0f', -'kissing face with smiling eyes': u'\U0001f619', -'telescope': u'\U0001f52d', -'rowboat': u'\U0001f6a3', -'graduation cap': u'\U0001f393', -'fish cake with swirl design': u'\U0001f365', -'down-pointing small red triangle': u'\U0001f53d', -'astonished face': u'\U0001f632', -'name badge': u'\U0001f4db', -'horizontal traffic light': u'\U0001f6a5', -'digit one + combining enclosing keycap': u'1\ufe0f\u20e3', -'recreational vehicle': u'\U0001f699', -'earth globe asia-australia': u'\U0001f30f', -'squared cjk unified ideograph-5272': u'\U0001f239', -'frog face': u'\U0001f438', -'bell with cancellation stroke': u'\U0001f515', -'crescent moon': u'\U0001f319', -'regional indicator symbol letter j + regional indicator symbol letter p': u'\U0001f1ef\U0001f1f5', -'closed mailbox with raised flag': u'\U0001f4eb', -'bus': u'\U0001f68c', -'fireworks': u'\U0001f386', -'t-shirt': u'\U0001f455', -'ear of rice': u'\U0001f33e', -'white large square': u'\u2b1c', -'person with folded hands': u'\U0001f64f', -'wind chime': u'\U0001f390', -'ear': u'\U0001f442', -'bug': u'\U0001f41b', -'penguin': u'\U0001f427', -'shooting star': u'\U0001f320', -'skull': u'\U0001f480', -'black medium small square': u'\u25fe', -'large orange diamond': u'\U0001f536', -'face savouring delicious food': u'\U0001f60b', -'strawberry': u'\U0001f353', -'christmas tree': u'\U0001f384', -'clock face two oclock': u'\U0001f551', -'wine glass': u'\U0001f377', -'fried shrimp': u'\U0001f364', -'circled ideograph secret': u'\u3299\ufe0f', -'grinning face': u'\U0001f600', -'toilet': u'\U0001f6bd', -'outbox tray': u'\U0001f4e4', -'waning gibbous moon symbol': u'\U0001f316', -'cinema': u'\U0001f3a6', -'ballot box with check': u'\u2611\ufe0f', -'black small square': u'\u25aa\ufe0f', -'waxing gibbous moon symbol': u'\U0001f314', -'clockwise rightwards and leftwards open circle arrows with circled one overlay': u'\U0001f502', -'pig': u'\U0001f416', -'umbrella with rain drops': u'\u2614', -'open hands sign': u'\U0001f450', -'gemini': u'\u264a', -'person with pouting face': u'\U0001f64e', -'regional indicator symbol letter e + regional indicator symbol letter s': u'\U0001f1ea\U0001f1f8', -'black club suit': u'\u2663\ufe0f', -'black scissors': u'\u2702\ufe0f', -'squared katakana koko': u'\U0001f201', -'bar chart': u'\U0001f4ca', -'bactrian camel': u'\U0001f42b', -'clock face one-thirty': u'\U0001f55c', -'rainbow': u'\U0001f308', -'fuel pump': u'\u26fd', -'clapping hands sign': u'\U0001f44f', -'peach': u'\U0001f351', -'hatching chick': u'\U0001f423', -'yellow heart': u'\U0001f49b', -'unamused face': u'\U0001f612', -'beer mug': u'\U0001f37a', -'sunrise': u'\U0001f305', -'clock face twelve oclock': u'\U0001f55b', -'bookmark tabs': u'\U0001f4d1', -'mountain bicyclist': u'\U0001f6b5', -'fearful face': u'\U0001f628', -'face with no good gesture': u'\U0001f645', -'footprints': u'\U0001f463', -'pear': u'\U0001f350', -'taurus': u'\u2649', -'wolf face': u'\U0001f43a', -'triangular flag on post': u'\U0001f6a9', -'squared up with exclamation mark': u'\U0001f199', -'pig face': u'\U0001f437', -'american football': u'\U0001f3c8', -'white medium star': u'\u2b50', -'mount fuji': u'\U0001f5fb', -'ghost': u'\U0001f47b', -'droplet': u'\U0001f4a7', -'japanese ogre': u'\U0001f479', -'open file folder': u'\U0001f4c2', -'japanese post office': u'\U0001f3e3', -'dvd': u'\U0001f4c0', -'scroll': u'\U0001f4dc', -'negative squared latin capital letter p': u'\U0001f17f\ufe0f', -'videocassette': u'\U0001f4fc', -'regional indicator symbol letter r + regional indicator symbol letter u': u'\U0001f1f7\U0001f1fa', -'water buffalo': u'\U0001f403', -'smiling cat face with open mouth': u'\U0001f63a', -'shutdown' : u'\U0001F4A4', -'film frame' : u'\U0001F39E', +'clock face ten oclock': '\U0001f559', +'splashing sweat symbol': '\U0001f4a6', +'face with open mouth and cold sweat': '\U0001f630', +'office building': '\U0001f3e2', +'face screaming in fear': '\U0001f631', +'face with stuck-out tongue and winking eye': '\U0001f61c', +'musical keyboard': '\U0001f3b9', +'heavy check mark': '\u2714\ufe0f', +'articulated lorry': '\U0001f69b', +'non-potable water symbol': '\U0001f6b1', +'smiling face with heart-shaped eyes': '\U0001f60d', +'milky way': '\U0001f30c', +'disappointed but relieved face': '\U0001f625', +'smiling face with horns': '\U0001f608', +'smiling face with open mouth and tightly-closed eyes': '\U0001f606', +'regional indicator symbol letter k + regional indicator symbol letter r': '\U0001f1f0\U0001f1f7', +'melon': '\U0001f348', +'white small square': '\u25ab\ufe0f', +'smiling face with open mouth and smiling eyes': '\U0001f604', +'squared cjk unified ideograph-7121': '\U0001f21a', +'woman': '\U0001f469', +'medium white circle': '\u26aa', +'squared cool': '\U0001f192', +'no entry': '\u26d4', +'mountain cableway': '\U0001f6a0', +'mans shoe': '\U0001f45e', +'womans sandal': '\U0001f461', +'construction worker': '\U0001f477', +'pig nose': '\U0001f43d', +'ticket': '\U0001f3ab', +'circled ideograph accept': '\U0001f251', +'teacup without handle': '\U0001f375', +'cat face with wry smile': '\U0001f63c', +'dragon face': '\U0001f432', +'suspension railway': '\U0001f69f', +'dolphin': '\U0001f42c', +'crocodile': '\U0001f40a', +'medium black circle': '\u26ab', +'curly loop': '\u27b0', +'hundred points symbol': '\U0001f4af', +'womans boots': '\U0001f462', +'saxophone': '\U0001f3b7', +'rice cracker': '\U0001f358', +'ski and ski boot': '\U0001f3bf', +'information source': '\u2139\ufe0f', +'white medium square': '\u25fb\ufe0f', +'lady beetle': '\U0001f41e', +'triangular ruler': '\U0001f4d0', +'bicycle': '\U0001f6b2', +'baby angel': '\U0001f47c', +'glowing star': '\U0001f31f', +'crying face': '\U0001f622', +'cactus': '\U0001f335', +'spaghetti': '\U0001f35d', +'fork and knife': '\U0001f374', +'ribbon': '\U0001f380', +'hocho': '\U0001f52a', +'chequered flag': '\U0001f3c1', +'cooking': '\U0001f373', +'mobile phone with rightwards arrow at left': '\U0001f4f2', +'busts in silhouette': '\U0001f465', +'regional indicator symbol letter c + regional indicator symbol letter n': '\U0001f1e8\U0001f1f3', +'womans clothes': '\U0001f45a', +'house with garden': '\U0001f3e1', +'womans hat': '\U0001f452', +'waning crescent moon symbol': '\U0001f318', +'bird': '\U0001f426', +'squared ok': '\U0001f197', +'digit seven + combining enclosing keycap': '7\ufe0f\u20e3', +'copyright sign': '\xa9\ufe0f', +'herb': '\U0001f33f', +'monkey face': '\U0001f435', +'surfer': '\U0001f3c4', +'baseball': '\u26be\ufe0f', +'shaved ice': '\U0001f367', +'page facing up': '\U0001f4c4', +'arrow pointing rightwards then curving upwards': '\u2934\ufe0f', +'squared vs': '\U0001f19a', +'boy': '\U0001f466', +'bathtub': '\U0001f6c1', +'metro': '\U0001f687', +'straight ruler': '\U0001f4cf', +'last quarter moon symbol': '\U0001f317', +'person frowning': '\U0001f64d', +'circled latin capital letter m': '\u24c2\ufe0f', +'older man': '\U0001f474', +'sake bottle and cup': '\U0001f376', +'video game': '\U0001f3ae', +'upwards black arrow': '\u2b06\ufe0f', +'white up pointing backhand index': '\U0001f446', +'angry face': '\U0001f620', +'fishing pole and fish': '\U0001f3a3', +'family': '\U0001f46a', +'twisted rightwards arrows': '\U0001f500', +'ok hand sign': '\U0001f44c', +'clock face six oclock': '\U0001f555', +'baby bottle': '\U0001f37c', +'anticlockwise downwards and upwards open circle arrows': '\U0001f504', +'heavy large circle': '\u2b55', +'digit zero + combining enclosing keycap': '0\ufe0f\u20e3', +'beating heart': '\U0001f493', +'cloud': '\u2601\ufe0f', +'clock face seven oclock': '\U0001f556', +'japanese dolls': '\U0001f38e', +'hospital': '\U0001f3e5', +'fisted hand sign': '\U0001f44a', +'digit eight + combining enclosing keycap': '8\ufe0f\u20e3', +'poodle': '\U0001f429', +'face massage': '\U0001f486', +'evergreen tree': '\U0001f332', +'keycap ten': '\U0001f51f', +'camera': '\U0001f4f7', +'hot beverage': '\u2615', +'lock': '\U0001f512', +'regional indicator symbol letter d + regional indicator symbol letter e': '\U0001f1e9\U0001f1ea', +'anguished face': '\U0001f627', +'horse racing': '\U0001f3c7', +'chestnut': '\U0001f330', +'pencil': '\u270f\ufe0f', +'negative squared latin capital letter a': '\U0001f170\ufe0f', +'guardsman': '\U0001f482', +'door': '\U0001f6aa', +'envelope': '\u2709\ufe0f', +'south east arrow': '\u2198\ufe0f', +'floppy disk': '\U0001f4be', +'train': '\U0001f686', +'rabbit': '\U0001f407', +'baby': '\U0001f476', +'pouch': '\U0001f45d', +'small blue diamond': '\U0001f539', +'libra': '\u264e', +'sleeping symbol': '\U0001f4a4', +'steaming bowl': '\U0001f35c', +'black heart suit': '\u2665\ufe0f', +'cross mark': '\u274c', +'blue book': '\U0001f4d8', +'satellite antenna': '\U0001f4e1', +'jack-o-lantern': '\U0001f383', +'cat': '\U0001f408', +'cocktail glass': '\U0001f378', +'heart with ribbon': '\U0001f49d', +'extraterrestrial alien': '\U0001f47d', +'wavy dash': '\u3030\ufe0f', +'clock face eight-thirty': '\U0001f563', +'pouting cat face': '\U0001f63e', +'mens symbol': '\U0001f6b9', +'nail polish': '\U0001f485', +'hamburger': '\U0001f354', +'pushpin': '\U0001f4cc', +'tangerine': '\U0001f34a', +'telephone receiver': '\U0001f4de', +'crossed flags': '\U0001f38c', +'north east arrow': '\u2197\ufe0f', +'black rightwards arrow': '\u27a1\ufe0f', +'station': '\U0001f689', +'airplane': '\u2708\ufe0f', +'dress': '\U0001f457', +'sleeping face': '\U0001f634', +'trident emblem': '\U0001f531', +'sunrise over mountains': '\U0001f304', +'scorpius': '\u264f', +'dog face': '\U0001f436', +'white down pointing backhand index': '\U0001f447', +'trumpet': '\U0001f3ba', +'disappointed face': '\U0001f61e', +'ledger': '\U0001f4d2', +'high-speed train with bullet nose': '\U0001f685', +'tennis racquet and ball': '\U0001f3be', +'file folder': '\U0001f4c1', +'cityscape at dusk': '\U0001f306', +'elephant': '\U0001f418', +'flushed face': '\U0001f633', +'no bicycles': '\U0001f6b3', +'revolving hearts': '\U0001f49e', +'athletic shoe': '\U0001f45f', +'grinning cat face with smiling eyes': '\U0001f638', +'north west arrow': '\u2196\ufe0f', +'woman with bunny ears': '\U0001f46f', +'briefcase': '\U0001f4bc', +'up-pointing red triangle': '\U0001f53a', +'izakaya lantern': '\U0001f3ee', +'white flower': '\U0001f4ae', +'carp streamer': '\U0001f38f', +'white smiling face': '\u263a\ufe0f', +'squared cjk unified ideograph-7981': '\U0001f232', +'purple heart': '\U0001f49c', +'notebook': '\U0001f4d3', +'bear face': '\U0001f43b', +'sparkles': '\u2728', +'up down arrow': '\u2195\ufe0f', +'first quarter moon with face': '\U0001f31b', +'man': '\U0001f468', +'tomato': '\U0001f345', +'face with tears of joy': '\U0001f602', +'registered sign': '\xae\ufe0f', +'construction sign': '\U0001f6a7', +'input symbol for latin small letters': '\U0001f521', +'dragon': '\U0001f409', +'large red circle': '\U0001f534', +'tulip': '\U0001f337', +'squared cjk unified ideograph-6307': '\U0001f22f', +'wrench': '\U0001f527', +'sailboat': '\u26f5', +'clock face five oclock': '\U0001f554', +'speedboat': '\U0001f6a4', +'right-pointing magnifying glass': '\U0001f50e', +'haircut': '\U0001f487', +'black nib': '\u2712\ufe0f', +'kissing face': '\U0001f617', +'input symbol for latin capital letters': '\U0001f520', +'persevering face': '\U0001f623', +'digit three + combining enclosing keycap': '3\ufe0f\u20e3', +'meat on bone': '\U0001f356', +'speech balloon': '\U0001f4ac', +'curry and rice': '\U0001f35b', +'closed mailbox with lowered flag': '\U0001f4ea', +'input symbol for numbers': '\U0001f522', +'electric light bulb': '\U0001f4a1', +'leftwards black arrow': '\u2b05\ufe0f', +'imp': '\U0001f47f', +'paperclip': '\U0001f4ce', +'black question mark ornament': '\u2753', +'japanese castle': '\U0001f3ef', +'person raising both hands in celebration': '\U0001f64c', +'south west arrow': '\u2199\ufe0f', +'left right arrow': '\u2194\ufe0f', +'bride with veil': '\U0001f470', +'automated teller machine': '\U0001f3e7', +'direct hit': '\U0001f3af', +'cat face': '\U0001f431', +'school': '\U0001f3eb', +'banknote with dollar sign': '\U0001f4b5', +'roasted sweet potato': '\U0001f360', +'earth globe europe-africa': '\U0001f30d', +'snake': '\U0001f40d', +'kiss': '\U0001f48f', +'maple leaf': '\U0001f341', +'do not litter symbol': '\U0001f6af', +'video camera': '\U0001f4f9', +'headphone': '\U0001f3a7', +'bank': '\U0001f3e6', +'bread': '\U0001f35e', +'grimacing face': '\U0001f62c', +'digit five + combining enclosing keycap': '5\ufe0f\u20e3', +'flag in hole': '\u26f3', +'raised fist': '\u270a', +'rice ball': '\U0001f359', +'kissing cat face with closed eyes': '\U0001f63d', +'trolleybus': '\U0001f68e', +'oncoming taxi': '\U0001f696', +'clock face three oclock': '\U0001f552', +'alien monster': '\U0001f47e', +'goat': '\U0001f410', +'regional indicator symbol letter g + regional indicator symbol letter b': '\U0001f1ec\U0001f1e7', +'circled ideograph advantage': '\U0001f250', +'last quarter moon with face': '\U0001f31c', +'volcano': '\U0001f30b', +'clapper board': '\U0001f3ac', +'expressionless face': '\U0001f611', +'large blue diamond': '\U0001f537', +'nut and bolt': '\U0001f529', +'turtle': '\U0001f422', +'tiger face': '\U0001f42f', +'fish': '\U0001f41f', +'pot of food': '\U0001f372', +'thumbs down sign': '\U0001f44e', +'clock face two-thirty': '\U0001f55d', +'smiling face with open mouth': '\U0001f603', +'books': '\U0001f4da', +'light rail': '\U0001f688', +'speaker with cancellation stroke': '\U0001f507', +'oncoming automobile': '\U0001f698', +'squared cjk unified ideograph-6708': '\U0001f237\ufe0f', +'squared cjk unified ideograph-6709': '\U0001f236', +'girl': '\U0001f467', +'ice cream': '\U0001f368', +'white left pointing backhand index': '\U0001f448', +'lipstick': '\U0001f484', +'happy person raising one hand': '\U0001f64b', +'alarm clock': '\u23f0', +'rightwards arrow with hook': '\u21aa\ufe0f', +'factory': '\U0001f3ed', +'money bag': '\U0001f4b0', +'rabbit face': '\U0001f430', +'sparkle': '\u2747\ufe0f', +'fountain': '\u26f2', +'children crossing': '\U0001f6b8', +'delivery truck': '\U0001f69a', +'cyclone': '\U0001f300', +'thought balloon': '\U0001f4ad', +'custard': '\U0001f36e', +'clock face ten-thirty': '\U0001f565', +'firework sparkler': '\U0001f387', +'confounded face': '\U0001f616', +'four leaf clover': '\U0001f340', +'cookie': '\U0001f36a', +'grapes': '\U0001f347', +'heavy plus sign': '\u2795', +'customs': '\U0001f6c3', +'smoking symbol': '\U0001f6ac', +'princess': '\U0001f478', +'squared sos': '\U0001f198', +'game die': '\U0001f3b2', +'clockwise rightwards and leftwards open circle arrows': '\U0001f501', +'currency exchange': '\U0001f4b1', +'digit six + combining enclosing keycap': '6\ufe0f\u20e3', +'face without mouth': '\U0001f636', +'no pedestrians': '\U0001f6b7', +'winking face': '\U0001f609', +'face with ok gesture': '\U0001f646', +'black spade suit': '\u2660\ufe0f', +'bookmark': '\U0001f516', +'mouse face': '\U0001f42d', +'white medium small square': '\u25fd', +'down-pointing red triangle': '\U0001f53b', +'up-pointing small red triangle': '\U0001f53c', +'paw prints': '\U0001f43e', +'deciduous tree': '\U0001f333', +'heavy dollar sign': '\U0001f4b2', +'speaker with one sound wave': '\U0001f509', +'ophiuchus': '\u26ce', +'double curly loop': '\u27bf', +'bouquet': '\U0001f490', +'waxing crescent moon symbol': '\U0001f312', +'downwards black arrow': '\u2b07\ufe0f', +'clock face seven-thirty': '\U0001f562', +'flexed biceps': '\U0001f4aa', +'ring': '\U0001f48d', +'steam locomotive': '\U0001f682', +'tram car': '\U0001f68b', +'sheep': '\U0001f411', +'horse': '\U0001f40e', +'monkey': '\U0001f412', +'optical disc': '\U0001f4bf', +'blossom': '\U0001f33c', +'automobile': '\U0001f697', +'dizzy face': '\U0001f635', +'regional indicator symbol letter f + regional indicator symbol letter r': '\U0001f1eb\U0001f1f7', +'closed umbrella': '\U0001f302', +'fire engine': '\U0001f692', +'horse face': '\U0001f434', +'double exclamation mark': '\u203c\ufe0f', +'squared free': '\U0001f193', +'banana': '\U0001f34c', +'banknote with pound sign': '\U0001f4b7', +'railway car': '\U0001f683', +'eyes': '\U0001f440', +'cow face': '\U0001f42e', +'globe with meridians': '\U0001f310', +'memo': '\U0001f4dd', +'hotel': '\U0001f3e8', +'money with wings': '\U0001f4b8', +'digit nine + combining enclosing keycap': '9\ufe0f\u20e3', +'banknote with euro sign': '\U0001f4b6', +'person bowing deeply': '\U0001f647', +'weary face': '\U0001f629', +'heavy division sign': '\u2797', +'smiling face with open mouth and cold sweat': '\U0001f605', +'television': '\U0001f4fa', +'end with leftwards arrow above': '\U0001f51a', +'collision symbol': '\U0001f4a5', +'tanabata tree': '\U0001f38b', +'french fries': '\U0001f35f', +'black left-pointing triangle': '\u25c0\ufe0f', +'shower': '\U0001f6bf', +'put litter in its place symbol': '\U0001f6ae', +'tired face': '\U0001f62b', +'movie camera': '\U0001f3a5', +'pile of poo': '\U0001f4a9', +'tractor': '\U0001f69c', +'dash symbol': '\U0001f4a8', +'honey pot': '\U0001f36f', +'runner': '\U0001f3c3', +'ram': '\U0001f40f', +'clock face four-thirty': '\U0001f55f', +'ant': '\U0001f41c', +'pedestrian': '\U0001f6b6', +'rat': '\U0001f400', +'pensive face': '\U0001f614', +'eight spoked asterisk': '\u2733\ufe0f', +'vertical traffic light': '\U0001f6a6', +'japanese symbol for beginner': '\U0001f530', +'electric torch': '\U0001f526', +'department store': '\U0001f3ec', +'microphone': '\U0001f3a4', +'broken heart': '\U0001f494', +'necktie': '\U0001f454', +'clock face twelve-thirty': '\U0001f567', +'hammer': '\U0001f528', +'orange book': '\U0001f4d9', +'basketball and hoop': '\U0001f3c0', +'open lock': '\U0001f513', +'water wave': '\U0001f30a', +'monorail': '\U0001f69d', +'palm tree': '\U0001f334', +'police cars revolving light': '\U0001f6a8', +'tokyo tower': '\U0001f5fc', +'left luggage': '\U0001f6c5', +'barber pole': '\U0001f488', +'snowflake': '\u2744\ufe0f', +'kiss mark': '\U0001f48b', +'low brightness symbol': '\U0001f505', +'squared cjk unified ideograph-7533': '\U0001f238', +'open book': '\U0001f4d6', +'anger symbol': '\U0001f4a2', +'chocolate bar': '\U0001f36b', +'ambulance': '\U0001f691', +'guitar': '\U0001f3b8', +'six pointed star with middle dot': '\U0001f52f', +'eight pointed black star': '\u2734\ufe0f', +'mouth': '\U0001f444', +'handbag': '\U0001f45c', +'white heavy check mark': '\u2705', +'pager': '\U0001f4df', +'wheelchair symbol': '\u267f', +'playing card black joker': '\U0001f0cf', +'green apple': '\U0001f34f', +'love hotel': '\U0001f3e9', +'closed book': '\U0001f4d5', +'dog': '\U0001f415', +'face with stuck-out tongue': '\U0001f61b', +'clock face three-thirty': '\U0001f55e', +'pineapple': '\U0001f34d', +'love letter': '\U0001f48c', +'slot machine': '\U0001f3b0', +'squared cjk unified ideograph-6e80': '\U0001f235', +'bomb': '\U0001f4a3', +'minidisc': '\U0001f4bd', +'baby chick': '\U0001f424', +'clock face four oclock': '\U0001f553', +'radio': '\U0001f4fb', +'notebook with decorative cover': '\U0001f4d4', +'panda face': '\U0001f43c', +'chicken': '\U0001f414', +'face with stuck-out tongue and tightly-closed eyes': '\U0001f61d', +'bus stop': '\U0001f68f', +'couple with heart': '\U0001f491', +'inbox tray': '\U0001f4e5', +'fax machine': '\U0001f4e0', +'police officer': '\U0001f46e', +'virgo': '\u264d', +'clipboard': '\U0001f4cb', +'hear-no-evil monkey': '\U0001f649', +'gem stone': '\U0001f48e', +'frowning face with open mouth': '\U0001f626', +'green book': '\U0001f4d7', +'waving hand sign': '\U0001f44b', +'water closet': '\U0001f6be', +'pouting face': '\U0001f621', +'sagittarius': '\u2650', +'envelope with downwards arrow above': '\U0001f4e9', +'speaker with three sound waves': '\U0001f50a', +'capricorn': '\u2651', +'personal computer': '\U0001f4bb', +'watch': '\u231a', +'minibus': '\U0001f690', +'negative squared cross mark': '\u274e', +'baggage claim': '\U0001f6c4', +'watermelon': '\U0001f349', +'wedding': '\U0001f492', +'bust in silhouette': '\U0001f464', +'cherry blossom': '\U0001f338', +'number sign + combining enclosing keycap': '#\ufe0f\u20e3', +'passport control': '\U0001f6c2', +'clock face nine-thirty': '\U0001f564', +'heart with arrow': '\U0001f498', +'negative squared latin capital letter b': '\U0001f171\ufe0f', +'hourglass with flowing sand': '\u23f3', +'squared id': '\U0001f194', +'microscope': '\U0001f52c', +'grinning face with smiling eyes': '\U0001f601', +'father christmas': '\U0001f385', +'squared new': '\U0001f195', +'no entry sign': '\U0001f6ab', +'crying cat face': '\U0001f63f', +'soft ice cream': '\U0001f366', +'clock face eleven oclock': '\U0001f55a', +'digit four + combining enclosing keycap': '4\ufe0f\u20e3', +'oncoming police car': '\U0001f694', +'circus tent': '\U0001f3aa', +'seat': '\U0001f4ba', +'antenna with bars': '\U0001f4f6', +'dromedary camel': '\U0001f42a', +'flower playing cards': '\U0001f3b4', +'vibration mode': '\U0001f4f3', +'pisces': '\u2653', +'calendar': '\U0001f4c5', +'banknote with yen sign': '\U0001f4b4', +'two women holding hands': '\U0001f46d', +'hourglass': '\u231b', +'hibiscus': '\U0001f33a', +'bicyclist': '\U0001f6b4', +'postbox': '\U0001f4ee', +'tear-off calendar': '\U0001f4c6', +'lock with ink pen': '\U0001f50f', +'tropical drink': '\U0001f379', +'artist palette': '\U0001f3a8', +'pistol': '\U0001f52b', +'regional indicator symbol letter i + regional indicator symbol letter t': '\U0001f1ee\U0001f1f9', +'face with open mouth': '\U0001f62e', +'tent': '\u26fa', +'aquarius': '\u2652', +'squared ng': '\U0001f196', +'moyai': '\U0001f5ff', +'dizzy symbol': '\U0001f4ab', +'no one under eighteen symbol': '\U0001f51e', +'worried face': '\U0001f61f', +'loudly crying face': '\U0001f62d', +'face with cold sweat': '\U0001f613', +'clock face eleven-thirty': '\U0001f566', +'key': '\U0001f511', +'black sun with rays': '\u2600\ufe0f', +'person with blond hair': '\U0001f471', +'clock face one oclock': '\U0001f550', +'confetti ball': '\U0001f38a', +'see-no-evil monkey': '\U0001f648', +'man with gua pi mao': '\U0001f472', +'card index': '\U0001f4c7', +'two hearts': '\U0001f495', +'cow': '\U0001f404', +'sparkling heart': '\U0001f496', +'ear of maize': '\U0001f33d', +'red apple': '\U0001f34e', +'billiards': '\U0001f3b1', +'restroom': '\U0001f6bb', +'heavy multiplication x': '\u2716\ufe0f', +'heavy exclamation mark symbol': '\u2757', +'new moon symbol': '\U0001f311', +'public address loudspeaker': '\U0001f4e2', +'school satchel': '\U0001f392', +'black medium square': '\u25fc\ufe0f', +'shortcake': '\U0001f370', +'night with stars': '\U0001f303', +'blue heart': '\U0001f499', +'cooked rice': '\U0001f35a', +'cancer': '\u264b', +'bell': '\U0001f514', +'battery': '\U0001f50b', +'jeans': '\U0001f456', +'silhouette of japan': '\U0001f5fe', +'leo': '\u264c', +'squared cjk unified ideograph-55b6': '\U0001f23a', +'neutral face': '\U0001f610', +'dancer': '\U0001f483', +'face with look of triumph': '\U0001f624', +'moon viewing ceremony': '\U0001f391', +'boar': '\U0001f417', +'large blue circle': '\U0001f535', +'sun behind cloud': '\u26c5', +'bridge at night': '\U0001f309', +'fallen leaf': '\U0001f342', +'black diamond suit': '\u2666\ufe0f', +'swimmer': '\U0001f3ca', +'chart with upwards trend and yen sign': '\U0001f4b9', +'white question mark ornament': '\u2754', +'top hat': '\U0001f3a9', +'oden': '\U0001f362', +'helicopter': '\U0001f681', +'page with curl': '\U0001f4c3', +'snowman without snow': '\u26c4', +'hamster face': '\U0001f439', +'mushroom': '\U0001f344', +'fire': '\U0001f525', +'green heart': '\U0001f49a', +'small orange diamond': '\U0001f538', +'tiger': '\U0001f405', +'arrow pointing rightwards then curving downwards': '\u2935\ufe0f', +'foggy': '\U0001f301', +'pine decoration': '\U0001f38d', +'black large square': '\u2b1b', +'confused face': '\U0001f615', +'blowfish': '\U0001f421', +'information desk person': '\U0001f481', +'seedling': '\U0001f331', +'squared cjk unified ideograph-5408': '\U0001f234', +'pill': '\U0001f48a', +'white square button': '\U0001f533', +'bikini': '\U0001f459', +'newspaper': '\U0001f4f0', +'party popper': '\U0001f389', +'smiling face with smiling eyes': '\U0001f60a', +'anchor': '\u2693', +'musical note': '\U0001f3b5', +'hushed face': '\U0001f62f', +'statue of liberty': '\U0001f5fd', +'squared cjk unified ideograph-7a7a': '\U0001f233', +'sushi': '\U0001f363', +'purse': '\U0001f45b', +'clock face five-thirty': '\U0001f560', +'european castle': '\U0001f3f0', +'rooster': '\U0001f413', +'two men holding hands': '\U0001f46c', +'black right-pointing triangle': '\u25b6\ufe0f', +'violin': '\U0001f3bb', +'rugby football': '\U0001f3c9', +'mouse': '\U0001f401', +'ship': '\U0001f6a2', +'womens symbol': '\U0001f6ba', +'balloon': '\U0001f388', +'face with medical mask': '\U0001f637', +'performing arts': '\U0001f3ad', +'kimono': '\U0001f458', +'speaker': '\U0001f508', +'negative squared latin capital letter o': '\U0001f17e\ufe0f', +'honeybee': '\U0001f41d', +'digit two + combining enclosing keycap': '2\ufe0f\u20e3', +'smiling cat face with heart-shaped eyes': '\U0001f63b', +'snail': '\U0001f40c', +'leopard': '\U0001f406', +'high voltage sign': '\u26a1', +'credit card': '\U0001f4b3', +'koala': '\U0001f428', +'older woman': '\U0001f475', +'lemon': '\U0001f34b', +'whale': '\U0001f40b', +'chart with upwards trend': '\U0001f4c8', +'smiling face with sunglasses': '\U0001f60e', +'spiral shell': '\U0001f41a', +'warning sign': '\u26a0\ufe0f', +'squared cl': '\U0001f191', +'running shirt with sash': '\U0001f3bd', +'squared katakana sa': '\U0001f202\ufe0f', +'multiple musical notes': '\U0001f3b6', +'thumbs up sign': '\U0001f44d', +'bento box': '\U0001f371', +'poultry leg': '\U0001f357', +'heavy black heart': '\u2764\ufe0f', +'taxi': '\U0001f695', +'smirking face': '\U0001f60f', +'eyeglasses': '\U0001f453', +'circled ideograph congratulation': '\u3297\ufe0f', +'rocket': '\U0001f680', +'man with turban': '\U0001f473', +'man and woman holding hands': '\U0001f46b', +'musical score': '\U0001f3bc', +'link symbol': '\U0001f517', +'sleepy face': '\U0001f62a', +'heavy minus sign': '\u2796', +'clock face nine oclock': '\U0001f558', +'roller coaster': '\U0001f3a2', +'speak-no-evil monkey': '\U0001f64a', +'no mobile phones': '\U0001f4f5', +'snowboarder': '\U0001f3c2', +'sunflower': '\U0001f33b', +'rose': '\U0001f339', +'kissing face with closed eyes': '\U0001f61a', +'incoming envelope': '\U0001f4e8', +'cherries': '\U0001f352', +'black down-pointing double triangle': '\u23ec', +'cheering megaphone': '\U0001f4e3', +'face throwing a kiss': '\U0001f618', +'input symbol for symbols': '\U0001f523', +'leftwards arrow with hook': '\u21a9\ufe0f', +'high-heeled shoe': '\U0001f460', +'aerial tramway': '\U0001f6a1', +'chart with downwards trend': '\U0001f4c9', +'aubergine': '\U0001f346', +'round pushpin': '\U0001f4cd', +'regional indicator symbol letter u + regional indicator symbol letter s': '\U0001f1fa\U0001f1f8', +'cat face with tears of joy': '\U0001f639', +'top with upwards arrow above': '\U0001f51d', +'first quarter moon symbol': '\U0001f313', +'victory hand': '\u270c\ufe0f', +'baby symbol': '\U0001f6bc', +'doughnut': '\U0001f369', +'clock face six-thirty': '\U0001f561', +'black left-pointing double triangle': '\u23ea', +'left-pointing magnifying glass': '\U0001f50d', +'heart decoration': '\U0001f49f', +'soccer ball': '\u26bd', +'raised hand': '\u270b', +'candy': '\U0001f36c', +'front-facing baby chick': '\U0001f425', +'e-mail symbol': '\U0001f4e7', +'tram': '\U0001f68a', +'white up pointing index': '\u261d\ufe0f', +'new moon with face': '\U0001f31a', +'nose': '\U0001f443', +'japanese goblin': '\U0001f47a', +'smiling face with halo': '\U0001f607', +'birthday cake': '\U0001f382', +'closed lock with key': '\U0001f510', +'trade mark sign': '\u2122\ufe0f', +'on with exclamation mark with left right arrow above': '\U0001f51b', +'slice of pizza': '\U0001f355', +'church': '\u26ea', +'crown': '\U0001f451', +'spouting whale': '\U0001f433', +'police car': '\U0001f693', +'convenience store': '\U0001f3ea', +'high brightness symbol': '\U0001f506', +'growing heart': '\U0001f497', +'mahjong tile red dragon': '\U0001f004', +'sun with face': '\U0001f31e', +'black telephone': '\u260e\ufe0f', +'diamond shape with a dot inside': '\U0001f4a0', +'european post office': '\U0001f3e4', +'open mailbox with lowered flag': '\U0001f4ed', +'high-speed train': '\U0001f684', +'electric plug': '\U0001f50c', +'hot springs': '\u2668\ufe0f', +'radio button': '\U0001f518', +'black universal recycling symbol': '\u267b\ufe0f', +'carousel horse': '\U0001f3a0', +'aries': '\u2648', +'relieved face': '\U0001f60c', +'leaf fluttering in wind': '\U0001f343', +'bowling': '\U0001f3b3', +'soon with rightwards arrow above': '\U0001f51c', +'oncoming bus': '\U0001f68d', +'full moon with face': '\U0001f31d', +'full moon symbol': '\U0001f315', +'black square button': '\U0001f532', +'input symbol for latin letters': '\U0001f524', +'house building': '\U0001f3e0', +'weary cat face': '\U0001f640', +'trophy': '\U0001f3c6', +'tropical fish': '\U0001f420', +'wrapped present': '\U0001f381', +'white right pointing backhand index': '\U0001f449', +'package': '\U0001f4e6', +'potable water symbol': '\U0001f6b0', +'mobile phone off': '\U0001f4f4', +'negative squared ab': '\U0001f18e', +'ox': '\U0001f402', +'tongue': '\U0001f445', +'open mailbox with raised flag': '\U0001f4ec', +'octopus': '\U0001f419', +'clinking beer mugs': '\U0001f37b', +'ferris wheel': '\U0001f3a1', +'black right-pointing double triangle': '\u23e9', +'part alternation mark': '\u303d\ufe0f', +'crystal ball': '\U0001f52e', +'lollipop': '\U0001f36d', +'black up-pointing double triangle': '\u23eb', +'back with leftwards arrow above': '\U0001f519', +'white exclamation mark ornament': '\u2755', +'clock face eight oclock': '\U0001f557', +'clockwise downwards and upwards open circle arrows': '\U0001f503', +'sunset over buildings': '\U0001f307', +'bath': '\U0001f6c0', +'no smoking symbol': '\U0001f6ad', +'dango': '\U0001f361', +'mountain railway': '\U0001f69e', +'mobile phone': '\U0001f4f1', +'syringe': '\U0001f489', +'earth globe americas': '\U0001f30e', +'postal horn': '\U0001f4ef', +'exclamation question mark': '\u2049\ufe0f', +'kissing face with smiling eyes': '\U0001f619', +'telescope': '\U0001f52d', +'rowboat': '\U0001f6a3', +'graduation cap': '\U0001f393', +'fish cake with swirl design': '\U0001f365', +'down-pointing small red triangle': '\U0001f53d', +'astonished face': '\U0001f632', +'name badge': '\U0001f4db', +'horizontal traffic light': '\U0001f6a5', +'digit one + combining enclosing keycap': '1\ufe0f\u20e3', +'recreational vehicle': '\U0001f699', +'earth globe asia-australia': '\U0001f30f', +'squared cjk unified ideograph-5272': '\U0001f239', +'frog face': '\U0001f438', +'bell with cancellation stroke': '\U0001f515', +'crescent moon': '\U0001f319', +'regional indicator symbol letter j + regional indicator symbol letter p': '\U0001f1ef\U0001f1f5', +'closed mailbox with raised flag': '\U0001f4eb', +'bus': '\U0001f68c', +'fireworks': '\U0001f386', +'t-shirt': '\U0001f455', +'ear of rice': '\U0001f33e', +'white large square': '\u2b1c', +'person with folded hands': '\U0001f64f', +'wind chime': '\U0001f390', +'ear': '\U0001f442', +'bug': '\U0001f41b', +'penguin': '\U0001f427', +'shooting star': '\U0001f320', +'skull': '\U0001f480', +'black medium small square': '\u25fe', +'large orange diamond': '\U0001f536', +'face savouring delicious food': '\U0001f60b', +'strawberry': '\U0001f353', +'christmas tree': '\U0001f384', +'clock face two oclock': '\U0001f551', +'wine glass': '\U0001f377', +'fried shrimp': '\U0001f364', +'circled ideograph secret': '\u3299\ufe0f', +'grinning face': '\U0001f600', +'toilet': '\U0001f6bd', +'outbox tray': '\U0001f4e4', +'waning gibbous moon symbol': '\U0001f316', +'cinema': '\U0001f3a6', +'ballot box with check': '\u2611\ufe0f', +'black small square': '\u25aa\ufe0f', +'waxing gibbous moon symbol': '\U0001f314', +'clockwise rightwards and leftwards open circle arrows with circled one overlay': '\U0001f502', +'pig': '\U0001f416', +'umbrella with rain drops': '\u2614', +'open hands sign': '\U0001f450', +'gemini': '\u264a', +'person with pouting face': '\U0001f64e', +'regional indicator symbol letter e + regional indicator symbol letter s': '\U0001f1ea\U0001f1f8', +'black club suit': '\u2663\ufe0f', +'black scissors': '\u2702\ufe0f', +'squared katakana koko': '\U0001f201', +'bar chart': '\U0001f4ca', +'bactrian camel': '\U0001f42b', +'clock face one-thirty': '\U0001f55c', +'rainbow': '\U0001f308', +'fuel pump': '\u26fd', +'clapping hands sign': '\U0001f44f', +'peach': '\U0001f351', +'hatching chick': '\U0001f423', +'yellow heart': '\U0001f49b', +'unamused face': '\U0001f612', +'beer mug': '\U0001f37a', +'sunrise': '\U0001f305', +'clock face twelve oclock': '\U0001f55b', +'bookmark tabs': '\U0001f4d1', +'mountain bicyclist': '\U0001f6b5', +'fearful face': '\U0001f628', +'face with no good gesture': '\U0001f645', +'footprints': '\U0001f463', +'pear': '\U0001f350', +'taurus': '\u2649', +'wolf face': '\U0001f43a', +'triangular flag on post': '\U0001f6a9', +'squared up with exclamation mark': '\U0001f199', +'pig face': '\U0001f437', +'american football': '\U0001f3c8', +'white medium star': '\u2b50', +'mount fuji': '\U0001f5fb', +'ghost': '\U0001f47b', +'droplet': '\U0001f4a7', +'japanese ogre': '\U0001f479', +'open file folder': '\U0001f4c2', +'japanese post office': '\U0001f3e3', +'dvd': '\U0001f4c0', +'scroll': '\U0001f4dc', +'negative squared latin capital letter p': '\U0001f17f\ufe0f', +'videocassette': '\U0001f4fc', +'regional indicator symbol letter r + regional indicator symbol letter u': '\U0001f1f7\U0001f1fa', +'water buffalo': '\U0001f403', +'smiling cat face with open mouth': '\U0001f63a', +'shutdown' : '\U0001F4A4', +'film frame' : '\U0001F39E', } \ No newline at end of file diff --git a/octoprint_telegram/telegramCommands.py b/octoprint_telegram/telegramCommands.py index 6d9a004..77d919a 100644 --- a/octoprint_telegram/telegramCommands.py +++ b/octoprint_telegram/telegramCommands.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import + import logging, sarge, hashlib, datetime, time, operator, socket import octoprint.filemanager import requests @@ -333,10 +333,10 @@ def cmdFiles(self,chat_id,from_id,cmd,parameter): self.fileOption(pathHash,page,cmd,fileHash,opt,chat_id,from_id) else: storages = self.main._file_manager.list_files(recursive=False) - if len(storages.keys()) < 2: + if len(list(storages.keys())) < 2: self.main.send_msg("Loading files...",chatID=chat_id) self.generate_dir_hash_dict() - self.cmdFiles(chat_id,from_id,cmd,self.hashMe(str(storages.keys()[0]+"/"),8)+"|0") + self.cmdFiles(chat_id,from_id,cmd,self.hashMe(str(list(storages.keys())[0]+"/"),8)+"|0") else: self.generate_dir_hash_dict() keys=[] @@ -344,7 +344,7 @@ def cmdFiles(self,chat_id,from_id,cmd,parameter): keys.append([[self.main.emojis['cross mark']+" Close","No"]]) msg_id=self.main.getUpdateMsgId(chat_id) if parameter == "back" else "" self.main.send_msg(self.gEmo('save') + " *Select Storage*",chatID=chat_id,markup="Markdown",responses=keys,msg_id=msg_id) - except Exception, e: + except Exception as e: self._logger.warn("Command failed: %s" % e) self.main.send_msg(self.gEmo('warning') + " Command failed with exception: %s!" % e,chatID = chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) ############################################################################################ @@ -375,7 +375,7 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): self.main.send_msg(self.gEmo('warning') + " Command failed with return code %i: %s" % (returncode, stderr_text),chatID=chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) return self.main.send_msg(self.gEmo('check') + " System Command executed." ,chatID=chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) - except Exception, e: + except Exception as e: self._logger.warn("Command failed: %s" % e) self.main.send_msg(self.gEmo('warning') + " Command failed with exception: %s!" % e,chatID = chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) return @@ -387,7 +387,7 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): command = next((d for d in actions if 'action' in d and self.hashMe(d['action']) == parameter) , False) if command : if 'confirm' in command and params[0] != "do": - self.main.send_msg(self.gEmo('question') + unicode(command['name'])+"\nExecute system command?",responses=[[[self.main.emojis['check'] + gettext(" Execute"),"/sys_do_" + unicode(parameter)], [self.main.emojis['leftwards arrow with hook'] + gettext(" Back"),"/sys_back"]]],chatID=chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) + self.main.send_msg(self.gEmo('question') + str(command['name'])+"\nExecute system command?",responses=[[[self.main.emojis['check'] + gettext(" Execute"),"/sys_do_" + str(parameter)], [self.main.emojis['leftwards arrow with hook'] + gettext(" Back"),"/sys_back"]]],chatID=chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) return else: async = command["async"] if "async" in command else False @@ -405,7 +405,7 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): self.main.send_msg(self.gEmo('warning') + " Command failed with return code %i: %s" % (returncode, stderr_text),chatID=chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) return self.main.send_msg(self.gEmo('check') + " System Command " + command["name"] + " executed." ,chatID=chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) - except Exception, e: + except Exception as e: self._logger.warn("Command failed: %s" % e) self.main.send_msg(self.gEmo('warning') + " Command failed with exception: %s!" % e,chatID = chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) else: @@ -417,7 +417,7 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): i = 1 for action in self.main._settings.global_get(['system','actions']): if action['action'] != "divider": - tmpKeys.append([unicode(action['name']),"/sys_"+self.hashMe(action['action'])]) + tmpKeys.append([str(action['name']),"/sys_"+self.hashMe(action['action'])]) if i%2 == 0: keys.append(tmpKeys) tmpKeys = [] @@ -471,7 +471,7 @@ def cmdCtrl(self,chat_id,from_id,cmd,parameter): command = next((d for d in actions if d['hash'] == parameter), False) if command: if 'confirm' in command and params[0] != "do": - self.main.send_msg(self.gEmo('question') + unicode(command['name']) + "\nExecute control command?",responses=[[[self.main.emojis['check']+gettext("Execute"),"/ctrl_do_" + unicode(parameter)], [self.main.emojis['leftwards arrow with hook']+gettext(" Back"),"/ctrl_back"]]],chatID=chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) + self.main.send_msg(self.gEmo('question') + str(command['name']) + "\nExecute control command?",responses=[[[self.main.emojis['check']+gettext("Execute"),"/ctrl_do_" + str(parameter)], [self.main.emojis['leftwards arrow with hook']+gettext(" Back"),"/ctrl_back"]]],chatID=chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) return else: if 'script' in command: @@ -497,17 +497,17 @@ def cmdCtrl(self,chat_id,from_id,cmd,parameter): for action in self.get_controls_recursively(): empty=False try: - tmpKeys.append([unicode(action['name']),"/ctrl_" + str(action['hash'])]) + tmpKeys.append([str(action['name']),"/ctrl_" + str(action['hash'])]) if i%2 == 0: keys.append(tmpKeys) tmpKeys = [] i += 1 - except Exception, ex: + except Exception as ex: self._logger.info("An Exception in get action: " + str(ex) ) if len(tmpKeys) > 0: keys.append(tmpKeys) keys.append([[self.main.emojis['cross mark']+gettext(" Close"),"No"]]) - except Exception, ex: + except Exception as ex: self._logger.info("An Exception in get list action: " + str(ex) ) if empty: message += "\n\n"+self.gEmo('warning')+" No Printer Control Command found..." msg_id=self.main.getUpdateMsgId(chat_id) if parameter == "back" else "" @@ -651,7 +651,7 @@ def cmdTune(self,chat_id,from_id,cmd,parameter): return if self.tempTemp[toolNo] < 0: self.tempTemp[toolNo] = 0 - msg = self.gEmo('fire') + gettext(" Set temperature for tool "+params[1]+".\nCurrent: %(temp).02f/*%(time)d"+u'\u00b0'+"C*",temp=temps["tool"+params[1]]['actual'],time=self.tempTemp[toolNo]) + msg = self.gEmo('fire') + gettext(" Set temperature for tool "+params[1]+".\nCurrent: %(temp).02f/*%(time)d"+'\u00b0'+"C*",temp=temps["tool"+params[1]]['actual'],time=self.tempTemp[toolNo]) keys = [ [["+100","/tune_e_"+params[1]+"_+"],["+50","/tune_e_"+params[1]+"_+*"],["+10","/tune_e_"+params[1]+"_++"],["+5","/tune_e_"+params[1]+"_++*"],["+1","/tune_e_"+params[1]+"_+++"]], [["-100","/tune_e_"+params[1]+"_-"],["-50","/tune_e_"+params[1]+"_-*"],["-10","/tune_e_"+params[1]+"_--"],["-5","/tune_e_"+params[1]+"_--*"],["-1","/tune_e_"+params[1]+"_---"]], @@ -682,7 +682,7 @@ def cmdTune(self,chat_id,from_id,cmd,parameter): self.tempTemp[toolNo] = 0 self._logger.debug("BED TEMPS: "+str(temps)) self._logger.debug("BED self.TEMPS: "+str(self.tempTemp)) - msg = self.gEmo('hot springs') + gettext(" Set temperature for bed.\nCurrent: %(temp).02f/*%(time)d"+u'\u00b0'+"C*",temp=temps["bed"]['actual'],time=self.tempTemp[toolNo]) + msg = self.gEmo('hot springs') + gettext(" Set temperature for bed.\nCurrent: %(temp).02f/*%(time)d"+'\u00b0'+"C*",temp=temps["bed"]['actual'],time=self.tempTemp[toolNo]) keys = [ [["+100","/tune_b_+"],["+50","/tune_b_+*"],["+10","/tune_b_++"],["+5","/tune_b_++*"],["+1","/tune_b_+++"]], [["-100","/tune_b_-"],["-50","/tune_b_-*"],["-10","/tune_b_--"],["-5","/tune_b_--*"],["-1","/tune_b_---"]], @@ -698,7 +698,7 @@ def cmdTune(self,chat_id,from_id,cmd,parameter): keys = [[[self.main.emojis['black right-pointing double triangle']+gettext(" Feedrate"),"/tune_feed"], [self.main.emojis['black down-pointing double triangle']+gettext(" Flowrate"),"/tune_flow"]]] if self.main._printer.is_operational(): tmpKeys=[] - for i in xrange(0,profile["extruder"]["count"]): + for i in range(0,profile["extruder"]["count"]): tmpKeys.append([self.main.emojis['wrench']+" Tool "+str(i),"/tune_e_"+str(i)]) self.tempTemp.append(int(temps["tool"+str(i)]['target'])) if profile["heatedBed"]: @@ -728,10 +728,10 @@ def cmdFilament(self,chat_id,from_id,cmd,parameter): weight = spool["weight"] used = spool["used"] percent = int(100 - (used / weight * 100)) - message += unicode(spool["profile"]["vendor"]) + " " + unicode(spool["name"]) + " " + unicode(spool["profile"]["material"]) + " [" + str(percent) + "%]\n" + message += str(spool["profile"]["vendor"]) + " " + str(spool["name"]) + " " + str(spool["profile"]["material"]) + " [" + str(percent) + "%]\n" for selection in resp2["selections"]: if selection["tool"] == 0: - message += "\n\nCurrently selected: " + unicode(selection["spool"]["profile"]["vendor"]) + " " + unicode(selection["spool"]["name"]) + " " + unicode(selection["spool"]["profile"]["material"]) + message += "\n\nCurrently selected: " + str(selection["spool"]["profile"]["vendor"]) + " " + str(selection["spool"]["name"]) + " " + str(selection["spool"]["profile"]["material"]) msg_id=self.main.getUpdateMsgId(chat_id) self.main.send_msg(message,chatID=chat_id,msg_id = msg_id,inline=False) except ValueError: @@ -752,7 +752,7 @@ def cmdFilament(self,chat_id,from_id,cmd,parameter): errorText = resp.text self._logger.info("Response: %s" % resp) resp = resp.json() - message = self.gEmo('check') + " Selected spool is now: " + unicode(resp["selection"]["spool"]["profile"]["vendor"]) + " " + unicode(resp["selection"]["spool"]["name"]) + " " + unicode(resp["selection"]["spool"]["profile"]["material"]) + message = self.gEmo('check') + " Selected spool is now: " + str(resp["selection"]["spool"]["profile"]["vendor"]) + " " + str(resp["selection"]["spool"]["name"]) + " " + str(resp["selection"]["spool"]["profile"]["material"]) msg_id=self.main.getUpdateMsgId(chat_id) self.main.send_msg(message,chatID=chat_id,msg_id = msg_id,inline=False) except ValueError: @@ -774,7 +774,7 @@ def cmdFilament(self,chat_id,from_id,cmd,parameter): i = 1 for spool in resp["spools"]: self._logger.info("Appending spool: %s" % spool) - tmpKeys.append([unicode(spool["profile"]["vendor"]) + " " + unicode(spool['name']) + " " + unicode(spool["profile"]["material"]) ,"/filament_changeSpool_" + unicode(spool['id'])]) + tmpKeys.append([str(spool["profile"]["vendor"]) + " " + str(spool['name']) + " " + str(spool["profile"]["material"]) ,"/filament_changeSpool_" + str(spool['id'])]) if i%2 == 0: keys.append(tmpKeys) tmpKeys = [] @@ -827,7 +827,7 @@ def cmdHelp(self,chat_id,from_id,cmd,parameter): def fileList(self,pathHash,page,cmd,chat_id,wait = 0): try: fullPath = self.dirHashDict[pathHash] - storageKeys = self.main._file_manager.list_files(recursive=False).keys() + storageKeys = list(self.main._file_manager.list_files(recursive=False).keys()) dest = fullPath.split("/")[0] pathWoDest = "/".join(fullPath.split("/")[1:]) if len(fullPath.split("/")) > 1 else fullPath path = "/".join(fullPath.split("/")[1:]) @@ -837,24 +837,24 @@ def fileList(self,pathHash,page,cmd,chat_id,wait = 0): arrayD = [] self._logger.debug("fileList before loop folder " ) if self.main.version >= 1.3: - M = {k:v for k,v in files.iteritems() if v['type'] == "folder"} + M = {k:v for k,v in files.items() if v['type'] == "folder"} for key in M: arrayD.append([self.main.emojis['open file folder']+" "+key,cmd+"_"+pathHash+"|0|"+self.hashMe(fullPath+key+"/",8)+"|dir"]) array = [] self._logger.debug("fileList before loop files items") - L = {k:v for k,v in files.iteritems() if v['type']=="machinecode"} - for key,val in sorted(L.iteritems(), key=lambda x: x[1]['date'] , reverse=True): + L = {k:v for k,v in files.items() if v['type']=="machinecode"} + for key,val in sorted(iter(L.items()), key=lambda x: x[1]['date'] , reverse=True): try: self._logger.debug("should get info on item " ) vfilename = self.main.emojis['page facing up']+" "+('.').join(key.split('.')[:-1]) - self._logger.debug("vfilename : " + unicode(vfilename) ) + self._logger.debug("vfilename : " + str(vfilename) ) vhash = self.hashMe(pathWoDest + key) self._logger.debug("vhash : " + str(vhash) ) if vhash != "": vcmd = cmd+"_" + pathHash + "|"+str(page)+"|"+ vhash self._logger.debug("cmd : " + str(cmd) ) array.append([vfilename,vcmd]) - except Exception, ex: + except Exception as ex: self._logger.error("An Exception in fileList loop file items : " + str(ex) ) self._logger.error("files[key]" + str(files[key])) arrayD = sorted(arrayD) @@ -892,7 +892,7 @@ def fileList(self,pathHash,page,cmd,chat_id,wait = 0): pageStr = str(page+1)+"/"+str(len(files)/10 + (1 if len(files)%10 > 0 else 0)) self._logger.debug("fileList before send msg " ) self.main.send_msg(self.gEmo('save') + " Files in */"+pathWoDest[:-1]+"* \["+pageStr+"]",chatID=chat_id,markup="Markdown",responses=keys,msg_id = self.main.getUpdateMsgId(chat_id),delay=wait) - except Exception, ex: + except Exception as ex: self._logger.error("An Exception in fileList : " + str(ex) ) ############################################################################################ def fileDetails(self,pathHash,page,cmd,fileHash,chat_id,from_id,wait=0): @@ -903,7 +903,7 @@ def fileDetails(self,pathHash,page,cmd,fileHash,chat_id,from_id,wait=0): msg += ""+self.main.emojis['name badge']+"Name: " + path try: msg += "\n"+self.main.emojis['clock face twelve oclock']+"Uploaded: " + datetime.datetime.fromtimestamp(file['date']).strftime('%Y-%m-%d %H:%M:%S') - except Exception, ex: + except Exception as ex: self._logger.info("An Exception in get upload time : " + str(ex) ) msg += "\n"+self.main.emojis['flexed biceps']+"Size: " + self.formatSize(file['size']) filaLen = 0 @@ -927,7 +927,7 @@ def fileDetails(self,pathHash,page,cmd,fileHash,chat_id,from_id,wait=0): try: time_finish = self.main.calculate_ETA(printTime) msg += "\n"+self.main.emojis['chequered flag']+"Completed Time: "+ time_finish - except Exception, ex: + except Exception as ex: self._logger.info("An Exception in get final time : " + str(ex) ) if self.main._plugin_manager.get_plugin("cost"): if printTime != 0 and filaLen != 0: @@ -938,10 +938,10 @@ def fileDetails(self,pathHash,page,cmd,fileHash,chat_id,from_id,wait=0): try: curr = curr.decode("utf-8") msg += "\n"+self.main.emojis['money bag']+"Cost: "+curr+"%.02f " % ((filaLen/1000) * cpM + (printTime/3600) * cpH) - except Exception, ex: + except Exception as ex: self._logger.error("An Exception the cost function in decode : " + str(ex) ) msg += "\n"+self.main.emojis['money bag']+"Cost: -" - except Exception, ex: + except Exception as ex: self._logger.error("An Exception the cost function on get: " + str(ex) ) msg += "\n"+self.main.emojis['money bag']+"Cost: -" else: @@ -1004,7 +1004,7 @@ def fileOption(self,loc,page,cmd,hash,opt,chat_id,from_id): try: time_finish = self.main.calculate_ETA(printTime) msg += "\n"+self.main.emojis['chequered flag']+"Completed Time: "+ time_finish - except Exception, ex: + except Exception as ex: self._logger.error("An Exception in get final time : " + str(ex) ) if self.main._plugin_manager.get_plugin("cost"): if printTime != 0 and filaLen != 0: @@ -1015,11 +1015,11 @@ def fileOption(self,loc,page,cmd,hash,opt,chat_id,from_id): try: curr = curr.decode("utf-8") msg += "\n"+self.main.emojis['money bag']+"Cost: "+curr+"%.02f " % ((filaLen/1000) * cpM + (printTime/3600) * cpH) - except Exception, ex: + except Exception as ex: self._logger.error("An Exception the cost function in decode : " + str(ex) ) msg += "\n"+self.main.emojis['money bag']+"Cost: -" self._logger.debug("AF TRY") - except Exception, ex: + except Exception as ex: self._logger.error("An Exception the cost function on get: " + str(ex) ) msg += "\n"+self.main.emojis['money bag']+"Cost: -" else: @@ -1076,7 +1076,7 @@ def fileOption(self,loc,page,cmd,hash,opt,chat_id,from_id): else: keys = [[[self.main.emojis['leftwards arrow with hook']+" Back",cmd+"_" + loc + "|"+str(page)+"|"+ hash]]] self.tmpFileHash = hash - for key,val in sorted(self.dirHashDict.items(), key = operator.itemgetter(1)): + for key,val in sorted(list(self.dirHashDict.items()), key = operator.itemgetter(1)): keys.append([[self.main.emojis['open file folder']+" "+self.dirHashDict[key],cmd+"_" + loc + "|"+str(page)+"|"+ key + "|m_m"]]) self.main.send_msg(self.gEmo('question') + " *Choose destination to move file*",chatID=chat_id,responses=keys,msg_id=msg_id,markup="Markdown") @@ -1095,7 +1095,7 @@ def fileOption(self,loc,page,cmd,hash,opt,chat_id,from_id): else: keys = [[[self.main.emojis['leftwards arrow with hook']+" Back",cmd+"_" + loc + "|"+str(page)+"|"+ hash]]] self.tmpFileHash = hash - for key,val in sorted(self.dirHashDict.items(), key = operator.itemgetter(1)): + for key,val in sorted(list(self.dirHashDict.items()), key = operator.itemgetter(1)): keys.append([[self.main.emojis['open file folder']+" "+self.dirHashDict[key],cmd+"_" + loc + "|"+str(page)+"|"+ key + "|c_c"]]) self.main.send_msg(self.gEmo('question') + " *Choose destination to copy file*",chatID=chat_id,responses=keys,msg_id=msg_id,markup="Markdown") @@ -1204,7 +1204,7 @@ def generate_dir_hash_dict(self): self.dirHashDict.update({str(self.hashMe(key+"/",8)):key+"/"}) self.dirHashDict.update(self.generate_dir_hash_dict_recursively(tree[key],key+"/")) self._logger.debug(str(self.dirHashDict)) - except Exception, ex: + except Exception as ex: self._logger.error("An Exception in generate_dir_hash_dict : " + str(ex) ) ############################################################################################ def generate_dir_hash_dict_recursively(self,tree,loc): @@ -1214,7 +1214,7 @@ def generate_dir_hash_dict_recursively(self,tree,loc): if tree[key]['type']=="folder": myDict.update({self.hashMe(loc+key+"/",8):loc+key+"/"}) self.dirHashDict.update(self.generate_dir_hash_dict_recursively(tree[key]['children'],loc+key+"/")) - except Exception, ex: + except Exception as ex: self._logger.error("An Exception in generate_dir_hash_dict_recursively : " + str(ex) ) return myDict ############################################################################################ @@ -1225,7 +1225,7 @@ def find_file_by_hash(self, hash): result,file = self.find_file_by_hash_recursively(tree[key], hash) if result is not None: return key, result, file - except Exception, ex: + except Exception as ex: self._logger.error("An Exception in find_file_by_hash : " + str(ex) ) return None, None, None ############################################################################################ @@ -1249,7 +1249,7 @@ def get_controls_recursively(self, tree = None, base = "", first = ""): for key in tree: try: if type(key) is type({}): - keyName = unicode(key['name']) if 'name' in key else "" + keyName = str(key['name']) if 'name' in key else "" if base == "": first = " "+keyName if 'children' in key: @@ -1267,14 +1267,14 @@ def get_controls_recursively(self, tree = None, base = "", first = ""): if 'confirm' in key: newKey['confirm'] = key['confirm'] array.append(newKey) - except Exception, ex: + except Exception as ex: self._logger.error("An Exception in get key from tree : " + str(ex) ) return array ############################################################################################ def hashMe(self, text, length = 32): try: return hashlib.md5(text.encode()).hexdigest()[0:length] - except Exception, ex: + except Exception as ex: self._logger.error("An Exception in hashMe : " + str(ex) ) return "" ############################################################################################ @@ -1425,7 +1425,7 @@ def formatSize(self,bytes): if not bytes: return "-" units = ["bytes", "KB", "MB", "GB"] - for i in xrange(0, len(units)): + for i in range(0, len(units)): if bytes < 1024: return "%3.1f %s" % (bytes, units[i]) bytes = float(bytes) / 1024 diff --git a/octoprint_telegram/telegramNotifications.py b/octoprint_telegram/telegramNotifications.py index bf07301..7834011 100644 --- a/octoprint_telegram/telegramNotifications.py +++ b/octoprint_telegram/telegramNotifications.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import + import time, datetime, logging import octoprint.util from flask_babel import gettext @@ -210,7 +210,7 @@ def _sendNotification(self, payload, **kwargs): time_left = octoprint.util.get_formatted_timedelta(datetime.timedelta(seconds=(status['progress']['printTimeLeft'] or 0))) try: time_finish = self.main.calculate_ETA(time_left) - except Exception, ex: + except Exception as ex: time_finish = str(ex) self._logger.error("Exception on formatting message: " +str(ex)) file = status['job']['file']['name'] From 1e1c8e07ff3494e726c51b3df904c16d2297f9ea Mon Sep 17 00:00:00 2001 From: Sergei Zobov Date: Thu, 28 May 2020 16:55:07 +0300 Subject: [PATCH 2/7] Fix bytes decoding --- octoprint_telegram/__init__.py | 6 +- octoprint_telegram/telegramCommands.py | 64 ++++++++++----------- octoprint_telegram/telegramNotifications.py | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/octoprint_telegram/__init__.py b/octoprint_telegram/__init__.py index d3be365..d48f5a0 100644 --- a/octoprint_telegram/__init__.py +++ b/octoprint_telegram/__init__.py @@ -260,7 +260,7 @@ 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) @@ -268,14 +268,14 @@ def handleTextMessage(self, message, chat_id, from_id): #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.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 diff --git a/octoprint_telegram/telegramCommands.py b/octoprint_telegram/telegramCommands.py index 77d919a..8754063 100644 --- a/octoprint_telegram/telegramCommands.py +++ b/octoprint_telegram/telegramCommands.py @@ -46,7 +46,7 @@ def __init__(self, main): '/tune': {'cmd': self.cmdTune, 'param': True}, '/help': {'cmd': self.cmdHelp, 'bind_none': True} } - + ############################################################################################ # COMMAND HANDLERS @@ -80,11 +80,11 @@ def cmdGif(self,chat_id,from_id,cmd,parameter): #GWE 05/05/2019 add command to g sendOneInLoop = False try: self._logger.info("Will try to create a gif") - ret = "" + ret = "" if self.main._plugin_manager.get_plugin("multicam") and self.main._settings.get(["multicam"]): try: curr = self.main._settings.global_get(["plugins","multicam","multicam_profiles"]) - for li in curr: + for li in curr: try: url = li.get("URL") ret = self.main.create_gif_new(chat_id,5,url) @@ -97,7 +97,7 @@ def cmdGif(self,chat_id,from_id,cmd,parameter): #GWE 05/05/2019 add command to g self._logger.error("Exception occured on getting multicam options: "+ str(ex) ) else: ret = self.main.create_gif_new(chat_id,5,0) - + if ret == "": ret = self.main.create_gif_new(chat_id,5,0) @@ -125,7 +125,7 @@ def cmdSuperGif(self,chat_id,from_id,cmd,parameter): #GWE 05/05/2019 add command try: curr = self.main._settings.global_get(["plugins","multicam","multicam_profiles"]) self._logger.error("MUUUUUUUUUUUUUUUUUULTICAM "+ str(curr)) - for li in curr: + for li in curr: try: self._logger.error("MUUUUUUUUUUUUUUUUUULTICAM "+ str(li)) url = li.get("URL") @@ -140,7 +140,7 @@ def cmdSuperGif(self,chat_id,from_id,cmd,parameter): #GWE 05/05/2019 add command self._logger.error("Exception occured on getting multicam options: "+ str(ex) ) else: ret = self.main.create_gif_new(chat_id,10,0) - + if ret == "": ret = self.main.create_gif_new(chat_id,10,0) @@ -234,7 +234,7 @@ def cmdSettings(self,chat_id,from_id,cmd,parameter): msg = self.gEmo('settings') + gettext(" *Current notification settings are:*\n\n"+self.gEmo('height')+" Height: %(height).2fmm\n\n"+self.gEmo('clock')+" Time: %(time)dmin\n\n"+self.gEmo('film frame')+" Gif is activate: "+gif_emo+"\n\n"+self.gEmo('video camera')+" Multicam is activate: "+multicam_emo, height=self.main._settings.get_float(["notification_height"]), time=self.main._settings.get_int(["notification_time"])) - + msg_id=self.main.getUpdateMsgId(chat_id) if parameter == "back" else "" self.main.send_msg(msg, responses=[[[self.main.emojis['height']+gettext(" Set height"),"/settings_h"], [self.main.emojis['clock']+gettext(" Set time"),"/settings_t"], [self.main.emojis['film frame']+gettext(gif_txt),"/settings_g"], [self.main.emojis['video camera']+gettext(multicam_txt),"/settings_m"]], [[self.main.emojis['cross mark']+gettext(" Close"),"No"]]],chatID=chat_id,msg_id=msg_id,markup="Markdown") ############################################################################################ @@ -246,7 +246,7 @@ def cmdAbort(self,chat_id,from_id,cmd,parameter): if self.main._printer.is_printing(): self.main.send_msg(self.gEmo('question') + gettext(" Really abort the currently running print?"), responses=[[[self.main.emojis['check']+gettext(" Stop print"),"/abort_stop"], [self.main.emojis['cross mark']+gettext(" Close"),"No"]]],chatID=chat_id) else: - self.main.send_msg(self.gEmo('info') + gettext(" Currently I'm not printing, so there is nothing to stop."),chatID=chat_id,inline=False) + self.main.send_msg(self.gEmo('info') + gettext(" Currently I'm not printing, so there is nothing to stop."),chatID=chat_id,inline=False) ############################################################################################ def cmdTogglePause(self,chat_id,from_id,cmd,parameter): msg = "" @@ -255,11 +255,11 @@ def cmdTogglePause(self,chat_id,from_id,cmd,parameter): self.main._printer.toggle_pause_print() elif self.main._printer.is_paused(): msg =self.gEmo('black right-pointing triangle') + " Resuming the print." - self.main._printer.toggle_pause_print() + self.main._printer.toggle_pause_print() else: - msg = " Currently I'm not printing, so there is nothing to pause/resume." + msg = " Currently I'm not printing, so there is nothing to pause/resume." self.main.send_msg(msg, chatID=chat_id,inline=False) -############################################################################################ +############################################################################################ def cmdShutup(self,chat_id,from_id,cmd,parameter): if chat_id not in self.main.shut_up: self.main.shut_up[chat_id] = 0 @@ -325,7 +325,7 @@ def cmdFiles(self,chat_id,from_id,cmd,parameter): if fileHash == "" and opt =="": self.fileList(pathHash,page,cmd,chat_id) elif opt == "": - self.fileDetails(pathHash,page,cmd,fileHash,chat_id,from_id) + self.fileDetails(pathHash,page,cmd,fileHash,chat_id,from_id) else: if opt.startswith("dir"): self.fileList(fileHash,0,cmd,chat_id) @@ -365,9 +365,9 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): myCmd = self.main._settings.global_get(['server','commands','systemRestartCommand']) elif params[2] == "Shutdown System": myCmd = self.main._settings.global_get(['server','commands','systemShutdownCommand']) - + p = sarge.run(myCmd, stderr=sarge.Capture(), shell=True, async=False) - + if p.returncode != 0: returncode = p.returncode stderr_text = p.stderr.text @@ -424,7 +424,7 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): i += 1 if len(tmpKeys) > 0: keys.append(tmpKeys) - + tmpKeys = [] i = 1 serverCommands = { 'serverRestartCommand': ["Restart OctoPrint", "/sys_sys_Restart OctoPrint"], @@ -441,7 +441,7 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): i += 1 if len(tmpKeys) > 0: keys.append(tmpKeys) - + if len(keys) > 0 : message_text = " The following System Commands are known." else: @@ -450,9 +450,9 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): server_ip = [(s.connect((self.main._settings.global_get(["server","onlineCheck","host"]), self.main._settings.global_get(["server","onlineCheck","port"]))), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1] message_text += "\n\nIP: " + server_ip except Exception as ex: self._logger.error("Exception retrieving IP address: " + str(ex)) - + message = self.gEmo('info') + message_text - + keys.append([[self.main.emojis['cross mark']+gettext(" Close"),"No"]]) msg_id=self.main.getUpdateMsgId(chat_id) if parameter == "back" else "" self.main.send_msg(message,chatID=chat_id,responses=keys,msg_id=msg_id) @@ -739,7 +739,7 @@ def cmdFilament(self,chat_id,from_id,cmd,parameter): if (errorText != ""): message += "\nError text: " + str(errorText) msg_id=self.main.getUpdateMsgId(chat_id) - self.main.send_msg(message,chatID=chat_id,msg_id = msg_id,inline=False) + self.main.send_msg(message,chatID=chat_id,msg_id = msg_id,inline=False) if params[0] == "changeSpool": self._logger.info("Command to change spool: %s" % params) if len(params) > 1: @@ -800,7 +800,7 @@ def cmdFilament(self,chat_id,from_id,cmd,parameter): msg_id=self.main.getUpdateMsgId(chat_id) if parameter == "back" else "" self.main.send_msg(message,chatID=chat_id,responses=keys,msg_id=msg_id) -############################################################################################ +############################################################################################ def cmdHelp(self,chat_id,from_id,cmd,parameter): self.main.send_msg(self.gEmo('info') + gettext(" *The following commands are known:*\n\n" "/abort - Aborts the currently running print. A confirmation is required.\n" @@ -837,7 +837,7 @@ def fileList(self,pathHash,page,cmd,chat_id,wait = 0): arrayD = [] self._logger.debug("fileList before loop folder " ) if self.main.version >= 1.3: - M = {k:v for k,v in files.items() if v['type'] == "folder"} + M = {k:v for k,v in files.items() if v['type'] == "folder"} for key in M: arrayD.append([self.main.emojis['open file folder']+" "+key,cmd+"_"+pathHash+"|0|"+self.hashMe(fullPath+key+"/",8)+"|dir"]) array = [] @@ -885,7 +885,7 @@ def fileList(self,pathHash,page,cmd,chat_id,wait = 0): if pageUp != page: tmpKeys.append([self.main.emojis['black right-pointing triangle'],cmd+"_"+pathHash+"|"+str(pageUp)]) tmpKeys.extend(backBut) - + else: tmpKeys.extend(backBut) keys.append(tmpKeys) @@ -900,7 +900,7 @@ def fileDetails(self,pathHash,page,cmd,fileHash,chat_id,from_id,wait=0): self.tmpFileHash = "" meta = self.main._file_manager.get_metadata(dest,path) msg = self.gEmo("info") + " File Informations\n\n" - msg += ""+self.main.emojis['name badge']+"Name: " + path + msg += ""+self.main.emojis['name badge']+"Name: " + path try: msg += "\n"+self.main.emojis['clock face twelve oclock']+"Uploaded: " + datetime.datetime.fromtimestamp(file['date']).strftime('%Y-%m-%d %H:%M:%S') except Exception as ex: @@ -936,7 +936,7 @@ def fileDetails(self,pathHash,page,cmd,fileHash,chat_id,from_id,wait=0): cpM = self.main._settings.global_get_float(["plugins","cost","cost_per_length"]) curr = self.main._settings.global_get(["plugins","cost","currency"]) try: - curr = curr.decode("utf-8") + curr = curr msg += "\n"+self.main.emojis['money bag']+"Cost: "+curr+"%.02f " % ((filaLen/1000) * cpM + (printTime/3600) * cpH) except Exception as ex: self._logger.error("An Exception the cost function in decode : " + str(ex) ) @@ -945,7 +945,7 @@ def fileDetails(self,pathHash,page,cmd,fileHash,chat_id,from_id,wait=0): self._logger.error("An Exception the cost function on get: " + str(ex) ) msg += "\n"+self.main.emojis['money bag']+"Cost: -" else: - msg += "\n"+self.main.emojis['money bag']+"Cost: -" + msg += "\n"+self.main.emojis['money bag']+"Cost: -" keyPrint = [self.main.emojis['rocket']+" Print","/print_"+fileHash] keyDetails = [self.main.emojis['left-pointing magnifying glass']+" Details",cmd+"_"+pathHash+"|"+str(page)+"|"+fileHash+"|inf"] keyDownload = [self.main.emojis['save']+" Download",cmd+"_"+pathHash+"|"+str(page)+"|"+fileHash+"|dl"] @@ -955,7 +955,7 @@ def fileDetails(self,pathHash,page,cmd,fileHash,chat_id,from_id,wait=0): keyBack = [self.main.emojis['leftwards arrow with hook']+" Back",cmd+"_"+pathHash+"|"+str(page)] keysRow = [] keys = [] - chkID = chat_id + chkID = chat_id if self.main.isCommandAllowed(chat_id, from_id, "/print"): keysRow.append(keyPrint) keysRow.append(keyDetails) @@ -1013,12 +1013,12 @@ def fileOption(self,loc,page,cmd,hash,opt,chat_id,from_id): cpM = self.main._settings.global_get_float(["plugins","cost","cost_per_length"]) curr = self.main._settings.global_get(["plugins","cost","currency"]) try: - curr = curr.decode("utf-8") + curr = curr msg += "\n"+self.main.emojis['money bag']+"Cost: "+curr+"%.02f " % ((filaLen/1000) * cpM + (printTime/3600) * cpH) except Exception as ex: self._logger.error("An Exception the cost function in decode : " + str(ex) ) msg += "\n"+self.main.emojis['money bag']+"Cost: -" - self._logger.debug("AF TRY") + self._logger.debug("AF TRY") except Exception as ex: self._logger.error("An Exception the cost function on get: " + str(ex) ) msg += "\n"+self.main.emojis['money bag']+"Cost: -" @@ -1111,7 +1111,7 @@ def fileOption(self,loc,page,cmd,hash,opt,chat_id,from_id): self.fileList(loc,page,cmd,chat_id,wait = 3) else: keys = [[[self.main.emojis['check']+" Yes",cmd+"_" + loc + "|"+str(page)+"|"+ hash+"|d_d"],[self.main.emojis['cross mark']+" No",cmd+"_" + loc + "|"+str(page)+"|"+ hash]]] - self.main.send_msg(self.gEmo('warning')+" Delete "+path+" ?",chatID=chat_id,responses=keys,msg_id=msg_id) + self.main.send_msg(self.gEmo('warning')+" Delete "+path+" ?",chatID=chat_id,responses=keys,msg_id=msg_id) elif opt.startswith("s"): if opt == "s_n": self.main._settings.set_boolean(["fileOrder"],False) @@ -1217,7 +1217,7 @@ def generate_dir_hash_dict_recursively(self,tree,loc): except Exception as ex: self._logger.error("An Exception in generate_dir_hash_dict_recursively : " + str(ex) ) return myDict -############################################################################################ +############################################################################################ def find_file_by_hash(self, hash): try: tree = self.main._file_manager.list_files(recursive=True) @@ -1228,7 +1228,7 @@ def find_file_by_hash(self, hash): except Exception as ex: self._logger.error("An Exception in find_file_by_hash : " + str(ex) ) return None, None, None -############################################################################################ +############################################################################################ def find_file_by_hash_recursively(self, tree, hash, base=""): for key in tree: if tree[key]['type']=="folder": @@ -1377,7 +1377,7 @@ def ConAuto(self,chat_id,parameter): con = octoprint.printer.get_connection_options() keys=[[[self.main.emojis['check']+" ON","/con_s|a|true"],[self.main.emojis['error']+" OFF","/con_s|a|false"]],[[self.main.emojis['leftwards arrow with hook']+gettext(" Back"),"/con_s"]]] self.main.send_msg(self.gEmo('question') + " AutoConnect on startup.\nCurrent setting: "+str(con['autoconnect']),responses=keys,chatID=chat_id,msg_id=self.main.getUpdateMsgId(chat_id)) -############################################################################################ +############################################################################################ def ConConnect(self,chat_id,parameter): if parameter: if parameter[0] == "a": diff --git a/octoprint_telegram/telegramNotifications.py b/octoprint_telegram/telegramNotifications.py index 7834011..89c20a7 100644 --- a/octoprint_telegram/telegramNotifications.py +++ b/octoprint_telegram/telegramNotifications.py @@ -222,7 +222,7 @@ def _sendNotification(self, payload, **kwargs): emo = EmojiFormatter(self.main) try: # call format with emo class object to handle emojis, otherwise use locals - message = self.main._settings.get(["messages",kwargs['event'],"text"]).encode('utf-8').format(emo,**locals()) + message = self.main._settings.get(["messages",kwargs['event'],"text"]).format(emo,**locals()) except Exception as ex: self._logger.debug("Exception on formatting message: " + str(ex)) message = self.main.gEmo('warning') + " ERROR: I was not able to format the Notification for '"+event+"' properly. Please open your OctoPrint settings for " + self.main._plugin_name + " and check message settings for '" + event + "'." From 3322fb270f8ae4c3cffceb3792dbab05268a4f60 Mon Sep 17 00:00:00 2001 From: Sergei Zobov Date: Thu, 28 May 2020 17:26:12 +0300 Subject: [PATCH 3/7] Fix StringIO --- octoprint_telegram/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/octoprint_telegram/__init__.py b/octoprint_telegram/__init__.py index d48f5a0..00c28e7 100644 --- a/octoprint_telegram/__init__.py +++ b/octoprint_telegram/__init__.py @@ -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(io.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)) @@ -1403,14 +1403,14 @@ def take_image(self,snapshot_url=""): if data == None: return None if flipH or flipV or rotate: - image = Image.open(io.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 = io.StringIO() + output = io.BytesIO() image.save(output, format="JPEG") data = output.getvalue() output.close() @@ -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(io.StringIO(data)) + image = Image.open(io.BytesIO(data)) image.thumbnail((320, 240)) frames.append(image) #image.save('Gif_Telegram_%02d.jpg' % i, 'JPEG') From 827d15f265ec276fa9795b445676b4edacc841cc Mon Sep 17 00:00:00 2001 From: Sergei Zobov Date: Thu, 28 May 2020 19:03:45 +0300 Subject: [PATCH 4/7] Fix bytes error --- octoprint_telegram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octoprint_telegram/__init__.py b/octoprint_telegram/__init__.py index 00c28e7..49c8d03 100644 --- a/octoprint_telegram/__init__.py +++ b/octoprint_telegram/__init__.py @@ -1171,7 +1171,7 @@ 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 From abcc90231bfd4d9849ec5111a7221b98e5d036bb Mon Sep 17 00:00:00 2001 From: Sergei Zobov Date: Thu, 28 May 2020 19:09:47 +0300 Subject: [PATCH 5/7] Fix emoji creation --- octoprint_telegram/telegramNotifications.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octoprint_telegram/telegramNotifications.py b/octoprint_telegram/telegramNotifications.py index 89c20a7..f3e4bce 100644 --- a/octoprint_telegram/telegramNotifications.py +++ b/octoprint_telegram/telegramNotifications.py @@ -96,7 +96,7 @@ def __init__(self,main): def __format__(self,format): self.main._logger.debug("Formatting emoticon: `" + format +"`") if format in self.main.emojis: - return self.main.gEmo(format).encode("utf-8") + return self.main.gEmo(format) return "" class TMSG(): From 535b669955a777b9665fc956d0858cdacf28bfd3 Mon Sep 17 00:00:00 2001 From: Sergei Zobov Date: Thu, 16 Jul 2020 15:49:12 +0300 Subject: [PATCH 6/7] Pin version between >=3,<4 --- octoprint_telegram/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octoprint_telegram/__init__.py b/octoprint_telegram/__init__.py index 49c8d03..e208d2c 100644 --- a/octoprint_telegram/__init__.py +++ b/octoprint_telegram/__init__.py @@ -1765,7 +1765,7 @@ def __init__(self,version): __plugin_name__ = "Telegram Notifications" -__plugin_pythoncompat__ = ">=2.7,<4" +__plugin_pythoncompat__ = ">=3,<4" __plugin_implementation__ = get_implementation_class() __plugin_hooks__ = { "octoprint.plugin.softwareupdate.check_config": __plugin_implementation__.get_update_information, From 4bfbb9b69b663b9bca54a843c7430da358e79678 Mon Sep 17 00:00:00 2001 From: Sergei Zobov Date: Sat, 25 Jul 2020 20:49:17 +0300 Subject: [PATCH 7/7] [#244] fix python3.7 + sarge compatibility related to: https://bitbucket.org/vinay.sajip/sarge/issues/38/python-37-breakage --- octoprint_telegram/telegramCommands.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/octoprint_telegram/telegramCommands.py b/octoprint_telegram/telegramCommands.py index 8754063..179e745 100644 --- a/octoprint_telegram/telegramCommands.py +++ b/octoprint_telegram/telegramCommands.py @@ -366,7 +366,7 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): elif params[2] == "Shutdown System": myCmd = self.main._settings.global_get(['server','commands','systemShutdownCommand']) - p = sarge.run(myCmd, stderr=sarge.Capture(), shell=True, async=False) + p = sarge.run(myCmd, stderr=sarge.Capture(), shell=True, async_=False) if p.returncode != 0: returncode = p.returncode @@ -390,14 +390,14 @@ def cmdSys(self,chat_id,from_id,cmd,parameter): self.main.send_msg(self.gEmo('question') + str(command['name'])+"\nExecute system command?",responses=[[[self.main.emojis['check'] + gettext(" Execute"),"/sys_do_" + str(parameter)], [self.main.emojis['leftwards arrow with hook'] + gettext(" Back"),"/sys_back"]]],chatID=chat_id, msg_id = self.main.getUpdateMsgId(chat_id)) return else: - async = command["async"] if "async" in command else False + async_ = command["async"] if "async" in command else False self._logger.info("Performing command: %s" % command["command"]) try: # we run this with shell=True since we have to trust whatever # our admin configured as command and since we want to allow # shell-alike handling here... - p = sarge.run(command["command"], stderr=sarge.Capture(), shell=True, async=async) - if not async: + p = sarge.run(command["command"], stderr=sarge.Capture(), shell=True, async_=async_) + if not async_: if p.returncode != 0: returncode = p.returncode stderr_text = p.stderr.text