atsuki-t 3 лет назад
Родитель
Сommit
b688c97768

+ 79 - 2
packages/app/src/server/routes/apiv3/g2g-transfer.ts

@@ -4,16 +4,20 @@ import express, { NextFunction, Request, Router } from 'express';
 import { body } from 'express-validator';
 import { body } from 'express-validator';
 import multer from 'multer';
 import multer from 'multer';
 
 
+import { SupportedAction } from '~/interfaces/activity';
+import GrowiArchiveImportOption from '~/models/admin/growi-archive-import-option';
 import TransferKeyModel from '~/server/models/transfer-key';
 import TransferKeyModel from '~/server/models/transfer-key';
 import { isG2GTransferError } from '~/server/models/vo/g2g-transfer-error';
 import { isG2GTransferError } from '~/server/models/vo/g2g-transfer-error';
 import { IDataGROWIInfo, X_GROWI_TRANSFER_KEY_HEADER_NAME } from '~/server/service/g2g-transfer';
 import { IDataGROWIInfo, X_GROWI_TRANSFER_KEY_HEADER_NAME } from '~/server/service/g2g-transfer';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 import { TransferKey } from '~/utils/vo/transfer-key';
 import { TransferKey } from '~/utils/vo/transfer-key';
 
 
+
 import Crowi from '../../crowi';
 import Crowi from '../../crowi';
 import { apiV3FormValidator } from '../../middlewares/apiv3-form-validator';
 import { apiV3FormValidator } from '../../middlewares/apiv3-form-validator';
 import ErrorV3 from '../../models/vo/error-apiv3';
 import ErrorV3 from '../../models/vo/error-apiv3';
 
 
+import { generateOverwriteParams } from './import';
 import { ApiV3Response } from './interfaces/apiv3-response';
 import { ApiV3Response } from './interfaces/apiv3-response';
 
 
 const logger = loggerFactory('growi:routes:apiv3:transfer');
 const logger = loggerFactory('growi:routes:apiv3:transfer');
