瀏覽代碼

refactor serving file function asset service

Alex Tran 3 年之前
父節點
當前提交
30d07fd475
共有 3 個文件被更改,包括 79 次插入10378 次删除
  1. 1 10308
      server/package-lock.json
  2. 1 69
      server/src/api-v1/asset/asset.controller.ts
  3. 77 1
      server/src/api-v1/asset/asset.service.ts

文件差異過大導致無法顯示
+ 1 - 10308
server/package-lock.json


+ 1 - 69
server/src/api-v1/asset/asset.controller.ts

@@ -73,75 +73,7 @@ export class AssetController {
     @Response({ passthrough: true }) res: Res,
     @Response({ passthrough: true }) res: Res,
     @Query(ValidationPipe) query: ServeFileDto,
     @Query(ValidationPipe) query: ServeFileDto,
   ): Promise<StreamableFile> {
   ): Promise<StreamableFile> {
-    let file = null;
-    const asset = await this.assetService.findOne(authUser, query.did, query.aid);
-
-    // Handle Sending Images
-    if (asset.type == AssetType.IMAGE || query.isThumb == 'true') {
-      res.set({
-        'Content-Type': asset.mimeType,
-      });
-
-      if (query.isThumb === 'false' || !query.isThumb) {
-        file = createReadStream(asset.originalPath);
-      } else {
-        file = createReadStream(asset.resizePath);
-      }
-
-      return new StreamableFile(file);
-    } else if (asset.type == AssetType.VIDEO) {
-      // Handle Handling Video
-      const { size } = await fileInfo(asset.originalPath);
-      const range = headers.range;
-
-      if (range) {
-        /** Extracting Start and End value from Range Header */
-        let [start, end] = range.replace(/bytes=/, '').split('-');
-        start = parseInt(start, 10);
-        end = end ? parseInt(end, 10) : size - 1;
-
-        if (!isNaN(start) && isNaN(end)) {
-          start = start;
-          end = size - 1;
-        }
-        if (isNaN(start) && !isNaN(end)) {
-          start = size - end;
-          end = size - 1;
-        }
-
-        // Handle unavailable range request
-        if (start >= size || end >= size) {
-          console.error('Bad Request');
-          // Return the 416 Range Not Satisfiable.
-          res.status(416).set({
-            'Content-Range': `bytes */${size}`,
-          });
-
-          throw new BadRequestException('Bad Request Range');
-        }
-
-        /** Sending Partial Content With HTTP Code 206 */
-
-        res.status(206).set({
-          'Content-Range': `bytes ${start}-${end}/${size}`,
-          'Accept-Ranges': 'bytes',
-          'Content-Length': end - start + 1,
-          'Content-Type': asset.mimeType,
-        });
-
-        const videoStream = createReadStream(asset.originalPath, { start: start, end: end });
-
-        return new StreamableFile(videoStream);
-      } else {
-        res.set({
-          'Content-Type': asset.mimeType,
-        });
-
-        return new StreamableFile(createReadStream(asset.originalPath));
-      }
-    }
-
-    console.log('SHOULD NOT BE HERE');
+    return this.assetService.serveFile(authUser, query, res, headers);
   }
   }
 
 
   @Get('/new')
   @Get('/new')

+ 77 - 1
server/src/api-v1/asset/asset.service.ts

@@ -1,4 +1,4 @@
-import { BadRequestException, Injectable, Logger } from '@nestjs/common';
+import { BadRequestException, Injectable, Logger, StreamableFile } from '@nestjs/common';
 import { InjectRepository } from '@nestjs/typeorm';
 import { InjectRepository } from '@nestjs/typeorm';
 import { MoreThan, Repository } from 'typeorm';
 import { MoreThan, Repository } from 'typeorm';
 import { AuthUserDto } from '../../decorators/auth-user.decorator';
 import { AuthUserDto } from '../../decorators/auth-user.decorator';
@@ -8,6 +8,12 @@ import { AssetEntity, AssetType } from './entities/asset.entity';
 import _ from 'lodash';
 import _ from 'lodash';
 import { GetAllAssetQueryDto } from './dto/get-all-asset-query.dto';
 import { GetAllAssetQueryDto } from './dto/get-all-asset-query.dto';
 import { GetAllAssetReponseDto } from './dto/get-all-asset-response.dto';
 import { GetAllAssetReponseDto } from './dto/get-all-asset-response.dto';
+import { createReadStream, stat } from 'fs';
+import { ServeFileDto } from './dto/serve-file.dto';
+import { Response as Res } from 'express';
+import { promisify } from 'util';
+
+const fileInfo = promisify(stat);
 
 
 @Injectable()
 @Injectable()
 export class AssetService {
 export class AssetService {
@@ -122,4 +128,74 @@ export class AssetService {
       relations: ['exifInfo'],
       relations: ['exifInfo'],
     });
     });
   }
   }
+
+  public async serveFile(authUser: AuthUserDto, query: ServeFileDto, res: Res, headers: any) {
+    let file = null;
+    const asset = await this.findOne(authUser, query.did, query.aid);
+
+    // Handle Sending Images
+    if (asset.type == AssetType.IMAGE || query.isThumb == 'true') {
+      res.set({
+        'Content-Type': asset.mimeType,
+      });
+
+      if (query.isThumb === 'false' || !query.isThumb) {
+        file = createReadStream(asset.originalPath);
+      } else {
+        file = createReadStream(asset.resizePath);
+      }
+
+      return new StreamableFile(file);
+    } else if (asset.type == AssetType.VIDEO) {
+      // Handle Handling Video
+      const { size } = await fileInfo(asset.originalPath);
+      const range = headers.range;
+
+      if (range) {
+        /** Extracting Start and End value from Range Header */
+        let [start, end] = range.replace(/bytes=/, '').split('-');
+        start = parseInt(start, 10);
+        end = end ? parseInt(end, 10) : size - 1;
+
+        if (!isNaN(start) && isNaN(end)) {
+          start = start;
+          end = size - 1;
+        }
+        if (isNaN(start) && !isNaN(end)) {
+          start = size - end;
+          end = size - 1;
+        }
+
+        // Handle unavailable range request
+        if (start >= size || end >= size) {
+          console.error('Bad Request');
+          // Return the 416 Range Not Satisfiable.
+          res.status(416).set({
+            'Content-Range': `bytes */${size}`,
+          });
+
+          throw new BadRequestException('Bad Request Range');
+        }
+
+        /** Sending Partial Content With HTTP Code 206 */
+
+        res.status(206).set({
+          'Content-Range': `bytes ${start}-${end}/${size}`,
+          'Accept-Ranges': 'bytes',
+          'Content-Length': end - start + 1,
+          'Content-Type': asset.mimeType,
+        });
+
+        const videoStream = createReadStream(asset.originalPath, { start: start, end: end });
+
+        return new StreamableFile(videoStream);
+      } else {
+        res.set({
+          'Content-Type': asset.mimeType,
+        });
+
+        return new StreamableFile(createReadStream(asset.originalPath));
+      }
+    }
+  }
 }
 }

部分文件因文件數量過多而無法顯示