[SVN] updated to version 0.3.1

[DEP] [BROKE] new dependency: pytz (pip3 install pytz)
[FIX] fixed media downloading with telethon 0.18
[FIX] now using server time zone in status messages instead of UTC
[UPD] now removing chats & supergroups completely after we leaving with !leave command
[ADD] added commands:
      !remove — completely remove current user from contact list
      !import phone firstname lastname — try to add contact with phone number (untested)
This commit is contained in:
annelin
2018-07-01 21:29:34 +00:00
parent 0f648e6bd4
commit e66bda9cd8
5 changed files with 49 additions and 14 deletions

View File

@@ -1,3 +1,3 @@
sleekxmpp==1.3.2
Telethon==0.15.5
pytz

View File

@@ -1,3 +1,3 @@
from xmpp_tg.xmpp import XMPPTelegram
__version__ = '0.3.0'
__version__ = '0.3.1'

View File

@@ -27,7 +27,7 @@ import os
import queue
import threading
import time
from xmpp_tg.utils import display_tg_name
from xmpp_tg.utils import localtime, display_tg_name
from .utils import var_dump
import traceback
@@ -181,7 +181,7 @@ class TelegramGateClient(TelegramClient):
if type(obj.status) is UserStatusOnline:
self._status_updates[str(obj.user_id)] = { 'status': None, 'message': 'Online' }
elif type(obj.status) is UserStatusOffline:
self._status_updates[str(obj.user_id)] = { 'status': 'xa', 'message': obj.status.was_online.strftime('Last seen at %H:%M %d/%m/%Y') }
self._status_updates[str(obj.user_id)] = { 'status': 'xa', 'message': localtime(obj.status.was_online).strftime('Last seen at %H:%M %d/%m/%Y') }
elif type(obj.status) is UserStatusRecently:
self._status_updates[str(obj.user_id)] = { 'status': 'away', 'message': 'Last seen recently' }
else:
@@ -324,7 +324,7 @@ class TelegramGateClient(TelegramClient):
attr_v = self.get_document_attribute(attributes, DocumentAttributeFilename)
video_file = '|File:{}'.format(attr_v.file_name)
if media.caption:
if hasattr(media, 'caption'):
caption = media.caption + ' '
# Тоже свой формат
@@ -335,7 +335,7 @@ class TelegramGateClient(TelegramClient):
self._media_queue.put({'media': media, 'file': g_link['name']})
if media.caption: # Если есть описание - указываем
if hasattr(media, 'caption'): # Если есть описание - указываем
msg = '{} {}'.format(media.caption, msg)
elif type(media) is MessageMediaContact: # Контакт (с номером)

View File

