From da2de42645f9677ffe198e659c34096f57963f76 Mon Sep 17 00:00:00 2001 From: annelin Date: Tue, 11 Jun 2019 16:24:44 +0300 Subject: [PATCH] Release 1.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [!] Using YAML serilaization instead of sqlite3. You may convert your SQLite db to YAML format using this: (echo "---"; sqlite3 users.db 'select jid,login from users'|sed "s/|/: \'/g;s/$/\'/g") > users.dat [FIX] Fixed repllies [UPD] Sending presence probe after disconnect received — maybe there are another XMPP resource? ☺ [UPD] When XMPP user goes online if Telegram session already established -- resync statuses with Telegram network to get all contacts online immediately --- config.yml.example | 6 +++--- inc/telegramclient.rb | 16 +++++++++++----- inc/xmppcomponent.rb | 34 ++++++++++++++-------------------- zhabogram.rb | 1 - 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/config.yml.example b/config.yml.example index a1db7ea..3c0e1e9 100644 --- a/config.yml.example +++ b/config.yml.example @@ -3,8 +3,8 @@ telegram: api_id: '845316' # telegram API ID (my.telegram.org) # api_hash: '27fe5224bc822bf3a45e015b4f9dfdb7' # telegram API HASH (my.telegram.org) # verbosity: 2 # 1 = no verbosity, 2 = moderate verbosity, 3 = network requests debug - useragent: 'Zhabogram XMPP Gateway' # client name - version: '1.0' # client version + useragent: 'Zhabogram' # client name + version: '1.2' # client version use_test_dc: false # always use false loglevel: 0 # 0 = debug, 1 = info, 2 = warn, 3 = err, 4 = fatal, 5 = unknown (ruby logger class) content_path: '/var/zhabogram/content' # we will move (symlink) downloaded content here — you must setup web server that serve this directry @@ -16,7 +16,7 @@ xmpp: debug: false admins: - 'root@localhost' - db_path: 'users.db' # sqlite3 users (JID:Telegram Login) database + db_path: 'users.dat' # users store (JID:Telegram Login) jid: 'tlgrm.localhost' # component JID host: 'localhost' # XMPP server port: 8888 # component port diff --git a/inc/telegramclient.rb b/inc/telegramclient.rb index 94886e1..d5feb84 100644 --- a/inc/telegramclient.rb +++ b/inc/telegramclient.rb @@ -54,6 +54,7 @@ class TelegramClient @client.on(TD::Types::Update::User) do |update| self.user_handler(update) end # new user update? @client.on(TD::Types::Update::UserStatus) do |update| self.status_update_handler(update) end # register status handler @client.connect() + return true end # disconnect and destroy telegram client # @@ -339,13 +340,12 @@ class TelegramClient # handling replies # reply_to = 0 - if text[0] == '>' then + if text[0] == '>' and text.match(Regexp.new /^>( )?[0-9]{10,20}/) then text = text.split("\n") - reply_to = text[0].scan(/\d/).to_i - reply_to = 0 if reply_to < 10000 - text = splitted.drop(1).join("\n") if reply_to != 0 + reply_to = text[0].scan(/\d+/).first.to_i + text = text.drop(1).join("\n") end - + # handling files received from xmpp # message = TD::Types::InputMessageContent::Text.new(:text => { :text => text, :entities => []}, :disable_web_page_preview => false, :clear_draft => true ) message = TD::Types::InputMessageContent::Document.new(document: TD::Types::InputFile::Remote.new(id: text), caption: { :text => '', :entities => []}) if text.start_with? @@content_upload_prefix @@ -377,6 +377,12 @@ class TelegramClient return @cache[:users][user_id] if @cache[:users].key? user_id end + # sync statuses with XMPP roster + def sync_status() + @logger.debug "Syncing statuses with roster.." + @cache[:chats].each do |chat| self.process_status_update(chat.id, (@cache[:users].include? chat.id ? @cache[:users][chat.id].status : chat.title.to_s), true) end + end + # convert telegram status to XMPP one def process_status_update(user_id, status, immed = true) @logger.debug "Processing status update for user id %s.." % user_id.to_s diff --git a/inc/xmppcomponent.rb b/inc/xmppcomponent.rb index 614a648..9200b1b 100644 --- a/inc/xmppcomponent.rb +++ b/inc/xmppcomponent.rb @@ -32,28 +32,22 @@ class XMPPComponent @config = { host: params["host"] || 'localhost', port: params["port"] || 8899, jid: params["jid"] || 'tlgrm.localhost', secret: params['password'] || '', admins: params['admins'] || [], debug: params['debug'] } # default config @sessions = {} @presence_que = {} - @db = SQLite3::Database.new(params['db_path'] || 'users.db') - @db.execute("CREATE TABLE IF NOT EXISTS users(jid varchar(256), login varchar(256), PRIMARY KEY(jid) );") - @db.results_as_hash = true + @db = params['db_path'] || 'users.dat' self.load_db() end # load sessions from db # - def load_db(jid = nil) - @logger.info "Initializing database.." - query = (jid.nil?) ? "SELECT * FROM users" : "SELECT * FROM users where jid = '%s';" % jid - @logger.debug(query) - @db.execute(query) do |session| @sessions[session['jid']] = TelegramClient.new(self, session['jid'], session['login']) end + def load_db() + @logger.info "Loading sessions..." + File.open( @db, 'r' ) {|f| YAML.load(f).each do |jid,login| @sessions[jid] = TelegramClient.new(self, jid, login) end } end # store session to db # - def update_db(jid, delete = false, register = false) - login = (not register and @sessions.key? jid) ? @sessions[jid].login.to_s : register - return if not login - @logger.info "Writing database [%s].." % jid.to_s - query = (delete) ? "DELETE FROM users where jid = '%s';" % jid.to_s : "INSERT OR REPLACE INTO users(jid, login) VALUES('%s', '%s');" % [jid.to_s, login] - @logger.debug query - @db.execute(query) + def save_db() + @logger.info "Saving sessions..." + sessions_store = [] + @sessions.each do |jid,session| store << {jid: jid, login: session.login} end + File.open( @db, 'w' ) {|f| f.write(YAML.dump(sessions_store)) } end # connecting to XMPP server # @@ -97,7 +91,7 @@ class XMPPComponent return -11 rescue Exception => e @logger.error 'Connection failed: %s' % e - @db.close + self.save_db() exit -8 end end @@ -174,8 +168,8 @@ class XMPPComponent @logger.debug "Received presence :%s from <%s> to <%s>" % [prsnc.type.to_s, prsnc.from.to_s, prsnc.to.to_s] @logger.debug(prsnc.to_s) if prsnc.type == :subscribe then reply = prsnc.answer(false); reply.type = :subscribed; @component.send(reply); end # send "subscribed" reply to "subscribe" presence - if prsnc.to == @component.jid and @sessions.key? prsnc.from.bare.to_s and prsnc.type == :unavailable then @sessions[prsnc.from.bare.to_s].disconnect(); return; end # go offline when received offline presence from jabber user - if prsnc.to == @component.jid and @sessions.key? prsnc.from.bare.to_s then self.request_tz(prsnc.from); @sessions[prsnc.from.bare.to_s].connect(); return; end # connect if we have session + if prsnc.to == @component.jid and @sessions.key? prsnc.from.bare.to_s and prsnc.type == :unavailable then @sessions[prsnc.from.bare.to_s].disconnect(); self.presence(prsnc.from, nil, :subscribe) ; return; end # go offline when received offline presence from jabber user + if prsnc.to == @component.jid and @sessions.key? prsnc.from.bare.to_s then self.request_tz(prsnc.from); @sessions[prsnc.from.bare.to_s].connect() || @sessions[prsnc.from.bare.to_s].sync_status(); return; end # connect if we have session end # new iq (vcard/tz) request to XMPP component # @@ -226,7 +220,7 @@ class XMPPComponent @sessions[from.bare.to_s] = TelegramClient.new(self, from.bare.to_s, body.split[1]) if not (@sessions.key? from.bare.to_s and @sessions[from.bare.to_s].online?) @sessions[from.bare.to_s].connect() self.request_tz(from) - self.update_db(from.bare.to_s) + self.save_db() when '/code', '/password' # pass auth data to telegram @sessions[from.bare.to_s].process_auth(body.split[0], body.split[1]) if @sessions.key? from.bare.to_s when '/connect' # go online @@ -239,7 +233,7 @@ class XMPPComponent @sessions[from.bare.to_s].connect() if @sessions.key? from.bare.to_s when '/logout' # go offline and destroy session @sessions[from.bare.to_s].disconnect(true) if @sessions.key? from.bare.to_s - self.update_db(from.bare.to_s, true) + self.save_db() @sessions.delete(from.bare.to_s) when '/info' # show some debug information return if not @config[:admins].include? from.bare.to_s diff --git a/zhabogram.rb b/zhabogram.rb index 8e7148d..c935303 100644 --- a/zhabogram.rb +++ b/zhabogram.rb @@ -5,7 +5,6 @@ require 'xmpp4r' require 'xmpp4r/discovery' require 'digest' require 'base64' -require 'sqlite3' require 'fileutils' require 'tdlib-ruby' require_relative 'inc/telegramclient'