Procházet zdrojové kódy

ACTION_PAGE_BULK_EXPORT_COMPLETED

Futa Arai před 1 rokem
rodič
revize
b7c98e50c2

+ 18 - 3
apps/app/src/features/page-bulk-export/server/service/page-bulk-export.ts

@@ -9,6 +9,7 @@ import type { QueueObject } from 'async';
 import gc from 'expose-gc/function';
 import mongoose from 'mongoose';
 
+import { SupportedAction, SupportedTargetModel } from '~/interfaces/activity';
 import type { PageModel, PageDocument } from '~/server/models/page';
 import type { IAwsMultipartUploader } from '~/server/service/file-uploader/aws/multipart-upload';
 import { getBufferToFixedSizeTransform } from '~/server/util/stream';
@@ -29,6 +30,8 @@ class PageBulkExportService {
 
   crowi: any;
 
+  activityEvent: any;
+
   // multipart upload part size
   partSize = 5 * 1024 * 1024; // 5MB
 
@@ -36,6 +39,7 @@ class PageBulkExportService {
 
   constructor(crowi) {
     this.crowi = crowi;
+    this.activityEvent = crowi.event('activity');
   }
 
   async bulkExportWithBasePagePath(basePagePath: string, currentUser): Promise<void> {
@@ -76,7 +80,7 @@ class PageBulkExportService {
       format: PageBulkExportFormat.markdown,
     });
 
-    const multipartUploadWritable = this.getMultipartUploadWritable(multipartUploader, pageBulkExportJob);
+    const multipartUploadWritable = this.getMultipartUploadWritable(multipartUploader, pageBulkExportJob, currentUser);
 
     // Cannot directly pipe from pagesWritable to zipArchiver due to how the 'append' method works.
     // Hence, execution of two pipelines is required.
@@ -162,7 +166,7 @@ class PageBulkExportService {
     return zipArchiver;
   }
 
-  private getMultipartUploadWritable(multipartUploader: IAwsMultipartUploader, pageBulkExportJob: PageBulkExportJobDocument): Writable {
+  private getMultipartUploadWritable(multipartUploader: IAwsMultipartUploader, pageBulkExportJob: PageBulkExportJobDocument, user): Writable {
     let partNumber = 1;
 
     return new Writable({
@@ -180,11 +184,22 @@ class PageBulkExportService {
         }
         callback();
       },
-      async final(callback) {
+      final: async(callback) => {
         try {
           await multipartUploader.completeUpload();
           pageBulkExportJob.completedAt = new Date();
           await pageBulkExportJob.save();
+
+          const activity = await this.crowi.activityService.createActivity({
+            action: SupportedAction.ACTION_PAGE_BULK_EXPORT_COMPLETED,
+            user,
+            targetModel: SupportedTargetModel.MODEL_PAGE_BULK_EXPORT_JOB,
+            target: pageBulkExportJob,
+            snapshot: {
+              username: user.username,
+            },
+          });
+          this.activityEvent.emit('updated', activity, page, preNotify);
         }
         catch (err) {
           callback(err);

+ 5 - 0
apps/app/src/interfaces/activity.ts

@@ -4,6 +4,7 @@ import type { Ref, HasObjectId, IUser } from '@growi/core';
 const MODEL_PAGE = 'Page';
 const MODEL_USER = 'User';
 const MODEL_COMMENT = 'Comment';
+const MODEL_PAGE_BULK_EXPORT_JOB = 'PageBulkExportJob';
 
 // Action
 const ACTION_UNSETTLED = 'UNSETTLED';
@@ -51,6 +52,7 @@ const ACTION_PAGE_RECURSIVELY_REVERT = 'PAGE_RECURSIVELY_REVERT';
 const ACTION_PAGE_SUBSCRIBE = 'PAGE_SUBSCRIBE';
 const ACTION_PAGE_UNSUBSCRIBE = 'PAGE_UNSUBSCRIBE';
 const ACTION_PAGE_EXPORT = 'PAGE_EXPORT';
+const ACTION_PAGE_BULK_EXPORT_COMPLETED = 'ACTION_PAGE_BULK_EXPORT_COMPLETED';
 const ACTION_TAG_UPDATE = 'TAG_UPDATE';
 const ACTION_IN_APP_NOTIFICATION_ALL_STATUSES_OPEN = 'IN_APP_NOTIFICATION_ALL_STATUSES_OPEN';
 const ACTION_COMMENT_CREATE = 'COMMENT_CREATE';
@@ -166,6 +168,7 @@ const ACTION_ADMIN_SEARCH_INDICES_REBUILD = 'ADMIN_SEARCH_INDICES_REBUILD';
 export const SupportedTargetModel = {
   MODEL_PAGE,
   MODEL_USER,
+  MODEL_PAGE_BULK_EXPORT_JOB,
 } as const;
 
 export const SupportedEventModel = {
@@ -340,6 +343,7 @@ export const SupportedAction = {
   ACTION_ADMIN_SEARCH_CONNECTION,
   ACTION_ADMIN_SEARCH_INDICES_NORMALIZE,
   ACTION_ADMIN_SEARCH_INDICES_REBUILD,
+  ACTION_PAGE_BULK_EXPORT_COMPLETED,
 } as const;
 
 // Action required for notification
@@ -358,6 +362,7 @@ export const EssentialActionGroup = {
   ACTION_PAGE_RECURSIVELY_REVERT,
   ACTION_COMMENT_CREATE,
   ACTION_USER_REGISTRATION_APPROVAL_REQUEST,
+  ACTION_PAGE_BULK_EXPORT_COMPLETED,
 } as const;
 
 export const ActionGroupSize = {

+ 2 - 0
apps/app/src/server/crowi/index.js

@@ -19,6 +19,7 @@ import Xss from '~/services/xss';
 import loggerFactory from '~/utils/logger';
 import { projectRoot } from '~/utils/project-dir-utils';
 
+import PageBulkExportEvent from '../events/page-bulk-export';
 import UserEvent from '../events/user';
 import { modelsDependsOnCrowi } from '../models';
 import { aclService as aclServiceSingletonInstance } from '../service/acl';
@@ -119,6 +120,7 @@ class Crowi {
       bookmark: new (require('../events/bookmark'))(this),
       tag: new (require('../events/tag'))(this),
       admin: new (require('../events/admin'))(this),
+      pageBulkExport: new PageBulkExportEvent(),
     };
   }
 

+ 5 - 0
apps/app/src/server/events/page-bulk-export.ts

@@ -0,0 +1,5 @@
+import { EventEmitter } from 'events';
+
+class PageBulkExportEvent extends EventEmitter {}
+
+export default PageBulkExportEvent;

+ 2 - 1
apps/app/src/server/service/in-app-notification.ts

@@ -5,6 +5,7 @@ import { SubscriptionStatusType } from '@growi/core';
 import { subDays } from 'date-fns/subDays';
 import type { Types, FilterQuery, UpdateQuery } from 'mongoose';
 
+import type { IPageBulkExportJob } from '~/features/page-bulk-export/interfaces/page-bulk-export';
 import { AllEssentialActions } from '~/interfaces/activity';
 import type { PaginateResult } from '~/interfaces/in-app-notification';
 import { InAppNotificationStatuses } from '~/interfaces/in-app-notification';
@@ -198,7 +199,7 @@ export default class InAppNotificationService {
     return;
   };
 
-  createInAppNotification = async function(activity: ActivityDocument, target: IUser | IPage, preNotify: PreNotify): Promise<void> {
+  createInAppNotification = async function(activity: ActivityDocument, target: IUser | IPage | IPageBulkExportJob, preNotify: PreNotify): Promise<void> {
 
     const shouldNotification = activity != null && target != null && (AllEssentialActions as ReadonlyArray<string>).includes(activity.action);
 

+ 4 - 3
apps/app/src/server/service/in-app-notification/in-app-notification-utils.ts

@@ -1,15 +1,16 @@
 import type { IUser, IPage } from '@growi/core';
 
+import type { IPageBulkExportJob } from '~/features/page-bulk-export/interfaces/page-bulk-export';
 import { SupportedTargetModel } from '~/interfaces/activity';
 import * as pageSerializers from '~/models/serializers/in-app-notification-snapshot/page';
 
-const isIPage = (targetModel: string, target: IUser | IPage): target is IPage => {
+const isIPage = (targetModel: string, target: IUser | IPage | IPageBulkExportJob): target is IPage => {
   return targetModel === SupportedTargetModel.MODEL_PAGE;
 };
 
-export const generateSnapshot = (targetModel: string, target: IUser | IPage) => {
+export const generateSnapshot = (targetModel: string, target: IUser | IPage | IPageBulkExportJob): string | undefined => {
 
-  let snapshot;
+  let snapshot: string | undefined;
 
   if (isIPage(targetModel, target)) {
     snapshot = pageSerializers.stringifySnapshot(target);