<commit_before>require 'json'
require 'net/ftptls'

# silence the parenthesis warning in rest-client 1.6.1
old_verbose, $VERBOSE = $VERBOSE, nil ; require 'rest-client' ; $VERBOSE = old_verbose

module GoodData

  # = GoodData HTTP wrapper
  #
  # Provides a convenient HTTP wrapper for talking with the GoodData API.
  #
  # Remember that the connection is shared amongst the entire application.
  # Therefore you can't be logged in to more than _one_ GoodData account.
  # per session. Simultaneous connections to multiple GoodData accounts is not
  # supported at this time.
  #
  # The GoodData API is a RESTful API that communicates using JSON. This wrapper
  # makes sure that the session is stored between requests and that the JSON is
  # parsed both when sending and receiving.
  #
  # == Usage
  #
  # Before a connection can be made to the GoodData API, you have to supply the user
  # credentials using the set_credentials method:
  #
  #   Connection.new(username, password).set_credentials(username, password)
  #
  # To send a HTTP request use either the get, post or delete methods documented below.
  #
  class Connection

    DEFAULT_URL = 'https://secure.gooddata.com'
    LOGIN_PATH = '/gdc/account/login'
    TOKEN_PATH = '/gdc/account/token'

    # Set the GoodData account credentials.
    #
    # This have to be performed before any calls to the API.
    #
    # === Parameters
    #
    # * +username+ - The GoodData account username
    # * +password+ - The GoodData account password
    def initialize(username, password, url = nil, options = {})
      @status   = :not_connected
      @username = username
      @password = password
      @url      = url || DEFAULT_URL
      @options  = options
    end

    # Returns the user JSON object of the currently logged in GoodData user account.
    def user
      ensure_connection
      @user
    end

    # Performs a HTTP GET request.
    #
    # Retuns the JSON response formatted as a Hash object.
    #
    # === Parameters
    #
    # * +path+ - The HTTP path on the GoodData server (must be prefixed with a forward slash)
    #
    # === Examples
    #
    #   Connection.new(username, password).get '/gdc/projects'
    def get(path, options = {})
      GoodData.logger.debug "GET #{path}"
      ensure_connection
      process_response(options) { @server[path].get cookies }
    end

    # Performs a HTTP POST request.
    #
    # Retuns the JSON response formatted as a Hash object.
    #
    # === Parameters
    #
    # * +path+ - The HTTP path on the GoodData server (must be prefixed with a forward slash)
    # * +data+ - The payload data in the format of a Hash object
    #
    # === Examples
    #
    #   Connection.new(username, password).post '/gdc/projects', { ... }
    def post(path, data, options = {})
      payload = data.to_json
      GoodData.logger.debug "POST #{path}, payload: #{payload}"
      ensure_connection
      process_response(options) { @server[path].post payload, cookies }
    end

    # Performs a HTTP DELETE request.
    #
    # Retuns the JSON response formatted as a Hash object.
    #
    # === Parameters
    #
    # * +path+ - The HTTP path on the GoodData server (must be prefixed with a forward slash)
    #
    # === Examples
    #
    #   Connection.new(username, password).delete '/gdc/project/1'
    def delete(path)
      GoodData.logger.debug "DELETE #{path}"
      ensure_connection
      process_response { @server[path].delete cookies }
    end

    # Get the cookies associated with the current connection.
    def cookies
      @cookies ||= { :cookies => {} }
    end

    # Set the cookies used when communicating with the GoodData API.
    def merge_cookies!(cookies)
      self.cookies
      @cookies[:cookies].merge! cookies
    end

    # Returns true if a connection have been established to the GoodData API
    # and the login was successful.
    def logged_in?
      @status == :logged_in
    end

    # The connection will automatically be established once it's needed, which it
    # usually is when either the user, get, post or delete method is called. If you
    # want to force a connection (or a re-connect) you can use this method.
    def connect!
      connect
    end

    # Uploads a file to GoodData server via FTPS
    def upload(file, dir = nil)
      Net::FTPTLS.open('secure-di.gooddata.com', @username, @password) do |ftp|
        ftp.passive = true
        if dir then
          begin ; ftp.mkdir dir ; rescue ; ensure ; ftp.chdir dir ; end
        end
        ftp.binary = true
        ftp.put file
      end
    end

    private

    def ensure_connection
      connect if @status == :not_connected
    end

    def connect
      # GoodData.logger.info "Connecting to GoodData..."
      @status = :connecting
      authenticate
    end

    def authenticate
      credentials = {
        'postUserLogin' => {
          'login' => @username,
          'password' => @password,
          'remember' => 1
        }
      }

      @server = RestClient::Resource.new @url,
        :timeout => @options[:timeout],
        :headers => {<commit_msg>Upload files via WebDAV instead of FTP<commit_after>require 'json'

# silence the parenthesis warning in rest-client 1.6.1
old_verbose, $VERBOSE = $VERBOSE, nil ; require 'rest-client' ; $VERBOSE = old_verbose

module GoodData

  # = GoodData HTTP wrapper
  #
  # Provides a convenient HTTP wrapper for talking with the GoodData API.
  #
  # Remember that the connection is shared amongst the entire application.
  # Therefore you can't be logged in to more than _one_ GoodData account.
  # per session. Simultaneous connections to multiple GoodData accounts is not
  # supported at this time.
  #
  # The GoodData API is a RESTful API that communicates using JSON. This wrapper
  # makes sure that the session is stored between requests and that the JSON is
  # parsed both when sending and receiving.
  #
  # == Usage
  #
  # Before a connection can be made to the GoodData API, you have to supply the user
  # credentials using the set_credentials method:
  #
  #   Connection.new(username, password).set_credentials(username, password)
  #
  # To send a HTTP request use either the get, post or delete methods documented below.
  #
  class Connection

    DEFAULT_URL = 'https://secure.gooddata.com'
    LOGIN_PATH = '/gdc/account/login'
    TOKEN_PATH = '/gdc/account/token'
    STAGE_PATH = '/uploads'

    # Set the GoodData account credentials.
    #
    # This have to be performed before any calls to the API.
    #
    # === Parameters
    #
    # * +username+ - The GoodData account username
    # * +password+ - The GoodData account password
    def initialize(username, password, url = nil, options = {})
      @status   = :not_connected
      @username = username
      @password = password
      @url      = url || DEFAULT_URL
      @options  = options
    end

    # Returns the user JSON object of the currently logged in GoodData user account.
    def user
      ensure_connection
      @user
    end

    # Performs a HTTP GET request.
    #
    # Retuns the JSON response formatted as a Hash object.
    #
    # === Parameters
    #
    # * +path+ - The HTTP path on the GoodData server (must be prefixed with a forward slash)
    #
    # === Examples
    #
    #   Connection.new(username, password).get '/gdc/projects'
    def get(path, options = {})
      GoodData.logger.debug "GET #{path}"
      ensure_connection
      process_response(options) { @server[path].get cookies }
    end

    # Performs a HTTP POST request.
    #
    # Retuns the JSON response formatted as a Hash object.
    #
    # === Parameters
    #
    # * +path+ - The HTTP path on the GoodData server (must be prefixed with a forward slash)
    # * +data+ - The payload data in the format of a Hash object
    #
    # === Examples
    #
    #   Connection.new(username, password).post '/gdc/projects', { ... }
    def post(path, data, options = {})
      payload = data.to_json
      GoodData.logger.debug "POST #{path}, payload: #{payload}"
      ensure_connection
      process_response(options) { @server[path].post payload, cookies }
    end

    # Performs a HTTP DELETE request.
    #
    # Retuns the JSON response formatted as a Hash object.
    #
    # === Parameters
    #
    # * +path+ - The HTTP path on the GoodData server (must be prefixed with a forward slash)
    #
    # === Examples
    #
    #   Connection.new(username, password).delete '/gdc/project/1'
    def delete(path)
      GoodData.logger.debug "DELETE #{path}"
      ensure_connection
      process_response { @server[path].delete cookies }
    end

    # Get the cookies associated with the current connection.
    def cookies
      @cookies ||= { :cookies => {} }
    end

    # Set the cookies used when communicating with the GoodData API.
    def merge_cookies!(cookies)
      self.cookies
      @cookies[:cookies].merge! cookies
    end

    # Returns true if a connection have been established to the GoodData API
    # and the login was successful.
    def logged_in?
      @status == :logged_in
    end

    # The connection will automatically be established once it's needed, which it
    # usually is when either the user, get, post or delete method is called. If you
    # want to force a connection (or a re-connect) you can use this method.
    def connect!
      connect
    end

    # Uploads a file to GoodData server
    # /uploads/ resources are special in that they use a different
    # host and a basic authentication.
    def upload(file, dir = nil)
      # We should have followed a link. If it was correct.
      stage_url = DEFAULT_URL.sub(/\./, '-di.')

      # Make a directory, if needed
      if dir then
        RestClient::Request.execute(
          :method => :mkcol,
          :url => stage_url + STAGE_PATH + dir + '/',
          :user => @username,
          :password => <PASSWORD>,
          :timeout => @options[:timeout],
          :headers => {
            :user_agent => GoodData.gem_version_string,
          }
        )
      end

      # Upload the file
      RestClient::Request.execute(
        :method => :put,
        :url => stage_url + STAGE_PATH + dir + '/' + File.basename(file),
        :user => @username,
        :password => <PASSWORD>,
        :timeout => @options[:timeout],
        :headers => {
          :user_agent => GoodData.gem_version_string,
        },
        :payload => File.read(file)
      )
    end

    private

    def ensure_connection
      connect if @status == :not_connected
    end

    def connect
      # GoodData.logger.info "Connecting to GoodData..."
      @status = :connecting
      authenticate
    end

    def authenticate
      credentials = {
        'postUserLogin' => {
          'login' => @username,
          'password' => <PASSWORD>,
          'remember' => 1
        }
      }

      @server = RestClient::Resource.new @url,
        :timeout => @options[:timeout],
        :headers => {
{'fraction_non_alphanumeric': 0.09229227405247814, 'fraction_numerical': 0.0009110787172011661, 'mean_word_length': 2.414307931570762, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 35, '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': '5418505', 'n_tokens_mistral': 3134, 'n_tokens_neox': 3061, 'n_words': 1117}