<commit_before># Copyright (C) <NAME>

=begin rdoc
ActiveWebService's are used to communicate to RESTful Web Services.

Example:

class ChargifyWebService < ActiveWebService
  # always send Chargify data in json
  headers 'Content-Type' => 'application/json'

  rest :customer, :customers, '/customers.json'
  route :find_customer, '/customers/lookup.json', :resource => 'customer'
  # find_customer_by_reference
  route :customer_subscriptions, '/customers/:customer_id/subscriptions.json', :resource => :subscription

  route :product_families, '/product_families.xml', :resource => :product_families

  route :products, '/products.json', :resource => :product
  route :product, '/products/:product_id.json', :resource => :product
  route :find_product_by_handle, '/products/handle/:handle.json', :resource => :product

  rest :subscription, :subscriptions, '/subscriptions.json'
  route :cancel_subscription, '/subscriptions/:subscription_id.json', :resource => :subscription, :method => :delete, :expected_status => [200, 204]
  route :reactivate_subscription, '/subscriptions/:subscription_id/reactivate.xml', :resource => :subscription, :method => :put, :expected_status => 200
  route :subscription_transactions, '/subscriptions/:subscription_id/transactions.json', :resource => :transaction
  # Chargify offers the ability to upgrade or downgrade a Customer's subscription in the middle of a billing period.
  route :create_subscription_migration, '/subscriptions/:subscription_id/migrations.json', :resource => :subscription, :expected_status => 200
  route :reactivate_subscription, '/subscriptions/:subscription_id/reactivate.xml', :resource => :subscription, :method => :put, :expected_status => 200
  route :create_subscription_credit, '/subscriptions/:subscription_id/credits.json', :resource => :credit
  route :reset_subscription_balance, '/subscriptions/:subscription_id/reset_balance.xml', :resource => :subscription, :method => :put, :expected_status => 200

  route :transactions, '/transactions.json', :resource => :transaction

  route :create_charge, '/subscriptions/:subscription_id/charges.json', :resource => :charge

  route :components, '/product_families/:product_family_id/components.json', :resource => :component
  route :component_usages, '/subscriptions/:subscription_id/components/:component_id/usages.json', :resource => :usage
  route :create_component_usage, '/subscriptions/:subscription_id/components/:component_id/usages.json', :resource => :usage, :expected_status => 200

  route :coupon, '/product_families/:product_family_id/coupons/:coupon_id.json', :resource => :coupon
  route :find_coupon, '/product_families/:product_family_id/coupons/find.json', :resource => :coupon
  # find_coupon_by_code

  route :subscription_components, '/subscriptions/:subscription_id/components.json', :resource => :component
  route :edit_subscription_component, '/subscriptions/:subscription_id/components/:component_id.json', :resource => :component

  def initialize(api_key, subdomain)
    self.base_uri = "https://#{subdomain}.chargify.com"
    self.basic_auth = {:username => api_key, :password => 'x'}
  end

  # Need to convert the body from a hash to json by default HTTParty::Request calls to_params if body is a Hash
  def build_options!(options)
    super
    options[:body] = options[:body].to_json if options[:body]
  end
end

@service = ChargifyWebService 'my api key', 'my-subdomain'

# Would return all the products
@service.products

# List customers
@service.customers

# Get a customer
@service.customer 90

# Create a new customer
@service.create_customer {:first_name => 'Doug', :last_name => 'Youch', :email => '<EMAIL>'}

# Edit an existing customer
@service.edit_customer 90, {:first_name => 'Douglas'}

# Save a customer
@service.save :customer, {:reference => '581', :first_name => 'Doug', :last_name => 'Youch', :email => '<EMAIL>'} # create
@service.save :customer, {:first_name => 'Douglas', :id => 90} # edit

# Find a customer by reference
@service.find_customer_by_reference '581'


class LoremIpsumWebService < ActiveWebService

  route :create_lipsum, '/feed/json', :expected_status => 200, :return => :handle_response

  def initialize
    self.base_uri = "http://www.lipsum.com"
  end

  def handle_response(response)
    response['feed']['lipsum'] if response && response['feed']
  end
end

=end

