Parcourir la source

Added apiDoc documentation

rigwild il y a 4 ans
Parent
commit
88b91170a2

+ 1 - 0
.dockerignore

@@ -5,3 +5,4 @@ npm-debug.log
 /dist
 package-lock.json
 /test/images
+/doc

+ 1 - 0
.gitignore

@@ -25,3 +25,4 @@ yarn-error.log*
 /logs
 /test/images
 /data/*
+/doc

+ 7 - 12
package.json

@@ -9,7 +9,8 @@
     "app:dev": "vue-cli-service serve",
     "app:build": "vue-cli-service build",
     "app:lint": "vue-cli-service lint",
-    "test": "node test/api/_test_setup_start.js && ava --verbose && node test/api/_test_setup_stop.js"
+    "test": "node test/api/_test_setup_start.js && ava --verbose && node test/api/_test_setup_stop.js",
+    "doc": "apidoc -i server/routes -o doc"
   },
   "dependencies": {
     "boom": "^7.3.0",
@@ -47,17 +48,11 @@
       "esm"
     ]
   },
-  "eslintConfig": {
-    "root": true,
-    "env": {
-      "node": true
-    },
-    "extends": [
-      "plugin:vue/recommended",
-      "@vue/standard"
-    ],
-    "parserOptions": {
-      "parser": "babel-eslint"
+  "apidoc": {
+    "url" : "http://diran.univ-littoral.fr/api",
+    "sampleUrl" : "http://diran.univ-littoral.fr/api",
+    "template": {
+      "forceLanguage": "en"
     }
   },
   "postcss": {

+ 2 - 2
server/functions.js

@@ -67,8 +67,8 @@ export const checkRequiredParameters = (requiredParameters, parameters) => {
  * @throws invalid scene name
  */
 export const checkSceneName = sceneName => {
-  if (sceneName === '' || !/^(?!.*\.\.).*$/.test(sceneName))
-    throw boom.conflict(`The requested scene name "${sceneName}" is not valid.`)
+  if (!sceneName || sceneName === '.' || !/^(?!.*\.\.).*$/.test(sceneName))
+    throw boom.badRequest(`The requested scene name "${sceneName}" is not valid.`)
 }
 
 /**

+ 68 - 0
server/routes/getImage.js

@@ -9,6 +9,74 @@ import { asyncMiddleware, checkSceneName, checkRequiredParameters, getSceneFiles
 
 const router = express.Router()
 
+/**
+ * @api {get} /getImage?sceneName=:sceneName&imageQuality=:imageQuality Get an image from a scene
+ * @apiVersion 0.1.0
+ * @apiName GetImage
+ * @apiGroup API
+ *
+ * @apiDescription Get an image from a scene with the required quality
+ *
+ * @apiParam {String} sceneName The selected scene
+ * @apiParam {Number} imageQuality The required quality of the image
+ *
+ * @apiHeader (Response Headers) {String} Content-Type application/json; charset=utf-8
+ *
+ * @apiExample Usage example
+ * curl -i -L -X GET "http://localhost:5000/api/getImage?sceneName=bathroom&imageQuality=200"
+ *
+ * @apiSuccess {String} data Path to the image
+ * @apiSuccessExample {json} Success response example
+ * HTTP/1.1 200 OK /api/getImage?sceneName=bathroom&imageQuality=200
+ * {
+ *   "data": "/api/images/bathroom/bathroom_00200.png"
+ * }
+ *
+ * @apiError (Error 4xx) 400 Missing parameter(s)
+ * @apiErrorExample {json} Missing parameter
+ * HTTP/1.1 400 Bad Request
+ * {
+ *   "message": "Missing parameter(s). Required parameters : sceneName, imageQuality."
+ * }
+ *
+ * @apiError (Error 4xx) 400 Invalid query parameter
+ * @apiErrorExample {json} Invalid query parameter(s)
+ * HTTP/1.1 400 Bad Request
+ * {
+ *   "message": "Invalid query parameter(s).",
+ *   "data": [
+ *     "The requested scene name \".//../\" is not valid.",
+ *     "The specified quality is not an integer."
+ *   ]
+ * }
+ *
+ * @apiError (Error 4xx) 404 Quality not found
+ * @apiErrorExample {json} Quality not found
+ * HTTP/1.1 404 Not Found
+ * {
+ *   "message": "The requested quality (9999) was not found for the requested scene (bathroom)."
+ * }
+ *
+ * @apiError (Error 5xx) 500 Can't access the `IMAGES_PATH` directory
+ * @apiErrorExample {json} Images directory not accessible
+ * HTTP/1.1 500 Internal Server Error
+ * {
+ *   "message": "Can't access the \"images\" directory. Check it exists and you have read permission on it"
+ * }
+ *
+ * @apiError (Error 5xx) 500 Failed to parse a file's name
+ * @apiErrorExample {json} Failed to parse a file's name
+ * HTTP/1.1 500 Internal Server Error
+ * {
+ *   "message": "Failed to parse file names in the \"bathroom\"'s scene directory.",
+ *   "data": [
+ *     "The file name does not match convention (scene_000150.ext - /^(.*)?_([0-9]{2,})\\.(.*)$/) : \"bathroom_adz00020.png\".",
+ *     "The file name does not match convention (scene_000150.ext - /^(.*)?_([0-9]{2,})\\.(.*)$/) : \"bathroom_adz00020.png\"."
+ *   ]
+ * }
+ *
+ */
+
 /**
  * @typedef {Object} Image
  * @property {string} link the link (URL) to an image on the app

+ 86 - 0
server/routes/getImageExtracts.js

@@ -12,6 +12,92 @@ import { getImage } from './getImage'
 
 const router = express.Router()
 
+/**
+ * @api {get} /getImageExtracts?sceneName=:sceneName&imageQuality=:imageQuality&horizontalExtractCount=:horizontalExtractCount&verticalExtractCount=:verticalExtractCount Get image extracts
+ * @apiVersion 0.1.0
+ * @apiName GetImageExtracts
+ * @apiGroup API
+ *
+ * @apiDescription Get an image from a scene with the required quality and cut it with the requested configuration
+ *
+ * @apiParam {String} sceneName The selected scene
+ * @apiParam {Number} imageQuality The required quality of the image
+ * @apiParam {Number} horizontalExtractCount The amount of extracts for the horizontal axis
+ * @apiParam {Number} verticalExtractCount The amount of extracts for the vertical axis
+ *
+ * @apiHeader (Response Headers) {String} Content-Type application/json; charset=utf-8
+ *
+ * @apiExample Usage example
+ * curl -i -L -X GET "http://localhost:5000/api/getImageExtracts?sceneName=bathroom&imageQuality=200&horizontalExtractCount=1&verticalExtractCount=2"
+ *
+ * @apiSuccess {String[]} data Path to the extracted images
+ * @apiSuccessExample {json} Success response example
+ * HTTP/1.1 200 OK /api/getImageExtracts?sceneName=bathroom&imageQuality=200&horizontalExtractCount=1&verticalExtractCount=2
+ * {
+ *   "data": [
+ *     "/api/images/bathroom/extracts/x1_y2/zone00001/bathroom_zone00001_200.png",
+ *     "/api/images/bathroom/extracts/x1_y2/zone00002/bathroom_zone00002_200.png"
+ *   ]
+ * }
+ *
+ * @apiError (Error 4xx) 400 Missing parameter(s)
+ * @apiErrorExample {json} Missing parameter
+ * HTTP/1.1 400 Bad Request
+ * {
+ *   "message": "Missing parameter(s). Required parameters : sceneName, imageQuality, horizontalExtractCount, verticalExtractCount."
+ * }
+ *
+ * @apiError (Error 4xx) 400 Invalid query parameter
+ * @apiErrorExample {json} Invalid query parameter(s)
+ * HTTP/1.1 400 Bad Request
+ * {
+ *   "message": "Invalid query parameter(s).",
+ *   "data": [
+ *     "The requested scene name \".//../\" is not valid.",
+ *     "The specified quality is not an integer.",
+ *     "The specified number of extract for the horizontal axis is not an integer.",
+ *     "The specified number of extract for the vertical axis is not an integer."
+ *   ]
+ * }
+ *
+ * @apiError (Error 4xx) 400 Invalid configuration
+ * @apiErrorExample {json} Invalid configuration
+ * HTTP/1.1 400 Bad Request
+ * {
+ *   "message": "Invalid query parameter(s).",
+ *   "data": [
+ *     "Incompatible number of horizontal extracts (width % numberOfExtracts != 0).",
+ *     "Incompatible number of vertical extracts (height % numberOfExtracts != 0)."
+ *   ]
+ * }
+ *
+ * @apiError (Error 4xx) 404 Quality not found
+ * @apiErrorExample {json} Quality not found
+ * HTTP/1.1 404 Not Found
+ * {
+ *   "message": "The requested quality (9999) was not found for the requested scene (bathroom)."
+ * }
+ *
+ * @apiError (Error 5xx) 500 Can't access the `IMAGES_PATH` directory
+ * @apiErrorExample {json} Images directory not accessible
+ * HTTP/1.1 500 Internal Server Error
+ * {
+ *   "message": "Can't access the \"images\" directory. Check it exists and you have read permission on it"
+ * }
+ *
+ * @apiError (Error 5xx) 500 Failed to parse a file's name
+ * @apiErrorExample {json} Failed to parse a file's name
+ * HTTP/1.1 500 Internal Server Error
+ * {
+ *   "message": "Failed to parse file names in the \"bathroom\"'s scene directory.",
+ *   "data": [
+ *     "The file name does not match convention (scene_000150.ext - /^(.*)?_([0-9]{2,})\\.(.*)$/) : \"bathroom_adz00020.png\".",
+ *     "The file name does not match convention (scene_000150.ext - /^(.*)?_([0-9]{2,})\\.(.*)$/) : \"bathroom_adz00020.png\"."
+ *   ]
+ * }
+ *
+ */
+
 /**
  * Cut an image, save its extracts and get the url of these extracts
  *

+ 59 - 0
server/routes/listSceneQualities.js

@@ -5,6 +5,65 @@ import { asyncMiddleware, checkRequiredParameters, getSceneFilesData } from '../
 
 const router = express.Router()
 
+/**
+ * @api {get} /listSceneQualities?sceneName=:sceneName Get a list of available qualities for a scene
+ * @apiVersion 0.1.0
+ * @apiName ListScenesQualities
+ * @apiGroup API
+ *
+ * @apiDescription List all available qualities for a given scene
+ *
+ * @apiParam {String} sceneName The selected scene
+ *
+ * @apiHeader (Response Headers) {String} Content-Type application/json; charset=utf-8
+ *
+ * @apiExample Usage example
+ * curl -i -L -X GET "http://localhost:5000/api/listSceneQualities?sceneName=bathroom"
+ *
+ * @apiSuccess {Number[]} data List of available qualities
+ * @apiSuccessExample {json} Success response example
+ * HTTP/1.1 200 OK /api/listSceneQualities?sceneName=bathroom
+ * {
+ *   "data": [
+ *      10,
+ *      20,
+ *      30
+ *   ]
+ * }
+ *
+ * @apiError (Error 4xx) 400 Missing parameter(s)
+ * @apiErrorExample {json} Missing parameter
+ * HTTP/1.1 400 Bad Request
+ * {
+ *   "message": "Missing parameter(s). Required parameters : sceneName."
+ * }
+ *
+ * @apiError (Error 4xx) 400 The requested scene name is not valid
+ * @apiErrorExample {json} Invalid scene name
+ * HTTP/1.1 400 Bad Request
+ * {
+ *   "message": "The requested scene name \"bathroom/../\" is not valid."
+ * }
+ *
+ * @apiError (Error 5xx) 500 Can't access the `IMAGES_PATH` directory
+ * @apiErrorExample {json} Images directory not accessible
+ * HTTP/1.1 500 Internal Server Error
+ * {
+ *   "message": "Can't access the \"images\" directory. Check it exists and you have read permission on it"
+ * }
+ *
+ * @apiError (Error 5xx) 500 Failed to parse a file's name
+ * @apiErrorExample {json} Failed to parse a file's name
+ * HTTP/1.1 500 Internal Server Error
+ * {
+ *   "message": "Failed to parse file names in the \"bathroom\"'s scene directory.",
+ *   "data": [
+ *     "The file name does not match convention (scene_000150.ext - /^(.*)?_([0-9]{2,})\\.(.*)$/) : \"bathroom_adz00020.png\".",
+ *     "The file name does not match convention (scene_000150.ext - /^(.*)?_([0-9]{2,})\\.(.*)$/) : \"bathroom_adz00020.png\"."
+ *   ]
+ * }
+ */
+
 // Route which returns a list of all available qualities for a scene
 router.get('/', asyncMiddleware(async (req, res) => {
   // Check the request contains all the required parameters

+ 36 - 6
server/routes/listScenes.js

@@ -2,12 +2,45 @@
 
 import express from 'express'
 import { promises as fs } from 'fs'
+import path from 'path'
 import boom from 'boom'
 import { asyncMiddleware } from '../functions'
 import { imagesPath } from '../../config'
 
 const router = express.Router()
 
+/**
+ * @api {get} /listScenes Get a list of all available scenes
+ * @apiVersion 0.1.0
+ * @apiName GetListScenes
+ * @apiGroup API
+ *
+ * @apiDescription List all scenes availables in your `IMAGES_PATH` directory
+ * @apiSampleRequest /listScenes
+ *
+ * @apiHeader (Response Headers) {String} Content-Type application/json; charset=utf-8
+ *
+ * @apiExample Usage example
+ * curl -i -L -X GET "http://localhost:5000/api/listScenes"
+ *
+ * @apiSuccess {String[]} data List of available scenes
+ * @apiSuccessExample {json} Success response example
+ * HTTP/1.1 200 OK /api/listScenes
+ * {
+ *   "data": [
+ *      "bathroom",
+ *      "contemporary",
+ *   ]
+ * }
+ *
+ * @apiError (Error 5xx) 500 Can't access the `IMAGES_PATH` directory
+ * @apiErrorExample {json} Images directory not accessible
+ * HTTP/1.1 500 Internal Server Error
+ * {
+ *   "message": "Can't access the \"images\" directory. Check it exists and you have read permission on it"
+ * }
+ */
+
 /**
  * Get the list of all files in the images directory
  *
@@ -15,12 +48,9 @@ const router = express.Router()
  * @throws the directory does not exist or is not accessible
  */
 export const getSceneList = () => {
-  try {
-    return fs.readdir(imagesPath)
-  }
-  catch (err) {
-    throw boom.conflict(`Can't access the "${imagesPath}" directory. Check it exists and you have read permission on it.`)
-  }
+  return fs.readdir(imagesPath).catch(() => {
+    throw boom.internal(`Can't access the "${path.basename(imagesPath)}" directory. Check it exists and you have read permission on it.`)
+  })
 }
 
 // Route which returns a list of all available scenes in the `imagesPath` directory