Release 0.5
[NEW] Now using local Jabber timezone
This commit is contained in:
parent
04b8097a6f
commit
a799c1244b
|
@ -145,11 +145,11 @@ class TelegramClient
|
||||||
@client.download_file(file.id) if file # download it if already not
|
@client.download_file(file.id) if file # download it if already not
|
||||||
|
|
||||||
# forwards, replies and message id..
|
# forwards, replies and message id..
|
||||||
text = "[Forward from %s] %s" % [self.format_username(update.message.forward_info.sender_user_id), text] if update.message.forward_info.instance_of? TD::Types::MessageForwardInfo::MessageForwardedFromUser # fwd from user
|
text = "| fwd %s | %s" % [self.format_username(update.message.forward_info.sender_user_id), text] if update.message.forward_info.instance_of? TD::Types::MessageForwardInfo::MessageForwardedFromUser # fwd from user
|
||||||
text = "[Forward from channel %s (%s)] %s" % [update.message.forward_info.chat_id.to_s, update.message.forward_info.author_signature.to_s, text] if update.message.forward_info.instance_of? TD::Types::MessageForwardInfo::MessageForwardedPost # fwd from chat
|
text = "| fwd %s(%s) | %s" % [self.format_chatname(update.message.forward_info.chat_id), update.message.forward_info.author_signature.to_s, text] if update.message.forward_info.instance_of? TD::Types::MessageForwardInfo::MessageForwardedPost # fwd from chat
|
||||||
text = "[Reply to MSG %s] %s" % [update.message.reply_to_message_id.to_s, text] if update.message.reply_to_message_id.to_i != 0 # reply
|
text = "| reply %s | %s" % [self.format_reply(update.message.chat_id, update.message.reply_to_message_id), text] if update.message.reply_to_message_id.to_i != 0 # reply
|
||||||
text = "[MSG %s] [%s] %s" % [update.message.id.to_s, self.format_username(update.message.sender_user_id), text] # username/id
|
text = "%s | %s | %s" % [update.message.id.to_s, self.format_username(update.message.sender_user_id), text] # username/id
|
||||||
|
|
||||||
# send and add message id to unreads
|
# send and add message id to unreads
|
||||||
@cache[:unread_msg][update.message.chat_id] = update.message.id
|
@cache[:unread_msg][update.message.chat_id] = update.message.id
|
||||||
@xmpp.incoming_message(update.message.chat_id.to_s, text)
|
@xmpp.incoming_message(update.message.chat_id.to_s, text)
|
||||||
|
@ -184,7 +184,7 @@ class TelegramClient
|
||||||
@logger.debug 'Got MessageDeleted update'
|
@logger.debug 'Got MessageDeleted update'
|
||||||
@logger.debug update.to_json
|
@logger.debug update.to_json
|
||||||
return if not update.is_permanent
|
return if not update.is_permanent
|
||||||
text = "[MSG ID %s DELETE]" % update.message_ids.join(',')
|
text = "[MSG %s DELETE]" % update.message_ids.join(',')
|
||||||
@xmpp.incoming_message(update.chat_id.to_s, text)
|
@xmpp.incoming_message(update.chat_id.to_s, text)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -265,6 +265,8 @@ class TelegramClient
|
||||||
@client.search_chat_messages(chat_id, 0, 1, sender_user_id: @me.id, filter: TD::Types::SearchMessagesFilter::Empty.new).then {|msgs|
|
@client.search_chat_messages(chat_id, 0, 1, sender_user_id: @me.id, filter: TD::Types::SearchMessagesFilter::Empty.new).then {|msgs|
|
||||||
@client.delete_messages(chat_id, [msgs.messages[0].id], true)
|
@client.delete_messages(chat_id, [msgs.messages[0].id], true)
|
||||||
}.wait
|
}.wait
|
||||||
|
when '/dump'
|
||||||
|
response = @cache[:chats][chat_id].to_json
|
||||||
else
|
else
|
||||||
response = 'Unknown command.
|
response = 'Unknown command.
|
||||||
|
|
||||||
|
@ -315,15 +317,15 @@ class TelegramClient
|
||||||
end
|
end
|
||||||
|
|
||||||
# update users information and save it to cache #
|
# update users information and save it to cache #
|
||||||
def process_chat_info(chat_id)
|
def process_chat_info(chat_id, no_subscription = false)
|
||||||
@logger.debug 'Updating chat id %s..' % chat_id.to_s
|
@logger.debug 'Updating chat id %s..' % chat_id.to_s
|
||||||
|
|
||||||
# fullfil cache.. pasha durov, privet. #
|
# fullfil cache.. pasha durov, privet. #
|
||||||
@client.get_chat(chat_id).then { |chat|
|
@client.get_chat(chat_id).then { |chat|
|
||||||
@cache[:chats][chat_id] = chat # cache chat
|
@cache[:chats][chat_id] = chat # cache chat
|
||||||
@client.download_file(chat.photo.small.id) if chat.photo # download userpic
|
@client.download_file(chat.photo.small.id) if chat.photo # download userpic
|
||||||
@xmpp.presence(chat_id.to_s, :subscribe, nil, nil, @cache[:chats][chat_id].title.to_s) # send subscription request
|
@xmpp.presence(chat_id.to_s, :subscribe, nil, nil, @cache[:chats][chat_id].title.to_s) if not no_subscription # send subscription request
|
||||||
@xmpp.presence(chat_id.to_s, nil, :chat, nil, @cache[:chats][chat_id].title.to_s) if chat.type.instance_of? TD::Types::ChatType::BasicGroup or chat.type.instance_of? TD::Types::ChatType::Supergroup # send :chat status if its group/supergroup
|
@xmpp.presence(chat_id.to_s, nil, :chat, @cache[:chats][chat_id].title.to_s) if chat.type.instance_of? TD::Types::ChatType::BasicGroup or chat.type.instance_of? TD::Types::ChatType::Supergroup # send :chat status if its group/supergroup
|
||||||
self.process_user_info(chat.type.user_id) if chat.type.instance_of? TD::Types::ChatType::Private # process user if its a private chat
|
self.process_user_info(chat.type.user_id) if chat.type.instance_of? TD::Types::ChatType::Private # process user if its a private chat
|
||||||
}.wait
|
}.wait
|
||||||
end
|
end
|
||||||
|
@ -350,7 +352,7 @@ class TelegramClient
|
||||||
xmpp_status = "Online"
|
xmpp_status = "Online"
|
||||||
when TD::Types::UserStatus::Offline
|
when TD::Types::UserStatus::Offline
|
||||||
xmpp_show = (Time.now.getutc.to_i - status.was_online.to_i < 3600) ? :away : :xa
|
xmpp_show = (Time.now.getutc.to_i - status.was_online.to_i < 3600) ? :away : :xa
|
||||||
xmpp_status = DateTime.strptime(status.was_online.to_s,'%s').strftime("Last seen at %H:%M %d/%m/%Y")
|
xmpp_status = DateTime.strptime((status.was_online+Time.now.getlocal(@xmpp.timezone).utc_offset).to_s,'%s').strftime("Last seen at %H:%M %d/%m/%Y")
|
||||||
when TD::Types::UserStatus::Recently
|
when TD::Types::UserStatus::Recently
|
||||||
xmpp_show = :dnd
|
xmpp_show = :dnd
|
||||||
xmpp_status = "Last seen recently"
|
xmpp_status = "Last seen recently"
|
||||||
|
@ -390,6 +392,12 @@ class TelegramClient
|
||||||
return title, username, firstname, lastname, phone, bio, userpic
|
return title, username, firstname, lastname, phone, bio, userpic
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# roster status sync #
|
||||||
|
def sync_status()
|
||||||
|
@logger.debug "Syncing statuses.."
|
||||||
|
@cache[:users].each_value do |user| process_status_update(user.id, user.status) end
|
||||||
|
end
|
||||||
|
|
||||||
# graceful disconnect
|
# graceful disconnect
|
||||||
def disconnect(logout)
|
def disconnect(logout)
|
||||||
@logger.info 'Disconnect request received..'
|
@logger.info 'Disconnect request received..'
|
||||||
|
@ -404,12 +412,30 @@ class TelegramClient
|
||||||
|
|
||||||
# format tg user name #
|
# format tg user name #
|
||||||
def format_username(user_id)
|
def format_username(user_id)
|
||||||
if not @cache[:users].key? user_id then self.process_user_info(user_id) end
|
user_id = @me.id if user_id == 0 # @me
|
||||||
id = (@cache[:users][user_id].username == '') ? user_id : @cache[:users][user_id].username
|
if not @cache[:users].key? user_id then self.process_user_info(user_id) end # update cache
|
||||||
name = '%s %s (@%s)' % [@cache[:users][user_id].first_name, @cache[:users][user_id].last_name, id]
|
if not @cache[:users].key? user_id then return user_id end # return id if not found anything about this user
|
||||||
name.sub! ' ]', ']'
|
id = (@cache[:users][user_id].username == '') ? user_id : @cache[:users][user_id].username # username or user id
|
||||||
|
name = @cache[:users][user_id].first_name # firstname
|
||||||
|
name = name + ' ' + @cache[:users][user_id].last_name if @cache[:users][user_id].last_name != '' # lastname
|
||||||
|
return "%s (@%s)" % [name, id]
|
||||||
|
end
|
||||||
|
|
||||||
|
# format tg chat name #
|
||||||
|
def format_chatname(chat_id)
|
||||||
|
if not @cache[:chats].key? chat_id then self.process_chat_info(chat_id, true) end
|
||||||
|
if not @cache[:chats].key? chat_id then return chat_id end
|
||||||
|
name = '%s (%s)' % [@cache[:chats][chat_id].title, chat_id]
|
||||||
return name
|
return name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# format reply#
|
||||||
|
def format_reply(chat_id, message_id)
|
||||||
|
text = ''
|
||||||
|
@client.get_message(chat_id, message_id).then { |message| text = "%s" % message.content.text.text.to_s }.wait
|
||||||
|
text = (text.lines.count > 1) ? "%s..." % text.split("\n")[0] : text
|
||||||
|
return "MSG %s (%s..)" % [message_id.to_s, text]
|
||||||
|
end
|
||||||
|
|
||||||
# format content link #
|
# format content link #
|
||||||
def format_content_link(file_id, fname, local = false)
|
def format_content_link(file_id, fname, local = false)
|
||||||
|
@ -417,4 +443,5 @@ class TelegramClient
|
||||||
path = "%s/%s%s" % [prefix, Digest::SHA256.hexdigest(file_id), File.extname(fname)]
|
path = "%s/%s%s" % [prefix, Digest::SHA256.hexdigest(file_id), File.extname(fname)]
|
||||||
return path
|
return path
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -88,8 +88,8 @@ class XMPPComponent
|
||||||
# new message to XMPP component #
|
# new message to XMPP component #
|
||||||
def message_handler(msg)
|
def message_handler(msg)
|
||||||
@logger.info 'New message from [%s] to [%s]' % [msg.from, msg.to]
|
@logger.info 'New message from [%s] to [%s]' % [msg.from, msg.to]
|
||||||
return self.process_internal_command(msg.from.bare.to_s, msg.first_element_text('body') ) if msg.to == @@transport.jid # treat message as internal command if received as transport jid
|
return self.process_internal_command(msg.from, msg.first_element_text('body') ) if msg.to == @@transport.jid # treat message as internal command if received as transport jid
|
||||||
return @sessions[msg.from.bare.to_s].tg_outgoing(msg.to.to_s, msg.first_element_text('body')) #if @sessions.key? msg.from.bare.to_s and @sessions[msg.from.bare.to_s].online? # queue message for processing session is active for jid from
|
return @sessions[msg.from.bare.to_s].tg_outgoing(msg.from, msg.to.to_s, msg.first_element_text('body')) #if @sessions.key? msg.from.bare.to_s and @sessions[msg.from.bare.to_s].online? # queue message for processing session is active for jid from
|
||||||
end
|
end
|
||||||
|
|
||||||
def presence_handler(presence)
|
def presence_handler(presence)
|
||||||
|
@ -97,20 +97,27 @@ class XMPPComponent
|
||||||
@logger.debug(presence)
|
@logger.debug(presence)
|
||||||
if presence.type == :subscribe then reply = presence.answer(false); reply.type = :subscribed; @@transport.send(reply); end # send "subscribed" reply to "subscribe" presence
|
if presence.type == :subscribe then reply = presence.answer(false); reply.type = :subscribed; @@transport.send(reply); end # send "subscribed" reply to "subscribe" presence
|
||||||
if presence.to == @@transport.jid and @sessions.key? presence.from.bare.to_s and presence.type == :unavailable then @sessions[presence.from.bare.to_s].disconnect(); return; end # go offline when received offline presence from jabber user
|
if presence.to == @@transport.jid and @sessions.key? presence.from.bare.to_s and presence.type == :unavailable then @sessions[presence.from.bare.to_s].disconnect(); return; end # go offline when received offline presence from jabber user
|
||||||
if presence.to == @@transport.jid and @sessions.key? presence.from.bare.to_s then @sessions[presence.from.bare.to_s].connect(); return; end # connect if we have session
|
if presence.to == @@transport.jid and @sessions.key? presence.from.bare.to_s then @sessions[presence.from.bare.to_s].request_tz(presence.from); @sessions[presence.from.bare.to_s].connect(); return; end # connect if we have session
|
||||||
end
|
end
|
||||||
|
|
||||||
def iq_handler(iq)
|
def iq_handler(iq)
|
||||||
@logger.debug "New iq received"
|
@logger.debug "New iq received"
|
||||||
@logger.debug(iq.to_s)
|
@logger.debug(iq.to_s)
|
||||||
|
|
||||||
if iq.vcard and @sessions.key? iq.from.bare.to_s then
|
# vcard request #
|
||||||
|
if iq.type == :get and iq.vcard and @sessions.key? iq.from.bare.to_s then
|
||||||
|
@logger.debug "Got VCard request"
|
||||||
vcard = @sessions[iq.from.bare.to_s].make_vcard(iq.to.to_s)
|
vcard = @sessions[iq.from.bare.to_s].make_vcard(iq.to.to_s)
|
||||||
reply = iq.answer
|
reply = iq.answer
|
||||||
reply.type = :result
|
reply.type = :result
|
||||||
reply.elements["vCard"] = vcard
|
reply.elements["vCard"] = vcard
|
||||||
@@transport.send(reply)
|
@@transport.send(reply)
|
||||||
else
|
# time response #
|
||||||
|
elsif iq.type == :result and iq.elements["time"] and @sessions.key? iq.from.bare.to_s then
|
||||||
|
@logger.debug "Got Timezone response"
|
||||||
|
timezone = iq.elements["time"].elements["tzo"].text
|
||||||
|
@sessions[iq.from.bare.to_s].set_tz(timezone)
|
||||||
|
elsif iq.type == :get then
|
||||||
reply = iq.answer
|
reply = iq.answer
|
||||||
reply.type = :error
|
reply.type = :error
|
||||||
end
|
end
|
||||||
|
@ -122,26 +129,27 @@ class XMPPComponent
|
||||||
#############################
|
#############################
|
||||||
|
|
||||||
# process internal /command #
|
# process internal /command #
|
||||||
def process_internal_command(jfrom, body)
|
def process_internal_command(from, body)
|
||||||
case body.split[0] # /command argument = [command, argument]
|
case body.split[0] # /command argument = [command, argument]
|
||||||
when '/login' # creating new session if not exists and connect if user already has session
|
when '/login' # creating new session if not exists and connect if user already has session
|
||||||
@sessions[jfrom] = XMPPSession.new(jfrom, body.split[1]) if not @sessions.key? jfrom
|
@sessions[from.bare.to_s] = XMPPSession.new(from.bare.to_s, body.split[1]) if not @sessions.key? from.bare.to_s
|
||||||
@sessions[jfrom].connect()
|
@sessions[from.bare.to_s].request_tz(from)
|
||||||
self.update_db(jfrom)
|
@sessions[from.bare.to_s].connect()
|
||||||
|
self.update_db(from.bare.to_s)
|
||||||
when '/code', '/password' # pass auth data if we have session
|
when '/code', '/password' # pass auth data if we have session
|
||||||
@sessions[jfrom].tg_auth(body.split[0], body.split[1]) if @sessions.key? jfrom
|
@sessions[from.bare.to_s].tg_auth(body.split[0], body.split[1]) if @sessions.key? from.bare.to_s
|
||||||
when '/connect' # going online
|
when '/connect' # going online
|
||||||
@sessions[jfrom].connect() if @sessions.key? jfrom
|
@sessions[from.bare.to_s].connect() if @sessions.key? from.bare.to_s
|
||||||
when '/disconnect' # going offline without destroying a session
|
when '/disconnect' # going offline without destroying a session
|
||||||
@sessions[jfrom].disconnect() if @sessions.key? jfrom
|
@sessions[from.bare.to_s].disconnect() if @sessions.key? from.bare.to_s
|
||||||
when '/logout' # destroying session
|
when '/logout' # destroying session
|
||||||
@sessions[jfrom].disconnect(true) if @sessions.key? jfrom
|
@sessions[from.bare.to_s].disconnect(true) if @sessions.key? from.bare.to_s
|
||||||
self.update_db(jfrom, true)
|
self.update_db(from.bare.to_s, true)
|
||||||
@sessions.delete(jfrom)
|
@sessions.delete(from.bare.to_s)
|
||||||
else # unknown command -- display help #
|
else # unknown command -- display help #
|
||||||
msg = Jabber::Message.new
|
msg = Jabber::Message.new
|
||||||
msg.from = @@transport.jid
|
msg.from = @@transport.jid
|
||||||
msg.to = jfrom
|
msg.to = from.bare.to_s
|
||||||
msg.body = ::HELP_MESSAGE
|
msg.body = ::HELP_MESSAGE
|
||||||
msg.type = :chat
|
msg.type = :chat
|
||||||
@@transport.send(msg)
|
@@transport.send(msg)
|
||||||
|
@ -154,7 +162,7 @@ end
|
||||||
## XMPP Session Class #######
|
## XMPP Session Class #######
|
||||||
#############################
|
#############################
|
||||||
class XMPPSession < XMPPComponent
|
class XMPPSession < XMPPComponent
|
||||||
attr_reader :user_jid, :tg_login
|
attr_reader :user_jid, :tg_login, :timezone
|
||||||
attr_accessor :online
|
attr_accessor :online
|
||||||
|
|
||||||
# start XMPP user session and Telegram client instance #
|
# start XMPP user session and Telegram client instance #
|
||||||
|
@ -162,6 +170,7 @@ class XMPPSession < XMPPComponent
|
||||||
@logger = Logger.new(STDOUT); @logger.level = @@loglevel; @logger.progname = '[XMPPSession: %s/%s]' % [jid, tg_login] # init logger
|
@logger = Logger.new(STDOUT); @logger.level = @@loglevel; @logger.progname = '[XMPPSession: %s/%s]' % [jid, tg_login] # init logger
|
||||||
@logger.info "Initializing new session.."
|
@logger.info "Initializing new session.."
|
||||||
@user_jid, @tg_login = jid, tg_login
|
@user_jid, @tg_login = jid, tg_login
|
||||||
|
@timezone = '-00:00'
|
||||||
end
|
end
|
||||||
|
|
||||||
# connect to tg #
|
# connect to tg #
|
||||||
|
@ -210,8 +219,9 @@ class XMPPSession < XMPPComponent
|
||||||
###########################################
|
###########################################
|
||||||
|
|
||||||
# queue message (we will share this queue within :message_queue to Telegram client thread) #
|
# queue message (we will share this queue within :message_queue to Telegram client thread) #
|
||||||
def tg_outgoing(to, text = '')
|
def tg_outgoing(from, to, text = '')
|
||||||
@logger.debug "Sending message to be sent to Telegram network user -> " % to
|
@logger.debug "Sending message to be sent to Telegram network user -> " % to
|
||||||
|
self.request_tz(from) if not self.tz_set?
|
||||||
@telegram.process_outgoing_msg(to.split('@')[0].to_i, text)
|
@telegram.process_outgoing_msg(to.split('@')[0].to_i, text)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -245,6 +255,25 @@ class XMPPSession < XMPPComponent
|
||||||
return vcard
|
return vcard
|
||||||
end
|
end
|
||||||
|
|
||||||
|
## timezones ##
|
||||||
|
def request_tz(jid)
|
||||||
|
@logger.debug "Request timezone from JID %s" % jid.to_s
|
||||||
|
iq = Jabber::Iq.new
|
||||||
|
iq.type = :get
|
||||||
|
iq.to = jid
|
||||||
|
iq.from = @@transport.jid
|
||||||
|
iq.id = 'time_req_1'
|
||||||
|
iq.add_element("time", {"xmlns" => "urn:xmpp:time"})
|
||||||
|
@logger.debug iq.to_s
|
||||||
|
@@transport.send(iq)
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_tz(timezone)
|
||||||
|
@logger.debug "Set TZ to %s" % timezone
|
||||||
|
@timezone = timezone
|
||||||
|
@logger.debug "Resyncing contact list.."
|
||||||
|
@telegram.sync_status()
|
||||||
|
end
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
|
|
||||||
|
@ -252,4 +281,5 @@ class XMPPSession < XMPPComponent
|
||||||
def online?() @online end
|
def online?() @online end
|
||||||
def online!() @logger.info "Connection established"; @online = true; self.presence(nil, :subscribe); self.presence(nil, nil, nil, "Logged in as " + @tg_login.to_s) end
|
def online!() @logger.info "Connection established"; @online = true; self.presence(nil, :subscribe); self.presence(nil, nil, nil, "Logged in as " + @tg_login.to_s) end
|
||||||
def offline!() @online = false; self.presence(nil, :unavailable, nil, "Logged out"); @telegram = nil; end
|
def offline!() @online = false; self.presence(nil, :unavailable, nil, "Logged out"); @telegram = nil; end
|
||||||
|
def tz_set?() return @timezone != '-00:00' end
|
||||||
end
|
end
|
||||||
|
|
Reference in a new issue