Module: Dialog

Extended by:
Dry::Configurable
Defined in:
lib/naming.rb,
lib/require.rb,
lib/version.rb,
lib/tdlib/auth.rb,
lib/tdlib/func.rb,
lib/tdlib/init.rb,
lib/dialog_ruby.rb,
lib/tooling/log.rb,
lib/tooling/lang.rb,
lib/configuration.rb,
lib/metamess/_run.rb,
lib/metamess/func.rb,
lib/triggers/init.rb,
lib/triggers/false.rb,
lib/telegram/botapi.rb,
lib/metamess/event_c.rb,
lib/telegram/wrappers.rb,
lib/dialect/codegen/run.rb,
lib/telegram/infra_info.rb,
lib/triggers/_meta/full.rb,
lib/triggers/start/start.rb,
lib/dialect/canvas/canvas.rb,
lib/triggers/deploy/deploy.rb,
lib/dialect/codegen/codegen.rb,
lib/metamess/event/notify_o.rb,
lib/triggers/start/start_bot.rb,
lib/triggers/start/start_pre.rb,
lib/storage/redis/redisPubSub.rb,
lib/storage/redis/rediscached.rb,
lib/metamess/content/content_o.rb,
lib/metamess/service/service_o.rb,
lib/dialect/canvas/mod/send/func.rb,
lib/metamess/event/notify_o-create_f.rb,
lib/metamess/event/notify_o-pinned_f.rb,
lib/metamess/event/notify_o-migrate_f.rb,
lib/dialect/canvas/element/data/search.rb,
lib/dialect/canvas/mod/send/_keyboards.rb,
lib/metamess/content/content_o-media_f.rb,
lib/metamess/content/content_o-simple_f.rb,
lib/metamess/event/notify_o-chattitle_f.rb,
lib/metamess/service/service_o-inline_f.rb,
lib/dialect/canvas/element/send/restrict.rb,
lib/dialect/canvas/mod/send/general/chat.rb,
lib/dialect/canvas/mod/send/general/user.rb,
lib/metamess/content/content_o-command_f.rb,
lib/metamess/event/notify_o-chatmember_f.rb,
lib/dialect/canvas/element/send/keyboards.rb,
lib/dialect/canvas/element/send/recognize.rb,
lib/metamess/service/service_o-callback_f.rb,
lib/dialect/canvas/element/send/tdlib_chat.rb,
lib/dialect/canvas/mod/send/general/_heads.rb,
lib/dialect/canvas/mod/send/general/common.rb,
lib/dialect/canvas/element/send/bot_message.rb,
lib/dialect/canvas/mod/send/general/message.rb,
lib/dialect/canvas/element/send/tdlib_message.rb,
lib/dialect/canvas/element/convert/SearchBaloo.rb,
lib/dialect/canvas/mod/send/_Inline_query_result.rb,
lib/dialect/canvas/element/send/Inline_query_result.rb,
lib/dialect/codegen/repack/functional/1.Expect2Events.rb,
lib/dialect/codegen/repack/functional/7.ElementChains.rb,
lib/dialect/canvas/mod/send/inline_query_result/common.rb,
lib/dialect/codegen/repack/constructor/Element2ModSend.rb,
lib/dialect/codegen/repack/constructor/ElementsInElements.rb,
lib/dialect/codegen/repack/functional/5.2.Element2ModSend.rb,
lib/dialect/codegen/repack/functional/2.2.1.Events2ModReceive.rb,
lib/dialect/codegen/repack/functional/5.1.Element2ModElements.rb,
lib/dialect/codegen/repack/functional/2.2.2.ModReceive2AppEvent.rb,
lib/dialect/codegen/repack/constructor/DockedGroupings2AppFunctions.rb

Overview

####### ######## ####### ######## ########

 / / / /    License    \ \ \ \ 
Copyleft culture, Copyright (C) is prohibited here
This work is licensed under a CC BY-SA 4.0
Creative Commons Attribution-ShareAlike 4.0 License
Refer to the http://creativecommons.org/licenses/by-sa/4.0/
#######    ########    #######    ########    ########
/ / / /    Code Climate    \ \ \ \ 
Language = ruby
Indent = space;    2 chars;
#######    ########    #######    ########    ########

Defined Under Namespace

