From d20295326f24685f2f709a71558fde42ae4611a9 Mon Sep 17 00:00:00 2001 From: Jurgis Sakalauskas Date: Tue, 6 Dec 2022 10:40:58 +0200 Subject: [PATCH] Static: extract view file --- README.md | 2 +- src/Static/Dto/file.dto.ts | 13 +++++++ src/Static/View/index.view.ts | 61 +++++++++++++++++++++++++++++++++ src/Static/static.controller.ts | 8 +++-- src/Static/static.service.ts | 53 ++++++++-------------------- 5 files changed, 94 insertions(+), 43 deletions(-) create mode 100644 src/Static/Dto/file.dto.ts create mode 100644 src/Static/View/index.view.ts diff --git a/README.md b/README.md index ea3082e..b2f5852 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A rewrite attempt from "vanilla" node.js into framework based (Nest.js). ## License -No licence (Nest is MIT) +No licence ## Below are left from nest readme diff --git a/src/Static/Dto/file.dto.ts b/src/Static/Dto/file.dto.ts new file mode 100644 index 0000000..1707933 --- /dev/null +++ b/src/Static/Dto/file.dto.ts @@ -0,0 +1,13 @@ +export default class FileDto { + constructor( + readonly name: string, + readonly size: number, + readonly date: Date, + readonly isDirectory: boolean, + ) { + this.name = name; + this.size = size; + this.date = date; + this.isDirectory = isDirectory; + } +} diff --git a/src/Static/View/index.view.ts b/src/Static/View/index.view.ts new file mode 100644 index 0000000..1104a86 --- /dev/null +++ b/src/Static/View/index.view.ts @@ -0,0 +1,61 @@ +import FileDto from '../Dto/file.dto'; + +export default class IndexView { + public render(relPath: string, files: Array): string { + return this.buildHtml(relPath, files); + } + + private buildHtml(relPath: string, files: Array): string { + const longestFileLength = this.getLongestFileLength(files); + + let result: string; + const resultHtmlStart = ` + + Index of ${relPath} + +

Index of ${relPath}

+
`;
+
+    result = `../`;
+
+    for (const file of files) {
+      result += this.getFileLink(file, longestFileLength);
+    }
+
+    const resultHtmlEnd = `

`; + + return resultHtmlStart + result + resultHtmlEnd; + } + + private getFileLink(file: FileDto, longestFileLength: number) { + const arrDate: Array = file.date.toUTCString().split(' '); + const strDate: string = + ' '.repeat(longestFileLength - file.name.length) + + `${arrDate[1]}-${arrDate[2]}-${arrDate[3]} ${arrDate[4]}`; + + if (file.isDirectory) { + const strSize = ' '.repeat(19) + '-'; + return ( + '\n' + `${file.name}/${strDate + strSize}` + ); + } + let strSize = file.size.toString(); + strSize = ' '.repeat(20 - strSize.length) + strSize; + + return ( + '\n' + `${file.name} ${strDate + strSize}` + ); + } + + private getLongestFileLength(files: Array) { + let longestFileLength = 0; + for (const file of files) { + longestFileLength = + longestFileLength < file.name.length + ? file.name.length + : longestFileLength; + } + longestFileLength += 10; + return longestFileLength; + } +} diff --git a/src/Static/static.controller.ts b/src/Static/static.controller.ts index d5f4a31..ee4213d 100644 --- a/src/Static/static.controller.ts +++ b/src/Static/static.controller.ts @@ -1,6 +1,7 @@ import { Controller, Get, Next, Req, Res } from '@nestjs/common'; import { NextFunction, Request, Response } from 'express'; import { StaticService } from './static.service'; +import IndexView from './View/index.view'; @Controller('*') export class StaticController { @@ -11,11 +12,12 @@ export class StaticController { @Res() response: Response, @Next() next: NextFunction, ) { - const dirIndexHtml = await this.staticService.provideDirIndex(request.url); - if (dirIndexHtml === null) { + const dirIndex = await this.staticService.provideDirIndex(request.url); + if (dirIndex === null) { return next(); } + const view = new IndexView(); - return response.status(200).send(dirIndexHtml); + return response.status(200).send(view.render(request.url, dirIndex)); } } diff --git a/src/Static/static.service.ts b/src/Static/static.service.ts index b76d224..1da4c7f 100644 --- a/src/Static/static.service.ts +++ b/src/Static/static.service.ts @@ -6,10 +6,11 @@ import { import { readdir, stat } from 'fs/promises'; import { Stats } from 'fs'; import { join } from 'path'; +import FileDto from './Dto/file.dto'; @Injectable() export class StaticService { - async provideDirIndex(relPath: string): Promise { + async provideDirIndex(relPath: string): Promise> { if (relPath.indexOf('..') > -1) { throw new UnauthorizedException( 'You are not authorized to visit ' + relPath, @@ -28,35 +29,17 @@ export class StaticService { return null; } - return this.readDirectory(path, relPath); + return this.readDirectory(path); } - private async readDirectory(path: string, relPath: string) { + private async readDirectory(path: string): Promise> { let files = await readdir(path); - let longestFileLength = 0; files = files.filter((fileName: string) => { - const fileIncluded = fileName[0] !== '.'; - longestFileLength = - fileIncluded && longestFileLength < fileName.length - ? fileName.length - : longestFileLength; - - return fileIncluded; + return fileName[0] !== '.'; }); - longestFileLength += 10; - - let result: string; - const resultHtmlStart = ` - - Index of ${relPath} - -

Index of ${relPath}

-
`;
-
-    result = `../`;
-
+    const filesDtos: Array = [];
     for (const file of files) {
       const stats: Stats | false = await stat(join(path, file)).catch(
         () => false,
@@ -65,24 +48,16 @@ export class StaticService {
       if (stats === false) {
         continue;
       }
-      const arrDate: Array = stats.birthtime.toUTCString().split(' ');
-      const strDate: string =
-        ' '.repeat(longestFileLength - file.length) +
-        `${arrDate[1]}-${arrDate[2]}-${arrDate[3]} ${arrDate[4]}`;
+      const fileDto = new FileDto(
+        file,
+        stats.size,
+        stats.birthtime,
+        stats.isDirectory(),
+      );
 
-      if (stats.isDirectory()) {
-        const strSize = ' '.repeat(19) + '-';
-        result += '\n' + `${file}/${strDate + strSize}`;
-        continue;
-      }
-      let strSize = stats.size.toString();
-      strSize = ' '.repeat(20 - strSize.length) + strSize;
-
-      result += '\n' + `${file} ${strDate + strSize}`;
+      filesDtos.push(fileDto);
     }
 
-    const resultHtmlEnd = `

`; - - return resultHtmlStart + result + resultHtmlEnd; + return filesDtos; } }