<commit_before>require 'json'

module Expando
  # Responsible for updating intent objects on Api.ai based on the contents of
  # files in `/intents`.
  class IntentUpdater < Updater
    # !@attribute name
    #   @return [String] the name of the intent to be updated
    attr_accessor :name

    # !@attribute intents_path
    #   @return [String] the path to the directory containing the intent source files
    attr_accessor :intents_path

    # Initialize a new `IntentUpdater`.
    #
    # @see Updater#initialize
    def initialize( * )
      super
    end

    # Update the named entity on Api.ai.
    #
    # @return [Hash] if request successful. This is the response body.
    # @return [ApiAiRuby::RequestError] if request is in error.
    def update!
      response = @client.update_intent_request( intent_json )

      handle_response( response, :intent )
    end

    private

    # Construct a proper JSON object for updating the intent, based on its current
    #   state plus the expanded templates
    #
    # @return [Hash] The constructed JSON of for the intent.
    def intent_json
      @id = intent_id

      log_message "Fetching latest version of #{ @name } intent"
      json = @client.get_intent_request( @id )

      json[ :userSays ] = expanded_utterances

      # TODO: Make this a separate, tested method
      responses = File.readlines File.join( File.expand_path( @intents_path ), '..', 'responses', @name.to_s + '.txt' )
      responses = responses.collect { |response| response.chomp }

      responsesJson = json[ :responses ]
      responsesJson[ 0 ][ :speech ] = responses
      json[:responses] = responsesJson

      # Clean up portions of the JSON response that we don't need in the request
      %w{templates state priority webhookUsed}.each { |key| json.delete( key.to_sym ) }

      json
    end

    # Fetch the ID of the intent with this name on Api.ai.
    #
    # @return [String] The ID of the intent with this `@name` on Api.ai.
    def intent_id
      log_message "Fetching id of #{ @name } intent"
      intents = @client.get_intents_request

      matching_intent = intents.select { |intent| intent[ :name ] == @name.to_s }

      if matching_intent.empty?
        # TODO: Consult Exceptional Ruby for a better way to do this
        raise "There is no intent named #{@name}"
      else
        return matching_intent.first[ :id ]
      end
    end

    # @return [Array<String>] The expanded list of intent utterances.<commit_msg>Skip response files when not present<commit_after>require 'json'

module Expando
  # Responsible for updating intent objects on Api.ai based on the contents of
  # files in `/intents`.
  class IntentUpdater < Updater
    # !@attribute name
    #   @return [String] the name of the intent to be updated
    attr_accessor :name

    # !@attribute intents_path
    #   @return [String] the path to the directory containing the intent source files
    attr_accessor :intents_path

    # Initialize a new `IntentUpdater`.
    #
    # @see Updater#initialize
    def initialize( * )
      super
    end

    # Update the named entity on Api.ai.
    #
    # @return [Hash] if request successful. This is the response body.
    # @return [ApiAiRuby::RequestError] if request is in error.
    def update!
      response = @client.update_intent_request( intent_json )

      handle_response( response, :intent )
    end

    private

    # Construct a proper JSON object for updating the intent, based on its current
    #   state plus the expanded templates
    #
    # @return [Hash] The constructed JSON of for the intent.
    def intent_json
      @id = intent_id

      log_message "Fetching latest version of #{ @name } intent"
      json = @client.get_intent_request( @id )

      json[ :userSays ] = expanded_utterances

      # TODO: Make this a separate, tested method
      responses_path = File.join( File.expand_path( @intents_path ), '..', 'responses', @name.to_s + '.txt' )

      if File.exist?(responses_path)
        responses = File.readlines
        responses = responses.collect { |response| response.chomp }

        responsesJson = json[ :responses ]
        responsesJson[ 0 ][ :speech ] = responses
        json[:responses] = responsesJson
      end

      # Clean up portions of the JSON response that we don't need in the request
      %w{templates state priority webhookUsed}.each { |key| json.delete( key.to_sym ) }

      json
    end

    # Fetch the ID of the intent with this name on Api.ai.
    #
    # @return [String] The ID of the intent with this `@name` on Api.ai.
    def intent_id
      log_message "Fetching id of #{ @name } intent"
      intents = @client.get_intents_request

      matching_intent = intents.select { |intent| intent[ :name ] == @name.to_s }

      if matching_intent.empty?
        # TODO: Consult Exceptional Ruby for a better way to do this
        raise "There is no intent named #{@name}"
      else
        return matching_intent.first[ :id ]
      end
    end

    # @return [Array<String>] The expanded list of intent utterances.
{'fraction_non_alphanumeric': 0.08461538461538462, 'fraction_numerical': 0.0003944773175542406, 'mean_word_length': 2.704163623082542, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2242076', 'n_tokens_mistral': 1475, 'n_tokens_neox': 1457, 'n_words': 534}