class ActiveWebService
  class Error < Exception; end
  class InvalidResponse < Error; end
  class MethodMissing < Error; end

  include HTTParty

  attr_accessor :base_uri, :basic_auth
  attr_reader :response, :request_url, :request_options, :request_method

  # Defines a web service route
  #
  # name of the method to create
  # name has special meaning.
  # If starts with create or add the method will be set to post.
  # If starts with edit or update the method will be set to put.
  # If starts with delete the method will be set to delete.
  # Else by default the method is get.
  #
  # path is the path to the web service
  #
  # === Options
  #
  # [:method]
  #   The request method get/post/put/delete. Default is get.
  # [:expected_status]
  #   Expected status code of the response, will raise InvalidResponse. Can be an array of codes.
  # [:return]
  #   The method to call or the class to create before method returns.
  # [:resource]
  #   The name of the element to return from the response.
  def self.route(name, path, options={})
    args = path.scan /:[a-z_]+/
    function_args = args.collect{ |arg| arg[1..-1] }

    method = options[:method]
    expected_status = options[:expected_status]
    if method.nil?
      if name.to_s =~ /^(create|add|edit|update|delete)_/
        case $1
        when 'create'
          method = 'post'
          expected_status ||= [200, 201]
        when 'add'
          method = 'post'
          expected_status ||= [200, 201]
        when 'edit'
          method = 'put'
          expected_status ||= 200
        when 'update'
          method = 'put'
          expected_status ||= 200
        when 'delete'
          method = 'delete'
          expected_status ||= [200, 204]
        end
      else
        method = 'get'
        expected_status ||= 200
      end
    end

    method = method.to_s
    function_args << 'body' if method == 'post' || method == 'put'
    function_args << 'options={}'

    method_src = <<-METHOD
    def #{name}(#{function_args.join(',')})
      path = "#{path}"
    METHOD

    args.each_with_index do |arg, idx|
      method_src << "path.sub! '#{arg}', #{function_args[idx]}.to_s\n"
    end

    if method == 'post' || method == 'put'
      if options[:resource]
        method_src << "options[:body] = {'#{options[:resource].to_s}' => body}\n"
      else
        method_src << "options[:body] = body\n"
      end<commit_msg>Added :no_body options to remove the body from a post or put route<commit_after># Copyright (C) <NAME>

=begin rdoc
ActiveWebService's are used to communicate to RESTful Web Services.

Example:

class ChargifyWebService < ActiveWebService
  # always send Chargify data in json
  headers 'Content-Type' => 'application/json'

  rest :customer, :customers, '/customers.json'
  route :find_customer, '/customers/lookup.json', :resource => 'customer'
  # find_customer_by_reference
  route :customer_subscriptions, '/customers/:customer_id/subscriptions.json', :resource => :subscription

  route :product_families, '/product_families.xml', :resource => :product_families

  route :products, '/products.json', :resource => :product
  route :product, '/products/:product_id.json', :resource => :product
  route :find_product_by_handle, '/products/handle/:handle.json', :resource => :product

  rest :subscription, :subscriptions, '/subscriptions.json'
  route :cancel_subscription, '/subscriptions/:subscription_id.json', :resource => :subscription, :method => :delete, :expected_status => [200, 204]
  route :reactivate_subscription, '/subscriptions/:subscription_id/reactivate.xml', :resource => :subscription, :method => :put, :expected_status => 200
  route :subscription_transactions, '/subscriptions/:subscription_id/transactions.json', :resource => :transaction
  # Chargify offers the ability to upgrade or downgrade a Customer's subscription in the middle of a billing period.
  route :create_subscription_migration, '/subscriptions/:subscription_id/migrations.json', :resource => :subscription, :expected_status => 200
  route :reactivate_subscription, '/subscriptions/:subscription_id/reactivate.xml', :resource => :subscription, :method => :put, :expected_status => 200
  route :create_subscription_credit, '/subscriptions/:subscription_id/credits.json', :resource => :credit
  route :reset_subscription_balance, '/subscriptions/:subscription_id/reset_balance.xml', :resource => :subscription, :method => :put, :expected_status => 200

  route :transactions, '/transactions.json', :resource => :transaction

  route :create_charge, '/subscriptions/:subscription_id/charges.json', :resource => :charge

  route :components, '/product_families/:product_family_id/components.json', :resource => :component
  route :component_usages, '/subscriptions/:subscription_id/components/:component_id/usages.json', :resource => :usage
  route :create_component_usage, '/subscriptions/:subscription_id/components/:component_id/usages.json', :resource => :usage, :expected_status => 200

  route :coupon, '/product_families/:product_family_id/coupons/:coupon_id.json', :resource => :coupon
  route :find_coupon, '/product_families/:product_family_id/coupons/find.json', :resource => :coupon
  # find_coupon_by_code

  route :subscription_components, '/subscriptions/:subscription_id/components.json', :resource => :component
  route :edit_subscription_component, '/subscriptions/:subscription_id/components/:component_id.json', :resource => :component

  def initialize(api_key, subdomain)
    self.base_uri = "https://#{subdomain}.chargify.com"
    self.basic_auth = {:username => api_key, :password => 'x'}
  end

  # Need to convert the body from a hash to json by default HTTParty::Request calls to_params if body is a Hash
  def build_options!(options)
    super
    options[:body] = options[:body].to_json if options[:body]
  end