Modules: BotApi, Canvas, Dialect, ElementData, ElementSend, Lang, Metamess, ModSend, Naming, RedisCached, RedisPubSub, TDLib, Wrappers Classes: Log

Constant Summary collapse

VERSION =
'0.1.8'.freeze

Class Method Summary collapse

Class Method Details

._requireObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/require.rb', line 16

def _require
  ### SYSTEM
  require 'pp'
  require 'timeout'
  require 'logger'
  require 'socket'
  require 'fileutils'
  require 'uri'
  require 'open3'
  require 'erb'
  require 'shellwords'

  ### GEMS
  require 'dialect_lookup'
  require 'tdlib-ruby'
  require 'telegram/bot'
  require 'i18n'
  require 'redis'
  require 'concurrent'
  require 'oj'
  require 'sidekiq-cron'
  require 'sidekiq-rate-limiter'
  #lazy_object

  ### DRY
  require 'dry-configurable'
  # require 'dry-monads'
  # require 'dry-matcher'
  # require 'dry-transaction'
  # require 'dry/inflector'
  # require 'dry-validation'
  # require 'dry-struct'
  # require 'dry-types'

  #dry-events - pub/sub

  ### CODE
  Dir.glob(File.join("#{File.dirname(__FILE__)}/**", "*.rb")).each{|f| require f}
end

.bot(args) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/triggers/start/start_bot.rb', line 30

def bot(args)
  args[:globals] = {}
  
  ### LANG
  i18n = Dialog::Lang.initial
  
  ## BUG - TEMPORARY DISABLE
#       tdlibInit(args)
#       args[:tdlib][:cli].on_ready do |client|
#         a = client.fetch('@type' => 'getMe')
#         args[:globals][:cliId] = a['id'].to_i
#       end        
  begin    
    Dialog::redis.call(['info', 'clients'])
  rescue
    Dialog.logger.error "No Redis connection!"
    sleep(2) 
    retry
  end
  Telegram::Bot::Client.run Dialog.config.secure.token do |bot|
    args[:bot]= bot; args[:bot].freeze
    
    #bot getMe
    Dialog.logger.info 'BotAPI getMe-request started'        
    me = bot.api.send(:getMe)
    Dialog.logger.info 'BotAPI getMe-request completed'     
    
    #bot globals
    args[:globals][:botUsername] = me["result"]["username"]
    args[:globals][:botFirstName] = me["result"]["first_name"]
    args[:globals][:botFirstNameArray] = me["result"]["first_name"].split("\s")
    args[:globals].freeze
    
    #common queue
    args[:queue] = {}
    args[:queue][:threadCommon] = Concurrent::CachedThreadPool.new
    
    #Success
    Dialog.logger.info "Started: Bot named \"#{args[:globals][:botUsername]}\", botInstance=\"#{Dialog.config.naming.instance}\" of botInterface=\"#{Dialog.config.naming.interface}\", ID=\"#{Dialog.config.naming.id}\", loglevel=\"#{Dialog.config.log.base}\""

    begin        
      bot.listen do |rmsg|
        args[:rmsg] = rmsg
        Dialog.clear(args) 
        Dialog.clearApi(args)
        args[:perf] = {init: Time.now}
          if args[:rmsg].respond_to?(:from)
            fromId = args[:rmsg][:from][:id]
            args[:queue][fromId] ||= {}
            args[:queue][fromId][:thread] = Concurrent::ImmediateExecutor.new unless args[:queue][fromId][:thread]
            args[:queue][fromId][:thread].post do
              runMessage(args)
            end
          else
            Concurrent::Future.execute(executor: args[:queue][:threadCommon]) do
              runMessage(args)
            end                
          end

      end
      rescue
#         rescue Exception => @e
      retry
#           Dialog.logger.error "ERROR - #{@e.inspect}\n\n Backtrace:\n #{@e.backtrace.join("\n\t")}\n  #           MMSG:\n#{args[:mmsg]}\n" if @e             
    end        
  end
end

.checkEnv(env, val, err = []) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/configuration.rb', line 20

def self.checkEnv(env, val, err=[])
  if ENV[env].nil?
    case val
      when true;  res = true  
      when false; res = false && err << "There is no #{env} in envs"
      else        res = val 
    end
  else res = ENV[env]; end
    puts err
  return res
end

.clear(args) ⇒ Object



