File size: 2,692 Bytes
d988ae4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { Injectable, Logger } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
import { promisify } from 'util';

const writeFileAsync = promisify(fs.writeFile);
const readFileAsync = promisify(fs.readFile);
const unlinkAsync = promisify(fs.unlink);
const mkdirAsync = promisify(fs.mkdir);
const existsAsync = promisify(fs.exists);

@Injectable()
export class FilesystemService {
  private readonly logger = new Logger(FilesystemService.name);
  private readonly uploadDir: string;

  constructor() {
    // Create uploads directory in the project root
    this.uploadDir = process.env.UPLOAD_DIR || path.join(process.cwd(), 'uploads');
    this.initUploadDir().catch(err => {
      this.logger.error(`Failed to initialize upload directory: ${err.message}`);
    });
  }

  private async initUploadDir(): Promise<void> {
    if (!await existsAsync(this.uploadDir)) {
      await mkdirAsync(this.uploadDir, { recursive: true });
      this.logger.log(`Upload directory '${this.uploadDir}' created successfully`);
    }
  }

  async uploadFile(file: Express.Multer.File, roomCode: string, fileName: string): Promise<string> {
    // Create room directory if it doesn't exist
    const roomDir = path.join(this.uploadDir, roomCode);
    if (!await existsAsync(roomDir)) {
      await mkdirAsync(roomDir, { recursive: true });
    }

    // Save file to disk
    const filePath = path.join(roomDir, fileName);
    await writeFileAsync(filePath, file.buffer);
    
    // Return the relative path to the file
    return `/${roomCode}/${fileName}`;
  }

  async getFile(roomCode: string, fileName: string): Promise<Buffer> {
    const filePath = path.join(this.uploadDir, roomCode, fileName);
    return await readFileAsync(filePath);
  }

  async deleteFile(roomCode: string, fileName: string): Promise<boolean> {
    try {
      const filePath = path.join(this.uploadDir, roomCode, fileName);
      await unlinkAsync(filePath);
      return true;
    } catch (error) {
      this.logger.error(`Failed to delete file: ${error.message}`);
      return false;
    }
  }

  async deleteRoomFiles(roomCode: string): Promise<boolean> {
    try {
      const roomDir = path.join(this.uploadDir, roomCode);
      if (await existsAsync(roomDir)) {
        // Delete all files in the directory
        const files = fs.readdirSync(roomDir);
        for (const file of files) {
          await unlinkAsync(path.join(roomDir, file));
        }
        
        // Remove the directory itself
        fs.rmdirSync(roomDir);
      }
      return true;
    } catch (error) {
      this.logger.error(`Failed to delete room files: ${error.message}`);
      return false;
    }
  }
}