def _add_message(self, text): """ Appends a message to the message queue. :type text: builtins.str :return: """ try: logger.debug("Received Message: \"{str}\"".format(str=text)) json_dict = json.loads(text) message = DictObject.objectify(json_dict) message = fix_message(message) except ValueError as e: for check in fix_plain_output.all: m = check[0].match(text) if m: message = DictObject(manual_result=m.groupdict(), type=check[1]) logger.warn( "Manually parsed output! This should be json!\nMessage:>{}<" .format(text)) break else: logger.warn( "Received message could not be parsed.\nMessage:>{}<". format(text), exc_info=True) return if self.append_json: message.merge_dict({u("json"): text}) with self._queue_access: self._queue.append(message) self._new_messages.release()
def _add_message(self, text): """ Appends a message to the message queue. :type text: builtins.str :return: """ try: logger.debug("Received Message: \"{str}\"".format(str=text)) json_dict = json.loads(text) message = DictObject.objectify(json_dict) message = fix_message(message) except ValueError as e: for check in fix_plain_output.all: m = check[0].match(text) if m: message = DictObject(manual_result=m.groupdict(), type=check[1]) logger.warn("Manually parsed output! This should be json!\nMessage:>{}<".format(text)) break else: logger.warn("Received message could not be parsed.\nMessage:>{}<".format(text), exc_info=True) return if self.append_json: message.merge_dict({u("json"): text}) with self._queue_access: self._queue.append(message) self._new_messages.release()
def load(self): try: with open('data/tags.json', 'r') as f: data = json.load(f, object_pairs_hook=OrderedDict) self.list = DictObject(data) print('\t[OK] tags.json loaded.') except: self.list = DictObject() print('\t[Failed] tags.json NOT loaded.')
def load_database(self, merge=False): logger.debug( "Loading database from {file}.".format(file=self._database_file)) with open(self._database_file, "r") as file: json_data = file.read() # end with data = self._str_to_json(json_data) if not merge: logging.debug("Not merging.") self._attribute_to_key_map.clear() self.clear() DictObject.__init__(self, data) else: logging.debug("Merging data.") self.merge_dict(data)
def _do_request(self, url, params=None, files=None, use_long_polling=None, request_timeout=None): """ :param url: The complete url to send to :type url: str :keyword params: Parameter for that connection :keyword files: Optional files parameters :keyword use_long_polling: if it should use long polling. (see http://docs.python-requests.org/en/latest/api/#requests.Response.iter_content) :type use_long_polling: bool :keyword request_timeout: When the request should time out. :type request_timeout: int :return: json data received :rtype: DictObject.DictObject """ import requests r = requests.post(url, params=params, files=files, stream=use_long_polling, verify=True, timeout=request_timeout) # No self signed certificates. Telegram should be trustworthy anyway... from DictObject import DictObject try: logger.debug("Response: {}".format(r.json())) json_data = DictObject.objectify(r.json()) except Exception: logger.exception("Parsing answer failed.\nRequest: {r!s}\nContent: {r.content}".format(r=r)) raise # end if json_data["response"] = r # TODO: does this failes on json lists? Does TG does that? return json_data
def __init__(self, e): if isinstance(e, str): try: e = xml.fromstring(e) except Exception: LOGGER.exception("Skipping malformed line") return if isinstance(e, xml.Element): e = etree_to_dict(e) if isinstance(e, dict): e = DictObject.objectify(e) assert isinstance(e, DictObject) assert hasattr(e.item, "type") self.type = ascii_integers_to_string(e.item.type) self.code = ascii_integers_to_string(e.item.code) self.length = int(e.item.length) if "data" in e.item: assert self.length > 0 # length is zero if data is undefined. self.data = encoded_to_str(e.item.data["#text"], e.item.data["@encoding"], as_bytes=True) if e.item.data["@encoding"] == "base64": self._data_base64 = try_decode(e.item.data["#text"]) else: self._data_base64 = None else: assert self.length == 0 # length is zero if data is undefined. self.data = try_encode("") self._data_base64 = None
def do(self, command, files=None, use_long_polling=False, request_timeout=None, **query): """ Returns the input as dict so that the result of any method is the do arguments. :param command: :param files: :param use_long_polling: :param request_timeout: :param query: :return: """ if command in self.fake_responses: return self._postprocess_data(self.fake_responses[command]) # end if url, params = self._prepare_request(command, query) data = { "call": { 'command': command, 'files': files, 'use_long_polling': use_long_polling, 'request_timeout': request_timeout, '**query': query }, "url": url, "json": params, "is_python_object": self.return_python_objects } return DictObject.objectify(data)
def get_weather_icon(icon): weather_emoji = DictObject() if icon[:4] == 'nt_': weather_emoji['clear'] = u'🌙' weather_emoji['sunny'] = u'🌙' icon = icon.lstrip('nt_') else: weather_emoji['clear'] = u'☀️' weather_emoji['sunny'] = u'☀️' weather_emoji['chancesnow'] = u'❄️' weather_emoji['chanceflurries'] = u'❄️' weather_emoji['chancerain'] = u'🌧' weather_emoji['chancesleet'] = u'🌧' weather_emoji['chancetstorms'] = u'🌩' weather_emoji['cloudy'] = u'☁️' weather_emoji['flurries'] = u'❄️' weather_emoji['fog'] = u'🌫' weather_emoji['hazy'] = u'🌫' weather_emoji['mostlycloudy'] = u'🌤' weather_emoji['partlycloudy'] = u'⛅️' weather_emoji['partlysunny'] = u'⛅️' weather_emoji['sleet'] = u'🌧' weather_emoji['rain'] = u'🌧' weather_emoji['snow'] = u'❄️' weather_emoji['tstorms'] = u'⛈' return weather_emoji[icon]
def __init__(self, e): if isinstance(e, str): try: e = xml.fromstring(e) except xml.ParseError: logger.warn("Skipping malformed line: {line}".format(line=e), exc_info=True) return if isinstance(e, xml.Element): e = etree_to_dict(e) if isinstance(e, dict): e = DictObject.objectify(e) assert isinstance(e, DictObject) assert hasattr(e.item, "type") self.type = ascii_integers_to_string(e.item.type) self.code = ascii_integers_to_string(e.item.code) self.length = int(e.item.length) if "data" in e.item: assert self.length > 0 # length is zero if data is undefined. self.data = encoded_to_str(e.item.data["#text"], e.item.data["@encoding"], as_bytes=True) if e.item.data["@encoding"] == "base64": self._data_base64 = to_unicode(e.item.data["#text"]) else: self._data_base64 = None else: assert self.length == 0 # length is zero if data is undefined. self.data = to_binary("") self._data_base64 = None
def create_formatter(self): return DictObject.objectify( dict( color_black=self.prepare_color(self.BLACK), color_red=self.prepare_color(self.RED), color_green=self.prepare_color(self.GREEN), color_yellow=self.prepare_color(self.YELLOW), color_blue=self.prepare_color(self.BLUE), color_lightblue=self.prepare_color(self.LIGHT_BLUE), color_magenta=self.prepare_color(self.MAGENTA), color_cyan=self.prepare_color(self.CYAN), color_white=self.prepare_color(self.WHITE), color_grey=self.prepare_color(self.GREY), color_off=self.prepare_color( self.DEFAULT), # Default foreground color background_red=self.prepare_color(self.BG_RED), background_grey=self.prepare_color(self.BG_GREY), background_default=self.prepare_color( self.BG_DEFAULT), # turn of background background_off=self.prepare_color( self.BG_DEFAULT), # Default background color inverse_on=self.prepare_color( 7 ), # Reverse (invert the foreground and background colors) inverse_off=self.prepare_color(27), # Reset reverse all_off=self.prepare_color(self.RESET), ))
def get_bot_profile(): global bot_profile url = create_url(bot_info_method) response = requests.get(url) data = response.json() if data["ok"]: bot_profile = DictObject.objectify(data["result"])
def _add_message(self, text): """ Appends a message to the message queue. :type text: builtins.str :return: """ try: logger.debug("Received Message: \"{str}\"".format(str=text)) json_dict = json.loads(text) message = DictObject.objectify(json_dict) message = self.parse_message(message) except ValueError as e: logger.warn( "Received message could not be parsed.\nMessage:>{}<".format( text), exc_info=True) return if isinstance(message, InitMessage): self.init_queue.append_message(message) elif isinstance(message, ProposeMessage): self.propose_queue.append_message(message) elif isinstance(message, PrevoteMessage): self.prevote_queue.append_message(message) elif isinstance(message, VoteMessage): self.vote_queue.append_message(message) else: logger.warning( "Discarded unknown message type: {msg_type}, {msg}".format( msg_type=type(message), msg=message))
def _prepare_request(self, command, query): """ :param command: The Url command parameter :type command: str :param query: will get json encoded. :type query: dict :return: """ from luckydonaldUtils.encoding import to_native as n from pytgbot.api_types.sendable import Sendable from pytgbot.api_types import as_array from DictObject import DictObject import json params = {} for key in query.keys(): element = query[key] if element is not None: if isinstance(element, Sendable): params[key] = json.dumps(as_array(element)) else: params[key] = element url = self._base_url.format(api_key=n(self.api_key), command=n(command)) return DictObject(url=url, params=params)
def init(): path = "bot/" + API_KEY + "/income" hostname = HOSTNAME if not hostname: info = DictObject.objectify(requests.get('http://ipinfo.io').json()) logger.info("PATH: {}".format(info)) hostname = str(info.ip) # end if webhook_url = "https://" + hostname + "/" + URL_PATH + "/" + path logger.success("URL: {}".format(webhook_url)) # In case sending a custom public key # from pytgbot.api_types.sendable import InputFile # response = bot.set_webhook(webhook_url, certificate=InputFile("/certs/ YOUR FILE")) # In case of a valid HTTPS host, you can go with: response = bot.set_webhook(webhook_url) logger.success(response) import json return json.dumps({ "status": "ok", "webhook": webhook_url, "response": repr(response) })
def process_received_message(message): global pending_hide_keyboard logger.info(message) message = DictObject.objectify(message) username = message['from'].username if hasattr(message['from'], 'username') else None processed_event = process_chat_event(message)#text or location if not processed_event: is_text = hasattr(message, 'text') if not is_text: #if it's not text it will not be processed for commands or direct message process_no_text_message(message, username) return processed_command = process_command(message, username) if not processed_command: processed_reply = commands.process_expected_reply(message.chat.id,\ message['from']['id'],\ username,\ message.text) if processed_reply: # Processed as reply, won't continue pending_hide_keyboard = True return (direct_msg, clean_text) = direct_message(message) direct_conversation = is_direct_conversation(message) if direct_msg: process_chat_message(message, clean_text) if not direct_msg or direct_conversation: process_message_trigger(message, clean_text, username)
def process_received_message(message): global pending_hide_keyboard logger.info(message) message = DictObject.objectify(message) username = message['from'].username if hasattr(message['from'], 'username') else None processed_event = process_chat_event(message) #text or location if not processed_event: is_text = hasattr(message, 'text') if not is_text: #if it's not text it will not be processed for commands or direct message process_no_text_message(message, username) return processed_command = process_command(message, username) if not processed_command: processed_reply = commands.process_expected_reply(message.chat.id,\ message['from']['id'],\ username,\ message.text) if processed_reply: # Processed as reply, won't continue pending_hide_keyboard = True return (direct_msg, clean_text) = direct_message(message) direct_conversation = is_direct_conversation(message) if direct_msg: process_chat_message(message, clean_text) if not direct_msg or direct_conversation: process_message_trigger(message, clean_text, username)
class KcRet(object): __Rets__ = DictObject({}) def __init__(self, _lambda): self._lambda = _lambda def __call__(self, *args, **kwargs): return self._lambda(KcRet.__Rets__)
def load(self): try: with open('data/config.json', 'r') as f: data = DictObject( json.load(f, object_pairs_hook=OrderedDict)) self.wrapper = data.wrapper self.owner = data.owner self.keys = DictObject(data['keys']) self.plugins = data.plugins self.timeout = data.timeout self.start = data.start self.language = data.language print('\t[OK] config.json loaded.') except: self.keys = DictObject() print('\t[Failed] config.json NOT loaded.')
def load_message_triggers(): global message_triggers global configuration triggers_file = configuration.get('Message triggers', 'file_path') with open(triggers_file) as data_file: message_triggers = json.load(data_file) message_triggers = DictObject.objectify(message_triggers) logger.info("Loading message triggers...")
def get_json(url, objectify=True, **kwargs): kwargs.setdefault("headers", HEADERS) json = requests.get(url, **kwargs).json() if objectify: return DictObject.objectify(json) return json # end def
def load(self): try: file = config.language except NameError: file = 'default' try: with open('lang/%s.json' % file, 'r') as f: data = DictObject( json.load(f, object_pairs_hook=OrderedDict)) self.messages = data.messages self.errors = data.errors self.interactions = data.interactions print('\t[OK] %s.json loaded.' % file) except: self.messages = DictObject() self.errors = DictObject() self.interactions = DictObject() print('\t[Failed] %s.json NOT loaded.' % file)
def toJson(self, __PathPre__='', **kwargs): jsoned = DictObject() for i in ObjGet.attrs(self, regMatch='^[a-zA-Z]', limit_callable=False): ipath = __PathPre__ + i v = getattr(self, i) isJsonItem(v, raiseName=self.__class__.__name__ + '::' + ipath) jsoned[i] = v if not isinstance(v, JsonLike) else v.toJson( __PathPre__=ipath + '.') return jsoned
def get_bot_profile(): global bot_profile url = create_url(bot_info_method) response = requests.get(url) if response.status_code>= 400: logger.error('url: %s', url) logger.error('response: %s - %s', response.status_code, response.text) data = response.json() if data["ok"]: bot_profile = DictObject.objectify(data["result"])
def get_bot_profile(): global bot_profile url = create_url(bot_info_method) response = requests.get(url) if response.status_code >= 400: logger.error('url: %s', url) logger.error('response: %s - %s', response.status_code, response.text) data = response.json() if data["ok"]: bot_profile = DictObject.objectify(data["result"])
def run(self, m): input = get_input(m, ignore_reply=False) if not input: return self.bot.send_message(m, generate_command_help( self, m.content), extra={'format': 'HTML'}) # return self.bot.send_message(m, self.bot.trans.errors.missing_parameter, extra={'format': 'HTML'}) delay = first_word(input) if delay: delaytime = delay[:-1] unit = delay[-1:] if not is_int(delaytime) or is_int(unit) or not self.to_seconds( delaytime, unit): return self.bot.send_message( m, self.bot.trans.plugins.reminders.strings.wrongdelay) alarm = time() + self.to_seconds(delaytime, unit) text = all_but_first_word(input) if not text: return self.bot.send_message( m, self.bot.trans.plugins.reminders.strings.noreminder) reminder = DictObject(OrderedDict()) reminder.id = '%s:%s' % (m.sender.id, time()) reminder.alarm = alarm reminder.chat_id = m.conversation.id reminder.text = text reminder.first_name = m.sender.first_name if m.sender.username: reminder.username = m.sender.username self.bot.reminders = wait_until_received('reminders/' + self.bot.name) self.sort_reminders() self.bot.reminders['list'].append(reminder) self.sort_reminders() if unit == 's': delay = delay.replace('s', ' seconds') if unit == 'm': delay = delay.replace('m', ' minutes') if unit == 'h': delay = delay.replace('h', ' hours') if unit == 'd': delay = delay.replace('d', ' days') message = self.bot.trans.plugins.reminders.strings.added % ( m.sender.first_name, delay, text) return self.bot.send_message(m, message, extra={'format': 'HTML'})
class DataStore(object): store = DictObject() def get_my_name(self): ans = [] frame = inspect.currentframe() tmp = dict( list(frame.f_globals.items()) + list(frame.f_locals.items())) print(tmp) for k, var in tmp.items(): if isinstance(var, self.__class__): print('%s - %s' % (k, var)) if hash(self) == hash(var) and k is not 'self': ans.append(k) return ans[0] def __getitem__(self, key): if key not in self.store.keys(): raise Exception("'" + key + "'" + " is not a valid key") return dict.__getitem__(self.store, key) def __setitem__(self, key, value): if key not in self.store.keys(): raise Exception("'" + key + "'" + " is not a valid key") dict.__setitem__(self.store, key, value) def load(self): print(self.get_my_name()) file_name = 'data/%s.json' % self.get_my_name() if exists(file_name): try: with open(file_name) as f: self.store = json.load(f) print('\t[OK] %s loaded.' % self.get_my_name()) except: print('\t[Failed] %s loaded.' % self.get_my_name()) else: print('not found') def save(self): file_name = 'data/%s.json' % self.get_my_name() if self.store: try: with open(file_name) as f: json.dump(self.store, f) print('\t[OK] %s saved.' % self.get_my_name()) except: print('\t[Failed] %s saved.' % self.get_my_name()) else: print('not found') def print_it(self): if self.store: pprint(self.store)
def load_database(self, merge=False): logging.debug("Loading database from {file}.".format(file=self._database_file)) try: with open(self._database_file, "r", encoding='utf8') as file: json_data = file.read() except FileNotFoundError: logging.warning("File {file!r} was not found! Not loading anything!".format(file=self._database_file)) return except Exception as e: logging.exception("Exception in loading file:") raise data = json.loads(json_data) if not merge: logging.debug("Not merging.") self._attribute_to_key_map.clear() self.clear() DictObject.__init__(self, data) else: logging.debug("Merging data.") self.merge_dict(data)
def load_database(self, merge=False): logging.debug("Loading database from {file}.".format(file=self._database_file)) try: with open(self._database_file, "r") as file: json_data = file.read() except FileNotFoundError: logging.warning("File {file!r} was not found! Not loading anything!".format(file=self._database_file)) return except Exception as e: logging.exception("Exception in loading file:") raise data = json.loads(json_data) if not merge: logging.debug("Not merging.") self._attribute_to_key_map.clear() self.clear() DictObject.__init__(self, data) else: logging.debug("Merging data.") self.merge_dict(data)
def user_id(self, username): if username.startswith('@'): command = 'resolve_username ' + username[1:] resolve = self.sender.raw(command) dict = DictObject(json.loads(resolve)) else: dict = self.sender.user_info(username) if 'peer_id' in dict: return dict.peer_id else: return False
def do(self, command, files=None, **query): """ Send a request to the api. :param action: :param data: :param query: :return: """ url = self._base_url.format(api_key=n(self.api_key), command=n(command)) r = requests.post(url, params=query, files=files, verify=True) # No self signed certificates. Telegram should be trustworthy anyway... return DictObject.objectify(r.json())
def run(self, m): input = get_input(m, ignore_reply=False) if not input: return self.bot.send_message( m, self.bot.trans.errors.missing_parameter, extra={'format': 'HTML'}) self.reminders.load_database() # Lists all pins # delay = first_word(input) if delay: delaytime = delay[:-1] unit = delay[-1:] if not is_int(delaytime) or is_int(unit): return self.bot.send_message( m, self.bot.trans.plugins.reminders.strings.wrongdelay) alarm = time() + self.to_seconds(delaytime, unit) text = all_but_first_word(input) if not text: return self.bot.send_message( m, self.bot.trans.plugins.reminders.strings.noreminder) reminder = DictObject(OrderedDict()) reminder.id = '%s:%s' % (m.sender.id, time()) reminder.alarm = alarm reminder.chat_id = m.conversation.id reminder.text = text reminder.first_name = m.sender.first_name reminder.username = m.sender.username self.reminders.list.append(reminder) self.sort_reminders() self.reminders.store_database() if unit == 's': delay = delay.replace('s', ' segundos') if unit == 'm': delay = delay.replace('m', ' minutos') if unit == 'h': delay = delay.replace('h', ' horas') if unit == 'd': delay = delay.replace('d', ' días') message = self.bot.trans.plugins.reminders.strings.added % ( m.sender.first_name, delay, text) return self.bot.send_message(m, message, extra={'format': 'HTML'})
def load_message_triggers(): global message_triggers global configuration logger.info("Loading message triggers...") triggers_file = configuration.get('Message triggers', 'file_path') if os.path.isfile(triggers_file): with open(triggers_file) as data_file: message_triggers = json.load(data_file) message_triggers = DictObject.objectify(message_triggers) else: logger.info("Creating triggers file: " + triggers_file) message_triggers = [] json.dump(message_triggers, open(triggers_file, 'w'))
def load_permissions(): permissions = None permissions_file = configuration.get('Privileges', 'permissions_file') logger.info("Loading permissions...") if os.path.isfile(permissions_file): with open(permissions_file) as data_file: permissions = json.load(data_file) permissions = DictObject.objectify(permissions) else: logger.info("Creating permissions file: " + permissions_file) permissions = {"root": "", "admins": [], "privileged_users": []} json.dump(permissions, open(permissions_file, 'w')) return permissions
def process_received_message(message): logger.info(message) message = DictObject.objectify(message) processed_event = process_chat_event(message) if not processed_event: processed_command = process_command(message) if not processed_command: (direct_msg, clean_text) = direct_message(message) direct_conversation = is_direct_conversation(message) if direct_msg: process_chat_message(message, clean_text) if not direct_msg or direct_conversation: process_message_trigger(message, clean_text)
def containers(self, exclude_self=False): """ Gets metadata for all containers in this scale grouping. :return: """ filters = [ '{0}={1}'.format(self.LABEL_COMPOSE_PROJECT, self.project), '{0}={1}'.format(self.LABEL_COMPOSE_SERVICE, self.service), # '{0}={1}'.format(LABEL_ONE_OFF, "True" if one_off else "False") ] return DictObject.objectify([ c for c in self.cli.containers(filters={'label': filters}) if not (exclude_self and c['Id'][:12] == self.hostname_env[:12]) ])
def get_weather_icon(icon): weather_emoji = DictObject() if icon[2] == 'n': weather_emoji['01'] = u'🌙' else: weather_emoji['01'] = u'☀️' weather_emoji['02'] = u'⛅️' weather_emoji['03'] = u'🌤' weather_emoji['04'] = u'☁️' weather_emoji['09'] = u'🌧' weather_emoji['10'] = u'🌧' weather_emoji['11'] = u'⛈' weather_emoji['13'] = u'❄️' weather_emoji['50'] = u'🌫' return weather_emoji[icon[:2]]
def send_request(url, params=None, headers=None, files=None, data=None, post=False, parse=True, verify=True): try: if post: r = requests.post(url, params=params, headers=headers, files=files, data=data, timeout=100, verify=verify) else: r = requests.get(url, params=params, headers=headers, files=files, data=data, timeout=100, verify=verify) except: logging.error('Error making request to: %s' % url) if verify: return send_request(url, params, headers, files, data, post, parse, False) else: return None if r.status_code != 200: logging.error(r.text) while r.status_code == 429: sleep(5) return send_request(url, params, headers, files, data, post, parse) # r = r.get(url, params=params, headers=headers, # files=files, data=data) try: if parse: return DictObject(json.loads(r.text)) else: return r.url except Exception as e: catch_exception(e) return None
def __init__(self, text, receiver=None, reply_id=DEFAULT_MESSAGE_ID, parse_mode=DEFAULT_MARKDOWN_IS_NONE, reply_markup=None, disable_notification=False, disable_web_page_preview=True, call=None): super().__init__(receiver=receiver, reply_id=reply_id, reply_markup=reply_markup, disable_notification=disable_notification) if parse_mode is TextMessage.DEFAULT_MARKDOWN_IS_NONE: if call: call = DictObject.objectify(call) logger.warning("No parse mode was set, do you need the old default 'markdown'?\n" "Called from function {caller.name} at file {caller.file}:{caller.line}\n" "The line is:\n" "{caller.code}".format(**call) ) else: logger.warning("No parse mode was set, do you need the old default 'markdown'?\nCaller unknown.") # end if parse_mode = "text" # end if if parse_mode == "text": parse_mode = None # because "text" does not exist on TG Api. # end if texts = text_split(text, MAX_TEXT_LENGTH, max_parts=2) if len(texts) == 0: raise ValueError("Text was empty") if len(texts) == 1: logger.debug("Message has length {all} ({all_bytes} bytes). Not split.".format( all=len(text), all_bytes=len(escape(text).encode("utf-8")) )) else: logger.debug( "Message of length {all} ({all_bytes} bytes) split into {part} ({part_bytes} bytes) + {rest} more.".format( all=len(text), all_bytes=len(escape(text).encode("utf-8")), part=len(texts[0]), part_bytes=len(escape(texts[0]).encode("utf-8")), rest=len(texts) - 1 ) ) # end if self.disable_web_page_preview = disable_web_page_preview self.parse_mode = parse_mode self.text = texts[0] if len(texts) > 1: self.receiver = receiver self._next_msg = TextMessage( texts[1], receiver=receiver, parse_mode=self.parse_mode, reply_markup=reply_markup, disable_notification=disable_notification ) # end if if not text: raise ValueError("No text provided.")
def load_permissions(): permissions = None permissions_file = configuration.get('Privileges', 'permissions_file') logger.info("Loading permissions...") if os.path.isfile(permissions_file): with open(permissions_file) as data_file: permissions = json.load(data_file) permissions = DictObject.objectify(permissions) else: logger.info("Creating permissions file: " + permissions_file) permissions = { "root": "", "admins": [], "privileged_users": [] } json.dump(permissions, open(permissions_file, 'w')) return permissions
def run(self, m): input = get_input(m, ignore_reply=False) if not input: return self.bot.send_message(m, self.bot.trans.errors.missing_parameter, extra={"format": "HTML"}) self.reminders.load_database() # Lists all pins # delay = first_word(input) if delay: delaytime = delay[:-1] unit = delay[-1:] if not is_int(delaytime) or is_int(unit): return self.bot.send_message(m, self.bot.trans.plugins.reminders.strings.wrongdelay) alarm = time() + self.to_seconds(delaytime, unit) text = all_but_first_word(input) if not text: return self.bot.send_message(m, self.bot.trans.plugins.reminders.strings.noreminder) reminder = DictObject(OrderedDict()) reminder.id = "%s:%s" % (m.sender.id, time()) reminder.alarm = alarm reminder.chat_id = m.conversation.id reminder.text = text reminder.first_name = m.sender.first_name reminder.username = m.sender.username self.reminders.list.append(reminder) self.sort_reminders() self.reminders.store_database() if unit == "s": delay = delay.replace("s", " seconds") if unit == "m": delay = delay.replace("m", " minutes") if unit == "h": delay = delay.replace("h", " hours") if unit == "d": delay = delay.replace("d", " days") message = self.bot.trans.plugins.reminders.strings.added % (m.sender.first_name, delay, text) return self.bot.send_message(m, message, extra={"format": "HTML"})
def get_pokemon_config(): args_dict = None config_path = os.path.join(get_pokemon_directory(), pokesearch_config_file) with open(config_path) as file: args_dict = json.load(file) # args_dict = { # 'auth_service': 'google', # 'username': '******', # 'password': '******', # 'location': '20.6704923,-103.3713086', # 'step-limit': 10, # 'ignore': False, # 'only': '13', # 'display-pokestop': False, # 'display-gym': False, # 'locale': 'en', # 'onlylure': False, # 'ampm_clock': False, # 'debug': False # } return DictObject.objectify(args_dict)
def do(self, command, files=None, use_long_polling=False, request_timeout=None, **query): """ Returns the input as dict so that the result of any method is the do arguments. :param command: :param files: :param use_long_polling: :param request_timeout: :param query: :return: """ if command in self.fake_responses: return self._postprocess_data(self.fake_responses[command]) # end if url, params = self._prepare_request(command, query) data = { "call": {'command': command, 'files': files, 'use_long_polling': use_long_polling, 'request_timeout': request_timeout, '**query': query}, "url": url, "json": params, "is_python_object": self.return_python_objects } return DictObject.objectify(data)
def _do_request(self, url, params=None, files=None, use_long_polling=None, request_timeout=None): """ :param url: The complete url to send to :type url: str :keyword params: Parameter for that connection :keyword files: Optional files parameters :keyword use_long_polling: if it should use long polling. (see http://docs.python-requests.org/en/latest/api/#requests.Response.iter_content) :type use_long_polling: bool :keyword request_timeout: When the request should time out. :type request_timeout: int :return: json data received :rtype: DictObject.DictObject """ import requests r = requests.post( url, params=params, files=files, stream=use_long_polling, verify=True, timeout=request_timeout ) # No self signed certificates. Telegram should be trustworthy anyway... from DictObject import DictObject try: logger.debug("Response: {}".format(r.json())) json_data = DictObject.objectify(r.json()) except Exception: logger.exception("Parsing answer failed.\nRequest: {r!s}\nContent: {r.content}".format(r=r)) raise # end if json_data["response"] = r # TODO: does this failes on json lists? Does TG does that? return json_data
def execute_function(self, function_name, *arguments, **kwargs): """ Execute a function. Will check a bit, if the parameters looks fitting. If you specify retry_connect=int keyword. This is wrapped by .execute_function() to support both py3 and py2 syntax. :param function_name: The function name. :type function_name: str Now you may apply your arguments for that command. :keyword reply_id: The message id which this command is a reply to. (will be ignored on non-sending commands) :type reply_id: int or None :keyword enable_preview: If the URL found in a message should have a preview. Defaults to False. (Will be ignored by the CLI with non-sending commands) :type enable_preview: bool :keyword retry_connect: How often it should try to reconnect (-1 = infinite times) or fail if it can't establish the first connection. (default is 2) :type retry_connect: int :keyword result_timeout: How long, in seconds, we wait for the cli to answer the send command. Set to None to use the global default timeout (`Sender.default_answer_timeout`) instead of the default timeout for the given command. To use the default timeout for that command omit this parameter. :type result_timeout: int or None :return: parsed result or raises an exception :rtype: Object or IllegalResponseException :raises pytg.exceptions.NoResponse: If the CLI answer command timed out. """ command_name, new_args = self._validate_input(function_name, arguments) reply_id = None # python 2 fix if "reply_id" in kwargs: reply_id = kwargs["reply_id"] enable_preview = None if "enable_preview" in kwargs: enable_preview = kwargs["enable_preview"] retry_connect = 2 if "retry_connect" in kwargs: retry_connect = kwargs["retry_connect"] if self._do_quit and "quit" not in command_name: raise AssertionError("Socket already terminated.") result_parser = functions[function_name][FUNC_RES] result_timeout = functions[function_name][FUNC_TIME] if "result_timeout" in kwargs: result_timeout = kwargs["result_timeout"] modifier = [] # reply id modifier if reply_id: if not isinstance(reply_id, int): # reply id modifier workaround if function_name in reply_functions: alternative_command = reply_functions[function_name] logger.warn("Trying to substitute command \"{cmd}\" to \"{alt}\" to provide backwards compatibiltity for the reply parameter.\n" "Please note this is *very* hacky and should NOT be trusted or used!!\n" "See https://github.com/luckydonald/pytg/issues/65 for details.".format(cmd=function_name, alt=alternative_command)) arguments = list(arguments) # because it is a tuple. arguments[0] = reply_id # should - in theory - replace the peer with the reply id. del kwargs["reply_id"] # so we don't try to substitute again. # This is at least the syntax of msg -> reply return self.execute_function(alternative_command, *arguments, **kwargs) else: raise AttributeError("reply_id keyword argument is not integer. " "Please use the reply methods with the permantent-msg-ids instead!") else: modifier.append("[reply =%i]" % reply_id) # preview modifier modifier.append("[enable_preview]" if enable_preview else "[disable_preview]") modifier_str = " ".join(modifier) try: request = self._build_request(command_name, new_args, modifier=modifier_str) if result_timeout: result = self._do_send(request, answer_timeout=result_timeout, retry_connect=retry_connect) else: result = self._do_send(request, answer_timeout=self.default_answer_timeout, retry_connect=retry_connect) except ConnectionError: raise except NoResponse: raise except Exception as err: args_ = inspect.getargspec(result_parser)[0] if "exception" not in args_: logger.exception("Result parser does not allow exceptions, but we got one: ") raise IllegalResponseException("Result parser does not allow exceptions.") try: return_result = result_parser(exception=err) return return_result except TypeError: logger.error("Result parser did not allow exceptions.") raise # end try _do_command if inspect.isclass(result_parser): assert issubclass(result_parser, ResultParser) # if it is a class it should subclass ResultParser. result_parser = result_parser() # get an instance # end if if result_parser != res.raw: # skip json'ing stuff marked as raw output. try: json_dict = json.loads(result) message = DictObject.objectify(json_dict) message = fix_message(message) result = message except: logger.exception("Parsing of answer failed, maybe not valid json?\nMessage:\n{}".format(result)) return IllegalResponseException("Parsing of answer failed, maybe not valid json?\nMessage: >{}<".format(result)) # TODO: This is *very* bad code. try: return result_parser(message) except FailException as e: e.command = request raise e # else (raw only) return result_parser(result) # raw() only
def handle_websocket(ws): if not ws: bottle.abort(400, 'Expected WebSocket request.') logger.debug(ws) session = bottle.request.environ.get('beaker.session', {}) username = session.get('username', 'anonymous') response = { 'event': "session.state", 'result': "FAIL", 'status': "not authenticated", } if username != 'anonymous' or \ bottle.request.remote_addr == '127.0.0.1': web_clients[ws] = { 'username': username, 'lock': threading.Lock() } response = { 'event': "session.state", 'result': "SUCCESS", 'status': "connected", 'username': username, } protected_ws_send(ws, response) else: ws.send(json.dumps(response)) bottle.abort(401, 'Unauthorized.') return while True: try: msg = ws.receive() if msg is None: continue logger.debug('%s@%s %s', username, bottle.request.remote_addr, msg) data = DictObject() try: data = DictObject(json.loads(msg)) except Exception, e: logger.exception('message is not valid json data: %s', e) continue logger.debug('<%s', data) response = DictObject() channel, command = data.event.split('.',1) if channel == 'session': if command == 'state': response.result = "SUCCESS" response.status = "connected" response.username = username else: logger.error("unknown command '%s'", command) elif channel == 'telegram': cmd = getattr(tg.sender, command, None) if cmd: try: response = cmd(*data.get('args',[])) logger.debug('>%s', response) if type(response) != DictObject: response = DictObject({ 'contents': response }) if command == 'dialog_list': for c in response['contents']: last_message = tg.sender.history('%s#%s' % (c.peer_type, c.peer_id), 1) if len(last_message): c.last_timestamp = last_message[0].date if c.peer_type == 'chat': info = tg.sender.chat_info('%s#%s' % (c.peer_type, c.peer_id)) c.update(info) elif c.peer_type == 'channel': try: admins = tg.sender.channel_get_admins('%s#%s' % (c.peer_type, c.peer_id)) members = tg.sender.channel_get_members('%s#%s' % (c.peer_type, c.peer_id)) c.own = True for m in members: if m in admins: m.admin = True c.members = members except IllegalResponseException: pass elif command == 'history': if response.get('contents'): has_media = False for msg in response['contents']: if msg.get('media',''): has_media = True msg.media.complete = False if has_media: threading.Thread(target=history_download_media, args=(ws, data, response)).start() except NoResponse as e: logger.warning('%s', e) except Exception as e: logger.exception('%s', e) else: logger.error("unknown command '%s'", command) else: logger.error("unknown channel '%s'", channel) if response: response.event = data.event if data.get('args'): response.args = data.args if data.get('extra'): response.extra = data.extra protected_ws_send(ws,response) except WebSocketError: if ws in web_clients: del web_clients[ws] break
def execute_function(self, function_name, *arguments, **kwargs): """ Execute a function. Will check a bit, if the parameters looks fitting. If you specify retry_connect=int keyword. This is wrapped by .execute_function() to support both py3 and py2 syntax. :param function_name: The function name. :type function_name: str Now you may apply your arguments for that command. :keyword reply_id: The message id which this command is a reply to. (will be ignored on non-sending commands) :type reply_id: int or None :keyword enable_preview: If the URL found in a message should have a preview. Defaults to False. (Will be ignored by the CLI with non-sending commands) :type enable_preview: bool :keyword retry_connect: How often it should try to reconnect (-1 = infinite times) or fail if it can't establish the first connection. (default is 2) :type retry_connect: int :return: parsed result/exception :rtype: Object or IllegalResponseException :raises pytg.exceptions.NoResponse: If the CLI answer command timed out. """ command_name, new_args = self._validate_input(function_name, arguments) reply_id=None # python 2 fix if "reply_id" in kwargs: reply_id = kwargs["reply_id"] enable_preview=None if "enable_preview" in kwargs: enable_preview = kwargs["enable_preview"] retry_connect=2 if "retry_connect" in kwargs: retry_connect = kwargs["retry_connect"] if self._do_quit and not "quit" in command_name: raise AssertionError("Socket already terminated.") result_parser = functions[function_name][FUNC_RES] result_timeout = functions[function_name][FUNC_TIME] try: if result_timeout: result = self._do_command(command_name, new_args, answer_timeout=result_timeout, retry_connect=retry_connect, enable_preview=enable_preview, reply_id=reply_id) else: result = self._do_command(command_name, new_args, answer_timeout=self.default_answer_timeout, retry_connect=retry_connect, enable_preview=enable_preview, reply_id=reply_id) except ConnectionError as err: raise except NoResponse as err: args_ = inspect.getargspec(result_parser)[0] if not "exception" in args_: logger.exception("Result parser does not allow exceptions, but we got one: ") raise IllegalResponseException("Result parser does not allow exceptions.") try: return_result = result_parser(exception=err) return return_result except TypeError: logger.error("Result parser did not allow exceptions.") raise if result_parser != res.raw: # skip json'ing stuff marked as raw output. try: json_dict = json.loads(result) message = DictObject.objectify(json_dict) message = fix_message(message) except: logger.exception("Parsing of answer failed, maybe not valid json?\nMessage: >{}<".format(result)) #result_parser todo return IllegalResponseException("Parsing of answer failed, maybe not valid json?\nMessage: >{}<".format(result)) #TODO: This is *very* bad code. return result_parser(message) return result_parser(result) # raw()
def get_json(url, objectify=True, **kwargs): kwargs.setdefault("headers", HEADERS) json = requests.get(url, **kwargs).json() if objectify: return DictObject.objectify(json) return json
def main(): global logger global scheduler global chatbot global chat_events global message_triggers global configuration parser = argparse.ArgumentParser(description="Telegram bot program") parser.add_argument("-l", "--log", help="File to write log", default=None, metavar="FILE") parser.add_argument("-v", "--verbose", help="Enable verbose mode", default=None) parser.add_argument("-c", "--config_file", help="Set configuration file", type=argparse.FileType('r')) args = parser.parse_args() #Logger configuration logging_level = None if args.verbose: logging_level = logging.INFO logger = tglog.config_logger(name = LOGGER_NAME, log_file = args.log, replace_stdout=True, logLevel=logging_level) #Configuration file config_file = args.config_file config = configparser.RawConfigParser() if not config_file is None: config.readfp(config_file) else: config_path = config_file_path() logger.info("Loading configuration file: {file}".format(file=config_path)) if config_path is None or not os.path.isfile(config_path): logger.error("Config file:{config_file} doesn't exist.".format(config_file=config_path)) logger.error("Please provide a configuration file via -c argument or setting up {var_name} environment variable.".format(var_name=CONFIG_ENV_VAR)) return 1 config.read(config_path) configuration = config logger.info("Configuration file loaded sucessfully") # Load chat events events_file = config.get('Chat events', 'file_path') with open(events_file) as data_file: chat_events = json.load(data_file) chat_events = DictObject.objectify(chat_events) logger.info("Loading chat events...") # Load message events load_message_triggers() #Chat bot configuration chatbot_db = config.get('Chatterbot', 'db_path') chatbot = ChatBot("Terminal", storage_adapter="chatterbot.adapters.storage.JsonDatabaseAdapter", logic_adapter="chatterbot.adapters.logic.EngramAdapter", io_adapter="chatterbot.adapters.io.TerminalAdapter", database=chatbot_db, logging=True) logger.info("Chatterbot initialized...") # Load message commands sender = TelegramSender() commands.load_commands(sender, logger) #Telegram listener create_url.url_format = config.get('Telegram','url_format') create_url.bot_token = config.get('Telegram', 'bot_token') if create_url.bot_token == '': logger.error("bot_token is missing, please add a token to tgbot.cgf") return 1 try: logger.info("Retrieving bot profile...") get_bot_profile() logger.info("Listening for incoming messages...") while True: get_updates() except GeneratorExit: pass except KeyboardInterrupt: pass else: pass #Finish logger.info("Telegram bot terminated")
def main(): global logger global scheduler global chatbot global chat_events global message_triggers global configuration parser = argparse.ArgumentParser(description="Telegram bot program") parser.add_argument("-l", "--log", help="File to write log", default=None, metavar="FILE") parser.add_argument("-a", "--authorization-token", metavar="AUTHORIZATION_TOKEN", help="Set new Telegram authorization token", default=None) parser.add_argument("-v", "--verbose", help="Enable verbose mode", action='store_true', default=None) parser.add_argument("-t", "--train", help="Train chat bot based on the english corpus", action='store_true', default=None) parser.add_argument("-c", "--config-file", metavar="CONFIG_FILE", help="Set configuration file", type=argparse.FileType('r')) args = parser.parse_args() #Logger configuration logging_level = None if args.verbose: logging_level = logging.INFO logger = tglog.config_logger(name = LOGGER_NAME, log_file = args.log, replace_stdout=True, logLevel=logging_level) #Configuration file config_file = args.config_file config = configparser.RawConfigParser() if not config_file is None: config.readfp(config_file) else: config_path = config_file_path() logger.info("Loading configuration file: {file}".format(file=config_path)) if config_path is None or not os.path.isfile(config_path): logger.error("Config file:{config_file} doesn't exist.".format(config_file=config_path)) logger.error("Please provide a configuration file via -c argument or setting up {var_name} environment variable.".format(var_name=CONFIG_ENV_VAR)) return 1 config.read(config_path) configuration = config logger.info("Configuration file loaded sucessfully") # Set new token if necessary if args.authorization_token: config.set('Telegram', 'bot_token', args.authorization_token) with open(config_path, 'w') as configfile: config.write(configfile) logger.info('New authorization token saved.') # Get Telegram API properties create_url.url_format = config.get('Telegram','url_format') create_url.bot_token = config.get('Telegram', 'bot_token') if create_url.bot_token == 'TOKEN_BOT': logger.error("bot_token is missing, please add a token to tgbot.cgf") logger.error("Full config path: " + config_file_path()) return 1 # Load chat events events_file = config.get('Chat events', 'file_path') with open(events_file) as data_file: chat_events = json.load(data_file) chat_events = DictObject.objectify(chat_events) logger.info("Loading chat events...") # Load message events load_message_triggers() # Load permissions load_permissions() # Chat bot configuration chatbot_db = config.get('Chatterbot', 'db_path') try: chatbot = init_chatbot(chatbot_db) except MissingCorpusError: logger.warning("Corpora needs to be downloaded in order to use Chatterbot... downloading") textblob.download_corpora.download_all() chatbot = init_chatbot(chatbot_db) if args.train: logger.info("Bot is being trained...") chatbot.set_trainer(ChatterBotCorpusTrainer) chatbot.train("chatterbot.corpus.english") logger.info("Chatterbot initialized...") logger.info("Bot token: " + create_url.bot_token) # Load message commands sender = TelegramSender() commands.load_commands(sender, logger) # Telegram listener try: logger.info("Retrieving bot profile...") get_bot_profile() logger.info("Listening for incoming messages...") while True: get_updates() except GeneratorExit: clean_program() except KeyboardInterrupt: clean_program() else: clean_program() #Finish logger.info("Telegram bot terminated")