@@ -131,6 +135,79 @@ module.exports = (crowi: Crowi): Router => {
     const zipFile = importService.getFile(file.filename);
     const zipFile = importService.getFile(file.filename);
     let data;
     let data;
 
 
+    // ぶちこみ
+
+    const { collections, optionsMap } = req.body;
+
+    /*
+     * unzip, parse
+     */
+    let meta;
+    let innerFileStats;
+    try {
+      // unzip
+      await importService.unzip(zipFile);
+
+      // eslint-disable-next-line no-unused-vars
+      const { meta: parsedMeta, innerFileStats: _innerFileStats } = await growiBridgeService.parseZipFile(zipFile);
+      innerFileStats = _innerFileStats;
+      meta = parsedMeta;
+    }
+    catch (err) {
+      logger.error(err);
+      // adminEvent.emit('onErrorForImport', { message: err.message });
+      return;
+    }
+
+    /*
+     * validate with meta.json
+     */
+    try {
+      importService.validate(meta);
+    }
+    catch (err) {
+      logger.error(err);
+      // adminEvent.emit('onErrorForImport', { message: err.message });
+      return;
+    }
+
+    // generate maps of ImportSettings to import
+    const importSettingsMap = {};
+    innerFileStats.forEach(({ fileName, collectionName }) => {
+      // instanciate GrowiArchiveImportOption
+      const options = new GrowiArchiveImportOption(null, optionsMap[collectionName]);
+
+      let importSettings;
+      // generate options
+      if (collectionName === 'configs') {
+        importSettings = importService.generateImportSettings('flushAndInsert');
+      }
+      else {
+        importSettings = importService.generateImportSettings('upsert');
+      }
+      importSettings.jsonFileName = fileName;
+
+      // generate overwrite params
+      importSettings.overwriteParams = generateOverwriteParams(collectionName, req, options);
+
+      importSettingsMap[collectionName] = importSettings;
+    });
+
+    /*
+     * import
+     */
+    try {
+      importService.import(collections, importSettingsMap);
+      const parameters = { action: SupportedAction.ACTION_ADMIN_GROWI_DATA_IMPORTED };
+      // activityEvent.emit('update', res.locals.activity._id, parameters);
+    }
+    catch (err) {
+      logger.error(err);
+      // adminEvent.emit('onErrorForImport', { message: err.message });
+    }
+
+    // ここまで
+
     try {
     try {
       data = await growiBridgeService.parseZipFile(zipFile);
       data = await growiBridgeService.parseZipFile(zipFile);
     }
     }
@@ -212,7 +289,7 @@ module.exports = (crowi: Crowi): Router => {
   // TODO: Use socket to send progress info to the client
   // TODO: Use socket to send progress info to the client
   // eslint-disable-next-line max-len
   // eslint-disable-next-line max-len
   pushRouter.post('/transfer', accessTokenParser, loginRequiredStrictly, adminRequired, validator.transfer, apiV3FormValidator, async(req: Request, res: ApiV3Response) => {
   pushRouter.post('/transfer', accessTokenParser, loginRequiredStrictly, adminRequired, validator.transfer, apiV3FormValidator, async(req: Request, res: ApiV3Response) => {
-    const { transferKey: transferKeyString, collections } = req.body;
+    const { transferKey: transferKeyString, collections, optionsMap } = req.body;
 
 
     // Parse transfer key
     // Parse transfer key
     let tk: TransferKey;
     let tk: TransferKey;
@@ -244,7 +321,7 @@ module.exports = (crowi: Crowi): Router => {
 
 
     // Start transfer
     // Start transfer
     try {
     try {
-      await g2gTransferPusherService.startTransfer(tk, collections);
+      await g2gTransferPusherService.startTransfer(tk, collections, optionsMap);
     }
     }
     catch (err) {
     catch (err) {
       logger.error(err);
       logger.error(err);

+ 1 - 1
packages/app/src/server/routes/apiv3/import.js

@@ -55,7 +55,7 @@ const router = express.Router();
  * @param {object} req Request Object
  * @param {object} req Request Object
  * @param {GrowiArchiveImportOption} options GrowiArchiveImportOption instance
  * @param {GrowiArchiveImportOption} options GrowiArchiveImportOption instance
  */
  */
-const generateOverwriteParams = (collectionName, req, options) => {
+export const generateOverwriteParams = (collectionName, req, options) => {
   switch (collectionName) {
   switch (collectionName) {
     case 'pages':
     case 'pages':
       return require('./overwrite-params/pages')(req, options);
       return require('./overwrite-params/pages')(req, options);

+ 5 - 2
packages/app/src/server/service/g2g-transfer.ts

@@ -45,8 +45,9 @@ interface Pusher {
    * Start transfer data between GROWIs
    * Start transfer data between GROWIs
    * @param {TransferKey} tk TransferKey object
    * @param {TransferKey} tk TransferKey object
    * @param {string[]} collections Collection name string array
    * @param {string[]} collections Collection name string array
+   * @param {any} optionsMap Options map
    */
    */
-  startTransfer(tk: TransferKey, collections: string[]): Promise<void>
+  startTransfer(tk: TransferKey, collections: string[], optionsMap: any): Promise<void>
 }
 }
 
 
 interface Receiver {
 interface Receiver {
@@ -114,7 +115,7 @@ export class G2GTransferPusherService implements Pusher {
 
 
   public async transferAttachments(): Promise<void> { return }
   public async transferAttachments(): Promise<void> { return }
 
 
-  public async startTransfer(tk: TransferKey, collections: string[]): Promise<void> {
+  public async startTransfer(tk: TransferKey, collections: string[], optionsMap: any): Promise<void> {
     const { appUrl, key } = tk;
     const { appUrl, key } = tk;
 
 
     let zipFileStream: ReadStream;
     let zipFileStream: ReadStream;
@@ -137,6 +138,8 @@ export class G2GTransferPusherService implements Pusher {
 
 
       const appTitle = this.crowi.appService.getAppTitle();
       const appTitle = this.crowi.appService.getAppTitle();
       form.append('transferDataZipFile', zipFileStream, `${appTitle}-${Date.now}.growi.zip`);
       form.append('transferDataZipFile', zipFileStream, `${appTitle}-${Date.now}.growi.zip`);
+      form.append('collections', collections);
+      form.append('optionsMap', optionsMap);
       await rawAxios.post('/_api/v3/g2g-transfer/', form, {
       await rawAxios.post('/_api/v3/g2g-transfer/', form, {
         baseURL: appUrl.origin,
         baseURL: appUrl.origin,
         headers: {
         headers: {