132 lines
4.6 KiB
TypeScript
132 lines
4.6 KiB
TypeScript
import { MultipartFile } from '@adonisjs/core/bodyparser'
|
|
import { Entry, FileEntry, FolderEntry } from '#base_modules/FileManager/types/entries'
|
|
import {
|
|
default as EntryListService,
|
|
EntryListParams,
|
|
EntryListResult,
|
|
} from '#base_modules/FileManager/services/entry_list_service'
|
|
import createStorageService from '#base_modules/FileManager/services/storage_service/create_storage_service'
|
|
import {
|
|
FileStream,
|
|
StorageService,
|
|
} from '#base_modules/FileManager/services/storage_service/storage_service_interface'
|
|
import FilePreviewService from '#base_modules/FileManager/services/file_preview_service'
|
|
import EntrySearchService from '#base_modules/FileManager/services/entry_search_service'
|
|
import PathService from '#base_modules/FileManager/services/path_service'
|
|
import {
|
|
EntryExistsException,
|
|
FilenameMissingExtensionException,
|
|
} from '#exceptions/file_manager_exeptions'
|
|
|
|
export default class FileManagerService {
|
|
private filePreviewService = new FilePreviewService()
|
|
private entrySearchService = new EntrySearchService()
|
|
private entryListService = new EntryListService()
|
|
private pathService = new PathService()
|
|
private storageService: StorageService
|
|
|
|
constructor(storageService?: StorageService) {
|
|
if (storageService) this.storageService = storageService
|
|
else this.storageService = createStorageService()
|
|
}
|
|
|
|
public async listDirectory(path: string, params: EntryListParams): Promise<EntryListResult> {
|
|
const entries = await this.storageService.listDirectoryEntries(path)
|
|
|
|
return this.entryListService.apply(entries, params)
|
|
}
|
|
|
|
public async getFileEntryWithPreview(path: string): Promise<FileEntry & { content?: string }> {
|
|
const entry = await this.storageService.getFileEntry(path)
|
|
|
|
return this.filePreviewService.withPreview(entry, () =>
|
|
this.storageService.getFileContent(path)
|
|
)
|
|
}
|
|
|
|
public getFileStream(path: string): Promise<FileStream> {
|
|
return this.storageService.getFileStream(path)
|
|
}
|
|
|
|
public async createDirectory(path: string, name: string): Promise<FolderEntry> {
|
|
const result = await this.storageService.createDirectory(path, name)
|
|
|
|
return {
|
|
name,
|
|
path: result.path,
|
|
type: 'folder',
|
|
}
|
|
}
|
|
|
|
public async deleteEntry(path: string): Promise<void> {
|
|
await this.storageService.deleteEntry(path)
|
|
}
|
|
|
|
public async moveEntry(path: string, name: string): Promise<Entry> {
|
|
const entry = await this.storageService.getEntry(path)
|
|
const dir = this.pathService.dirname(path)
|
|
const newPath = dir ? this.pathService.join(dir, name) : name
|
|
|
|
if (entry.type === 'file' && !this.pathService.getFileNameMeta(name).ext) {
|
|
throw new FilenameMissingExtensionException()
|
|
}
|
|
|
|
if (await this.storageService.entryExists(newPath)) {
|
|
throw new EntryExistsException()
|
|
}
|
|
|
|
const result = await this.storageService.moveEntry(path, newPath)
|
|
|
|
return this.storageService.getEntry(result.path)
|
|
}
|
|
|
|
public async writeFile(path: string, file: MultipartFile): Promise<Entry> {
|
|
const dir = this.pathService.toStoragePath(path)
|
|
const safeName = await this.pathService.generateUniqueName(dir, file.clientName, (target) => {
|
|
return this.storageService.entryExists(target)
|
|
})
|
|
const writePath = this.pathService.join(dir, safeName)
|
|
const result = await this.storageService.writeFile(writePath, file)
|
|
|
|
return this.storageService.getEntry(result.path)
|
|
}
|
|
|
|
public async copyEntries(paths: string[]): Promise<Entry[]> {
|
|
const results: Entry[] = []
|
|
|
|
for (const path of paths) {
|
|
try {
|
|
const sourceEntry = await this.storageService.getFileEntry(path)
|
|
const dir = this.pathService.dirname(sourceEntry.path)
|
|
const newName = await this.pathService.generateUniqueName(
|
|
dir,
|
|
sourceEntry.name,
|
|
(target) => this.storageService.entryExists(target),
|
|
(data) => {
|
|
const template = 'copy_'
|
|
const regex = new RegExp(`\\s?${template}(\\d+)$`)
|
|
const base = data.base.replace(regex, '').trim()
|
|
|
|
return `${base} ${template}${data.count}${data.extension}`
|
|
}
|
|
)
|
|
const copyPath = this.pathService.join(dir, newName)
|
|
const result = await this.storageService.copyEntry(path, copyPath)
|
|
const copiedEntry = await this.storageService.getFileEntry(result.path)
|
|
|
|
results.push(copiedEntry)
|
|
} catch {
|
|
continue
|
|
}
|
|
}
|
|
|
|
return results
|
|
}
|
|
|
|
public async search(path: string, query: string, signal?: AbortSignal): Promise<Entry[]> {
|
|
const entries = await this.storageService.listAllEntries(path)
|
|
|
|
return this.entrySearchService.search(entries, query, signal)
|
|
}
|
|
}
|