# Uploading folder

As we described the complexity of folder operations in Downloading folder, to make things easier, this step is also done with the help of aemulari. The process is the same as with downloading folder, the only difference is that now the command is upload-folder and there are some new arguments. Here's the help message:

$ ./aemulari upload-folder --help

Upload folder usage:
  --profile-id TEXT     Profile ID to use
  --path TEXT           Path to the profile folder. You can omit this option if
                        you did not specify a custom path when creating folder 
                        with this utility
  --delete              Delete folder after upload
  --profile-lock TEXT   If the profile was started with session lock, this 
                        option is required
  --api-key TEXT        Your API key

Common options:
  --verbose             Be verbose (enable logging)


If the operation succeeds, the executable will exit with code 0. Otherwise, see the table below.

# Exit codes

Code Meaning
0 Success
1 Unknown error, can indicate anything from invalid arguments to some network errors. There should be an error message printed to stdout
2 Network error (bad curl code somewhere). There must be an error message printed to stdout
4 Folder was uploaded successfully, but the program failed to delete it after. Caller should delete it manually. There must also be an error message printed to stdout
101 Unauthorized. The api key is invalid
104 Not Found. The profile does not exist or your API Key does not belong to the profile's cluster
109 Conflict. The profile is being used and you did not provide the profileLock
122 Unprocessable Entity. The profile is currently synchronizing with the server (somebody is uploading profile folder)
123 Locked. The provided profile lock is incorrect. Somebody might have overridden the previous session before you
200 Internal Server Error

You will get the server's error message printed to stdout in case you get error codes 101-200. Usually you should contact support if you get exit codes 1, 2 or 200 and have no way of fixing it yourself.

# Code example

val pathToAemulari = "/home/myuser/.surfinite/aemulari/aemulari"

val profileId = "my_profile_id"
val apiKey = "MY_API_KEY"
val profileLock = "profile_lock_from_start_profile_response"

val pathToProfile = "/home/myuser/surfiprofiles/$profileId"

// Start aemulari with our arguments
val process = ProcessBuilder(
    listOf(
        pathToAemulari,
        "upload-folder",
        "--profile-id", profileId,
        "--path", pathToProfile,
        "--api-key", apiKey,
        "--profile-lock", profileLock,
        "--delete"
    )
)
    .redirectOutput(ProcessBuilder.Redirect.INHERIT)
    .redirectError(ProcessBuilder.Redirect.INHERIT)
    .start()

// Wait for the process to exit
process.waitFor()

val exitCode = process.exitValue()
when (exitCode) {
    0 -> println("Success")
    4 -> {
        // For some reason the folder was not deleted,
        // so delete it manually
        File(pathToProfile).deleteRecursively()
        println("Success")
    }
    else -> {
        // The error message was already printed, as we called
        // redirectOutput(INHERIT), so just print the exit code
        println("Got error from aemulari. Code: $exitCode")
    }
}