Skip to content

Add logpath(data, path), expand json functionality and proper file access functions #3198

Description

@Earth-And-Moon

I know that I have already opened two other suggestions within the last 2 days, but after I found out that contributions to kOS are welcome I decided to suggest some useful extensions to kOS that I feel are lacking.

Logpath(data, path)

Currently, kOS has a run "path" command that requires a hardcoded string, and a synonymous runpath(path) function that supports supplying a string from any source, e.g. from a variable or a function call. It would be useful to have the same for log data to "path": logpath(data, path) so that you can e.g. name your logs based on the current time or ship name, without specifying a hardcoded string path. A long time ago I had to write a long if else tree in a shared telemetry recorder script for the ship name to log to separate paths for each type of vehicle.

Examples:

log "test" to "0:/logs/a.txt". // works

set path to "0:/logs/ships/" + ship:name + ".txt". // assuming ship:name is a safe path, but that is a different thing
log "test" to path. // This will log to a file called "path" but not to the path specified above.
logpath("test", path). // logs "test" to the calculated path and works.

JSON extensions

kOS also has writejson(data, path) and readjson(path) functions.
Some extensions to json functionality:

Modifications to existing functions:
writejson(path, data, pretty=true) adds a new pretty parameter. If pretty is false, removes indentation and line breaks for more compressed data.

New functions:
readjsondefault(path, default) behaves the same as readjson(path) but returns default if the json at the given path is not parsable/readable or if the file does not exist or other errors occur while trying to parse the json data.

dumpjson(object, pretty=true) would return the jsonified data as a string instead of writing it to a file like writejson. If pretty is false, removes indentation and useless spaces for more compact data.
parsejson(data) would parse the json from the string data instead of reading it from a file like readjson, returning an error if the json is invalid.
parsejsondefault(data, default) would parse the json from the string data instead of reading it from a file like readjson, but returns default if the json is not parsable/readable or if the file does not exist or other errors occur while trying to parse the json data
isvalidjson(string) returns true if the string is valid json, otherwise false.
checkjson(string) returns the error message as a string if the provided string is not parsable, otherwise returns an empty string.

Now the main part of this suggestion, proper file access.

But what about writing, modifying or tampering with other file types like csv or plain text files? With log you can only add data.

openpath(path, mode) would require a valid file path path and a mode including but not limited to "w", "r", "a", "x", defaulting to "r" (see also the Python docs for more common modes.
That function would return a File structure that exposes common file modification functions like :write(data), :read() etc. (compare Python and other languages).
Finally, file:close() closes the file.

Examples:


// Let's assume this ship is called "Kerbal Y" and is at an altitude of 85653.75 m above the sea level of its current parent object.

set f to openpath("0:/storage/important_data.txt", "w").
f:write(ship:name + "\n").
f:close()

set g to openpath("0:/storage/important_data.txt", "a").
g:writeline(ship:altitude).
g:close()

// later, you want to add data, like the result of a calculation based on the ship's mass of 6.7 tons, so you do this:

set file to openpath("0:/storage/important_data.txt", "a").
file:write(ship:mass * 10 + "\n").
file:close().

// finally, you want to read the data you stored a few minutes ago in a different script:

set data_file to openpath("0:/storage/important_data.txt", "r").

data_file:write(ship:name + "\n").
set data to data_file:read().
data_file:close().

print(data_file).

The result should be:

Kerbal Y
85653.75
67

The access of files can maybe be limited to the disk volumes of the kOS processor.

Proposed (nonexhaustive) API for File:

File:name the full name of the file, e.g. "important_data.txt", maybe with set access to rename it.
File:path the full kOS path of the file, e.g. "0:/storage/important_data.txt".
File:extension the full extension file, e.g. ".txt".
File:created the creation unix timestamp of the file.
File:lastmodified the last modification unix timestamp of the file.
File:closed to check if the file has been closed before.
File:exists to check if the file still exists (it may have been deleted since it was opened).
File:valid to check if the file still exists or has been closed before (a combnation of the two previous suffixes).

File:read(n) returns the next n characters of the file contents.
File:readline(n) returns all remaining characters of the file contents until the next newline.
File:readtoend(n) returns all remaining characters of the file contents.
File:seek(n) moves the current reader position to n (0 is start of the file, maybe allow negative indexes to count from the end of the file).
File:position returns the current reader position.

File:readlines(n) returns an array of strings for all lines of the file contents.
File:readall(n) returns the whole content of the file as a single string.

File:write(data) overwrites the contents of the file with data or appends it based on the open mode.
File:writeline(data) overwrites the contents of the file with data or appends it based on the open mode. Automatically adds a newline.

Functions incompatible to the current open mode should lead to an error.

File:close() closes the file, making any further usage of suffixes of this object invalid (except for :valid, :closed and what is inherited from its parent classes).

Compare similar file handling in Julia, C# (reading and writing), Python and other languages.

I know that this is a rather long suggestion, but I just want to help making this programming language more modern and extending its functionality to partially match with other programming languages.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions