Support renaming multiple files at once

This commit is contained in:
Dane Everitt 2020-07-11 16:00:30 -07:00
parent 43f8ec23b8
commit 2653321fc2
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
6 changed files with 35 additions and 29 deletions

View file

@ -67,7 +67,7 @@ class FileController extends ClientApiController
* *
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException * @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
*/ */
public function listDirectory(ListFilesRequest $request, Server $server): array public function directory(ListFilesRequest $request, Server $server): array
{ {
try { try {
$contents = $this->fileRepository $contents = $this->fileRepository
@ -90,7 +90,7 @@ class FileController extends ClientApiController
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
* @throws \Pterodactyl\Exceptions\Http\Server\FileSizeTooLargeException * @throws \Pterodactyl\Exceptions\Http\Server\FileSizeTooLargeException
*/ */
public function getFileContents(GetFileContentsRequest $request, Server $server): Response public function contents(GetFileContentsRequest $request, Server $server): Response
{ {
return new Response( return new Response(
$this->fileRepository->setServer($server)->getContent( $this->fileRepository->setServer($server)->getContent(
@ -140,7 +140,7 @@ class FileController extends ClientApiController
* @param \Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
public function writeFileContents(WriteFileContentRequest $request, Server $server): JsonResponse public function write(WriteFileContentRequest $request, Server $server): JsonResponse
{ {
$this->fileRepository->setServer($server)->putContent( $this->fileRepository->setServer($server)->putContent(
$request->get('file'), $request->get('file'),
@ -157,7 +157,7 @@ class FileController extends ClientApiController
* @param \Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
public function createFolder(CreateFolderRequest $request, Server $server): JsonResponse public function create(CreateFolderRequest $request, Server $server): JsonResponse
{ {
$this->fileRepository $this->fileRepository
->setServer($server) ->setServer($server)
@ -173,11 +173,11 @@ class FileController extends ClientApiController
* @param \Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
public function renameFile(RenameFileRequest $request, Server $server): JsonResponse public function rename(RenameFileRequest $request, Server $server): JsonResponse
{ {
$this->fileRepository $this->fileRepository
->setServer($server) ->setServer($server)
->renameFile($request->input('rename_from'), $request->input('rename_to')); ->renameFiles($request->input('root'), $request->input('files'));
return new JsonResponse([], Response::HTTP_NO_CONTENT); return new JsonResponse([], Response::HTTP_NO_CONTENT);
} }
@ -189,7 +189,7 @@ class FileController extends ClientApiController
* @param \Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
public function copyFile(CopyFileRequest $request, Server $server): JsonResponse public function copy(CopyFileRequest $request, Server $server): JsonResponse
{ {
$this->fileRepository $this->fileRepository
->setServer($server) ->setServer($server)
@ -203,7 +203,7 @@ class FileController extends ClientApiController
* @param \Pterodactyl\Models\Server $server * @param \Pterodactyl\Models\Server $server
* @return array * @return array
*/ */
public function compressFiles(CompressFilesRequest $request, Server $server): array public function compress(CompressFilesRequest $request, Server $server): array
{ {
$file = $this->fileRepository->setServer($server) $file = $this->fileRepository->setServer($server)
->compressFiles( ->compressFiles(

View file

@ -25,8 +25,11 @@ class RenameFileRequest extends ClientApiRequest implements ClientPermissionsReq
public function rules(): array public function rules(): array
{ {
return [ return [
'rename_from' => 'string|required', 'root' => 'required|nullable|string',
'rename_to' => 'string|required', 'files' => 'required|array',
'files.*' => 'array',
'files.*.to' => 'required|string',
'files.*.from' => 'required|string',
]; ];
} }
} }

View file

@ -109,11 +109,11 @@ class DaemonFileRepository extends DaemonRepository
/** /**
* Renames or moves a file on the remote machine. * Renames or moves a file on the remote machine.
* *
* @param string $from * @param string|null $root
* @param string $to * @param array $files
* @return \Psr\Http\Message\ResponseInterface * @return \Psr\Http\Message\ResponseInterface
*/ */
public function renameFile(string $from, string $to): ResponseInterface public function renameFiles(?string $root, array $files): ResponseInterface
{ {
Assert::isInstanceOf($this->server, Server::class); Assert::isInstanceOf($this->server, Server::class);
@ -121,8 +121,8 @@ class DaemonFileRepository extends DaemonRepository
sprintf('/api/servers/%s/files/rename', $this->server->uuid), sprintf('/api/servers/%s/files/rename', $this->server->uuid),
[ [
'json' => [ 'json' => [
'rename_from' => urldecode($from), 'root' => $root ?? '/',
'rename_to' => urldecode($to), 'files' => $files,
], ],
] ]
); );
@ -163,7 +163,7 @@ class DaemonFileRepository extends DaemonRepository
sprintf('/api/servers/%s/files/delete', $this->server->uuid), sprintf('/api/servers/%s/files/delete', $this->server->uuid),
[ [
'json' => [ 'json' => [
'root' => $root, 'root' => $root ?? '/',
'files' => $files, 'files' => $files,
], ],
] ]

View file

@ -5,11 +5,11 @@ interface Data {
renameTo: string; renameTo: string;
} }
export default (uuid: string, { renameFrom, renameTo }: Data): Promise<void> => { export default (uuid: string, directory: string, files: Data[]): Promise<void> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
http.put(`/api/client/servers/${uuid}/files/rename`, { http.put(`/api/client/servers/${uuid}/files/rename`, {
rename_from: renameFrom, root: directory,
rename_to: renameTo, files: files.map(f => ({ from: f.renameFrom, to: f.renameTo })),
}) })
.then(() => resolve()) .then(() => resolve())
.catch(reject); .catch(reject);

View file

@ -3,7 +3,7 @@ import Modal, { RequiredModalProps } from '@/components/elements/Modal';
import { Form, Formik, FormikHelpers } from 'formik'; import { Form, Formik, FormikHelpers } from 'formik';
import Field from '@/components/elements/Field'; import Field from '@/components/elements/Field';
import { join } from 'path'; import { join } from 'path';
import renameFile from '@/api/server/files/renameFile'; import renameFiles from '@/api/server/files/renameFiles';
import { ServerContext } from '@/state/server'; import { ServerContext } from '@/state/server';
import { FileObject } from '@/api/server/files/loadDirectory'; import { FileObject } from '@/api/server/files/loadDirectory';
import tw from 'twin.macro'; import tw from 'twin.macro';
@ -21,10 +21,12 @@ type Props = RequiredModalProps & { file: FileObject; useMoveTerminology?: boole
export default ({ file, useMoveTerminology, ...props }: Props) => { export default ({ file, useMoveTerminology, ...props }: Props) => {
const { uuid } = useServer(); const { uuid } = useServer();
const { mutate } = useFileManagerSwr(); const { mutate } = useFileManagerSwr();
const { clearAndAddHttpError } = useFlash(); const { clearFlashes, clearAndAddHttpError } = useFlash();
const directory = ServerContext.useStoreState(state => state.files.directory); const directory = ServerContext.useStoreState(state => state.files.directory);
const submit = ({ name }: FormikValues, { setSubmitting }: FormikHelpers<FormikValues>) => { const submit = ({ name }: FormikValues, { setSubmitting }: FormikHelpers<FormikValues>) => {
clearFlashes('files');
const len = name.split('/').length; const len = name.split('/').length;
if (!useMoveTerminology && len === 1) { if (!useMoveTerminology && len === 1) {
// Rename the file within this directory. // Rename the file within this directory.
@ -36,7 +38,8 @@ export default ({ file, useMoveTerminology, ...props }: Props) => {
const renameFrom = join(directory, file.name); const renameFrom = join(directory, file.name);
const renameTo = join(directory, name); const renameTo = join(directory, name);
renameFile(uuid, { renameFrom, renameTo })
renameFiles(uuid, directory, [ { renameFrom, renameTo } ])
.then(() => props.onDismissed()) .then(() => props.onDismissed())
.catch(error => { .catch(error => {
mutate(); mutate();

View file

@ -53,15 +53,15 @@ Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateServ
}); });
Route::group(['prefix' => '/files'], function () { Route::group(['prefix' => '/files'], function () {
Route::get('/list', 'Servers\FileController@listDirectory'); Route::get('/list', 'Servers\FileController@directory');
Route::get('/contents', 'Servers\FileController@getFileContents'); Route::get('/contents', 'Servers\FileController@contents');
Route::get('/download', 'Servers\FileController@download'); Route::get('/download', 'Servers\FileController@download');
Route::put('/rename', 'Servers\FileController@renameFile'); Route::put('/rename', 'Servers\FileController@rename');
Route::post('/copy', 'Servers\FileController@copyFile'); Route::post('/copy', 'Servers\FileController@copy');
Route::post('/write', 'Servers\FileController@writeFileContents'); Route::post('/write', 'Servers\FileController@write');
Route::post('/compress', 'Servers\FileController@compressFiles'); Route::post('/compress', 'Servers\FileController@compress');
Route::post('/delete', 'Servers\FileController@delete'); Route::post('/delete', 'Servers\FileController@delete');
Route::post('/create-folder', 'Servers\FileController@createFolder'); Route::post('/create-folder', 'Servers\FileController@create');
}); });
Route::group(['prefix' => '/schedules'], function () { Route::group(['prefix' => '/schedules'], function () {