<commit_before>module ActiveMerchant
  module Shipping
    class DHL < Carrier
      cattr_reader :name

      @@name = "DHL"

      URL = 'https://api.dhlglobalmail.com'

      def requirements
        [:username, :password]
      end

      def initialize(options = {})
        super options
        @base_header = {'Accept' => 'application/json', 'Content-Type' => 'application/json;charset=UTF-8'}
        @retries = 0
        @threshold = options[:threshold] || 1
      end


      def find_tracking_info(number)
        token = get_token
        url = "#{URL}/v1/mailitems/track.json?access_token=#{token}&client_id=#{@options[:client_id]}&number=#{number}"
        response = Response.new(ssl_get(url, headers=@base_header))
        puts response.json
        if response.invalid_token?
          clear_token
          raise ResponseError('Max retries of authentication exceeded, could not get access token') unless @retries < @threshold
          @retries += 1
          call_tracking(number)
        end
        @retries = 0
        parse_tracking_response(response)
      end

      def parse_tracking_response(response)
        success = response.ok?
        message = response.error_message
        shipment_events = []

        if success
          shipment_events = response.events.map(&:access_token)
        end

        TrackingResponse.new(success, message, response.data,
                             :carrier => @@name,
                             :status => response.status,
                             :shipment_events => shipment_events
        )
      end

      def parse_event(event)
        code = event['id']
        description = event['description']
        time = Time.strptime("#{event['time']} #{event['date']}", '%H:%M:%S %Y-%m-%d' )
        {:code => code, :description => description, :time => time}
      end

      private

      def clear_token
        @private_token = nil
      end

      def get_token
        @private_token ||= retrieve_token
      end

      def retrieve_token
        url = "#{@root}/v1/auth/access_token.json?username=#{@options[:username]}&password=#{@options[:password]}"
        response = Response.new(ssl_get(url, headers=@base_header))
        raise ResponseError('Unable to authenticate, got this message: ' + response.error_message) unless response.ok?
        response.data['access_token']
      end

      class Response
        attr_accessor :json
        attr_accessor :meta
        attr_accessor :data

        def initialize (raw_content)
          @json = JSON.parse(raw_content)
          @status = @json['meta']['code']
          @meta = @json['meta']
          @data = @json['data']
          @error = @meta['error']
        end

        def ok?
          @status == 200
        end

        def invalid_token?
          !ok? && @error && @error.any?{|e| e['error_type'] == 'INVALID_TOKEN'}
        end

        def error_message
          ok? && @error && @error.first['error_message']
        end
<commit_msg>update DHL api to make it easier to test<commit_after># -*- coding: utf-8 -*-
module ActiveMerchant
  module Shipping
    class DHL < Carrier
      cattr_reader :name

      @@name = 'DHL'

      URL = 'https://api.dhlglobalmail.com'
      HEADER = {'Accept' => 'application/json', 'Content-Type' => 'application/json;charset=UTF-8'}

      def requirements
        [:username, :password, :client_id]
      end

      def initialize(options = {})
        super options
        @retries = 0
        @threshold = options[:threshold] || 1
        @private_token = options[:override_token] if options.has_key? :override_token
      end

      def find_tracking_info(number)
        token = get_token
        url = get_tracking_url(number, token)
        response = call_api(url)
        puts response.json
        if response.invalid_token?
          clear_token
          raise ResponseError('Max retries of authentication exceeded, could not get access token') unless @retries < @threshold
          @retries += 1
          call_tracking(number)
        end
        @retries = 0
        parse_tracking_response(response)
      end

      def get_tracking_url(number, token)
        "#{URL}/v1/mailitems/track.json?access_token=#{token}&client_id=#{@options[:client_id]}&number=#{number}"
      end

      def parse_tracking_response(response)
        success = response.ok?
        message = response.error_message
        shipment_events = []

        if success
          shipment_events = response.events.map(&:access_token)
        end

        TrackingResponse.new(success, message, response.data,
                             :carrier => @@name,
                             :status => response.status,
                             :shipment_events => shipment_events,
                             :last_request => @last_request
        )
      end

      def parse_event(event)
        code = event['id']
        description = event['description']
        time = Time.strptime("#{event['time']} #{event['date']}", '%H:%M:%S %Y-%m-%d' )
        {:code => code, :description => description, :time => time}
      end

      def retrieve_token
        url = get_token_url
        response = call_api(url)
        raise ResponseError('Unable to authenticate, got this message: ' + response.error_message) unless response.ok?
        response.data['access_token']
      end

      def get_token_url
        "#{URL}/v1/auth/access_token.json?username=#{@options[:username]}&password=#{@options[:password]}"
      end

      private

      def clear_token
        @private_token = nil
      end

      def get_token
        @private_token ||= retrieve_token
      end



      def call_api(url)
        @last_request = url
        response = nil
        begin
          response = Response.new(RestClient.get(url, @base_header))
        rescue RestClient::BadRequest => e
          ap e
        end
        response
      end

      class Response
        attr_accessor :json
        attr_accessor :meta
        attr_accessor :data

        def initialize (raw_content)
          @json = JSON.parse(raw_content)
          @status = @json['meta']['code']
          @meta = @json['meta']
          @data = @json['data']
          @error = @meta['error']
        end

        def ok?
          @status == 200
        end

        def invalid_token?
          !ok? && @error && @error.any?{|e| e['error_type'] == 'INVALID_TOKEN'}
        end

        def error_message
          ok? && @error && @error.first['error_message']
        end

{'fraction_non_alphanumeric': 0.1146360153256705, 'fraction_numerical': 0.003218390804597701, 'mean_word_length': 2.0452636490900606, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 21, 'https://': 2, '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': '1074725', 'n_tokens_mistral': 1878, 'n_tokens_neox': 1799, 'n_words': 405}