parent
fbf38d5800
commit
60bfb9b969
@ -0,0 +1,258 @@ |
|||||||
|
# Scriptform Manual |
||||||
|
|
||||||
|
## Table of Contents |
||||||
|
|
||||||
|
1. Invocations |
||||||
|
1. [Form definition (JSON) files](#form_def) |
||||||
|
1. [Field types](#form_def) |
||||||
|
- [String](#form_def) |
||||||
|
- [Integer](#form_def) |
||||||
|
- [Float](#form_def) |
||||||
|
- [Date](#form_def) |
||||||
|
- [Radio](#form_def) |
||||||
|
- [Select](#form_def) |
||||||
|
- [Text](#form_def) |
||||||
|
- [Password](#form_def) |
||||||
|
- [File](#form_def) |
||||||
|
1. [Callbacks](#form_def) |
||||||
|
- [Script callbacks]() |
||||||
|
- [Validation]() |
||||||
|
- [Field Values]() |
||||||
|
- [Output]() |
||||||
|
- [Python callbacks]() |
||||||
|
1. [Users](#users) |
||||||
|
|
||||||
|
## Invocations |
||||||
|
|
||||||
|
### Behind Apache |
||||||
|
|
||||||
|
Enable Apache modules mod_proxy and mod_proxy_http: |
||||||
|
|
||||||
|
$ sudo a2enmod proxy |
||||||
|
$ sudo a2enmod proxy_http |
||||||
|
|
||||||
|
Configure: |
||||||
|
|
||||||
|
Redirect permanent /scriptform /scriptform/ |
||||||
|
ProxyPass /scriptform/ http://localhost:8000/ |
||||||
|
ProxyPassReverse /scriptform/ http://localhost:8000/ |
||||||
|
|
||||||
|
Make sure the path ends in a slash! (That's what the redirect is for). |
||||||
|
|
||||||
|
## Form definition (JSON) files |
||||||
|
|
||||||
|
Forms are defined in JSON format. They are referred to as *Form Definition* |
||||||
|
files. A single JSON file may contain multiple forms. Scriptform will show them |
||||||
|
on an overview page, and the user can select which form they want to fill out. |
||||||
|
|
||||||
|
Structurally, they are made up of the following elements: |
||||||
|
|
||||||
|
- **`title`**: Text to show at the top of each page. **Required**, **String**. |
||||||
|
- **`forms`**: Dictionary where the key is the form id and the value is a |
||||||
|
dictionary that is the definition for a single form. **Required**, **Dictionary**. |
||||||
|
- **`title`**: Title for the form. **Required**, **String**. |
||||||
|
- **`description`**: A description of the form. May include HTML tags. **Required**, **String**. |
||||||
|
- **`submit_title`**: The text on the submit button of the form. |
||||||
|
- **`script`**: The path to an executable script of binary that will be |
||||||
|
called if the form is submitted. See also [[Callbacks]]. If this field is |
||||||
|
omitted, Scriptform will instead call a python callable (function, |
||||||
|
method) that's been registered. Scriptform will raise an error if the |
||||||
|
script isn't found, if the script isn't executable or (if the `script` |
||||||
|
tag is omitted) if no Python callback is registered to handle this form. |
||||||
|
**String**. |
||||||
|
- **`script_raw`**: If present and `true`, the output of the script is sent |
||||||
|
to the browser as-is. The script must include the proper headers and body |
||||||
|
itself. This allows you to output images, stream files, etc. |
||||||
|
- **`fields`**: List of fields in the form. Each field is a dictionary. |
||||||
|
**Required**, **List of dictionaries**. |
||||||
|
- **`name`**: The name of the field. This is what is passed as an |
||||||
|
environment variable to the callback. |
||||||
|
- **`title`**: The title for the field, shown just above the actual |
||||||
|
field. |
||||||
|
- **`type`**: Field type. Supported types are: *string*, *integer*, |
||||||
|
*float*, *date*, *radio*, *select*, *text*, *password* and *file*. |
||||||
|
For more information, see [Field types]. |
||||||
|
- **`required`**: Whether the field is required. |
||||||
|
- **`...`**: Other options, which depend on the type of field. |
||||||
|
- **`users`**: A dictionary of users where the key is the username and the |
||||||
|
value is the plaintext password. This field is not required. **Dictionary**. |
||||||
|
|
||||||
|
For example, here's a form definition file that contains two forms: |
||||||
|
|
||||||
|
{ |
||||||
|
"title": "Test server", |
||||||
|
"forms": { |
||||||
|
"import": { |
||||||
|
"title": "Import data", |
||||||
|
"description": "Import SQL into a database", |
||||||
|
"submit_title": "Import", |
||||||
|
"script": "job_import.sh", |
||||||
|
"fields": [ |
||||||
|
{ |
||||||
|
"name": "target_db", |
||||||
|
"title": "Database to import to", |
||||||
|
"type": "select", |
||||||
|
"options": [ |
||||||
|
["devtest", "Dev Test db"], |
||||||
|
["prodtest", "Prod Test db"] |
||||||
|
] |
||||||
|
}, |
||||||
|
{ |
||||||
|
"name": "sql_file", |
||||||
|
"title": "SQL file", |
||||||
|
"type": "file" |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"add_user": { |
||||||
|
"title": "Add user", |
||||||
|
"description": "Add a user to the htaccess file or change their password", |
||||||
|
"submit_title": "Add user", |
||||||
|
"script": "job_add_user.sh", |
||||||
|
"fields": [ |
||||||
|
{ |
||||||
|
"name": "username", |
||||||
|
"title": "Username", |
||||||
|
"type": "string" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"name": "password1", |
||||||
|
"title": "Password", |
||||||
|
"type": "password" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"name": "password2", |
||||||
|
"title": "Password (Repear)", |
||||||
|
"type": "password" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Field types |
||||||
|
|
||||||
|
### String |
||||||
|
|
||||||
|
The `string` field type presents the user with a single line input field. |
||||||
|
|
||||||
|
### Integer |
||||||
|
|
||||||
|
The `integer` field type presents the user with an input box in wich they may |
||||||
|
enter an integer number. Depending on the browser's support for HTML5 forms, |
||||||
|
the input field may have spin-buttons to increase and decrease the value. |
||||||
|
|
||||||
|
The `integer` field type supports the following additional options: |
||||||
|
|
||||||
|
- **`max`**: The maximum allowed value for the field. |
||||||
|
- **`min`**: The minimum allowed value for the field. |
||||||
|
|
||||||
|
### Float |
||||||
|
|
||||||
|
The `float` field type presents the user with an input box in which they enter |
||||||
|
a Real number (fractions). |
||||||
|
|
||||||
|
The `float` field type supports the following additional options: |
||||||
|
|
||||||
|
- ... |
||||||
|
|
||||||
|
### Date |
||||||
|
|
||||||
|
### Radio |
||||||
|
|
||||||
|
### Select |
||||||
|
|
||||||
|
### Text |
||||||
|
|
||||||
|
### Password |
||||||
|
|
||||||
|
### File |
||||||
|
|
||||||
|
## Callbacks |
||||||
|
|
||||||
|
Callbacks are called after the form has been submitted and its values have been |
||||||
|
validated. They are the actual implementations of the form's action. |
||||||
|
|
||||||
|
There are two types of callbacks: |
||||||
|
|
||||||
|
- Scripts |
||||||
|
- Python callables (functions or methods) |
||||||
|
|
||||||
|
### Scripts |
||||||
|
|
||||||
|
A script callback can be any kind of executable, written in any kind of |
||||||
|
language. As long as it is executable, can read the environment and output |
||||||
|
things to stdout, it can be used as a callback. |
||||||
|
|
||||||
|
#### Validation |
||||||
|
|
||||||
|
Fields of the form are validated by Scriptform before the script is called. |
||||||
|
Exactly what is validated depends on the options specified in the Form |
||||||
|
Definition file. For more info on that, see the *Field Types* section of this |
||||||
|
manual. |
||||||
|
|
||||||
|
#### Field values |
||||||
|
|
||||||
|
Field values are passed to the script in its environment. For instance, a form |
||||||
|
field definition: |
||||||
|
|
||||||
|
|
||||||
|
{ |
||||||
|
"name": "ip_address", |
||||||
|
"title": "IP Address", |
||||||
|
"type": "string" |
||||||
|
} |
||||||
|
|
||||||
|
becomes available in a shell script as: |
||||||
|
|
||||||
|
echo $ip_address |
||||||
|
|
||||||
|
or in a Python script as: |
||||||
|
|
||||||
|
import os |
||||||
|
print os.environ['ip_address'] |
||||||
|
|
||||||
|
Uploaded files are streamed to temporary files by Scriptform. The name of the |
||||||
|
temporary file is then passed on as the field's value. For example, given the |
||||||
|
following field definition: |
||||||
|
|
||||||
|
{ |
||||||
|
"name": "csv_file", |
||||||
|
"title": "CSV file to import", |
||||||
|
"type": "file" |
||||||
|
} |
||||||
|
|
||||||
|
The contents of the file is available in a shell script as: |
||||||
|
|
||||||
|
echo $csv_file # output: /tmp/tmp_scriptform_Xu72bK |
||||||
|
ROWS=$(wc -l $csv_file) |
||||||
|
echo "The CSV file has $(expr $ROWS - 1) rows" |
||||||
|
|
||||||
|
These temporary files are automatically cleaned up after the script's exeuction |
||||||
|
ends. |
||||||
|
|
||||||
|
Examples of file uploads can be found in the `examples/simple` and |
||||||
|
`examples/megacorp` directories. |
||||||
|
|
||||||
|
#### Output |
||||||
|
|
||||||
|
If the script's exit code is 0, the output of the script (stdout) is captured |
||||||
|
and shown to the user in the browser. |
||||||
|
|
||||||
|
If a script's exit code is not 0, it is assumed an error occured. Scriptform |
||||||
|
will show the script's stderr output (in red) to the user instead of stdin. |
||||||
|
|
||||||
|
If the form definition has a `script_raw` field, and its value is `true`, |
||||||
|
Scriptform will pass the output of the script to the browser as-is. This allows |
||||||
|
scripts to show images, stream a file download to the browser or even show |
||||||
|
completely custom HTML output. The script's output must be a valid HTTP |
||||||
|
response, including headers and a body. Examples of raw script output can be |
||||||
|
found in the `examples/raw` directory. |
||||||
|
|
||||||
|
### Python callbacks |
||||||
|
|
||||||
|
## <a name="users">Users</a> |
||||||
|
|
Loading…
Reference in new issue