[SVN] updated version to 0.3.0

[FIX] fixed sending subscription request from groups that are removed or from what you've been left and also fixed double auth request
[UPD] now using telethon version == 0.18
[UPD] code optimized and reworked
[UPD] status updates are moved to separate thread to use timer
[UPD] slightly changed status handling (now Available has "Online" status message, "Last seen recently" now is away, not XA, "Last seen ..." is now XA,  "Last seen long time ago" is now DND, chats are ffc)
[UPD] command "!del" removed and replaced with another, see above
[UPD] configuration options `xmpp_use_roster_exchange` and `xmpp_keep_online` was removed from configuration file
[UPD] [BREAK] database structure was changed; please, remove and re-create db.sqlite
[ADD] [BREAK] new options in config file: `logfile` (please, specify it!), and unneccessarry `tg_server_ip`, `tg_server_port`, `tg_server_dc`
[ADD] per-user configuration, parameters stored in database. configurable params:
      - use_roster_exchange: use XEP-0144 for roster import (default: false) (recommended: true, if your client supports that XEP)
      - keep_online: keep telegram session even if jabber goes offline (default: false) (recommended: true, if you wants to receive all events as offline messages when you will go online)
      - status_update_interval: interval (sec.) in what we will update all contact statuses to prevent presence spamming, because telegram sending status updates every fucking second (default: 60)
      To modify your personal config, please, send !configure to gateway