@@ -3,9 +3,12 @@
"""
import types
import time
import pytz
from datetime import datetime
def display_tg_name(peer):
if hasattr(peer,'title') and hasattr(peer,'broadcast') and peer.broadcast: # channel
return '[C] ' + peer.title
@@ -36,6 +39,14 @@ def get_contact_jid(peer, gatejid):
else:
return None
def localtime(utc_dt):
if time.daylight:
offsetHour = time.altzone / 3600
else:
offsetHour = time.timezone / 3600
local_tz = pytz.timezone('Etc/GMT%+d' % offsetHour)
local_dt = utc_dt.replace(tzinfo = pytz.utc).astimezone(local_tz)
return local_tz.normalize(local_dt)
def var_dump(obj, depth=7, l=""):
# fall back to repr

View File

@@ -7,12 +7,12 @@ import sleekxmpp
from sleekxmpp.componentxmpp import ComponentXMPP
import xml.etree.ElementTree as ET
from telethon.tl.functions.messages import GetDialogsRequest, SendMessageRequest, ImportChatInviteRequest, GetFullChatRequest, AddChatUserRequest, DeleteChatUserRequest, CreateChatRequest
from telethon.tl.functions.messages import GetDialogsRequest, SendMessageRequest, ImportChatInviteRequest, GetFullChatRequest, AddChatUserRequest, DeleteChatUserRequest, CreateChatRequest, DeleteHistoryRequest
from telethon.tl.functions.account import UpdateStatusRequest, GetAuthorizationsRequest, UpdateProfileRequest, UpdateUsernameRequest
from telethon.tl.functions.contacts import DeleteContactRequest, BlockRequest, UnblockRequest
from telethon.tl.functions.contacts import DeleteContactRequest, BlockRequest, UnblockRequest, ImportContactsRequest
from telethon.tl.functions.channels import JoinChannelRequest, LeaveChannelRequest, InviteToChannelRequest, EditBannedRequest, CreateChannelRequest
from telethon.tl.types import InputPeerEmpty, InputPeerUser, InputPeerChat, InputPeerChannel
from telethon.tl.types import InputPeerEmpty, InputPeerUser, InputPeerChat, InputPeerChannel, InputPhoneContact
from telethon.tl.types import User, Chat, Channel
from telethon.tl.types import PeerChannel, PeerChat, PeerUser, Chat, ChatForbidden, Channel, ChannelForbidden
from telethon.tl.types import UserStatusOnline, UserStatusRecently, UserStatusOffline
@@ -24,7 +24,7 @@ from telethon.helpers import generate_random_long
from telethon.errors import SessionPasswordNeededError
from xmpp_tg.mtproto import TelegramGateClient
from xmpp_tg.utils import var_dump, display_tg_name, get_contact_jid
from xmpp_tg.utils import var_dump, display_tg_name, get_contact_jid, localtime
import xmpp_tg.monkey # Патчим баги в библиотеках
class XMPPTelegram(ComponentXMPP):
@@ -77,7 +77,7 @@ class XMPPTelegram(ComponentXMPP):
vcard = self.plugin['xep_0054'].make_vcard()
vcard['FN'] = self.config['title']
vcard['DESC'] = 'Send /help for information'
vcard['DESC'] = 'Send !help for information'
self.plugin['xep_0054'].publish_vcard(jid=self.boundjid.bare, vcard=vcard)
def __del__(self):
@@ -268,6 +268,7 @@ class XMPPTelegram(ComponentXMPP):
'!reload_dialogs - Reloads dialogs list from Telegram\n\n'
'!add - Find and add Telegram contact. Any formats accepted (nickname or t.me link)\n\n'
'!join - Join Telegram conference via invite link \n\n'
'!import phone firstname lastname - Add Telegram contact with phone number \n\n'
'!group GroupName @InviteContact - Create a normal group\n'
'!supergroup SupergroupName - Create a supergroup\n'
'!channel ChannelName - Create a channel\n\n'
@@ -395,6 +396,15 @@ class XMPPTelegram(ComponentXMPP):
about = iq['body'][7:]
self.tg_connections[jid].invoke(UpdateProfileRequest(about = about))
elif parsed[0] == '!import' and len(parsed) >= 3: # create new channel
phone = parsed[1]
firstname = parsed[2]
lastname = parsed[3] if len(parsed) > 3 else None
contact = InputPhoneContact(client_id=generate_random_long(), phone=phone, first_name=firstname, last_name=lastname)
self.tg_connections[jid].invoke(ImportContactsRequest([contact]))
self.tg_process_dialogs(jid)
else: # --------------------------------------------------
self.gate_reply_message(iq, 'Unknown command. Try !help for list all commands.')
@@ -407,6 +417,7 @@ class XMPPTelegram(ComponentXMPP):
'!help - Displays this text\n'
'!block - Blacklists current user\n'
'!unblock - Unblacklists current user\n'
'!remove - Removes history and contact from your contact list\n'
)
elif parsed[0] == '!block':
tg_id = int(iq['to'].node[1:])
@@ -420,6 +431,16 @@ class XMPPTelegram(ComponentXMPP):
self.tg_connections[jid].invoke(UnblockRequest( InputPeerUser(tg_id, self.tg_dialogs[jid]['users'][tg_id].access_hash) ) )
self.gate_reply_message(iq, 'User %s unblacklisted!' % nickname)
elif parsed[0] == '!remove':
tg_id = int(iq['to'].node[1:])
peer = InputPeerUser(tg_id, self.tg_dialogs[jid]['users'][tg_id].access_hash)
c_jid = get_contact_jid(self.tg_dialogs[jid]['users'][tg_id], self.boundjid.bare)
self.tg_connections[jid].invoke( DeleteContactRequest(peer) )
self.tg_connections[jid].invoke( DeleteHistoryRequest( peer, max_id = 0, just_clear = None ) )
self.send_presence(pto = jid, pfrom = c_jid, ptype = 'unavailable')
self.send_presence(pto = jid, pfrom = c_jid, ptype = 'unsubscribed')
self.send_presence(pto = jid, pfrom = c_jid, ptype = 'unsubscribe')
def process_chat_group_command(self, iq):
@@ -436,13 +457,16 @@ class XMPPTelegram(ComponentXMPP):
elif parsed[0] == '!leave':
tg_id = int(iq['to'].node[1:])
if tg_id in self.tg_dialogs[jid]['supergroups']:
self.tg_connections[jid].invoke(LeaveChannelRequest( InputPeerChannel(tg_id, self.tg_dialogs[jid]['supergroups'][tg_id].access_hash) ) )
peer = InputPeerChannel(tg_id, self.tg_dialogs[jid]['supergroups'][tg_id].access_hash)
self.tg_connections[jid].invoke( LeaveChannelRequest(peer) )
self.tg_connections[jid].invoke( DeleteHistoryRequest( peer, max_id = 0, just_clear = None ) )
c_jid = get_contact_jid(self.tg_dialogs[jid]['supergroups'][tg_id], self.boundjid.bare)
self.send_presence(pto = jid, pfrom = c_jid, ptype = 'unavailable')
self.send_presence(pto = jid, pfrom = c_jid, ptype = 'unsubscribed')
self.send_presence(pto = jid, pfrom = c_jid, ptype = 'unsubscribe')
if tg_id in self.tg_dialogs[jid]['groups']:
self.tg_connections[jid].invoke( DeleteChatUserRequest(tg_id, self.tg_connections[jid].me) )
self.tg_connections[jid].invoke( DeleteHistoryRequest( InputPeerChat(tg_id), max_id = 0, just_clear = None ) )
c_jid = get_contact_jid(self.tg_dialogs[jid]['groups'][tg_id], self.boundjid.bare)
self.send_presence(pto = jid, pfrom = c_jid, ptype = 'unavailable')
self.send_presence(pto = jid, pfrom = c_jid, ptype = 'unsubscribed')
@@ -603,7 +627,7 @@ class XMPPTelegram(ComponentXMPP):
elif type(usr.status) is UserStatusRecently:
self.send_presence(pto=jid, pfrom=u_jid, pshow='away', pstatus='Last seen recently')
elif type(usr.status) is UserStatusOffline:
self.send_presence(pto=jid, pfrom=u_jid, pshow='xa', pstatus=usr.status.was_online.strftime('Last seen at %H:%M %d/%m/%Y') )
self.send_presence(pto=jid, pfrom=u_jid, pshow='xa', pstatus=localtime(usr.status.was_online).strftime('Last seen at %H:%M %d/%m/%Y') )
else:
self.send_presence(pto=jid, pfrom=u_jid, pshow='dnd', pstatus='Last seen a long time ago')