21
22
23
24
# File 'lib/triggers/start/start_pre.rb', line 21

def clear(args)
  args[:x] = {metamess: {}, redis: {}, data: {}, labels: {}, send: {}, exec: {}}
  args[:smsg] = {}
end

.clearApi(args) ⇒ Object



30
31
32
# File 'lib/triggers/start/start_pre.rb', line 30

def clearApi(args)
  args[:api] = {}
end

.clearRedis(args) ⇒ Object



26
27
28
# File 'lib/triggers/start/start_pre.rb', line 26

def clearRedis(args)
  args[:x][:redis] = {}
end

.createObject



16
17
18
19
20
21
22
23
24
25
# File 'lib/dialog_ruby.rb', line 16

def create
  version = RUBY_VERSION.split('.').map { |x| x.to_i }
  if (version <=> [2, 5, 0]) >= 1
    require_relative './require.rb'
    _require
    send("trigger_#{Dialog.config.run.scope}".to_sym)
  else
    puts "Minimum required Ruby version - 2.5.0"
  end
end

.deploy_botObject



38
39
40
41
# File 'lib/triggers/deploy/deploy.rb', line 38

def deploy_bot
  erb('systemd/[email protected]', "#{Dir.home}/.config/systemd/user/[email protected]")
  systemd("dialog_bot@#{Dialog.config.naming.full}")
end

.deploy_devenvObject



46
47
# File 'lib/triggers/deploy/deploy.rb', line 46

def deploy_devenv
end

.deploy_gitsyncObject



49
50
# File 'lib/triggers/deploy/deploy.rb', line 49

def deploy_gitsync
end

.deploy_redisObject



28
29
30
31
32
33
34
35
# File 'lib/triggers/deploy/deploy.rb', line 28

def deploy_redis
  redisDir = "#{Dialog.config.path.dialogData}/redis"
  FileUtils.mkdir_p redisDir
  erb('systemd/dialog_redis.service', "#{Dir.home}/.config/systemd/user/dialog_redis.service")
  erb('conf/redis_local.conf', "#{redisDir}/redis_local.conf")
  erb('conf/redis_global.conf', "#{redisDir}/redis_global.conf")
  systemd('dialog_redis')
end

.deploy_tdlibObject



43
44
# File 'lib/triggers/deploy/deploy.rb', line 43

def deploy_tdlib
end

.dialectDriven(args) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/triggers/start/start.rb', line 38

def dialectDriven(args)
  require 'dialect_lookup'
  state = {
    dialectFolder:  Dialog.config.dialect.folder, 
    myAppName:      Dialog.config.naming.app, 
    sqlite:         Dialog.config.dialect.sqlite, 
    jsonFolder:  "#{Dialog.config.path.dialogRender}/json/"
  }
  ::Dialect::Lookup.new.run(state)
#       File.delete(Dialog.config.dialect.sqlite)
end

.erb(erbFile, dst) ⇒ Object



21
22
23
24
25
26
# File 'lib/triggers/deploy/deploy.rb', line 21

def erb(erbFile, dst)
  if not File.file?(dst)
    tmpl = ERB.new(File.read("#{Dialog.config.path.dialog_ruby}/exec/#{erbFile}")).result(binding)
    File.open(dst, 'w') do |f| f.write tmpl; end         
  end
end

.getDialog_rubyPathObject



18
# File 'lib/configuration.rb', line 18

def self.getDialog_rubyPath; return File.dirname(__FILE__);  end

.getDialogPathObject



17
# File 'lib/configuration.rb', line 17

def self.getDialogPath; return @dialogPath;  end

.jsonDriven(args, type) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/triggers/start/start.rb', line 51

def jsonDriven(args, type)
  FileUtils.rm_rf(Dir.glob("#{Dialog.config.path.dialogRender}/code_#{type}/*.rb"))     
  args[:dialect] = {}      
  
  json = "#{Dialog.config.path.dialogRender}/json/#{Dialog.config.dialect.folder}_#{Dialog.config.naming.app}.json"
  jsonLoad = Oj.load(File.read(json), symbol_keys: true)
  args[:dialect] = jsonLoad[:stages][Dialog.config.dialect.folder.to_sym]
  Dialog::Dialect.run(args, type)
  
  args[:dialect] ={} 
  args[:tmp] = {}      
  Dir.glob(File.join("#{Dialog.config.path.dialogRender}/code_#{type}/**", "*.rb")).sort.each{|f| require f}
  Dialog.logger.info "Rendered bot code is ok"      
