Module: Client

Included in:
NaviClient::Cloud, NaviClient::ImapApi
Defined in:
lib/client.rb

Overview

This module provides the common functionality that will be needed for local and cloud module.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#downloadedObject

Returns the value of attribute downloaded.



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

def downloaded
  @downloaded
end

#message_idsObject

Returns the value of attribute message_ids.



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

def message_ids
  @message_ids
end

#total_emailsObject

Returns the value of attribute total_emails.



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

def total_emails
  @total_emails
end

Instance Method Details

#depcrecated_encrypt(data) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/client.rb', line 182

def depcrecated_encrypt(data)
  cipher = OpenSSL::Cipher::AES.new(256, :CFB)
  cipher.encrypt

  yml_config = config

  key_iv_exists = (yml_config['key'] && yml_config['iv']) ? (!yml_config['key'].empty? && !yml_config['iv'].empty? ) : false

  if key_iv_exists
    # this condition must be true for cloud version
    cipher.key = Base64.decode64(File.read(yml_config['key']))
    cipher.iv = Base64.decode64(File.read(yml_config['iv']))
  else
    cipher.key = key = cipher.random_key
    cipher.iv = iv = cipher.random_iv

    key_path, iv_path = save_aes_key_iv(key, iv)

    yml_config['key'] = key_path
    yml_config['iv'] = iv_path

    update_config(yml_config)
  end

  encrypted = cipher.update(data)
  Base64.encode64(encrypted)
end

#encrypt(data) ⇒ Object



178
179
180
# File 'lib/client.rb', line 178

def encrypt(data)
  Base64.encode64(data)
end

#errorsObject



33
34
35
# File 'lib/client.rb', line 33

def errors
  @errors
end

#fetch_emails(&process_email_block) ⇒ Object

retrieve_emails

retrieve any mail from a folder, followin specified serach condition for any mail retrieved call a specified block



84
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/client.rb', line 84

def fetch_emails(&process_email_block)

  @message_ids.each_with_index do |message_id, i|
    begin
      # fetch all the email contents
      data = @imap.uid_fetch(message_id, "RFC822")
      data.each do |d|
        msg = d.attr['RFC822']
        # instantiate a Mail object to avoid further IMAP parameters nightmares
        mail = Mail.read_from_string msg

        # call the block with mail object as param
        process_email_block.call mail, i, i == @message_ids.length-1, message_id

        # mark as read
        if @mark_as_read
          @imap.store(message_id, "+FLAGS", [:Seen])
        end
      end
    rescue => e
      unless logger.nil?
        logger.info "Issue processing email for uuid ##{message_id}, #{e.message}"
      end

      logToLoggly({event:"EMAIL_SYNC_FAILED", env: @env, storage: @client_type, email: @current_user_email, uuid: message_id, error: e.message})
      raise e
    end
  end
end

#imap_connection(server, username, password, exitOnFail = true) ⇒ Object

imap_connection

connect the app with imap server



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/client.rb', line 42

def imap_connection(server, username, password, exitOnFail = true)
  # connect to IMAP server
  @imap = Net::IMAP.new server, ssl: true, certs: nil, verify: false

  Net::IMAP.debug = @net_imap_debug

  # http://ruby-doc.org/stdlib-2.1.5/libdoc/net/imap/rdoc/Net/IMAP.html#method-i-capability
  capabilities = @imap.capability

  @logger.debug("imap capabilities: #{capabilities.join(',')}") if @debug

  if @client_type == 'local'
    unless capabilities.include? "IDLE" || @debug
      @logger.info "'IDLE' IMAP capability not available in server: #{server}"
      @imap.disconnect
      exit if exitOnFail
    end
  end

  begin
    # login
    @imap. username, password
    @errors = nil
  rescue Net::IMAP::NoResponseError => e
    # mostly due to credentials error
    @errors = {exception: e}
  rescue Net::IMAP::BadResponseError => e
    @errors = {exception: e}
  rescue
    @errors = {exception: e}
  end

  # return IMAP connection handler
  @imap