[ADD] added new commands to gateway:
      !configure (for configuration update)
      !add @contact (to find Telegram contact and try to start conversation; any format accepted (t.me link, @username or maybe phone, I don't know... )
      !join t.me/joinchat/secret (to join Telegram conference via invite link, https://t.me/joinchat/xxxxx accepted)
      !group name @contact (try to create normal group with @contact; you can add more later) [UNTESTED]
      !supergroup name (try to create supergroup) [UNTESTED]
      !channel name (try to create channel) [UNTESTED]
      !name first last (change telegram name)
      !username usernme (change telegram @username)
      !about some about text (change about text)
[ADD] added new commands to dialogs with normal users:
      !help
      !block (blacklists user)
      !unblock (unblacklists user)
[ADD] added new commands to group/channel dialogs:
      !help
      !leave (leave current group or supergroup)
      !invite (invite @user to current group/supergroup)
      !kick (kicks @user to/from group/supergroup)

... and also small fixes and improvements
This commit is contained in:
annelin
2018-07-01 09:42:35 +00:00
parent ea15b74348
commit 0f648e6bd4
6 changed files with 258 additions and 229 deletions

View File

@@ -42,30 +42,32 @@ class TelegramGateClient(TelegramClient):
self.xmpp_gate = xmpp_gate
self.jid = jid
self.phone = phone
self.user_options = {'nl_after_info': True, 'status_update_interval': 60}
self._media_queue = queue.Queue()
self._media_thread = threading.Thread(name='MediaDownloaderThread', target=self.media_thread_downloader)
self._media_thread.start()
self._status_updates = dict()
self._status_update_thread = threading.Thread(name = 'StatusUpdateThread', target = self.status_updater_thread)
self._groups_users = dict()
self._message_cache_users = dict()
self._message_cache_groups = dict()
self._message_cache_supergroups = dict()
self._status_last = dict()
self._del_pts = 0
def xmpp_update_handler(self, obj):
print('new update for ' + self.jid)
print(type(obj), obj.__dict__)
print("We have received update for <%s>" % self.jid)
print(obj)
# link to self-user #
# we have received some updates, so we're logined and can get <me> object and start mtd / upd threads #
if not self.me:
me = self.get_me()
self.me = InputPeerUser(me.id, me.access_hash)
self._media_thread.start()
self._status_update_thread.start()
'''
Боты
@@ -80,7 +82,7 @@ class TelegramGateClient(TelegramClient):
# Здесь будет очень длинный пиздец ^__^
nl = '\n' if self.user_options['nl_after_info'] else ''
nl = '\n'
try:
@@ -95,16 +97,8 @@ class TelegramGateClient(TelegramClient):
# message from normal group #
if type(obj) in [UpdateShortChatMessage] and not obj.out:
fwd_from = self._process_forward_msg(obj) if obj.fwd_from else '' # process forward messages
nickname = ''
# get sender information from chat info
if obj.from_id not in self._groups_users:
chat_info = self.invoke(GetFullChatRequest(obj.chat_id))
for usr in chat_info.users:
self._groups_users[usr.id] = usr
nickname = display_tg_name(self._groups_users[obj.from_id].first_name, self._groups_users[obj.from_id].last_name)
usr = self._get_user_information(obj.from_id)
nickname = display_tg_name(usr)
# send message
self.gate_send_message(mfrom='g' + str(obj.chat_id), mbody ='[MSG {}] [User: {}] {}{}'.format(obj.id, nickname, fwd_from, obj.message) )
@@ -159,7 +153,7 @@ class TelegramGateClient(TelegramClient):
# get sender information from chat info #
if not is_user and not obj.message.post:
usr = self._get_user_information(obj.message.from_id)
nickname = display_tg_name(usr.first_name, usr.last_name)
nickname = display_tg_name(usr)
msg = '[User: {}] {}'.format(nickname, msg)
@@ -183,34 +177,24 @@ class TelegramGateClient(TelegramClient):
# Status Updates #
if type(obj) is UpdateUserStatus:
# save last update time #
if (obj.user_id in self._status_last) and ( (time.time() - self._status_last[obj.user_id]['time'] < self.user_options['status_update_interval']) or self._status_last[obj.user_id]['status'] == obj.status ):
return
self._status_last[obj.user_id] = {'status': obj.status, 'time': time.time()}
# process status update #
if type(obj.status) is UserStatusOnline:
self.xmpp_gate.send_presence( pto=self.jid, pfrom='u'+str(obj.user_id)+'@'+self.xmpp_gate.config['jid'])
self._status_updates[str(obj.user_id)] = { 'status': None, 'message': 'Online' }
elif type(obj.status) is UserStatusOffline:
self.xmpp_gate.send_presence( pto=self.jid, pfrom='u'+str(obj.user_id)+'@'+self.xmpp_gate.config['jid'], ptype='xa', pstatus=obj.status.was_online.strftime('Last seen at %H:%M %d/%m/%Y') )
self._status_updates[str(obj.user_id)] = { 'status': 'xa', 'message': obj.status.was_online.strftime('Last seen at %H:%M %d/%m/%Y') }
elif type(obj.status) is UserStatusRecently:
self.xmpp_gate.send_presence( pto=self.jid, pfrom='u' + str(obj.user_id) + '@' + self.xmpp_gate.config['jid'], pstatus='Last seen recently' )
self._status_updates[str(obj.user_id)] = { 'status': 'away', 'message': 'Last seen recently' }
else:
print(type(obj.status))
print(obj.update.status.__dict__)
pass
except Exception:
print('Exception occurs!')
print(traceback.format_exc())
print(' ')
def gate_send_message(self, mfrom, mbody):
tg_from = int(mfrom[1:])
if not tg_from in self.xmpp_gate.tg_dialogs[self.jid]['users'] and not tg_from in self.xmpp_gate.tg_dialogs[self.jid]['groups'] and not tg_from in self.xmpp_gate.tg_dialogs[self.jid]['supergroups']:
print('Re-init dialog list...')
tg_from = int(mfrom[1:])
if not tg_from in self.xmpp_gate.tg_dialogs[self.jid]['users'] and not tg_from in self.xmpp_gate.tg_dialogs[self.jid]['groups'] and not tg_from in self.xmpp_gate.tg_dialogs[self.jid]['supergroups']: # new contact appeared
self.xmpp_gate.tg_process_dialogs( self.jid )
self.xmpp_gate.send_message( mto=self.jid, mfrom=mfrom + '@' + self.xmpp_gate.config['jid'], mtype='chat', mbody=mbody)
@@ -279,7 +263,7 @@ class TelegramGateClient(TelegramClient):
if message.fwd_from.from_id: # От пользователя
usr = self._get_user_information(message.fwd_from.from_id)
fwd_from = display_tg_name(usr.first_name, usr.last_name)
fwd_from = display_tg_name(usr)
if message.fwd_from.channel_id: # От канала
fwd_from = 'Channel {}'.format(message.fwd_from.channel_id)
@@ -296,7 +280,6 @@ class TelegramGateClient(TelegramClient):
:return:
"""
msg = ''
# print(var_dump(media))
if type(media) is MessageMediaDocument: # Документ или замаскированная сущность
attributes = media.document.attributes
@@ -378,7 +361,7 @@ class TelegramGateClient(TelegramClient):
msg = ''
usr = self._get_user_information(message.from_id)
nickname = display_tg_name(usr.first_name, usr.last_name)
nickname = display_tg_name(usr)
# supergroup created #
if type(message.action) is MessageActionChannelCreate:
@@ -393,19 +376,19 @@ class TelegramGateClient(TelegramClient):
added_users = []
for user_id in message.action.users:
usr = self._get_user_information(user_id)
added_users.append(display_tg_name(usr.first_name, usr.last_name))
added_users.append(display_tg_name(usr))
msg = 'User [{}] has just invited [{}]'.format(nickname, ','.join(added_users))
# user exit #
elif type(message.action) is MessageActionChatDeleteUser:
usr = self._get_user_information(message.action.user_id)
msg = 'User [{}] has just left the room'.format(display_tg_name(usr.first_name, usr.last_name))
msg = 'User [{}] has just left the room'.format(display_tg_name(usr))
# user joined #
elif type(message.action) is MessageActionChatJoinedByLink:
usr = self._get_user_information(message.action.user_id)
msg = 'User [{}] joined the room'.format(display_tg_name(usr.first_name, usr.last_name))
msg = 'User [{}] joined the room'.format(display_tg_name(usr))
# chat name modified #
elif type(message.action) is MessageActionChatEditTitle:
@@ -418,7 +401,7 @@ class TelegramGateClient(TelegramClient):
if len(message_req.messages) > 0:
pinned_message = message_req.messages[0].message
pinned_from = self._get_user_information(message_req.messages[0].from_id)
msg = 'User [{}] pinned message: [{}]: {}'.format(nickname, display_tg_name(pinned_from.first_name, pinned_from.last_name), pinned_message)
msg = 'User [{}] pinned message: [{}]: {}'.format(nickname, display_tg_name(pinned_from), pinned_message)
# group converted to supergroup
elif type(message.action) in [MessageActionChatMigrateTo, MessageActionChannelMigrateFrom]:
@@ -446,3 +429,16 @@ class TelegramGateClient(TelegramClient):
print('MTD ::: Media downloaded')
except Exception:
print(traceback.format_exc())
def status_updater_thread(self):
while True:
try:
if len(self._status_updates) > 0:
for uid, status in self._status_updates.items():
self.xmpp_gate.send_presence( pto=self.jid, pfrom='u'+str(uid)+'@'+self.xmpp_gate.config['jid'], pshow = status['status'], pstatus = status['message'] )
except Exception:
print(traceback.format_exc())
self._status_updates = dict()
time.sleep( self.xmpp_gate.accounts[self.jid]['status_update_interval'])