108 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
import Log from '#models/log'
 | 
						|
import type { HttpContext } from '@adonisjs/core/http'
 | 
						|
import fs from 'node:fs'
 | 
						|
import path, { dirname } from 'node:path'
 | 
						|
import { fileURLToPath } from 'node:url'
 | 
						|
 | 
						|
const FILENAME = fileURLToPath(import.meta.url)
 | 
						|
const DIRNAME = dirname(FILENAME)
 | 
						|
 | 
						|
export default class LogsController {
 | 
						|
  async list({ request, response, auth }: HttpContext) {
 | 
						|
    const search = request.input('search', '')
 | 
						|
    const perPage = request.input('per_page', 10)
 | 
						|
    const page = request.input('page', 1)
 | 
						|
 | 
						|
    // Fetch logs that are associated with the user's stations with pagination
 | 
						|
    const query = Log.query()
 | 
						|
      .select('logs.*')
 | 
						|
      .preload('line', (lineQuery) => {
 | 
						|
        lineQuery.preload('station')
 | 
						|
      })
 | 
						|
 | 
						|
    const logs = await query.paginate(page, perPage)
 | 
						|
 | 
						|
    return response.ok({
 | 
						|
      status: true,
 | 
						|
      data: logs,
 | 
						|
    })
 | 
						|
  }
 | 
						|
 | 
						|
  async viewLog({ request, response }: HttpContext) {
 | 
						|
    const logFilePath = request.input('path')
 | 
						|
 | 
						|
    try {
 | 
						|
      const normalizedPath = path.normalize(logFilePath)
 | 
						|
      const fullPath = path.join(DIRNAME, '..', '..', normalizedPath)
 | 
						|
 | 
						|
      if (!fs.existsSync(fullPath)) {
 | 
						|
        return response.notFound({
 | 
						|
          status: false,
 | 
						|
          message: 'Log file not found',
 | 
						|
        })
 | 
						|
      }
 | 
						|
 | 
						|
      // Đọc file với encoding buffer trước
 | 
						|
      const buffer = fs.readFileSync(fullPath)
 | 
						|
 | 
						|
      // Thử các encoding khác nhau
 | 
						|
      let logContent
 | 
						|
      try {
 | 
						|
        // Thử với utf-8 trước
 | 
						|
        logContent = buffer.toString('utf-8')
 | 
						|
        if (logContent.includes('\u0000')) {
 | 
						|
          // Nếu có null bytes, thử với encoding khác
 | 
						|
          logContent = buffer.toString('ascii')
 | 
						|
        }
 | 
						|
      } catch {
 | 
						|
        // Fallback to ascii if utf-8 fails
 | 
						|
        logContent = buffer.toString('ascii')
 | 
						|
      }
 | 
						|
 | 
						|
      // Loại bỏ các null bytes
 | 
						|
      logContent = logContent.replace(/\u0000/g, '')
 | 
						|
 | 
						|
      return response.ok({
 | 
						|
        status: true,
 | 
						|
        data: logContent,
 | 
						|
      })
 | 
						|
    } catch (error) {
 | 
						|
      return response.internalServerError({
 | 
						|
        status: false,
 | 
						|
        message: 'Failed to read log file',
 | 
						|
        error: error.message,
 | 
						|
      })
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  async downloadLog({ request, response }: HttpContext) {
 | 
						|
    try {
 | 
						|
      const logPath = request.input('path')
 | 
						|
      const fullPath = path.join(DIRNAME, '..', '..', logPath)
 | 
						|
 | 
						|
      if (!fs.existsSync(fullPath)) {
 | 
						|
        return response.notFound({
 | 
						|
          status: false,
 | 
						|
          message: 'Log file not found',
 | 
						|
        })
 | 
						|
      }
 | 
						|
 | 
						|
      // Lấy tên file từ đường dẫn
 | 
						|
      const fileName = path.basename(logPath)
 | 
						|
 | 
						|
      // Set headers cho download
 | 
						|
      response.header('Content-Type', 'application/octet-stream')
 | 
						|
      response.header('Content-Disposition', `attachment; filename="${fileName}"`)
 | 
						|
 | 
						|
      // Stream file về client
 | 
						|
      return response.stream(fs.createReadStream(fullPath))
 | 
						|
    } catch (error) {
 | 
						|
      return response.internalServerError({
 | 
						|
        status: false,
 | 
						|
        message: 'Failed to download log file',
 | 
						|
        error: error.message,
 | 
						|
      })
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |