<commit_before>module Dbox
  class ConfigurationError < RuntimeError; end
  class ServerError < RuntimeError; end
  class RemoteMissing < RuntimeError; end
  class RemoteAlreadyExists < RuntimeError; end
  class RequestDenied < RuntimeError; end

  class API
    include Loggable

    def self.authorize
      auth = Authenticator.new(conf)
      authorize_url = auth.get_request_token
      puts "Please visit the following URL in your browser, log into Dropbox, and authorize the app you created.\n\n#{authorize_url}\n\nWhen you have done so, press [ENTER] to continue."
      STDIN.readline
      res = auth.get_access_token
      puts "export DROPBOX_AUTH_KEY=#{res.token}"
      puts "export DROPBOX_AUTH_SECRET=#{res.secret}"
      puts
      puts "This auth token will last for 10 years, or when you choose to invalidate it, whichever comes first."
      puts
      puts "Now either include these constants in yours calls to dbox, or set them as environment variables."
      puts "In bash, including them in calls looks like:"
      puts "$ DROPBOX_AUTH_KEY=#{res.token} DROPBOX_AUTH_SECRET=#{res.secret} dbox ..."
    end

    def self.connect
      api = new()
      api.connect
      api
    end

    # IMPORTANT: API.new is private. Please use API.authorize or API.connect as the entry point.
    private_class_method :new
    def initialize
      @conf = self.class.conf
    end

    def connect
      auth_key = ENV["DROPBOX_AUTH_KEY"]
      auth_secret = ENV["DROPBOX_AUTH_SECRET"]

      raise(ConfigurationError, "Please set the DROPBOX_AUTH_KEY environment variable to an authenticated Dropbox session key") unless auth_key
      raise(ConfigurationError, "Please set the DROPBOX_AUTH_SECRET environment variable to an authenticated Dropbox session secret") unless auth_secret

      @auth = Authenticator.new(@conf, auth_key, auth_secret)
      @client = DropboxClient.new(@conf["server"], @conf["content_server"], @conf["port"], @auth)
    end

    def run(path)
      begin
        res = yield
        case res
        when Hash
          res
        when String
          res
        when Net::HTTPNotFound
          raise RemoteMissing, "#{path} does not exist on Dropbox"
        when Net::HTTPForbidden
          raise RequestDenied, "Operation on #{path} denied"
        else
          raise RuntimeError, "Unexpected result: #{res.inspect}"
        end
      rescue DropboxError => e
        log.debug e.inspect
        raise ServerError, "Server error -- might be a hiccup, please try your request again (#{e.message})"
      end
    end

    def metadata(path = "/")
      log.debug "Fetching metadata for #{path}"
      run(path) do
        @client.metadata(@conf["root"], escape_path(path))
      end
    end

    def create_dir(path)
      log.info "Creating #{path}"
      run(path) do
        case res = @client.file_create_folder(@conf["root"], path)
        when Net::HTTPForbidden
          raise RemoteAlreadyExists, "The directory at #{path} already exists"
        else
          res
        end
      end
    end

    def delete_dir(path)
      log.info "Deleting #{path}"
      run(path) do
        @client.file_delete(@conf["root"], path)
      end
    end

    def get_file(path)
      log.info "Downloading #{path}"
      run(path) do<commit_msg>Error message fix.<commit_after>module Dbox
  class ConfigurationError < RuntimeError; end
  class ServerError < RuntimeError; end
  class RemoteMissing < RuntimeError; end
  class RemoteAlreadyExists < RuntimeError; end
  class RequestDenied < RuntimeError; end

  class API
    include Loggable

    def self.authorize
      auth = Authenticator.new(conf)
      authorize_url = auth.get_request_token
      puts "Please visit the following URL in your browser, log into Dropbox, and authorize the app you created.\n\n#{authorize_url}\n\nWhen you have done so, press [ENTER] to continue."
      STDIN.readline
      res = auth.get_access_token
      puts "export DROPBOX_AUTH_KEY=#{res.token}"
      puts "export DROPBOX_AUTH_SECRET=#{res.secret}"
      puts
      puts "This auth token will last for 10 years, or when you choose to invalidate it, whichever comes first."
      puts
      puts "Now either include these constants in yours calls to dbox, or set them as environment variables."
      puts "In bash, including them in calls looks like:"
      puts "$ DROPBOX_AUTH_KEY=#{res.token} DROPBOX_AUTH_SECRET=#{res.secret} dbox ..."
    end

    def self.connect
      api = new()
      api.connect
      api
    end

    # IMPORTANT: API.new is private. Please use API.authorize or API.connect as the entry point.
    private_class_method :new
    def initialize
      @conf = self.class.conf
    end

    def connect
      auth_key = ENV["DROPBOX_AUTH_KEY"]
      auth_secret = ENV["DROPBOX_AUTH_SECRET"]

      raise(ConfigurationError, "Please set the DROPBOX_AUTH_KEY environment variable to an authenticated Dropbox session key") unless auth_key
      raise(ConfigurationError, "Please set the DROPBOX_AUTH_SECRET environment variable to an authenticated Dropbox session secret") unless auth_secret

      @auth = Authenticator.new(@conf, auth_key, auth_secret)
      @client = DropboxClient.new(@conf["server"], @conf["content_server"], @conf["port"], @auth)
    end

    def run(path)
      begin
        res = yield
        case res
        when Hash
          res
        when String
          res
        when Net::HTTPNotFound
          raise RemoteMissing, "#{path} does not exist on Dropbox"
        when Net::HTTPForbidden
          raise RequestDenied, "Operation on #{path} denied"
        else
          raise RuntimeError, "Unexpected result: #{res.inspect}"
        end
      rescue DropboxError => e
        log.debug e.inspect
        raise ServerError, "Server error -- might be a hiccup, please try your request again (#{e.message})"
      end
    end

    def metadata(path = "/")
      log.debug "Fetching metadata for #{path}"
      run(path) do
        @client.metadata(@conf["root"], escape_path(path))
      end
    end

    def create_dir(path)
      log.info "Creating #{path}"
      run(path) do
        case res = @client.file_create_folder(@conf["root"], path)
        when Net::HTTPForbidden
          raise RemoteAlreadyExists, "Either the directory at #{path} already exists, or it has invalid characters in the name"
        else
          res
        end
      end
    end

    def delete_dir(path)
      log.info "Deleting #{path}"
      run(path) do
        @client.file_delete(@conf["root"], path)
      end
    end

    def get_file(path)
      log.info "Downloading #{path}"
      run(path) do
{'fraction_non_alphanumeric': 0.08438818565400844, 'fraction_numerical': 0.0006027727546714888, 'mean_word_length': 2.6648260629486473, 'pattern_counts': {'":': 0, '<': 13, '<?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': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5062738', 'n_tokens_mistral': 1916, 'n_tokens_neox': 1892, 'n_words': 626}