Added swagger docs, scripts to generate API doc

pull/1/head
Piero Toffanin 2016-09-16 20:20:30 -04:00
rodzic 3958b8a543
commit f51a77d995
9 zmienionych plików z 570 dodań i 21 usunięć

Wyświetl plik

@ -107,7 +107,7 @@ Make a pull request to the dev branch for small contributions. For big contribut
- [X] GPC List support
- [ ] Autoremove Abandoned Tasks
- [ ] Continuous Integration Setup
- [ ] Documentation
- [X] Documentation
- [ ] Unit Testing
## API Docs

Wyświetl plik

@ -0,0 +1,2 @@
node generateSwaggerAPI.js
java -jar swagger2markup-cli-1.0.1.jar convert -i swagger.json -f index

Wyświetl plik

@ -19,19 +19,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
let swaggerJSDoc = require('swagger-jsdoc');
let fs = require('fs');
let packageJson = JSON.parse(fs.readFileSync('../package.json'));
let options = {
swaggerDefinition: {
info: {
title: 'Node-OpenDroneMap',
version: '0.1.0',
title: packageJson.name,
version: packageJson.version,
description: packageJson.description,
license: {
name: 'GPLv3',
url: 'http://www.gnu.org/licenses/'
name: packageJson.license
},
contact: {
name: 'Piero Toffanin',
url: 'https://www.masseranolabs.com',
email: 'pt@masseranolabs.com'
name: packageJson.author,
email: packageJson.authorEmail
}
},
consumes: ["application/json"],

355
docs/index.adoc 100644
Wyświetl plik

@ -0,0 +1,355 @@
= node-opendronemap
[[_overview]]
== Overview
REST API to access OpenDroneMap
=== Version information
[%hardbreaks]
_Version_ : 1.0
=== Contact information
[%hardbreaks]
_Contact_ : Piero Toffanin
_Contact Email_ : pt@masseranolabs.com
=== License information
[%hardbreaks]
_License_ : GPL-3.0
=== URI scheme
[%hardbreaks]
_BasePath_ : /
_Schemes_ : HTTP
=== Consumes
* `application/json`
=== Produces
* `application/json`
* `application/zip`
[[_paths]]
== Paths
[[_getoptions_get]]
=== GET /getOptions
==== Description
Retrieves the command line options that can be passed to process a task
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|*200*|Options|< <<_getoptions_get_response_200,Response 200>> > array
|===
[[_getoptions_get_response_200]]
*Response 200*
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|*domain* +
_optional_|Valid range of values (for example, "positive integer" or "float &gt; 0.0")|string
|*help* +
_optional_|Description of what this option does|string
|*name* +
_optional_|Command line option (exactly as it is passed to the OpenDroneMap process, minus the leading '–')|string
|*type* +
_optional_|Datatype of the value of this option|enum (int, float, string, bool)
|*value* +
_optional_|Default value of this option|string
|===
[[_task_cancel_post]]
=== POST /task/cancel
==== Description
Cancels a task (stops its execution, or prevents it from being executed)
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4,.^2"]
|===
|Type|Name|Description|Schema|Default
|*Body*|*uuid* +
_required_|UUID of the task|string|
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|*200*|Command Received|<<_response,Response>>
|===
[[_task_new_post]]
=== POST /task/new
==== Description
Creates a new task and places it at the end of the processing queue
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4,.^2"]
|===
|Type|Name|Description|Schema|Default
|*FormData*|*images* +
_required_|Images to process, plus an optional GPC file. If included, the GPC file should have .txt extension|file|
|*FormData*|*name* +
_optional_|An optional name to be associated with the task|string|
|*FormData*|*options* +
_optional_|Serialized JSON string of the options to use for processing, as an array of the format: [{name: option1, value: value1}, {name: option2, value: value2}, …]. For example, [{"name":"cmvs-maxImages","value":"500"},{"name":"time","value":true}]. For a list of all options, call /getOptions|string|
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|*200*|Success|<<_task_new_post_response_200,Response 200>>
|*default*|Error|<<_error,Error>>
|===
[[_task_new_post_response_200]]
*Response 200*
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|*uuid* +
_required_|UUID of the newly created task|string
|===
==== Consumes
* `multipart/form-data`
[[_task_remove_post]]
=== POST /task/remove
==== Description
Removes a task and deletes all of its assets
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4,.^2"]
|===
|Type|Name|Description|Schema|Default
|*Body*|*uuid* +
_required_|UUID of the task|string|
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|*200*|Command Received|<<_response,Response>>
|===
[[_task_restart_post]]
=== POST /task/restart
==== Description
Restarts a task that was previously canceled or that had failed to process
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4,.^2"]
|===
|Type|Name|Description|Schema|Default
|*Body*|*uuid* +
_required_|UUID of the task|string|
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|*200*|Command Received|<<_response,Response>>
|===
[[_task_uuid_download_asset_get]]
=== GET /task/{uuid}/download/{asset}
==== Description
Retrieves an asset (the output of OpenDroneMap's processing) associated with a task
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4,.^2"]
|===
|Type|Name|Description|Schema|Default
|*Path*|*asset* +
_required_|Type of asset to download. Use "all" for zip file containing all assets. Other options are not yet available|enum (all)|
|*Path*|*uuid* +
_required_|UUID of the task|string|
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|*200*|Asset File|file
|*default*|Error message|<<_error,Error>>
|===
[[_task_uuid_info_get]]
=== GET /task/{uuid}/info
==== Description
Gets information about this task, such as name, creation date, processing time, status, command line options and number of images being processed. See schema definition for a full list.
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4,.^2"]
|===
|Type|Name|Description|Schema|Default
|*Path*|*uuid* +
_required_|UUID of the task|string|
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|*200*|Task Information|<<_task_uuid_info_get_response_200,Response 200>>
|*default*|Error|<<_error,Error>>
|===
[[_task_uuid_info_get_response_200]]
*Response 200*
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|*dateCreated* +
_optional_|Timestamp|integer
|*imagesCount* +
_optional_|Number of images|integer
|*name* +
_optional_|Name|string
|*options* +
_optional_|List of options used to process this task|< <<_task_uuid_info_get_options,options>> > array
|*processingTime* +
_optional_|Milliseconds that have elapsed since the task started being processed.|integer
|*status* +
_optional_|Status code (10 = QUEUED, 20 = RUNNING, 30 = FAILED, 40 = COMPLETED, 50 = CANCELED)|integer
|*uuid* +
_optional_|UUID|string
|===
[[_task_uuid_info_get_options]]
*options*
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|*name* +
_optional_|Option name (example: "odm_meshing-octreeDepth")|string
|*value* +
_optional_|Value (example: 9)|string
|===
[[_task_uuid_output_get]]
=== GET /task/{uuid}/output
==== Description
Retrieves the console output of the OpenDroneMap's process. Useful for monitoring execution and to provide updates to the user.
==== Parameters
[options="header", cols=".^2,.^3,.^9,.^4,.^2"]
|===
|Type|Name|Description|Schema|Default
|*Path*|*uuid* +
_required_|UUID of the task|string|
|*Query*|*line* +
_optional_|Optional line number that the console output should be truncated from. For example, passing a value of 100 will retrieve the console output starting from line 100. Defaults to 0 (retrieve all console output).|integer|
|===
==== Responses
[options="header", cols=".^2,.^14,.^4"]
|===
|HTTP Code|Description|Schema
|*200*|Console Output|string
|*default*|Error|<<_error,Error>>
|===
[[_definitions]]
== Definitions
[[_error]]
=== Error
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|*error* +
_required_|Description of the error|string
|===
[[_response]]
=== Response
[options="header", cols=".^3,.^11,.^4"]
|===
|Name|Description|Schema
|*error* +
_optional_|Error message if an error occured|string
|*success* +
_required_|true if the command succeeded, false otherwise.|boolean
|===

File diff suppressed because one or more lines are too long

Plik binarny nie jest wyświetlany.

208
index.js
Wyświetl plik

@ -69,6 +69,46 @@ let upload = multer({
let taskManager;
let server;
/** @swagger
* /task/new:
* post:
* description: Creates a new task and places it at the end of the processing queue
* consumes:
* - multipart/form-data
* parameters:
* -
* name: images
* in: formData
* description: Images to process, plus an optional GPC file. If included, the GPC file should have .txt extension
* required: true
* type: file
* -
* name: name
* in: formData
* description: An optional name to be associated with the task
* required: false
* type: string
* -
* name: options
* in: formData
* description: 'Serialized JSON string of the options to use for processing, as an array of the format: [{name: option1, value: value1}, {name: option2, value: value2}, ...]. For example, [{"name":"cmvs-maxImages","value":"500"},{"name":"time","value":true}]. For a list of all options, call /getOptions'
* required: false
* type: string
* responses:
* 200:
* description: Success
* schema:
* type: object
* required: [uuid]
* properties:
* uuid:
* type: string
* description: UUID of the newly created task
* default:
* description: Error
* schema:
* $ref: '#/definitions/Error'
*/
app.post('/task/new', addRequestId, upload.array('images'), (req, res) => {
if (req.files.length === 0) res.json({error: "Need at least 1 file."});
else{
@ -118,7 +158,7 @@ app.post('/task/new', addRequestId, upload.array('images'), (req, res) => {
if (err) cb(err);
else{
taskManager.addNew(task);
res.json({uuid: req.id, success: true});
res.json({uuid: req.id});
cb();
}
}, req.body.options);
@ -137,12 +177,121 @@ let getTaskFromUuid = (req, res, next) => {
}else res.json({error: `${req.params.uuid} not found`});
};
/** @swagger
* /task/{uuid}/info:
* get:
* description: Gets information about this task, such as name, creation date, processing time, status, command line options and number of images being processed. See schema definition for a full list.
* parameters:
* -
* name: uuid
* in: path
* description: UUID of the task
* required: true
* type: string
* responses:
* 200:
* description: Task Information
* schema:
* type: object
* properties:
* uuid:
* type: string
* description: UUID
* name:
* type: string
* description: Name
* dateCreated:
* type: integer
* description: Timestamp
* processingTime:
* type: integer
* description: Milliseconds that have elapsed since the task started being processed.
* status:
* type: integer
* description: Status code (10 = QUEUED, 20 = RUNNING, 30 = FAILED, 40 = COMPLETED, 50 = CANCELED)
* enum: [10, 20, 30, 40, 50]
* options:
* type: array
* description: List of options used to process this task
* items:
* type: object
* properties:
* name:
* type: string
* description: 'Option name (example: "odm_meshing-octreeDepth")'
* value:
* type: string
* description: 'Value (example: 9)'
* imagesCount:
* type: integer
* description: Number of images
* default:
* description: Error
* schema:
* $ref: '#/definitions/Error'
*/
app.get('/task/:uuid/info', getTaskFromUuid, (req, res) => {
res.json(req.task.getInfo());
});
/** @swagger
* /task/{uuid}/output:
* get:
* description: Retrieves the console output of the OpenDroneMap's process. Useful for monitoring execution and to provide updates to the user.
* parameters:
* -
* name: uuid
* in: path
* description: UUID of the task
* required: true
* type: string
* -
* name: line
* in: query
* description: Optional line number that the console output should be truncated from. For example, passing a value of 100 will retrieve the console output starting from line 100. Defaults to 0 (retrieve all console output).
* required: false
* type: integer
* responses:
* 200:
* description: Console Output
* schema:
* type: string
* default:
* description: Error
* schema:
* $ref: '#/definitions/Error'
*/
app.get('/task/:uuid/output', getTaskFromUuid, (req, res) => {
res.json(req.task.getOutput(req.query.line));
});
/** @swagger
* /task/{uuid}/download/{asset}:
* get:
* description: Retrieves an asset (the output of OpenDroneMap's processing) associated with a task
* parameters:
* - name: uuid
* in: path
* type: string
* description: UUID of the task
* required: true
* - name: asset
* in: path
* type: string
* description: Type of asset to download. Use "all" for zip file containing all assets. Other options are not yet available
* required: true
* enum:
* - all
* responses:
* 200:
* description: Asset File
* schema:
* type: file
* default:
* description: Error message
* schema:
* $ref: '#/definitions/Error'
*/
app.get('/task/:uuid/download/:asset', getTaskFromUuid, (req, res) => {
if (!req.params.asset || req.params.asset === "all"){
res.download(req.task.getAssetsArchivePath(), "all.zip", err => {
@ -153,13 +302,16 @@ app.get('/task/:uuid/download/:asset', getTaskFromUuid, (req, res) => {
}
});
let uuidCheck = (req, res, next) => {
if (!req.body.uuid) res.json({error: "uuid param missing."});
else next();
};
/** @swagger
* definition:
* Error:
* type: object
* required:
* - error
* properties:
* error:
* type: string
* description: Description of the error
* Response:
* type: object
* required:
@ -167,10 +319,15 @@ let uuidCheck = (req, res, next) => {
* properties:
* success:
* type: boolean
* description: true if the command succeeded, false otherwise.
* error:
* type: string
* description: Error message if an error occured
*/
let uuidCheck = (req, res, next) => {
if (!req.body.uuid) res.json({error: "uuid param missing."});
else next();
};
let successHandler = res => {
return err => {
@ -187,7 +344,7 @@ let successHandler = res => {
* -
* name: uuid
* in: body
* description: UUID of the task to cancel
* description: UUID of the task
* required: true
* schema:
* type: string
@ -209,7 +366,7 @@ app.post('/task/cancel', uuidCheck, (req, res) => {
* -
* name: uuid
* in: body
* description: UUID of the task to cancel
* description: UUID of the task
* required: true
* schema:
* type: string
@ -231,7 +388,7 @@ app.post('/task/remove', uuidCheck, (req, res) => {
* -
* name: uuid
* in: body
* description: UUID of the task to cancel
* description: UUID of the task
* required: true
* schema:
* type: string
@ -245,6 +402,39 @@ app.post('/task/restart', uuidCheck, (req, res) => {
taskManager.restart(req.body.uuid, successHandler(res));
});
/** @swagger
* /getOptions:
* get:
* description: Retrieves the command line options that can be passed to process a task
* responses:
* 200:
* description: Options
* schema:
* type: array
* items:
* type: object
* properties:
* name:
* type: string
* description: Command line option (exactly as it is passed to the OpenDroneMap process, minus the leading '--')
* type:
* type: string
* description: Datatype of the value of this option
* enum:
* - int
* - float
* - string
* - bool
* value:
* type: string
* description: Default value of this option
* domain:
* type: string
* description: Valid range of values (for example, "positive integer" or "float > 0.0")
* help:
* type: string
* description: Description of what this option does
*/
app.get('/getOptions', (req, res) => {
odmOptions.getOptions((err, options) => {
if (err) res.json({error: err.message});

Wyświetl plik

@ -1,7 +1,7 @@
{
"name": "node-opendronemap",
"version": "0.1.0",
"description": "Node.js API to access OpenDroneMap",
"version": "1.0",
"description": "REST API to access OpenDroneMap",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
@ -14,6 +14,7 @@
"opendronemap"
],
"author": "Piero Toffanin",
"authorEmail": "pt@masseranolabs.com",
"license": "GPL-3.0",
"bugs": {
"url": "https://github.com/pierotofy/node-OpenDroneMap/issues"

Wyświetl plik

@ -294,7 +294,7 @@ $(function(){
.on('filebatchuploadsuccess', function(e, params){
$("#images").fileinput('reset');
if (params.response.success && params.response.uuid){
if (params.response && params.response.uuid){
taskList.add(new Task(params.response.uuid));
}
})