export.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. const loggerFactory = require('@alias/logger');
  2. const logger = loggerFactory('growi:routes:apiv3:export');
  3. const fs = require('fs');
  4. const express = require('express');
  5. const router = express.Router();
  6. /**
  7. * @swagger
  8. * tags:
  9. * name: Export
  10. */
  11. /**
  12. * @swagger
  13. *
  14. * components:
  15. * schemas:
  16. * ExportStatus:
  17. * description: ExportStatus
  18. * type: object
  19. * properties:
  20. * zipFileStats:
  21. * type: array
  22. * items:
  23. * type: object
  24. * description: the property of each file
  25. * progressList:
  26. * type: array
  27. * items:
  28. * type: object
  29. * description: progress data for each exporting collections
  30. * isExporting:
  31. * type: boolean
  32. * description: whether the current exporting job exists or not
  33. */
  34. module.exports = (crowi) => {
  35. const accessTokenParser = require('../../middlewares/access-token-parser')(crowi);
  36. const loginRequired = require('../../middlewares/login-required')(crowi);
  37. const adminRequired = require('../../middlewares/admin-required')(crowi);
  38. const csrf = require('../../middlewares/csrf')(crowi);
  39. const { exportService } = crowi;
  40. this.adminEvent = crowi.event('admin');
  41. // setup event
  42. this.adminEvent.on('onProgressForExport', (data) => {
  43. crowi.getIo().sockets.emit('admin:onProgressForExport', data);
  44. });
  45. this.adminEvent.on('onStartZippingForExport', (data) => {
  46. crowi.getIo().sockets.emit('admin:onStartZippingForExport', data);
  47. });
  48. this.adminEvent.on('onTerminateForExport', (data) => {
  49. crowi.getIo().sockets.emit('admin:onTerminateForExport', data);
  50. });
  51. /**
  52. * @swagger
  53. *
  54. * /export/status:
  55. * get:
  56. * tags: [Export]
  57. * operationId: getExportStatus
  58. * summary: /export/status
  59. * description: get properties of stored zip files for export
  60. * responses:
  61. * 200:
  62. * description: the zip file statuses
  63. * content:
  64. * application/json:
  65. * schema:
  66. * properties:
  67. * status:
  68. * $ref: '#/components/schemas/ExportStatus'
  69. */
  70. router.get('/status', accessTokenParser, loginRequired, adminRequired, async(req, res) => {
  71. const status = await exportService.getStatus();
  72. // TODO: use res.apiv3
  73. return res.json({
  74. ok: true,
  75. status,
  76. });
  77. });
  78. /**
  79. * @swagger
  80. *
  81. * /export:
  82. * post:
  83. * tags: [Export]
  84. * operationId: createExport
  85. * summary: /export
  86. * description: generate zipped jsons for collections
  87. * responses:
  88. * 200:
  89. * description: a zip file is generated
  90. * content:
  91. * application/json:
  92. * schema:
  93. * properties:
  94. * status:
  95. * $ref: '#/components/schemas/ExportStatus'
  96. */
  97. router.post('/', accessTokenParser, loginRequired, adminRequired, csrf, async(req, res) => {
  98. // TODO: add express validator
  99. try {
  100. const { collections } = req.body;
  101. exportService.export(collections);
  102. // TODO: use res.apiv3
  103. return res.status(200).json({
  104. ok: true,
  105. });
  106. }
  107. catch (err) {
  108. // TODO: use ApiV3Error
  109. logger.error(err);
  110. return res.status(500).send({ status: 'ERROR' });
  111. }
  112. });
  113. /**
  114. * @swagger
  115. *
  116. * /export/{fileName}:
  117. * delete:
  118. * tags: [Export]
  119. * operationId: deleteExport
  120. * summary: /export/{fileName}
  121. * description: delete the file
  122. * parameters:
  123. * - name: fileName
  124. * in: path
  125. * description: the file name of zip file
  126. * required: true
  127. * schema:
  128. * type: string
  129. * responses:
  130. * 200:
  131. * description: the file is deleted
  132. * content:
  133. * application/json:
  134. * schema:
  135. * type: object
  136. */
  137. router.delete('/:fileName', accessTokenParser, loginRequired, adminRequired, csrf, async(req, res) => {
  138. // TODO: add express validator
  139. const { fileName } = req.params;
  140. try {
  141. const zipFile = exportService.getFile(fileName);
  142. fs.unlinkSync(zipFile);
  143. // TODO: use res.apiv3
  144. return res.status(200).send({ ok: true });
  145. }
  146. catch (err) {
  147. // TODO: use ApiV3Error
  148. logger.error(err);
  149. return res.status(500).send({ ok: false });
  150. }
  151. });
  152. return router;
  153. };