test
This commit is contained in:
543
xmpp_tg/xmpp.py
543
xmpp_tg/xmpp.py
@@ -99,242 +99,6 @@ class MessageHandler():
|
|||||||
reply = trim(method.__doc__)
|
reply = trim(method.__doc__)
|
||||||
return reply
|
return reply
|
||||||
|
|
||||||
class XMPPTelegram(ComponentXMPP):
|
|
||||||
"""
|
|
||||||
Main XMPPTelegram class.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, config_dict):
|
|
||||||
"""
|
|
||||||
Transport initialization
|
|
||||||
:param config_dict:
|
|
||||||
"""
|
|
||||||
|
|
||||||
ComponentXMPP.__init__(self, config_dict['jid'], config_dict['secret'], config_dict['server'],
|
|
||||||
config_dict['port'])
|
|
||||||
|
|
||||||
self.auto_authorize = True
|
|
||||||
# self.auto_subscribe = True
|
|
||||||
|
|
||||||
self.config = config_dict
|
|
||||||
self.accounts = dict() # personal configuration per JID
|
|
||||||
self.tg_connections = dict()
|
|
||||||
self.tg_phones = dict()
|
|
||||||
self.tg_dialogs = dict()
|
|
||||||
self.contact_list = dict()
|
|
||||||
|
|
||||||
self.db_connection = self.init_database()
|
|
||||||
|
|
||||||
self.register_plugin('xep_0030') # Service discovery
|
|
||||||
self.register_plugin('xep_0054') # VCard-temp
|
|
||||||
self.register_plugin('xep_0172') # NickNames
|
|
||||||
|
|
||||||
self.add_event_handler('message', self.message)
|
|
||||||
self.add_event_handler('presence_unsubscribe', self.event_presence_unsub)
|
|
||||||
self.add_event_handler('presence_unsubscribed', self.event_presence_unsub)
|
|
||||||
self.add_event_handler('presence', self.event_presence)
|
|
||||||
self.add_event_handler('got_online', self.handle_online)
|
|
||||||
self.add_event_handler('got_offline', self.handle_offline)
|
|
||||||
self.add_event_handler('session_start', self.handle_start)
|
|
||||||
|
|
||||||
|
|
||||||
self.plugin['xep_0030'].add_identity(
|
|
||||||
category='gateway',
|
|
||||||
itype='telegram',
|
|
||||||
name=self.config['title'],
|
|
||||||
node=self.boundjid.node,
|
|
||||||
jid=self.boundjid.bare,
|
|
||||||
lang='no'
|
|
||||||
)
|
|
||||||
|
|
||||||
vcard = self.plugin['xep_0054'].make_vcard()
|
|
||||||
vcard['FN'] = self.config['title']
|
|
||||||
vcard['DESC'] = 'Send !help for information'
|
|
||||||
self.plugin['xep_0054'].publish_vcard(jid=self.boundjid.bare, vcard=vcard)
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
"""
|
|
||||||
Destructor
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
self.db_connection.close()
|
|
||||||
|
|
||||||
def handle_start(self, arg):
|
|
||||||
"""
|
|
||||||
Successful connection to Jabber server
|
|
||||||
:param arg:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
users = self.db_connection.execute("SELECT * FROM accounts").fetchall()
|
|
||||||
for usr in users:
|
|
||||||
self.accounts[usr['jid']] = usr
|
|
||||||
self.send_presence(pto=usr['jid'], pfrom=self.boundjid.bare, ptype='probe')
|
|
||||||
|
|
||||||
def message(self, iq):
|
|
||||||
"""
|
|
||||||
Message from XMPP
|
|
||||||
:param iq:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
jid = iq['from'].bare
|
|
||||||
|
|
||||||
if iq['to'] == self.config['jid'] and iq['type'] == 'chat': # message to gateway
|
|
||||||
if iq['body'].startswith('!'):
|
|
||||||
self.process_command(iq)
|
|
||||||
else:
|
|
||||||
self.gate_reply_message(iq, 'Only commands accepted. Try !help for more info.')
|
|
||||||
|
|
||||||
elif iq['type'] == 'chat': # --- outgoing message ---
|
|
||||||
if jid in self.tg_connections and self.tg_connections[jid].is_user_authorized():
|
|
||||||
if iq['body'].startswith('!'): # it is command!
|
|
||||||
if iq['to'].bare.startswith( ('u', 'b') ):
|
|
||||||
self.process_chat_user_command(iq)
|
|
||||||
elif iq['to'].bare.startswith('g') or iq['to'].bare.startswith('s') or iq['to'].bare.startswith('c'):
|
|
||||||
self.process_chat_group_command(iq)
|
|
||||||
else:
|
|
||||||
self.gate_reply_message(iq, 'Error.')
|
|
||||||
|
|
||||||
else: # -- normal message --
|
|
||||||
try:
|
|
||||||
tg_id = int(iq['to'].node[1:])
|
|
||||||
except ValueError:
|
|
||||||
self.gate_reply_message(iq, 'Invalid JID')
|
|
||||||
tg_peer = None
|
|
||||||
msg = iq['body']
|
|
||||||
reply_mid = None
|
|
||||||
|
|
||||||
if msg.startswith('>'): # quoting check
|
|
||||||
msg_lines = msg.split('\n')
|
|
||||||
matched = re.match(r'>[ ]*(?P<mid>[\d]+)[ ]*', msg_lines[0]) #TODO: check regex
|
|
||||||
matched = matched.groupdict() if matched else {}
|
|
||||||
|
|
||||||
if 'mid' in matched: # citation
|
|
||||||
reply_mid = int(matched['mid'])
|
|
||||||
msg = '\n'.join(msg_lines[1:])
|
|
||||||
|
|
||||||
if iq['to'].bare.startswith( ('u', 'b') ): # normal user
|
|
||||||
tg_peer = InputPeerUser(tg_id, self.tg_dialogs[jid]['users'][tg_id].access_hash)
|
|
||||||
elif iq['to'].bare.startswith('g'): # generic group
|
|
||||||
tg_peer = InputPeerChat(tg_id)
|
|
||||||
elif iq['to'].bare.startswith( ('s', 'c') ): # supergroup
|
|
||||||
tg_peer = InputPeerChannel(tg_id, self.tg_dialogs[jid]['supergroups'][tg_id].access_hash)
|
|
||||||
|
|
||||||
# peer OK.
|
|
||||||
if tg_peer:
|
|
||||||
result = None
|
|
||||||
|
|
||||||
# detect media
|
|
||||||
if msg.startswith('http') and re.match(r'(?:http\:|https\:)?\/\/.*\.(?:' + self.config['media_external_formats'] + ')', msg):
|
|
||||||
urls = re.findall(r'(?:http\:|https\:)?\/\/.*\.(?:' + self.config['media_external_formats'] + ')', msg)
|
|
||||||
message = msg.replace(urls[0], '')
|
|
||||||
media = InputMediaPhotoExternal(urls[0], "Image")
|
|
||||||
try:
|
|
||||||
result = self.tg_connections[jid].invoke(SendMediaRequest(tg_peer, media, message, random_id = generate_random_long(), reply_to_msg_id = reply_mid))
|
|
||||||
except Exception:
|
|
||||||
print('Media upload failed.')
|
|
||||||
|
|
||||||
# media send failed. #
|
|
||||||
if not result:
|
|
||||||
result = self.tg_connections[jid].invoke(SendMessageRequest(tg_peer, msg, generate_random_long(), reply_to_msg_id=reply_mid))
|
|
||||||
|
|
||||||
# find sent message id and save it
|
|
||||||
if result and hasattr(result, 'id'): # update id
|
|
||||||
msg_id = result.id
|
|
||||||
self.tg_dialogs[jid]['messages'][tg_id] = {'id': msg_id, 'body': msg}
|
|
||||||
#self.send_message(mto=iq['from'], mfrom=iq['to'], mtype='chat', mbody='[Your MID:{}]'.format(msg_id))
|
|
||||||
|
|
||||||
|
|
||||||
def event_presence_unsub(self, presence):
|
|
||||||
return
|
|
||||||
|
|
||||||
def event_presence(self, presence):
|
|
||||||
"""
|
|
||||||
Presence handler
|
|
||||||
:param presence:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
ptype = presence['type']
|
|
||||||
|
|
||||||
|
|
||||||
# handle "online" to transport:
|
|
||||||
if ptype == 'available' and presence['to'].bare == self.boundjid.bare:
|
|
||||||
self.handle_online(presence, False) # handle online
|
|
||||||
elif ptype == 'subscribe':
|
|
||||||
self.send_presence(pto=presence['from'].bare, pfrom=presence['to'].bare, ptype='subscribed')
|
|
||||||
elif ptype == 'subscribed':
|
|
||||||
pass
|
|
||||||
elif ptype == 'unsubscribe':
|
|
||||||
pass
|
|
||||||
elif ptype == 'unsubscribed':
|
|
||||||
pass
|
|
||||||
elif ptype == 'probe':
|
|
||||||
self.send_presence(pto=presence['from'], pfrom=presence['to'], ptype='available')
|
|
||||||
elif ptype == 'unavailable':
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# self.send_presence(pto=presence['from'], pfrom=presence['to'])
|
|
||||||
pass
|
|
||||||
|
|
||||||
def handle_online(self, event, sync_roster = True):
|
|
||||||
"""
|
|
||||||
Gateway's subscriber comes online
|
|
||||||
:param event:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
jid = event['from'].bare
|
|
||||||
to = event['to'].bare
|
|
||||||
|
|
||||||
# maybe if i'll ignore it — it will go ahead
|
|
||||||
if to != self.boundjid.bare:
|
|
||||||
return
|
|
||||||
|
|
||||||
if jid not in self.tg_connections:
|
|
||||||
result = self.db_connection.execute("SELECT * FROM accounts WHERE jid = ?", (jid,)).fetchone()
|
|
||||||
|
|
||||||
if result is not None:
|
|
||||||
self.spawn_tg_client(jid, result['tg_phone'])
|
|
||||||
else:
|
|
||||||
if not (self.tg_connections[jid].is_connected()):
|
|
||||||
self.tg_connections[jid].connect()
|
|
||||||
self.tg_connections[jid].invoke(UpdateStatusRequest(offline=False))
|
|
||||||
|
|
||||||
self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='online', pstatus='connected')
|
|
||||||
self.tg_process_dialogs(jid, sync_roster) # do not sync roster if we already have connection!
|
|
||||||
|
|
||||||
|
|
||||||
def handle_offline(self, event):
|
|
||||||
"""
|
|
||||||
Gateway's subscriber comes offline.
|
|
||||||
:param event:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
jid = event['from'].bare
|
|
||||||
|
|
||||||
# keep telegram online ?
|
|
||||||
if self.accounts[jid]['keep_online']:
|
|
||||||
return
|
|
||||||
|
|
||||||
if jid in self.tg_connections:
|
|
||||||
self.tg_connections[jid].invoke(UpdateStatusRequest(offline=True))
|
|
||||||
self.tg_connections[jid].disconnect()
|
|
||||||
|
|
||||||
def handle_interrupt(self, signal, frame):
|
|
||||||
"""
|
|
||||||
Interrupted (Ctrl+C).
|
|
||||||
:param event:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
|
|
||||||
for jid in self.tg_connections:
|
|
||||||
print('Disconnecting: %s' % jid)
|
|
||||||
self.tg_connections[jid].invoke(UpdateStatusRequest(offline=True))
|
|
||||||
self.tg_connections[jid].disconnect()
|
|
||||||
for contact_jid, contact_nickname in self.contact_list[jid].items():
|
|
||||||
self.send_presence(pto=jid, pfrom=contact_jid, ptype='unavailable')
|
|
||||||
self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='unavailable')
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
class GateMessageHandler(MessageHandler):
|
class GateMessageHandler(MessageHandler):
|
||||||
def configure(hndl, self):
|
def configure(hndl, self):
|
||||||
"""Get config/set config options"""
|
"""Get config/set config options"""
|
||||||
@@ -571,39 +335,6 @@ class XMPPTelegram(ComponentXMPP):
|
|||||||
|
|
||||||
'!roster - Lists yout TG roster\n')
|
'!roster - Lists yout TG roster\n')
|
||||||
|
|
||||||
|
|
||||||
def process_command(self, msg):
|
|
||||||
"""
|
|
||||||
Commands to gateway, users or chats (starts with !)
|
|
||||||
:param iq:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
logging.info("received message "+str(msg["body"])+" from "+str(msg["from"]))
|
|
||||||
is_command = msg["body"].startswith("!") and msg["body"][1] != "_"
|
|
||||||
|
|
||||||
if is_command:
|
|
||||||
command = msg["body"].split(" ")[0][1:]
|
|
||||||
handler = self.GateMessageHandler(msg)._handler
|
|
||||||
try:
|
|
||||||
reply = str(handler(self))
|
|
||||||
except Exception as e:
|
|
||||||
if self.config["debug"]:
|
|
||||||
reply = "******* DEBUG MODE ACTIVE *********\n"
|
|
||||||
reply += "An Exception occured while executing this command:"
|
|
||||||
reply += traceback.format_exc()
|
|
||||||
else:
|
|
||||||
if isinstance(e, NotAuthorizedError):
|
|
||||||
reply = str(e)
|
|
||||||
elif isinstance(e, self.MessageHandler.WrongNumberOfArgsError):
|
|
||||||
reply = str(e)
|
|
||||||
else:
|
|
||||||
logging.error("Exception in command from {}, command was '{}'".format(msg["from"],msg["body"]))
|
|
||||||
traceback.print_exc()
|
|
||||||
reply = "Internal error, please contact Sysadmin"
|
|
||||||
if reply is not None:
|
|
||||||
self.gate_reply_message(msg, reply)
|
|
||||||
#msg.reply(reply).send()
|
|
||||||
|
|
||||||
class ChatCommandHandler(MessageHandler):
|
class ChatCommandHandler(MessageHandler):
|
||||||
|
|
||||||
def __init__(self, msg):
|
def __init__(self, msg):
|
||||||
@@ -647,6 +378,272 @@ class XMPPTelegram(ComponentXMPP):
|
|||||||
del(self.tg_dialogs[hndl.jid]['messages'][hndl.tg_id])
|
del(self.tg_dialogs[hndl.jid]['messages'][hndl.tg_id])
|
||||||
self.tg_connections[hndl.jid].invoke( DeleteMessagesRequest([msg_id], revoke = True) )
|
self.tg_connections[hndl.jid].invoke( DeleteMessagesRequest([msg_id], revoke = True) )
|
||||||
|
|
||||||
|
class XMPPTelegram(ComponentXMPP):
|
||||||
|
"""
|
||||||
|
Main XMPPTelegram class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, config_dict):
|
||||||
|
"""
|
||||||
|
Transport initialization
|
||||||
|
:param config_dict:
|
||||||
|
"""
|
||||||
|
|
||||||
|
ComponentXMPP.__init__(self, config_dict['jid'], config_dict['secret'], config_dict['server'],
|
||||||
|
config_dict['port'])
|
||||||
|
|
||||||
|
self.auto_authorize = True
|
||||||
|
# self.auto_subscribe = True
|
||||||
|
|
||||||
|
self.config = config_dict
|
||||||
|
self.accounts = dict() # personal configuration per JID
|
||||||
|
self.tg_connections = dict()
|
||||||
|
self.tg_phones = dict()
|
||||||
|
self.tg_dialogs = dict()
|
||||||
|
self.contact_list = dict()
|
||||||
|
|
||||||
|
self.db_connection = self.init_database()
|
||||||
|
|
||||||
|
self.register_plugin('xep_0030') # Service discovery
|
||||||
|
self.register_plugin('xep_0054') # VCard-temp
|
||||||
|
self.register_plugin('xep_0172') # NickNames
|
||||||
|
|
||||||
|
self.add_event_handler('message', self.message)
|
||||||
|
self.add_event_handler('presence_unsubscribe', self.event_presence_unsub)
|
||||||
|
self.add_event_handler('presence_unsubscribed', self.event_presence_unsub)
|
||||||
|
self.add_event_handler('presence', self.event_presence)
|
||||||
|
self.add_event_handler('got_online', self.handle_online)
|
||||||
|
self.add_event_handler('got_offline', self.handle_offline)
|
||||||
|
self.add_event_handler('session_start', self.handle_start)
|
||||||
|
|
||||||
|
|
||||||
|
self.plugin['xep_0030'].add_identity(
|
||||||
|
category='gateway',
|
||||||
|
itype='telegram',
|
||||||
|
name=self.config['title'],
|
||||||
|
node=self.boundjid.node,
|
||||||
|
jid=self.boundjid.bare,
|
||||||
|
lang='no'
|
||||||
|
)
|
||||||
|
|
||||||
|
vcard = self.plugin['xep_0054'].make_vcard()
|
||||||
|
vcard['FN'] = self.config['title']
|
||||||
|
vcard['DESC'] = 'Send !help for information'
|
||||||
|
self.plugin['xep_0054'].publish_vcard(jid=self.boundjid.bare, vcard=vcard)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
"""
|
||||||
|
Destructor
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
self.db_connection.close()
|
||||||
|
|
||||||
|
def handle_start(self, arg):
|
||||||
|
"""
|
||||||
|
Successful connection to Jabber server
|
||||||
|
:param arg:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
users = self.db_connection.execute("SELECT * FROM accounts").fetchall()
|
||||||
|
for usr in users:
|
||||||
|
self.accounts[usr['jid']] = usr
|
||||||
|
self.send_presence(pto=usr['jid'], pfrom=self.boundjid.bare, ptype='probe')
|
||||||
|
|
||||||
|
def message(self, iq):
|
||||||
|
"""
|
||||||
|
Message from XMPP
|
||||||
|
:param iq:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
jid = iq['from'].bare
|
||||||
|
|
||||||
|
if iq['to'] == self.config['jid'] and iq['type'] == 'chat': # message to gateway
|
||||||
|
if iq['body'].startswith('!'):
|
||||||
|
self.process_command(iq)
|
||||||
|
else:
|
||||||
|
self.gate_reply_message(iq, 'Only commands accepted. Try !help for more info.')
|
||||||
|
|
||||||
|
elif iq['type'] == 'chat': # --- outgoing message ---
|
||||||
|
if jid in self.tg_connections and self.tg_connections[jid].is_user_authorized():
|
||||||
|
if iq['body'].startswith('!'): # it is command!
|
||||||
|
if iq['to'].bare.startswith( ('u', 'b') ):
|
||||||
|
self.process_chat_user_command(iq)
|
||||||
|
elif iq['to'].bare.startswith('g') or iq['to'].bare.startswith('s') or iq['to'].bare.startswith('c'):
|
||||||
|
self.process_chat_group_command(iq)
|
||||||
|
else:
|
||||||
|
self.gate_reply_message(iq, 'Error.')
|
||||||
|
|
||||||
|
else: # -- normal message --
|
||||||
|
try:
|
||||||
|
tg_id = int(iq['to'].node[1:])
|
||||||
|
except ValueError:
|
||||||
|
self.gate_reply_message(iq, 'Invalid JID')
|
||||||
|
tg_peer = None
|
||||||
|
msg = iq['body']
|
||||||
|
reply_mid = None
|
||||||
|
|
||||||
|
if msg.startswith('>'): # quoting check
|
||||||
|
msg_lines = msg.split('\n')
|
||||||
|
matched = re.match(r'>[ ]*(?P<mid>[\d]+)[ ]*', msg_lines[0]) #TODO: check regex
|
||||||
|
matched = matched.groupdict() if matched else {}
|
||||||
|
|
||||||
|
if 'mid' in matched: # citation
|
||||||
|
reply_mid = int(matched['mid'])
|
||||||
|
msg = '\n'.join(msg_lines[1:])
|
||||||
|
|
||||||
|
if iq['to'].bare.startswith( ('u', 'b') ): # normal user
|
||||||
|
tg_peer = InputPeerUser(tg_id, self.tg_dialogs[jid]['users'][tg_id].access_hash)
|
||||||
|
elif iq['to'].bare.startswith('g'): # generic group
|
||||||
|
tg_peer = InputPeerChat(tg_id)
|
||||||
|
elif iq['to'].bare.startswith( ('s', 'c') ): # supergroup
|
||||||
|
tg_peer = InputPeerChannel(tg_id, self.tg_dialogs[jid]['supergroups'][tg_id].access_hash)
|
||||||
|
|
||||||
|
# peer OK.
|
||||||
|
if tg_peer:
|
||||||
|
result = None
|
||||||
|
|
||||||
|
# detect media
|
||||||
|
if msg.startswith('http') and re.match(r'(?:http\:|https\:)?\/\/.*\.(?:' + self.config['media_external_formats'] + ')', msg):
|
||||||
|
urls = re.findall(r'(?:http\:|https\:)?\/\/.*\.(?:' + self.config['media_external_formats'] + ')', msg)
|
||||||
|
message = msg.replace(urls[0], '')
|
||||||
|
media = InputMediaPhotoExternal(urls[0], "Image")
|
||||||
|
try:
|
||||||
|
result = self.tg_connections[jid].invoke(SendMediaRequest(tg_peer, media, message, random_id = generate_random_long(), reply_to_msg_id = reply_mid))
|
||||||
|
except Exception:
|
||||||
|
print('Media upload failed.')
|
||||||
|
|
||||||
|
# media send failed. #
|
||||||
|
if not result:
|
||||||
|
result = self.tg_connections[jid].invoke(SendMessageRequest(tg_peer, msg, generate_random_long(), reply_to_msg_id=reply_mid))
|
||||||
|
|
||||||
|
# find sent message id and save it
|
||||||
|
if result and hasattr(result, 'id'): # update id
|
||||||
|
msg_id = result.id
|
||||||
|
self.tg_dialogs[jid]['messages'][tg_id] = {'id': msg_id, 'body': msg}
|
||||||
|
#self.send_message(mto=iq['from'], mfrom=iq['to'], mtype='chat', mbody='[Your MID:{}]'.format(msg_id))
|
||||||
|
|
||||||
|
|
||||||
|
def event_presence_unsub(self, presence):
|
||||||
|
return
|
||||||
|
|
||||||
|
def event_presence(self, presence):
|
||||||
|
"""
|
||||||
|
Presence handler
|
||||||
|
:param presence:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
ptype = presence['type']
|
||||||
|
|
||||||
|
|
||||||
|
# handle "online" to transport:
|
||||||
|
if ptype == 'available' and presence['to'].bare == self.boundjid.bare:
|
||||||
|
self.handle_online(presence, False) # handle online
|
||||||
|
elif ptype == 'subscribe':
|
||||||
|
self.send_presence(pto=presence['from'].bare, pfrom=presence['to'].bare, ptype='subscribed')
|
||||||
|
elif ptype == 'subscribed':
|
||||||
|
pass
|
||||||
|
elif ptype == 'unsubscribe':
|
||||||
|
pass
|
||||||
|
elif ptype == 'unsubscribed':
|
||||||
|
pass
|
||||||
|
elif ptype == 'probe':
|
||||||
|
self.send_presence(pto=presence['from'], pfrom=presence['to'], ptype='available')
|
||||||
|
elif ptype == 'unavailable':
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# self.send_presence(pto=presence['from'], pfrom=presence['to'])
|
||||||
|
pass
|
||||||
|
|
||||||
|
def handle_online(self, event, sync_roster = True):
|
||||||
|
"""
|
||||||
|
Gateway's subscriber comes online
|
||||||
|
:param event:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
jid = event['from'].bare
|
||||||
|
to = event['to'].bare
|
||||||
|
|
||||||
|
# maybe if i'll ignore it — it will go ahead
|
||||||
|
if to != self.boundjid.bare:
|
||||||
|
return
|
||||||
|
|
||||||
|
if jid not in self.tg_connections:
|
||||||
|
result = self.db_connection.execute("SELECT * FROM accounts WHERE jid = ?", (jid,)).fetchone()
|
||||||
|
|
||||||
|
if result is not None:
|
||||||
|
self.spawn_tg_client(jid, result['tg_phone'])
|
||||||
|
else:
|
||||||
|
if not (self.tg_connections[jid].is_connected()):
|
||||||
|
self.tg_connections[jid].connect()
|
||||||
|
self.tg_connections[jid].invoke(UpdateStatusRequest(offline=False))
|
||||||
|
|
||||||
|
self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='online', pstatus='connected')
|
||||||
|
self.tg_process_dialogs(jid, sync_roster) # do not sync roster if we already have connection!
|
||||||
|
|
||||||
|
|
||||||
|
def handle_offline(self, event):
|
||||||
|
"""
|
||||||
|
Gateway's subscriber comes offline.
|
||||||
|
:param event:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
jid = event['from'].bare
|
||||||
|
|
||||||
|
# keep telegram online ?
|
||||||
|
if self.accounts[jid]['keep_online']:
|
||||||
|
return
|
||||||
|
|
||||||
|
if jid in self.tg_connections:
|
||||||
|
self.tg_connections[jid].invoke(UpdateStatusRequest(offline=True))
|
||||||
|
self.tg_connections[jid].disconnect()
|
||||||
|
|
||||||
|
def handle_interrupt(self, signal, frame):
|
||||||
|
"""
|
||||||
|
Interrupted (Ctrl+C).
|
||||||
|
:param event:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
for jid in self.tg_connections:
|
||||||
|
print('Disconnecting: %s' % jid)
|
||||||
|
self.tg_connections[jid].invoke(UpdateStatusRequest(offline=True))
|
||||||
|
self.tg_connections[jid].disconnect()
|
||||||
|
for contact_jid, contact_nickname in self.contact_list[jid].items():
|
||||||
|
self.send_presence(pto=jid, pfrom=contact_jid, ptype='unavailable')
|
||||||
|
self.send_presence(pto=jid, pfrom=self.boundjid.bare, ptype='unavailable')
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def process_command(self, msg):
|
||||||
|
"""
|
||||||
|
Commands to gateway, users or chats (starts with !)
|
||||||
|
:param iq:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
logging.info("received message "+str(msg["body"])+" from "+str(msg["from"]))
|
||||||
|
is_command = msg["body"].startswith("!") and msg["body"][1] != "_"
|
||||||
|
|
||||||
|
if is_command:
|
||||||
|
command = msg["body"].split(" ")[0][1:]
|
||||||
|
handler = GateMessageHandler(msg)._handler
|
||||||
|
try:
|
||||||
|
reply = str(handler(self))
|
||||||
|
except Exception as e:
|
||||||
|
if self.config["debug"]:
|
||||||
|
reply = "******* DEBUG MODE ACTIVE *********\n"
|
||||||
|
reply += "An Exception occured while executing this command:"
|
||||||
|
reply += traceback.format_exc()
|
||||||
|
else:
|
||||||
|
if isinstance(e, NotAuthorizedError):
|
||||||
|
reply = str(e)
|
||||||
|
elif isinstance(e, MessageHandler.WrongNumberOfArgsError):
|
||||||
|
reply = str(e)
|
||||||
|
else:
|
||||||
|
logging.error("Exception in command from {}, command was '{}'".format(msg["from"],msg["body"]))
|
||||||
|
traceback.print_exc()
|
||||||
|
reply = "Internal error, please contact Sysadmin"
|
||||||
|
if reply is not None:
|
||||||
|
self.gate_reply_message(msg, reply)
|
||||||
|
#msg.reply(reply).send()
|
||||||
|
|
||||||
def process_chat_user_command(self, msg):
|
def process_chat_user_command(self, msg):
|
||||||
logging.info("received command "+str(msg["body"])+" from "+str(msg["from"])+" for "+str(msg["to"]))
|
logging.info("received command "+str(msg["body"])+" from "+str(msg["from"])+" for "+str(msg["to"]))
|
||||||
@@ -654,7 +651,7 @@ class XMPPTelegram(ComponentXMPP):
|
|||||||
|
|
||||||
if is_command:
|
if is_command:
|
||||||
command = msg["body"].split(" ")[0][1:]
|
command = msg["body"].split(" ")[0][1:]
|
||||||
handler = self.ChatCommandHandler(msg)._handler
|
handler = ChatCommandHandler(msg)._handler
|
||||||
try:
|
try:
|
||||||
reply = str(handler(self))
|
reply = str(handler(self))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -665,7 +662,7 @@ class XMPPTelegram(ComponentXMPP):
|
|||||||
else:
|
else:
|
||||||
if isinstance(e, NotAuthorizedError):
|
if isinstance(e, NotAuthorizedError):
|
||||||
reply = str(e)
|
reply = str(e)
|
||||||
elif isinstance(e, self.MessageHandler.WrongNumberOfArgsError):
|
elif isinstance(e, MessageHandler.WrongNumberOfArgsError):
|
||||||
reply = str(e)
|
reply = str(e)
|
||||||
else:
|
else:
|
||||||
logging.error("Exception in command from {}, command was '{}'".format(msg["from"],msg["body"]))
|
logging.error("Exception in command from {}, command was '{}'".format(msg["from"],msg["body"]))
|
||||||
@@ -682,9 +679,7 @@ class XMPPTelegram(ComponentXMPP):
|
|||||||
'!s/find/replace - Edit last message. Use empty `find` to edit whole message and empty `replace` to delete it.\n'
|
'!s/find/replace - Edit last message. Use empty `find` to edit whole message and empty `replace` to delete it.\n'
|
||||||
'!block - Blacklists current user\n'
|
'!block - Blacklists current user\n'
|
||||||
'!unblock - Unblacklists current user\n'
|
'!unblock - Unblacklists current user\n'
|
||||||
'!remove - Removes history and contact from your contact list\n'
|
'!remove - Removes history and contact from your contact list\n' )
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def process_chat_group_command(self, iq):
|
def process_chat_group_command(self, iq):
|
||||||
parsed = iq['body'].split(' ')
|
parsed = iq['body'].split(' ')
|
||||||
|
|||||||
Reference in New Issue
Block a user