Browse Source

Added extracts remover service

rigwild 1 year ago
parent
commit
944b4e8566
8 changed files with 115 additions and 6 deletions
  1. 5 0
      README.md
  2. 64 0
      cleanExtracts.js
  3. 3 0
      config.js
  4. 18 0
      index.js
  5. 3 1
      package.json
  6. 2 2
      server/functions.js
  7. 1 3
      server/index.js
  8. 19 0
      yarn.lock

+ 5 - 0
README.md

@@ -31,6 +31,7 @@ Configure more deeply the way the app works by modifying *[config.js](config.js)
 | `fileNameConvention` | `/^(.*)?_([0-9]{2,})\.(.*)$/` | File name convention for images |
 | `extractsDirName` | `extracts` | Name of the directory containing extracts |
 | `sceneFileNameBlackList` | `['config', 'seuilExpe', 'extracts']` | Files to ignore in scenes |
+| `deleteExtractsCronTime` | `0 3 * * *` (every day at 03:00 AM) | Cron time for extracts deletion |
 | `logger` | Logs : `logs/server.combined.log` Errors : `logs/server.error.log` | Default application logger |
 | `wsLogger` | Logs : `logs/ws.log` Errors : `logs/ws.error.log` | WebSocket logger configuration |
 | `dbLogger` | Logs : `logs/db.log` Errors : `logs/db.error.log` | Database logger configuration |
@@ -111,6 +112,10 @@ SET NODE_ENV=production
 ```sh
 yarn run server:start
 ```
