Script File Handling

KosmicTask Help

Script File Handling

Tasks can process files as inputs and generate files as results. Two different file based task input types can be defined:

File Path
A file path input simply allows the user to select a path to an existing file. This type of input is generally useful for tasks that will only be executed on the local machine as the selected path, if it targets a file within the user's home folder, will likely be invalid if executed on a networked machine. The advantage of using a file path is that the selected file is not copied and the script can therefore access and modify the file directly.
File
A file input prompts the user to select a file to be processed by the task. The contents of the file are copied and the task script receives the path of the copied file as its argument. If the task is being executed on a networked instance of KosmicTask then the file is copied over the network to a temporary location. When the task completes the temporary copy of the file is deleted. File inputs are useful when creating shared file processing tasks that can accept one or more files as inputs and and return processed copies of those files as results.

A script simply receives a path to a file regardless of whether a file or file path input is used. In the case of a file path input the script receives the full path of the selected file. In the case of a file input the script receives the full path to a local copy of the file. The following example script accepts a single file path, '/Users/Shared/test.txt' as its argument and simply returns that path as its result:

echo -e "The input file path is \n$1"

If a File Path input type is used to select the file then the task result is:

The input file path is 
/Users/Shared/test.txt

The result indicates that the task script received the path to the chosen file. However, if a File input type is used to select the file then the task result looks something like:

The input file path is 
/Users/Muggins/Library/Caches/com.mugginsoft.kosmictaskserver.files/zL9Q3c/test.txt

This shows that the task script received a working copy of the selected file. This is the case even if file originates on another machine. The task can modify and process this temporary copy without modifying the original. Once the task completes it can return the modified file as all or part of the result. KosmicTask will try to maintain the original name for all files passed as inputs. Tasks can also accept multiple file inputs as illustrated in the example below:

import java.io.*;

class kosmicTask
{ 
    public static void main(String args[])
    {    
        String path1 = String.format("Path 1 is\n%s", args[0]);
        String path2 = String.format("Path 2 is\n%s", args[1]);
        
        String text1 = String.format("File 1 contains:\n %s\n", readFileAsString(args[0]));
        String text2 = String.format("File 2 contains:\n %s\n", readFileAsString(args[1]));
        
        // return as YAML format array
        System.out.println(String.format("--- [%s, %s, %s, %s]", path1, text1, path2, text2));
    }
    
    private static String readFileAsString(String filePath) 
    {
        byte[] buffer = new byte[(int) new File(filePath).length()];
        try {
            FileInputStream f = new FileInputStream(filePath);
            f.read(buffer);
        } catch(IOException e) {
        }
        return new String(buffer);
    }
}
Path 1 is /Users/Muggins/Library/Caches/com.mugginsoft.kosmictaskserver.files/6pvj6o/test.txt
File 1 contains: test

Path 2 is /Users/Muggins/Library/Caches/com.mugginsoft.kosmictaskserver.files/6pvj6o/519Uud.test.txt
File 2 contains: test

The output above shows that the task received two files (or two references to the same file) both named 'test.txt'. In order to preserve both files one is prefixed with a unique code. This technique is applied whenever there is a filename collision regardless of the number of files involved. Once a task completes and its results have been returned all the input file copies are deleted.

Returning Files as Results

KosmicTask can return the contents of a file by returning the file path within a dictionary result. The kosmicFile key is used to identify the file. KosmicTask scans all complex results for application keys and when it encounters the file key it sends the file contents as part of the result. When KosmicTask receives task results it copies any file data within the result to disk. These result files will be deleted when the last task view or result view that displays them closes. Task files are also retained for all the results in a task views history. To view all tasks that return files enter "kosmicFile" into the application search field.

The following example accepts a single file input and simply echoes the contents of the file and the file path back to the user:

#include 
int main(int argc, char *argv[])
{
    // return YAML format dictionary
    printf("--- {kosmicFile: %s, kosmicData: the input file path is %s}", argv[1],  argv[1]);
    
    return 0;
}

Multiple files can be included within a single result by a returning an array of file paths using the kosmicFile key. The following examples accept two file inputs and return two copies of each file:

require "KosmicTaskController"

