Class: Telegram::Client

Inherits:
API
  • Object
show all
Includes:
Logging
Defined in:
lib/telegram/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

configure_logger_for, #logger, logger_for

Methods inherited from API

#chat_add_user, #chat_del_user, #msg, #update!, #update_chats!, #update_contacts!, #update_profile!

Constructor Details

#initialize {|@config| ... } ⇒ Client

Returns a new instance of Client.

Yields:

  • (@config)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/telegram/client.rb', line 30

def initialize(&b)
  @config = OpenStruct.new(:daemon => 'bin/telegram', :key => 'tg-server.pub', :sock => 'tg.sock', :size => 5)
  yield @config
  @connected = 0
  @stdout = nil
  @connect_callback = nil
  @on = {}

  @profile = nil
  @contacts = []
  @chats = []
  @starts_at = nil
  @events = EM::Queue.new

  logger.info("Initialized")
end

Instance Attribute Details

#chatsObject (readonly)

Returns the value of attribute chats.



26
27
28
# File 'lib/telegram/client.rb', line 26

def chats
  @chats
end

#connectionObject (readonly)

Returns the value of attribute connection.



22
23
24
# File 'lib/telegram/client.rb', line 22

def connection
  @connection
end

#contactsObject (readonly)

Returns the value of attribute contacts.



25
26
27
# File 'lib/telegram/client.rb', line 25

def contacts
  @contacts
end

#onObject

Returns the value of attribute on.



28
29
30
# File 'lib/telegram/client.rb', line 28

def on
  @on
end

#profileObject (readonly)

Returns the value of attribute profile.



24
25
26
# File 'lib/telegram/client.rb', line 24

def profile
  @profile
end

Instance Method Details

#connect(&block) ⇒ Object



114
115
116
117
118
119
# File 'lib/telegram/client.rb', line 114

def connect(&block)
  logger.info("Trying to start telegram-cli and then connect")
  @connect_callback = block
  process_data
  EM.defer(execute, create_pool)
end

#connected?Boolean

Returns:

  • (Boolean)


144
145
146
# File 'lib/telegram/client.rb', line 144

def connected?
  @connected == @config.size
end

#create_poolObject



121
122
123
124
125
126
127
128
129
# File 'lib/telegram/client.rb', line 121

def create_pool
  @connection = ConnectionPool.new(@config.size) do
    client = EM.connect_unix_domain(@config.sock, Connection)
    client.on_connect = self.method(:on_connect)
    client.on_disconnect = self.method(:on_disconnect)
    client
  end
  proc {}
end

#executeObject



47
48
49
50
51
52
53
54
55
56
# File 'lib/telegram/client.rb', line 47

def execute
  command = "'#{@config.daemon}' -Ck '#{@config.key}' -I -WS '#{@config.sock}' --json"
  @stdout = IO.popen(command)
  loop do
    if t = @stdout.readline then
      break if t.include?('I: config')
    end
  end
  proc {}
end

#on_connectObject



131
132
133
134
135
136
137
138
# File 'lib/telegram/client.rb', line 131

def on_connect
  @connected += 1
  if connected?
    logger.info("Successfully connected to the Telegram CLI")
    EM.defer(&method(:poll))
    update!(&@connect_callback)
  end
end

#on_disconnectObject



140
141
142
# File 'lib/telegram/client.rb', line 140

def on_disconnect
  @connected -= 1
end

#pollObject



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/telegram/client.rb', line 58

def poll
  data = ''
  logger.info("Start polling for events")
  loop do
    begin
      byte = @stdout.read_nonblock 1
    rescue IO::WaitReadable
      IO.select([@stdout])
      retry
    rescue EOFError
      logger.error("EOFError occurred during the polling")
      return
    end
    data << byte unless @starts_at.nil?
    if byte.include?("\n")
      begin
        brace = data.index('{')
        data = data[brace..-2]
        data = Oj.load(data)
        @events << data
      rescue
      end
      data = ''
    end
  end
end

#process_dataObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/telegram/client.rb', line 85

def process_data
  process = Proc.new { |data|
    begin
      type = case data['event']
      when 'message'
        if data['from']['id'] != @profile.id
          EventType::RECEIVE_MESSAGE
        else
          EventType::SEND_MESSAGE
        end
      end

      action = data.has_key?('action') ? case data['action']
        when 'chat_add_user'
          ActionType::CHAT_ADD_USER
        else
          ActionType::UNKNOWN_ACTION
        end : ActionType::NO_ACTION

      event = Event.new(self, type, action, data)
      @on[type].call(event) if @on.has_key?(type)
    rescue Exception => e
      logger.error("Error occurred during the processing: #{data}\n #{e.inspect} #{e.backtrace}")
    end
    @events.pop(&process)
  }
  @events.pop(&process)
end