end

#init_messages(label, search_condition = ['ALL']) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/client.rb', line 115

def init_messages label, search_condition = ['ALL']

  # examine will read email and sets flags unread
  # https://stackoverflow.com/questions/16516464/read-gmail-xoauth-mails-without-marking-it-read
  @imap.examine label

  @message_ids = @imap.uid_search(search_condition)
  @total_emails = @message_ids.length
  downloaded_email = getMessageUUIds("#{@download_path}meta/")
  downloaded_email = downloaded_email.collect{|i| i.to_i}

  @downloaded = downloaded_email.length
  @downloaded = @downloaded - 2 if @downloaded > 1
  @downloaded = [@downloaded, @total_emails].min

  @message_ids = @message_ids - downloaded_email
  @message_ids = @message_ids&.sort {|msg_a, msg_b| msg_b <=> msg_a}

  if @debug
    if @message_ids.empty?
      @logger.info "No new emails found..."
    elsif downloaded_email.any?
      @logger.info "Found emails saved in your #{@client_type}. Downloading only #{@message_ids.count} new emails..."
    else
      @logger.info "Downloading #{@message_ids.count} emails."
    end
  end

end

#loggerObject



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

def logger
  @logger
end

#logToLoggly(messageBody) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/client.rb', line 226

def logToLoggly(messageBody)

  if(@logglyTag)
    begin
      HTTParty.post("http://logs-01.loggly.com/bulk/0d67f93b-6568-4b00-9eca-97d0ea0bd5a1/tag/#{@logglyTag}/",
                    body: messageBody.to_json,
                    headers: { 'Content-Type' => 'application/json' } )
    rescue
      true
    end

  else
    if @debug && !@logger.nil?
      @logger.info "Logging to Loggly disabled"
      @logger.info messageBody
    end
  end

end

#process_email(mail, uid, stamp = nil) ⇒ Object

Process each email downloaded from imap-server and creates meta file that will be sent over to the navi-ai service. Meta will content information like: [‘from’, ‘to’, ‘cc’, …, ‘body_url’]. This information is then used by navi-ai to parse the body content.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/client.rb', line 149

def process_email(mail, uid, stamp = nil)
  meta = Hash.new
  custom_uid = (Time.now.to_f * 1000).to_s + "_" + mail.__id__.to_s

  meta["from"] = mail[:from].to_s
  meta["to"] = mail[:to].to_s
  meta["cc"] = mail[:cc].to_s
  meta["subject"] = mail.subject
  meta["date"] = mail.date.to_s


  if mail.multipart?
    for i in 0...mail.parts.length
      m = download(mail.parts[i], custom_uid)
      meta.merge!(m) unless m.nil?
    end
  else
    m = download(mail, custom_uid)
    meta.merge!(m) unless m.nil?
  end

  if stamp.nil?
    save(meta, "meta/#{uid.to_s + '_' + custom_uid}")
  else
    save(meta, "meta/#{uid.to_s + '_' + custom_uid}", stamp)
  end

end

#setupLoggly(tag) ⇒ Object



246
247
248
# File 'lib/client.rb', line 246

def setupLoggly(tag)
  @logglyTag = tag
end

#shutdown(imap) ⇒ Object

If the gem is being used for local-lockbox mode, after fetching all emails, the process will go idle mode. If user send the interrupt command, it will call shutdown to disconnect the connection with imap server



217
218
219
220
221
222
223
224
# File 'lib/client.rb', line 217

def shutdown(imap)
  imap.idle_done
  imap.logout unless imap.disconnected?
  imap.disconnect

  @logger.info "#{$0} has ended (crowd applauds)"
  exit 0
end

#time_nowObject



210
211
212
# File 'lib/client.rb', line 210

def time_now
  Time.now.utc.iso8601(3)
end