/* ---------------------------------------------------------------------------- Question Server GitLab: This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ------------------------------------------------------------------------- */ export default { ReadFile: ReadFile, ReadJSON: ReadJSON, WriteFile: WriteFile, writeFileAsync: writeFileAsync, AppendToFile: AppendToFile, FileExists: FileExists, CreatePath: CreatePath, WatchFile: WatchFile, ReadDir: ReadDir, CopyFile: CopyFile, GetDateString: GetDateString, formatUrl: formatUrl, deleteFile: deleteFile, uploadFile: uploadFile, statFile: statFile, renameFile: renameFile, } import fs from 'fs' import { v4 as uuidv4 } from 'uuid' import logger from '../utils/logger' import { Request } from '../types/basicTypes' interface URLFormatOptions { pathname?: string query?: { [key: string]: string } } function formatUrl(options: URLFormatOptions): string { const path = options.pathname || '' if (!options.query || Object.keys(options.query).length === 0) { return path } const queryString = '?' + Object.keys(options.query) .map((key) => { return `${key}=${encodeURIComponent(options.query[key])}` }) .join('&') return path + queryString } function GetDateString( referenceDate?: Date | string, noTime?: boolean ): string { const date = referenceDate ? new Date(referenceDate) : new Date() if (noTime) { return ( date.getFullYear() + '-' + ('0' + (date.getMonth() + 1)).slice(-2) + '-' + ('0' + date.getDate()).slice(-2) ) } else { return ( date.getFullYear() + '-' + ('0' + (date.getMonth() + 1)).slice(-2) + '-' + ('0' + date.getDate()).slice(-2) + ' ' + ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2) + ':' + ('0' + date.getSeconds()).slice(-2) ) } } function CopyFile(from: string, to: string): void { CreatePath(to) fs.copyFileSync(from, to) } function ReadDir(path: string, listHidden?: boolean): Array { if (listHidden) { return fs.readdirSync(path) } else { return fs.readdirSync(path).filter((file) => { return !file.startsWith('.') }) } } function ReadJSON(name: string): any { try { return JSON.parse(ReadFile(name)) } catch (err) { console.error(err) throw new Error('Coulndt parse JSON in "ReadJSON", file: ' + name) } } function ReadFile(name: string): string { if (!FileExists(name)) { throw new Error('No such file: ' + name) } return fs.readFileSync(name, 'utf8') } function FileExists(path: string): boolean { return fs.existsSync(path) } function WatchFile(file: string, callback: Function): void { if (FileExists(file)) { fs.watchFile(file, () => { fs.readFile(file, 'utf8', (err, data) => { if (err) { // console.log(err) } else { callback(data) } }) }) } else { throw new Error(`${file} does not exits to watch`) } } function CreatePath(path: string, onlyPath?: boolean): void { if (FileExists(path)) { return } const spath = path.split('/') let currDir = spath[0] for (let i = 1; i < spath.length; i++) { if (currDir !== '' && !fs.existsSync(currDir)) { try { fs.mkdirSync(currDir) } catch (err) { console.log('Failed to make ' + currDir + ' directory... ') console.error(err) } } currDir += '/' + spath[i] } if (onlyPath) { fs.mkdirSync(path) } } function WriteFile(content: string, path: string): void { CreatePath(path) fs.writeFileSync(path, content) } function writeFileAsync(content: string, path: string): void { CreatePath(path) fs.writeFile(path, content, function (err) { if (err) { logger.Log( 'Error writing file: ' + path + ' (sync)', logger.GetColor('redbg') ) } }) } function AppendToFile(data: string, file: string): void { CreatePath(file) try { fs.appendFileSync(file, '\n' + data) } catch (err) { logger.Log( 'Error appendig to file log file: ' + file + ' (sync)', logger.GetColor('redbg') ) logger.Log(data) console.error(err) } } function deleteFile(fname: string): Boolean { if (FileExists(fname)) { fs.unlinkSync(fname) return true } return false } function uploadFile( req: Request, path: string ): Promise<{ body: Request['body'] fileName: string filePath: string }> { return new Promise((resolve, reject) => { try { if (!req.files) { logger.Log( `Unable to upload file, req.files is undefined`, logger.GetColor('redbg') ) return } const file = req.files.file // FIXME: Object.keys(req.files).forEach((file) => { saveFile() }) CreatePath(path, true) let fileName = file.name.replace(/\.+/g, '.').replace(/\/+/g, '/') let fileDestination = path + '/' + fileName if (FileExists(fileDestination)) { const id = uuidv4().split('-')[0] const temp = file.name.split('.') const extension = temp.pop() fileName = temp.join('.') + '_' + id + '.' + extension fileDestination = path + '/' + fileName } file.mv(fileDestination, (err: Error) => { if (err) { logger.Log(`Unable to upload file!`, logger.GetColor('redbg')) console.error(err) reject(err) } else { logger.Log( `Uploaded: ${fileName} to ${fileDestination}`, logger.GetColor('blue') ) resolve({ body: req.body, fileName: fileName, filePath: fileDestination, }) } }) } catch (err) { logger.Log( `Unable to upload file, error on stderr`, logger.GetColor('redbg') ) console.error(err) reject(err) } }) } function statFile(file: string): fs.Stats { if (FileExists(file)) { return fs.statSync(file) } else { return null } } function renameFile(oldPath: string, newPath: string): string { if (FileExists(oldPath)) { fs.renameSync(oldPath, newPath) return newPath } else { return null } }