Update support for moving/renaming files and folders
This commit is contained in:
parent
eed4be49ab
commit
811026895b
9 changed files with 97 additions and 41 deletions
|
@ -56,4 +56,13 @@ interface FileRepositoryInterface extends BaseRepositoryInterface
|
||||||
* @return \Psr\Http\Message\ResponseInterface
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
*/
|
*/
|
||||||
public function createDirectory(string $name, string $path): ResponseInterface;
|
public function createDirectory(string $name, string $path): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames or moves a file on the remote machine.
|
||||||
|
*
|
||||||
|
* @param string $from
|
||||||
|
* @param string $to
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function renameFile(string $from, string $to): ResponseInterface;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ use Illuminate\Contracts\Cache\Repository as CacheRepository;
|
||||||
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
|
||||||
use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\ListFilesRequest;
|
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\ListFilesRequest;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\RenameFileRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CreateFolderRequest;
|
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\CreateFolderRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\DownloadFileRequest;
|
use Pterodactyl\Http\Requests\Api\Client\Servers\Files\DownloadFileRequest;
|
||||||
|
|
||||||
|
@ -67,7 +68,22 @@ class FileController extends ClientApiController
|
||||||
->setServer($request->getModel(Server::class))
|
->setServer($request->getModel(Server::class))
|
||||||
->createDirectory($request->input('name'), $request->input('directory', '/'));
|
->createDirectory($request->input('name'), $request->input('directory', '/'));
|
||||||
|
|
||||||
return Response::create('s');
|
return Response::create('', Response::HTTP_NO_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames a file on the remote machine.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\Files\RenameFileRequest $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function renameFile(RenameFileRequest $request): Response
|
||||||
|
{
|
||||||
|
$this->fileRepository
|
||||||
|
->setServer($request->getModel(Server::class))
|
||||||
|
->renameFile($request->input('rename_from'), $request->input('rename_to'));
|
||||||
|
|
||||||
|
return Response::create('', Response::HTTP_NO_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Api\Client\Servers\Files;
|
||||||
|
|
||||||
|
use Pterodactyl\Contracts\Http\ClientPermissionsRequest;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
|
||||||
|
|
||||||
|
class RenameFileRequest extends ClientApiRequest implements ClientPermissionsRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The permission the user is required to have in order to perform this
|
||||||
|
* request action.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function permission(): string
|
||||||
|
{
|
||||||
|
return 'move-files';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'rename_from' => 'string|required',
|
||||||
|
'rename_to' => 'string|required',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,8 +59,8 @@ class FileRepository extends BaseWingsRepository implements FileRepositoryInterf
|
||||||
public function getDirectory(string $path): array
|
public function getDirectory(string $path): array
|
||||||
{
|
{
|
||||||
$response = $this->getHttpClient()->get(
|
$response = $this->getHttpClient()->get(
|
||||||
// Reason for the path check is because it is unnecessary on the Daemon but we need
|
// Reason for the path check is because it is unnecessary on the Daemon but we need
|
||||||
// to respect the interface.
|
// to respect the interface.
|
||||||
sprintf('/api/servers/%s/files/list/%s', $this->getServer()->uuid, $path === '/' ? '' : $path)
|
sprintf('/api/servers/%s/files/list/%s', $this->getServer()->uuid, $path === '/' ? '' : $path)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -86,4 +86,24 @@ class FileRepository extends BaseWingsRepository implements FileRepositoryInterf
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames or moves a file on the remote machine.
|
||||||
|
*
|
||||||
|
* @param string $from
|
||||||
|
* @param string $to
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function renameFile(string $from, string $to): ResponseInterface
|
||||||
|
{
|
||||||
|
return $this->getHttpClient()->put(
|
||||||
|
sprintf('/api/servers/%s/files/rename', $this->getServer()->uuid),
|
||||||
|
[
|
||||||
|
'json' => [
|
||||||
|
'rename_from' => $from,
|
||||||
|
'rename_to' => $to,
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import {withCredentials} from "@/api/http";
|
|
||||||
import {ServerApplicationCredentials} from "@/store/types";
|
|
||||||
import { join } from 'path';
|
|
||||||
|
|
||||||
type RenameObject = {
|
|
||||||
path: string,
|
|
||||||
fromName: string,
|
|
||||||
toName: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renames a file or folder on the server using the node.
|
|
||||||
*/
|
|
||||||
export function renameElement(server: string, credentials: ServerApplicationCredentials, data: RenameObject): Promise<void> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
withCredentials(server, credentials).post('/v1/server/file/rename', {
|
|
||||||
from: join(data.path, data.fromName),
|
|
||||||
to: join(data.path, data.toName),
|
|
||||||
})
|
|
||||||
.then(() => resolve())
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
}
|
|
12
resources/assets/scripts/api/server/files/renameFile.ts
Normal file
12
resources/assets/scripts/api/server/files/renameFile.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import http from "@/api/http";
|
||||||
|
|
||||||
|
export function renameFile(server: string, renameFrom: string, renameTo: string): Promise<void> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
http.put(`/api/client/servers/${server}/files/rename`, {
|
||||||
|
rename_from: renameFrom,
|
||||||
|
rename_to: renameTo,
|
||||||
|
})
|
||||||
|
.then(() => resolve())
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
}
|
|
@ -42,7 +42,7 @@
|
||||||
import Modal from "@/components/core/Modal.vue";
|
import Modal from "@/components/core/Modal.vue";
|
||||||
import MessageBox from "@/components/MessageBox.vue";
|
import MessageBox from "@/components/MessageBox.vue";
|
||||||
import {DirectoryContentObject} from "@/api/server/types";
|
import {DirectoryContentObject} from "@/api/server/types";
|
||||||
import {moveElement} from '@/api/server/files/copyElement';
|
import {renameFile} from '@/api/server/files/renameFile';
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
import {ApplicationState} from "@/store/types";
|
import {ApplicationState} from "@/store/types";
|
||||||
import {join} from 'path';
|
import {join} from 'path';
|
||||||
|
@ -106,12 +106,7 @@
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
moveElement(this.server.uuid, this.credentials, {
|
renameFile(this.server.uuid, join(this.fm.currentDirectory, this.file.name), join(this.fm.currentDirectory, this.moveTo))
|
||||||
// @ts-ignore
|
|
||||||
currentPath: join(this.fm.currentDirectory, this.file.name),
|
|
||||||
// @ts-ignore
|
|
||||||
newPath: join(this.fm.currentDirectory, this.moveTo),
|
|
||||||
})
|
|
||||||
.then(() => this.$emit('moved'))
|
.then(() => this.$emit('moved'))
|
||||||
.catch((error: AxiosError) => {
|
.catch((error: AxiosError) => {
|
||||||
this.error = `There was an error moving the requested ${(this.file.directory) ? 'folder' : 'file'}. Response was: ${error.message}`;
|
this.error = `There was an error moving the requested ${(this.file.directory) ? 'folder' : 'file'}. Response was: ${error.message}`;
|
||||||
|
|
|
@ -47,9 +47,10 @@
|
||||||
import MessageBox from '@/components/MessageBox.vue';
|
import MessageBox from '@/components/MessageBox.vue';
|
||||||
import {DirectoryContentObject} from "@/api/server/types";
|
import {DirectoryContentObject} from "@/api/server/types";
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
import {renameElement} from "@/api/server/files/renameElement";
|
import {renameFile} from "@/api/server/files/renameFile";
|
||||||
import {AxiosError} from 'axios';
|
import {AxiosError} from 'axios';
|
||||||
import {ApplicationState} from "@/store/types";
|
import {ApplicationState} from "@/store/types";
|
||||||
|
import {join} from "path";
|
||||||
|
|
||||||
type DataStructure = {
|
type DataStructure = {
|
||||||
error: null | string,
|
error: null | string,
|
||||||
|
@ -109,12 +110,7 @@
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
renameElement(this.server.uuid, this.credentials, {
|
renameFile(this.server.uuid, join(this.fm.currentDirectory, this.object.name), join(this.fm.currentDirectory, this.newName))
|
||||||
// @ts-ignore
|
|
||||||
path: this.fm.currentDirectory,
|
|
||||||
toName: this.newName,
|
|
||||||
fromName: this.object.name
|
|
||||||
})
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$emit('renamed', this.newName);
|
this.$emit('renamed', this.newName);
|
||||||
this.closeModal();
|
this.closeModal();
|
||||||
|
|
|
@ -43,7 +43,7 @@ Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateServ
|
||||||
|
|
||||||
Route::group(['prefix' => '/files'], function () {
|
Route::group(['prefix' => '/files'], function () {
|
||||||
Route::get('/list', 'Servers\FileController@listDirectory')->name('api.client.servers.files.list');
|
Route::get('/list', 'Servers\FileController@listDirectory')->name('api.client.servers.files.list');
|
||||||
|
Route::put('/rename', 'Servers\FileController@renameFile')->name('api.client.servers.files.rename');
|
||||||
Route::post('/create-folder', 'Servers\FileController@createFolder')->name('api.client.servers.files.create-folder');
|
Route::post('/create-folder', 'Servers\FileController@createFolder')->name('api.client.servers.files.create-folder');
|
||||||
|
|
||||||
Route::post('/download/{file}', 'Servers\FileController@download')
|
Route::post('/download/{file}', 'Servers\FileController@download')
|
||||||
|
|
Loading…
Reference in a new issue