end

@service = ChargifyWebService 'my api key', 'my-subdomain'

# Would return all the products
@service.products

# List customers
@service.customers

# Get a customer
@service.customer 90

# Create a new customer
@service.create_customer {:first_name => 'Doug', :last_name => 'Youch', :email => '<EMAIL>'}

# Edit an existing customer
@service.edit_customer 90, {:first_name => 'Douglas'}

# Save a customer
@service.save :customer, {:reference => '581', :first_name => 'Doug', :last_name => 'Youch', :email => '<EMAIL>'} # create
@service.save :customer, {:first_name => 'Douglas', :id => 90} # edit

# Find a customer by reference
@service.find_customer_by_reference '581'


class LoremIpsumWebService < ActiveWebService

  route :create_lipsum, '/feed/json', :expected_status => 200, :return => :handle_response

  def initialize
    self.base_uri = "http://www.lipsum.com"
  end

  def handle_response(response)
    response['feed']['lipsum'] if response && response['feed']
  end
end

=end

class ActiveWebService
  class Error < Exception; end
  class InvalidResponse < Error; end
  class MethodMissing < Error; end

  include HTTParty

  attr_accessor :base_uri, :basic_auth
  attr_reader :response, :request_url, :request_options, :request_method

  # Defines a web service route
  #
  # name of the method to create
  # name has special meaning.
  # If starts with create or add the method will be set to post.
  # If starts with edit or update the method will be set to put.
  # If starts with delete the method will be set to delete.
  # Else by default the method is get.
  #
  # path is the path to the web service
  #
  # === Options
  #
  # [:method]
  #   The request method get/post/put/delete. Default is get.
  # [:expected_status]
  #   Expected status code of the response, will raise InvalidResponse. Can be an array of codes.
  # [:return]
  #   The method to call or the class to create before method returns.
  # [:resource]
  #   The name of the element to return from the response.
  # [:no_body]
  #   Removes the body argument from a post/put route
  def self.route(name, path, options={})
    args = path.scan /:[a-z_]+/
    function_args = args.collect{ |arg| arg[1..-1] }

    method = options[:method]
    expected_status = options[:expected_status]
    if method.nil?
      if name.to_s =~ /^(create|add|edit|update|delete)_/
        case $1
        when 'create'
          method = 'post'
          expected_status ||= [200, 201]
        when 'add'
          method = 'post'
          expected_status ||= [200, 201]
        when 'edit'
          method = 'put'
          expected_status ||= 200
        when 'update'
          method = 'put'
          expected_status ||= 200
        when 'delete'
          method = 'delete'
          expected_status ||= [200, 204]
        end
      else
        method = 'get'
        expected_status ||= 200
      end
    end

    method = method.to_s
    function_args << 'body' if (method == 'post' || method == 'put') && options[:no_body].nil?
    function_args << 'options={}'

    method_src = <<-METHOD
    def #{name}(#{function_args.join(',')})
      path = "#{path}"
    METHOD

    args.each_with_index do |arg, idx|
      method_src << "path.sub! '#{arg}', #{function_args[idx]}.to_s\n"
    end

    if options[:no_body].nil?
      if method == 'post' || method == 'put'
        if options[:resource]
          method_src << "options[:body] = {'#{options[:resource].to_s}' => body}\n"
        else
          method_src << "options[:body] = body\n"
        end
      end
{'fraction_non_alphanumeric': 0.1289596047660564, 'fraction_numerical': 0.00959023539668701, 'mean_word_length': 4.005454545454546, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 105, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 8}, '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': '740740', 'n_tokens_mistral': 4270, 'n_tokens_neox': 4147, 'n_words': 1152}