<commit_before># encoding: utf-8

require 'has_guarded_handlers'
require 'adhearsion/translator/asterisk/ami_error_converter'
require 'concurrent/atomic/atomic_boolean'
require 'concurrent/atomic/atomic_reference'
require 'concurrent/map'

module Adhearsion
  module Translator
    class Asterisk
      class Call
        include HasGuardedHandlers

        InvalidCommandError = Class.new Error

        OUTBOUND_CHANNEL_MATCH = /.* <(?<channel>.*)>/.freeze

        attr_reader :id, :channel, :translator, :agi_env, :direction, :pending_joins

        HANGUP_CAUSE_TO_END_REASON = Hash.new { :error }
        HANGUP_CAUSE_TO_END_REASON[0] = :hungup
        HANGUP_CAUSE_TO_END_REASON[16] = :hungup
        HANGUP_CAUSE_TO_END_REASON[17] = :busy
        HANGUP_CAUSE_TO_END_REASON[18] = :timeout
        HANGUP_CAUSE_TO_END_REASON[19] = :reject
        HANGUP_CAUSE_TO_END_REASON[21] = :reject
        HANGUP_CAUSE_TO_END_REASON[22] = :reject
        HANGUP_CAUSE_TO_END_REASON[102] = :timeout

        def initialize(channel, translator, ami_client, connection, agi_env = nil, id = nil)
          @channel, @translator, @ami_client, @connection = channel, translator, ami_client, connection
          @agi_env = agi_env || {}
          @id = id || Adhearsion.new_uuid
          @components = Concurrent::Map.new
          @answered = Concurrent::AtomicBoolean.new
          @pending_joins = {}
          @progress_sent = Concurrent::AtomicBoolean.new
          @block_commands = Concurrent::AtomicBoolean.new
          @channel_variables = {}
          @hangup_cause = Concurrent::AtomicReference.new
        end

        def register_component(component)
          @components.put_if_absent(component.id, component)
        end

        def deregister_component(id)
          @components.delete id
        end

        def component_with_id(component_id)
          @components[component_id]
        end

        def send_offer
          @direction = :inbound
          send_pb_event offer_event
        end

        def channel_var(variable)
          @channel_variables[variable] || fetch_channel_var(variable)
        end

        def to_s
          "#<#{self.class}:#{id} Channel: #{channel.inspect}>"
        end
        alias :inspect :to_s

        def dial(dial_command)
          @direction = :outbound
          channel = dial_command.to || ''
          channel.match(OUTBOUND_CHANNEL_MATCH) { |m| channel = m[:channel] }
          params = { :async       => true,
                     :context     => REDIRECT_CONTEXT,
                     :exten       => REDIRECT_EXTENSION,
                     :priority    => REDIRECT_PRIORITY,
                     :channel     => channel,
                     :callerid    => dial_command.from
                   }
          params[:variable] = variable_for_headers dial_command.headers
          params[:timeout] = dial_command.timeout unless dial_command.timeout.nil?

          originate_action = Adhearsion::Rayo::Component::Asterisk::AMI::Action.new :name => 'Originate',
                                                                              :params => params
          originate_action.request!
          translator.async.execute_global_command originate_action
          dial_command.response = Adhearsion::Rayo::Ref.new uri: id
        end

        def outbound?
          direction == :outbound
        end

        def inbound?
          direction == :inbound<commit_msg>even more thread-safety around asterisk call<commit_after># encoding: utf-8

require 'has_guarded_handlers'
require 'adhearsion/translator/asterisk/ami_error_converter'
require 'concurrent/atomic/atomic_boolean'
require 'concurrent/atomic/atomic_reference'
require 'concurrent/map'

module Adhearsion
  module Translator
    class Asterisk
      class Call
        include HasGuardedHandlers

        InvalidCommandError = Class.new Error

        OUTBOUND_CHANNEL_MATCH = /.* <(?<channel>.*)>/.freeze

        attr_reader :id, :channel, :translator, :agi_env, :pending_joins

        HANGUP_CAUSE_TO_END_REASON = Hash.new { :error }
        HANGUP_CAUSE_TO_END_REASON[0] = :hungup
        HANGUP_CAUSE_TO_END_REASON[16] = :hungup
        HANGUP_CAUSE_TO_END_REASON[17] = :busy
        HANGUP_CAUSE_TO_END_REASON[18] = :timeout
        HANGUP_CAUSE_TO_END_REASON[19] = :reject
        HANGUP_CAUSE_TO_END_REASON[21] = :reject
        HANGUP_CAUSE_TO_END_REASON[22] = :reject
        HANGUP_CAUSE_TO_END_REASON[102] = :timeout

        def initialize(channel, translator, ami_client, connection, agi_env = nil, id = nil)
          @channel, @translator, @ami_client, @connection = channel, translator, ami_client, connection
          @agi_env = agi_env || {}
          @id = id || Adhearsion.new_uuid
          @components = Concurrent::Map.new
          @answered = Concurrent::AtomicBoolean.new
          @pending_joins = Concurrent::Map.new
          @progress_sent = Concurrent::AtomicBoolean.new
          @block_commands = Concurrent::AtomicBoolean.new
          @channel_variables = Concurrent::Map.new
          @hangup_cause = Concurrent::AtomicReference.new
          @direction = Concurrent::AtomicReference.new
        end

        def direction
          @direction.get
        end

        def register_component(component)
          @components.put_if_absent(component.id, component)
        end

        def deregister_component(id)
          @components.delete id
        end

        def component_with_id(component_id)
          @components[component_id]
        end

        def send_offer
          @direction.set :inbound
          send_pb_event offer_event
        end

        def channel_var(variable)
          @channel_variables[variable] || fetch_channel_var(variable)
        end

        def to_s
          "#<#{self.class}:#{id} Channel: #{channel.inspect}>"
        end
        alias :inspect :to_s

        def dial(dial_command)
          @direction.set :outbound
          channel = dial_command.to || ''
          channel.match(OUTBOUND_CHANNEL_MATCH) { |m| channel = m[:channel] }
          params = { :async       => true,
                     :context     => REDIRECT_CONTEXT,
                     :exten       => REDIRECT_EXTENSION,
                     :priority    => REDIRECT_PRIORITY,
                     :channel     => channel,
                     :callerid    => dial_command.from
                   }
          params[:variable] = variable_for_headers dial_command.headers
          params[:timeout] = dial_command.timeout unless dial_command.timeout.nil?

          originate_action = Adhearsion::Rayo::Component::Asterisk::AMI::Action.new :name => 'Originate',
                                                                              :params => params
          originate_action.request!
          translator.async.execute_global_command originate_action
          dial_command.response = Adhearsion::Rayo::Ref.new uri: id
        end

        def outbound?
          direction == :outbound
        end

        def inbound?
          direction == :inbound
{'fraction_non_alphanumeric': 0.08760986674227389, 'fraction_numerical': 0.004819960306209243, 'mean_word_length': 2.175067506750675, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '965515', 'n_tokens_mistral': 2133, 'n_tokens_neox': 2046, 'n_words': 365}