File1 = ARGV[0]
File2 = ARGV[1]

# build the files array
Files = Array[File1, File1, File2, File2]
Result = {'kosmicFile' => Files}

# print native object as YAML
KosmicTaskController.printObject(Result)
package require KosmicTaskController

set file1 [lindex $argv 0]
set file2 [lindex $argv 1]

# create huddle dictionary
set files [huddle list $file1 $file1 $file2 $file2]
set result [huddle create "kosmicFile" $files "kosmicData" "2 copies returned"]
	
# print native object as YAML
::KosmicTaskController::printObject $result

Creating Result Files

Tasks can create new files and write to them using standard input and output methods. If a file is created solely for the purpose of including it in a result then it is desirable that it be deleted when the task ends. The task script itself cannot delete the file because it has to exist after the script exits in order to be returned as part of the task result. To help with this situation KosmicTask includes support for a number of methods that can be used to generate temporary result files. Any files created with these methods will be automatically deleted when the task exits. Files created by any other means will not be affected and will persist after the task exits.

The exact method for creating temporary result files for each scripting language can be found within the usage document in the resource browser. In general though languages such as the Bash and other shells can create result files simply by creating the required files in the task's current working directory. Each task has a temporary working directory created for it at run time that is deleted once the task completes. Most of the out-of-process scripting languages use this method as demonstrated in the following examples which capture a screen image:

# capture screen image to file
# files created in the current directory will be deleted when the task ends
FILE="capture.png"

# capture screen
screencapture -t png $FILE

# return a YAML inline format dictionary
echo "---"
echo "{kosmicFile: $FILE , kosmicInfo: file returned}"
-- capture screen image to file
-- files create in the current directory will be deleted when the task ends
local file = "capture.png"

-- capture screen
os.execute("screencapture -t png " .. file)

-- return a YAML inline format dictionary with filename
local result = string.format("--- {kosmicFile: %s, kosmicInfo: file returned}", file)
print(result)
use warnings;

# capture screen image to file
# files created in the current directory will be deleted when the task ends
$FILE="capture.png";

# capture screen
`screencapture -t png $FILE`;

# return a YAML inline format dictionary with filename
print "--- {kosmicFile: $FILE, kosmicInfo: file returned}";

Many of the scripting languages that run in-process with the task runner, such as the Cocoa framework bridges, have access to a task controller. This object supports the resultFileWithName method which returns a path to a temporary result file. The following examples illustrate this method:

require 'osx/cocoa'

# KosmicTask controller
$taskController = OSX.NSClassFromString("KosmicTaskController")

def kosmictask()

    # create path to temp result file from taskController.
    # this file will be automatically deleted when the task ends.
    path = $taskController.resultFileWithName_("capture.png");
    
    # capture sceen shot to file
    system "screencapture -t png " + path
        
    result = {'kosmicFile' => path, 'kosmicInfo' => "file returned"}
        
    return result
end
function kosmicTask() 
{
	
     // form our image file result path
     // this file will be automatically deleted when the task ends.
    var path = KosmicTaskController.resultFileWithName('capture.png');
	
    // capture screen shot to file.
    // regular JavaScript has no operating or file system access so we use a Cocoa class
    var task = NSTask.launchedTaskWithLaunchPath_arguments('/usr/sbin/screenCapture', ['-t', 'png', path]);
    task.waitUntilExit;

    // form result dictionary 
    var result = {kosmicFile: path};
			
    return result
}

The final method provides support for result file creation via automation. The KosmicTask application supports the result file with name automation command as demonstrated below:

on KosmicTask()
    
    try
        
        -- get a result file object from KosmicTask.
        -- the file will be automatically deleted when the task ends.
        tell application "KosmicTask"
            set resultFile to result file with name "capture.png"
        end tell
        
        -- the shell script below will expect a POSIX path
        set picPosixPath to POSIX path of file resultFile
        
        -- do screen capture via shell
        do shell script "screencapture -t png " & quoted form of picPosixPath
        
        -- feedback
        return {kosmicFile:resultFile, kosmicInfo:"file returned"}
        
    on error errorMessage number errorNumber
        return {kosmicError:errorMessage}    
    end try
    
end KosmicTask