+If you specifically want to not start the extracts remover service (extracts are automatically deleted everyday), use the following.
+```sh
+server:start:no-delete-extracts
+```
 
 #### Automatically fix the API code syntax with ESLint
 ```sh

+ 64 - 0
cleanExtracts.js

@@ -0,0 +1,64 @@
+'use strict'
+
+const fs = require('fs-extra')
+const fsp = fs.promises
+
+const winston = require('winston')
+
+// File logger configuration
+const fileLogger = winston.createLogger({
+  level: 'info',
+  format: winston.format.json(),
+  transports: [
+    new winston.transports.File({ filename: 'logs/extractsRemoverService.log' }),
+    new winston.transports.File({ filename: 'logs/extractsRemoverService.error.log', level: 'error' }),
+    new winston.transports.Console({
+      level: 'debug',
+      handleExceptions: true,
+      format: winston.format.json()
+    })
+  ],
+  exitOnError: false
+})
+
+const { resolve: r } = require('path')
+
+const setup = async (imagesPath, shouldLog = false, logToFile = false) => {
+  try {
+    if (!(await fs.pathExists(imagesPath)))
+      throw new Error(`Could not locate the image directory. Images path: ${imagesPath}`)
+
+    // Get a list of all scenes
+    const scenes = await fsp.readdir(r(imagesPath))
+
+    for (const aScene of scenes) {
+      const extractsPath = r(imagesPath, aScene, 'extracts')
+
+      // Check the "extracts" dir exists
+      if (!(await fs.pathExists(extractsPath))) {
+        if (shouldLog) process.stdout.write(`"${aScene}/extracts" does not exist.\n`)
+        continue
+      }
+      if (shouldLog) process.stdout.write(`Deleting "${aScene}/extracts"...`)
+      await fs.remove(extractsPath)
+      if (shouldLog) process.stdout.write(' done.\n')
+    }
+
+    if (logToFile) fileLogger.info({ log: 'The extracts remover service finished successfully.', date: new Date() })
+  }
+  catch (err) {
+    if (shouldLog) console.error(err)
+    if (logToFile) fileLogger.error({ log: { error: err.message, stack: err.stack }, date: new Date() })
+  }
+}
+
+// Execute if param is set
+const argv = process.argv.slice(2)
+if (argv.includes('--execute')) {
+  if (!process.env.IMAGES_PATH)
+    return console.log('You must pass the "IMAGES_PATH" environment variable')
+
+  setup(process.env.IMAGES_PATH, false, true)
+}
+
+module.exports = setup

+ 3 - 0
config.js

@@ -35,5 +35,8 @@ export const extractsDirName = 'extracts'
 // Files to ignore in scenes
 export const sceneFileNameBlackList = ['config', 'seuilExpe', extractsDirName]
 
+// Cron time for extracts deletion (every day at 03:00 AM)
+export const deleteExtractsCronTime = '0 3 * * *'
+
 // Logger configurations (Default application, WebSocket, Database)
 export { logger, wsLogger, dbLogger }

+ 18 - 0
index.js

@@ -0,0 +1,18 @@
+'use strict'
+
+import { CronJob } from 'cron'
+
+import server from './server'
+import cleanExtracts from './cleanExtracts'
+import { imagesPath, deleteExtractsCronTime } from './config'
+
+const argv = process.argv.slice(2)
+
+// Start the extracts remover service
+if (!argv.includes('--no-delete')) { /* eslint no-new: 0 */
+  new CronJob(deleteExtractsCronTime, () => cleanExtracts(imagesPath, false, true), null, true, null, null, false)
+  console.log('Started the extracts remover service.')
+}
+
+// Start the server
+server()

+ 3 - 1
package.json

@@ -3,7 +3,8 @@
   "version": "0.2.2",
   "private": true,
   "scripts": {
-    "server:start": "node -r esm server/index.js",
+    "server:start": "node -r esm index.js",
+    "server:start:no-delete-extracts": "node -r esm index.js --no-delete",
     "server:lint": "eslint server/ --fix",
     "app:dev": "vue-cli-service serve",
     "app:build": "vue-cli-service build",
@@ -17,6 +18,7 @@
     "compression": "^1.7.4",
     "core-js": "^2.6.5",
     "cors": "^2.8.5",
+    "cron": "^1.7.1",
     "esm": "^3.2.22",
     "express": "^4.16.4",
     "helmet": "^3.16.0",

+ 2 - 2
server/functions.js

@@ -182,11 +182,11 @@ export const getSceneFilesData = async sceneName => {
  * @param {('info'|'message'|'error'|any|undefined)} event the type of event
  * @returns {string} the log object stringified
  */
-export const formatLog = (data, event = undefined) => (({
+export const formatLog = (data, event = undefined) => ({
   event,
   log: data,
   date: new Date()
-}))
+})
 
 /**
  * Format an error object

+ 1 - 3
server/index.js

@@ -51,7 +51,7 @@ else app.get('*', (req, res) => res.status(404).send('Client is not served.'))
 // Error handler (Middleware called when throwing in another middleware)
 app.use(errorHandler)
 
-const setup = async () => {
+export default async () => {
   // Connect to the MongoDB database
   await connectDb()
 
@@ -61,5 +61,3 @@ const setup = async () => {
   // Start the WebSocket server on top of the started HTTP server
   startWebSocketServer(server)
 }
-
-setup()

+ 19 - 0
yarn.lock

@@ -2796,6 +2796,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
     safe-buffer "^5.0.1"
     sha.js "^2.4.8"
 
+cron@^1.7.1:
+  version "1.7.1"
+  resolved "https://registry.yarnpkg.com/cron/-/cron-1.7.1.tgz#e85ee9df794d1bc6579896ee382053c3ce33778f"
+  integrity sha512-gmMB/pJcqUVs/NklR1sCGlNYM7TizEw+1gebz20BMc/8bTm/r7QUp3ZPSPlG8Z5XRlvb7qhjEjq/+bdIfUCL2A==
+  dependencies:
+    moment-timezone "^0.5.x"
+
 cross-spawn@^5.0.1, cross-spawn@^5.1.0:
   version "5.1.0"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@@ -6315,6 +6322,18 @@ mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@
   dependencies:
     minimist "0.0.8"
 
+moment-timezone@^0.5.x:
+  version "0.5.25"
+  resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.25.tgz#a11bfa2f74e088327f2cd4c08b3e7bdf55957810"
+  integrity sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==
+  dependencies:
+    moment ">= 2.9.0"
+
+"moment@>= 2.9.0":
+  version "2.24.0"
+  resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
+  integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
+
 mongodb-core@3.2.3, mongodb-core@^3.2.3:
   version "3.2.3"
   resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-3.2.3.tgz#eb9bcb876f169f5843fd135f7f7686dbac0e9e34"