end

.loggerObject



15
16
17
# File 'lib/tooling/log.rb', line 15

def self.logger
  @logger ||= Log.new(Dialog.config.log.base)
end

.perf(perf) ⇒ Object



35
36
37
38
39
40
# File 'lib/triggers/start/start_pre.rb', line 35

def perf(perf)
a = []
a << "mmsg: #{perf[:metamess] - perf[:init]}s" if perf.has_key?(:metamess)
a << "preApiAction: #{perf[:preApiAction] - perf[:init]}s" if perf.has_key?(:preApiAction)
a << "full: #{perf[:fullend] - perf[:init]}s"  
end

.redisObject



17
18
19
# File 'lib/triggers/start/start_pre.rb', line 17

def redis
  @redis ||= Redis.new(path: Dialog.config.db.redis_url)
end

.runMessage(args) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/triggers/start/start_bot.rb', line 100

def runMessage(args)      
    begin
#           Dialog.logger.debug "######### - REDIS STAT:\n #{Dialog::redis.call(['client', 'list'])}\n\n"
      Dialog::Metamess.firstpoint(args)
      args[:perf][:fullend] = Time.now                     
      Dialog.logger.info("## PERF: #{perf(args[:perf]).join(", ")}")  
      
    rescue Exception => @e
      Dialog.logger.error "ERROR - #{@e.inspect}\n\n Backtrace:\n #{@e.backtrace.join("\n\t")}\n \
      MMSG:\n#{args[:mmsg]}\n" if @e
      args[:bot].api.send("sendMessage".to_sym, {chat_id: Dialog.config.monitoring.channel, disable_notification: true, text: @e}) unless Dialog.config.monitoring.channel.nil?
      raise
    end
end

.systemd(service) ⇒ Object



52
53
54
55
# File 'lib/triggers/deploy/deploy.rb', line 52

def systemd(service)
  Open3.popen3('/usr/bin/systemctl', '--user', 'daemon-reload')
  Open3.popen3('/usr/bin/systemctl', '--user', 'restart', service)
end

.tdlibAuthObject



20
21
22
23
# File 'lib/triggers/init.rb', line 20

def tdlibAuth
  sess = Dialog::TDLib.tdlibInit(Dialog.config.run.mode)
  Dialog::TDLib.tdlibAuth(Dialog.config.run.mode, sess)
end

.tdlibInit(args) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/triggers/start/start_bot.rb', line 16

def tdlibInit(args)
  inits = ['cli']
  args[:tdlib] = {}
  inits.each do |init|
    unless File.exists?("#{Dialog.config.path.data}/tdlib/#{init}/td.binlog")
      Dialog.logger.error "ERROR: please make init of the '#{init}' using 'ruby dialog.rb init #{init}"
      exit(false)
    end
    args[:tdlib][init.to_sym] = Dialog::TDLib.tdlibInit(init)        
  end
  args[:tdlib].freeze
end

.trigger_deployObject



16
17
18
19
# File 'lib/triggers/deploy/deploy.rb', line 16

def trigger_deploy
  deploy_redis
  deploy_bot
end

.trigger_falseObject



16
17
18
# File 'lib/triggers/false.rb', line 16

def trigger_false
  Dialog.logger.error "Something wrong in runtime scenario"
end

.trigger_fullObject



16
17
18
# File 'lib/triggers/_meta/full.rb', line 16

def trigger_full
  
end

.trigger_initObject



16
17
18
# File 'lib/triggers/init.rb', line 16

def trigger_init
  Dialog.tdlibAuth
end

.trigger_startObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/triggers/start/start.rb', line 16

def trigger_start
  args = {}
  case Dialog.config.common.mode
  when 'check'
    jsonDriven(args, :check)
  when 'bot'
    jsonDriven(args, :prod)
    bot(args)
  when 'dev'
    dialectDriven(args)
    jsonDriven(args, :prod)
    bot(args)
  when 'dev_offline'
    dialectDriven(args)
    jsonDriven(args, :check)  
  else
     Dialog.logger.error "ERROR: no such mode - '#{Dialog.config.common.mode}'"
  end      
end