Fix up most of the file manager

This commit is contained in:
Dane Everitt 2017-01-19 16:58:57 -05:00
parent 042c28ca43
commit 83c776fc82
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
17 changed files with 1261 additions and 6 deletions

View file

@ -0,0 +1,73 @@
// Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
$(document).ready(function () {
$('.server-files').addClass('active');
const Editor = ace.edit('editor');
const Modelist = ace.require('ace/ext/modelist')
Editor.setTheme('ace/theme/chrome');
Editor.getSession().setMode(Modelist.getModeForPath(Pterodactyl.stat.name).mode);
Editor.getSession().setUseWrapMode(true);
Editor.setShowPrintMargin(false);
Editor.commands.addCommand({
name: 'save',
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
exec: function(editor) {
save();
},
readOnly: false
});
$('#save_file').on('click', function (e) {
e.preventDefault();
save();
});
function save() {
var fileName = $('input[name="file"]').val();
$('#save_file').html('<i class="fa fw-fw fa-spinner fa-spin"></i> Saving File').addClass('disabled');
$.ajax({
type: 'POST',
url: Router.route('server.files.save', { server: Pterodactyl.server.uuidShort }),
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
},
data: {
file: fileName,
contents: Editor.getValue()
}
}).done(function (data) {
$.notify({
message: 'File was successfully saved.'
}, {
type: 'success'
});
}).fail(function (jqXHR) {
$.notify({
message: jqXHR.responseText
}, {
type: 'danger'
});
}).always(function () {
$('#save_file').html('<i class="fa fa-fw fa-save"></i> &nbsp;Save File').removeClass('disabled');
});
}
});

View file

@ -0,0 +1,2 @@
//# sourceMappingURL=filemanager.min.js.map

View file

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"filemanager.min.js"}

View file

@ -0,0 +1,394 @@
"use strict";
// Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
class ActionsClass {
constructor(element, menu) {
this.element = element;
this.menu = menu;
}
destroy() {
this.element = undefined;
}
folder() {
const nameBlock = $(this.element).find('td[data-identifier="name"]');
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
const currentPath = decodeURIComponent(nameBlock.data('path'));
let inputValue = `${currentPath}${currentName}/`;
if ($(this.element).data('type') === 'file') {
inputValue = currentPath;
}
swal({
type: 'input',
title: 'Create Folder',
text: 'Please enter the path and folder name below.',
showCancelButton: true,
showConfirmButton: true,
closeOnConfirm: false,
showLoaderOnConfirm: true,
inputValue: inputValue
}, (val) => {
$.ajax({
type: 'POST',
headers: {
'X-Access-Token': Pterodactyl.server.daemonSecret,
'X-Access-Server': Pterodactyl.server.uuid,
},
contentType: 'application/json; charset=utf-8',
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/folder`,
timeout: 10000,
data: JSON.stringify({
path: val,
}),
}).done(data => {
swal.close();
Files.list();
}).fail(jqXHR => {
console.error(jqXHR);
var error = 'An error occured while trying to process this request.';
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
error = jqXHR.responseJSON.error;
}
swal({
type: 'error',
title: '',
text: error,
});
});
});
}
move() {
const nameBlock = $(this.element).find('td[data-identifier="name"]');
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
const currentPath = decodeURIComponent(nameBlock.data('path'));
swal({
type: 'input',
title: 'Move File',
text: 'Please enter the new path for the file below.',
showCancelButton: true,
showConfirmButton: true,
closeOnConfirm: false,
showLoaderOnConfirm: true,
inputValue: `${currentPath}${currentName}`,
}, (val) => {
$.ajax({
type: 'POST',
headers: {
'X-Access-Token': Pterodactyl.server.daemonSecret,
'X-Access-Server': Pterodactyl.server.uuid,
},
contentType: 'application/json; charset=utf-8',
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/move`,
timeout: 10000,
data: JSON.stringify({
from: `${currentPath}${currentName}`,
to: `${val}`,
}),
}).done(data => {
nameBlock.parent().addClass('warning').delay(200).fadeOut();
swal.close();
}).fail(jqXHR => {
console.error(jqXHR);
var error = 'An error occured while trying to process this request.';
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
error = jqXHR.responseJSON.error;
}
swal({
type: 'error',
title: '',
text: error,
});
});
});
}
rename() {
const nameBlock = $(this.element).find('td[data-identifier="name"]');
const currentLink = nameBlock.find('a');
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
const attachEditor = `
<input class="form-control input-sm" type="text" value="${currentName}" />
<span class="input-loader"><i class="fa fa-refresh fa-spin fa-fw"></i></span>
`;
nameBlock.html(attachEditor);
const inputField = nameBlock.find('input');
const inputLoader = nameBlock.find('.input-loader');
inputField.focus();
inputField.on('blur keydown', e => {
// Save Field
if (
(e.type === 'keydown' && e.which === 27)
|| e.type === 'blur'
|| (e.type === 'keydown' && e.which === 13 && currentName === inputField.val())
) {
if (!_.isEmpty(currentLink)) {
nameBlock.html(currentLink);
} else {
nameBlock.html(currentName);
}
inputField.remove();
ContextMenu.unbind().run();
return;
}
if (e.type === 'keydown' && e.which !== 13) return;
inputLoader.show();
const currentPath = decodeURIComponent(nameBlock.data('path'));
$.ajax({
type: 'POST',
headers: {
'X-Access-Token': Pterodactyl.server.daemonSecret,
'X-Access-Server': Pterodactyl.server.uuid,
},
contentType: 'application/json; charset=utf-8',
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/rename`,
timeout: 10000,
data: JSON.stringify({
from: `${currentPath}${currentName}`,
to: `${currentPath}${inputField.val()}`,
}),
}).done(data => {
nameBlock.attr('data-name', inputField.val());
if (!_.isEmpty(currentLink)) {
let newLink = currentLink.attr('href');
if (nameBlock.parent().data('type') !== 'folder') {
newLink = newLink.substr(0, newLink.lastIndexOf('/')) + '/' + inputField.val();
}
currentLink.attr('href', newLink);
nameBlock.html(
currentLink.html(inputField.val())
);
} else {
nameBlock.html(inputField.val());
}
inputField.remove();
}).fail(jqXHR => {
console.error(jqXHR);
var error = 'An error occured while trying to process this request.';
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
error = jqXHR.responseJSON.error;
}
nameBlock.addClass('has-error').delay(2000).queue(() => {
nameBlock.removeClass('has-error').dequeue();
});
inputField.popover({
animation: true,
placement: 'top',
content: error,
title: 'Save Error'
}).popover('show');
}).always(() => {
inputLoader.remove();
ContextMenu.unbind().run();
});
});
}
copy() {
const nameBlock = $(this.element).find('td[data-identifier="name"]');
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
const currentPath = decodeURIComponent(nameBlock.data('path'));
swal({
type: 'input',
title: 'Copy File',
text: 'Please enter the new path for the copied file below.',
showCancelButton: true,
showConfirmButton: true,
closeOnConfirm: false,
showLoaderOnConfirm: true,
inputValue: `${currentPath}${currentName}`,
}, (val) => {
$.ajax({
type: 'POST',
headers: {
'X-Access-Token': Pterodactyl.server.daemonSecret,
'X-Access-Server': Pterodactyl.server.uuid,
},
contentType: 'application/json; charset=utf-8',
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/copy`,
timeout: 10000,
data: JSON.stringify({
from: `${currentPath}${currentName}`,
to: `${val}`,
}),
}).done(data => {
swal({
type: 'success',
title: '',
text: 'File successfully copied.'
});
Files.list();
}).fail(jqXHR => {
console.error(jqXHR);
var error = 'An error occured while trying to process this request.';
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
error = jqXHR.responseJSON.error;
}
swal({
type: 'error',
title: '',
text: error,
});
});
});
}
download() {
const nameBlock = $(this.element).find('td[data-identifier="name"]');
const fileName = decodeURIComponent(nameBlock.attr('data-name'));
const filePath = decodeURIComponent(nameBlock.data('path'));
window.location = `/server/${Pterodactyl.server.uuidShort}/files/download/${filePath}${fileName}`;
}
delete() {
const nameBlock = $(this.element).find('td[data-identifier="name"]');
const delPath = decodeURIComponent(nameBlock.data('path'));
const delName = decodeURIComponent(nameBlock.data('name'));
swal({
type: 'warning',
title: '',
text: 'Are you sure you want to delete <code>' + delName + '</code>? There is <strong>no</strong> reversing this action.',
html: true,
showCancelButton: true,
showConfirmButton: true,
closeOnConfirm: false,
showLoaderOnConfirm: true
}, () => {
$.ajax({
type: 'DELETE',
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/f/${delPath}${delName}`,
headers: {
'X-Access-Token': Pterodactyl.server.daemonSecret,
'X-Access-Server': Pterodactyl.server.uuid,
}
}).done(data => {
nameBlock.parent().addClass('warning').delay(200).fadeOut();
swal({
type: 'success',
title: 'File Deleted'
});
}).fail(jqXHR => {
console.error(jqXHR);
swal({
type: 'error',
title: 'Whoops!',
html: true,
text: 'An error occured while attempting to delete this file. Please try again.',
});
});
});
}
decompress() {
const nameBlock = $(this.element).find('td[data-identifier="name"]');
const compPath = decodeURIComponent(nameBlock.data('path'));
const compName = decodeURIComponent(nameBlock.data('name'));
swal({
title: '<i class="fa fa-refresh fa-spin"></i> Decompressing...',
text: 'This might take a few seconds to complete.',
html: true,
allowOutsideClick: false,
allowEscapeKey: false,
showConfirmButton: false,
});
$.ajax({
type: 'POST',
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/decompress`,
headers: {
'X-Access-Token': Pterodactyl.server.daemonSecret,
'X-Access-Server': Pterodactyl.server.uuid,
},
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
files: `${compPath}${compName}`
})
}).done(data => {
swal.close();
Files.list(compPath);
}).fail(jqXHR => {
console.error(jqXHR);
var error = 'An error occured while trying to process this request.';
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
error = jqXHR.responseJSON.error;
}
swal({
type: 'error',
title: 'Whoops!',
html: true,
text: error
});
});
}
compress() {
const nameBlock = $(this.element).find('td[data-identifier="name"]');
const compPath = decodeURIComponent(nameBlock.data('path'));
const compName = decodeURIComponent(nameBlock.data('name'));
$.ajax({
type: 'POST',
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/server/file/compress`,
headers: {
'X-Access-Token': Pterodactyl.server.daemonSecret,
'X-Access-Server': Pterodactyl.server.uuid,
},
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
files: `${compPath}${compName}`,
to: compPath.toString()
})
}).done(data => {
Files.list(compPath, err => {
if (err) return;
const fileListing = $('#file_listing').find(`[data-name="${data.saved_as}"]`).parent();
fileListing.addClass('success pulsate').delay(3000).queue(() => {
fileListing.removeClass('success pulsate').dequeue();
});
});
}).fail(jqXHR => {
console.error(jqXHR);
var error = 'An error occured while trying to process this request.';
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
error = jqXHR.responseJSON.error;
}
swal({
type: 'error',
title: 'Whoops!',
html: true,
text: error
});
});
}
}

View file

@ -0,0 +1,195 @@
"use strict";
// Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
class ContextMenuClass {
constructor() {
this.activeLine = null;
}
run() {
this.directoryClick();
this.rightClick();
}
makeMenu(parent) {
$(document).find('#fileOptionMenu').remove();
if (!_.isNull(this.activeLine)) this.activeLine.removeClass('active');
let newFilePath = $('#headerTableRow').attr('data-currentDir');
if (parent.data('type') === 'folder') {
const nameBlock = parent.find('td[data-identifier="name"]');
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
const currentPath = decodeURIComponent(nameBlock.data('path'));
newFilePath = `${currentPath}${currentName}`;
}
let buildMenu = '<ul id="fileOptionMenu" class="dropdown-menu" role="menu" style="display:none" >';
if (Pterodactyl.permissions.moveFiles) {
buildMenu += '<li data-action="rename"><a tabindex="-1" href="#"><i class="fa fa-fw fa-pencil-square-o"></i> Rename</a></li> \
<li data-action="move"><a tabindex="-1" href="#"><i class="fa fa-fw fa-arrow-right"></i> Move</a></li>';
}
if (Pterodactyl.permissions.copyFiles) {
buildMenu += '<li data-action="copy"><a tabindex="-1" href="#"><i class="fa fa-fw fa-clone"></i> Copy</a></li>';
}
if (Pterodactyl.permissions.compressFiles) {
buildMenu += '<li data-action="compress" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-fw fa-file-archive-o"></i> Compress</a></li>';
}
if (Pterodactyl.permissions.decompressFiles) {
buildMenu += '<li data-action="decompress" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-fw fa-expand"></i> Decompress</a></li>';
}
if (Pterodactyl.permissions.createFiles) {
buildMenu += '<li class="divider"></li> \
<li data-action="file"><a href="/server/'+ Pterodactyl.server.uuidShort +'/files/add/?dir=' + newFilePath + '" class="text-muted"><i class="fa fa-fw fa-plus"></i> New File</a></li> \
<li data-action="folder"><a tabindex="-1" href="#"><i class="fa fa-fw fa-folder"></i> New Folder</a></li>';
}
if (Pterodactyl.permissions.downloadFiles || Pterodactyl.permissions.deleteFiles) {
buildMenu += '<li class="divider"></li>';
}
if (Pterodactyl.permissions.downloadFiles) {
buildMenu += '<li data-action="download" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-fw fa-download"></i> Download</a></li>';
}
if (Pterodactyl.permissions.deleteFiles) {
buildMenu += '<li data-action="delete" class="bg-danger"><a tabindex="-1" href="#"><i class="fa fa-fw fa-trash-o"></i> Delete</a></li>';
}
buildMenu += '</ul>';
return buildMenu;
}
rightClick() {
$('[data-action="toggleMenu"]').on('mousedown', () => {
event.preventDefault();
this.showMenu(event);
});
$('#file_listing > tbody td').on('contextmenu', event => {
this.showMenu(event);
});
}
showMenu(event) {
const parent = $(event.target).closest('tr');
const menu = $(this.makeMenu(parent));
if (parent.data('type') === 'disabled') return;
event.preventDefault();
$(menu).appendTo('body');
$(menu).data('invokedOn', $(event.target)).show().css({
position: 'absolute',
left: event.pageX - 150,
top: event.pageY,
});
this.activeLine = parent;
this.activeLine.addClass('active');
// Handle Events
const Actions = new ActionsClass(parent, menu);
if (Pterodactyl.permissions.moveFiles) {
$(menu).find('li[data-action="move"]').unbind().on('click', e => {
e.preventDefault();
Actions.move();
});
$(menu).find('li[data-action="rename"]').unbind().on('click', e => {
e.preventDefault();
Actions.rename();
});
}
if (Pterodactyl.permissions.copyFiles) {
$(menu).find('li[data-action="copy"]').unbind().on('click', e => {
e.preventDefault();
Actions.copy();
});
}
if (Pterodactyl.permissions.compressFiles) {
if (parent.data('type') === 'folder') {
$(menu).find('li[data-action="compress"]').removeClass('hidden');
}
$(menu).find('li[data-action="compress"]').unbind().on('click', e => {
e.preventDefault();
Actions.compress();
});
}
if (Pterodactyl.permissions.decompressFiles) {
if (_.without(['application/zip', 'application/gzip', 'application/x-gzip'], parent.data('mime')).length < 3) {
$(menu).find('li[data-action="decompress"]').removeClass('hidden');
}
$(menu).find('li[data-action="decompress"]').unbind().on('click', e => {
e.preventDefault();
Actions.decompress();
});
}
if (Pterodactyl.permissions.createFiles) {
$(menu).find('li[data-action="folder"]').unbind().on('click', e => {
e.preventDefault();
Actions.folder();
});
}
if (Pterodactyl.permissions.downloadFiles) {
if (parent.data('type') === 'file') {
$(menu).find('li[data-action="download"]').removeClass('hidden');
}
$(menu).find('li[data-action="download"]').unbind().on('click', e => {
e.preventDefault();
Actions.download();
});
}
if (Pterodactyl.permissions.deleteFiles) {
$(menu).find('li[data-action="delete"]').unbind().on('click', e => {
e.preventDefault();
Actions.delete();
});
}
$(window).on('click', () => {
$(menu).remove();
if(!_.isNull(this.activeLine)) this.activeLine.removeClass('active');
});
}
directoryClick() {
$('a[data-action="directory-view"]').on('click', function (event) {
event.preventDefault();
const path = $(this).parent().data('path') || '';
const name = $(this).parent().data('name') || '';
window.location.hash = encodeURIComponent(path + name);
Files.list();
});
}
}
window.ContextMenu = new ContextMenuClass;

View file

@ -0,0 +1,87 @@
"use strict";
// Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
class FileManager {
constructor() {
this.list(this.decodeHash());
}
list(path, next) {
if (_.isUndefined(path)) {
path = this.decodeHash();
}
this.loader(true);
$.ajax({
type: 'POST',
url: Pterodactyl.meta.directoryList,
headers: {
'X-CSRF-Token': Pterodactyl.meta.csrftoken,
},
data: {
directory: path,
},
}).done(data => {
this.loader(false);
$('#load_files').slideUp(10).html(data).slideDown(10, () => {
ContextMenu.run();
this.reloadFilesButton();
if (_.isFunction(next)) {
return next();
}
});
$('#internal_alert').slideUp();
}).fail(jqXHR => {
this.loader(false);
if (_.isFunction(next)) {
return next(new Error('Failed to load file listing.'));
}
swal({
type: 'error',
title: 'File Error',
text: 'An error occured while attempting to process this request. Please try again.',
});
console.error(jqXHR);
});
}
loader(show) {
if (show){
$('.file-overlay').fadeIn(100);
} else {
$('.file-overlay').fadeOut(100);
}
}
reloadFilesButton() {
$('i[data-action="reload-files"]').unbind().on('click', () => {
$('i[data-action="reload-files"]').addClass('fa-spin');
this.list();
});
}
decodeHash() {
return decodeURIComponent(window.location.hash.substring(1));
}
}
window.Files = new FileManager;

View file

@ -0,0 +1,129 @@
// Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
(function initUploader() {
var notifyUploadSocketError = false;
uploadSocket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/upload/' + Pterodactyl.server.uuid, {
'query': 'token=' + Pterodactyl.server.daemonSecret,
});
uploadSocket.io.on('connect_error', function (err) {
if(typeof notifyUploadSocketError !== 'object') {
notifyUploadSocketError = $.notify({
message: 'There was an error attempting to establish a connection to the uploader endpoint.<br /><br />' + err,
}, {
type: 'danger',
delay: 0
});
}
});
uploadSocket.on('error', err => {
siofu.destroy();
console.error(err);
});
uploadSocket.on('connect', function () {
if (notifyUploadSocketError !== false) {
notifyUploadSocketError.close();
notifyUploadSocketError = false;
}
});
var siofu = new SocketIOFileUpload(uploadSocket);
siofu.listenOnDrop(document.getElementById("load_files"));
window.addEventListener('dragover', function (event) {
event.preventDefault();
}, false);
window.addEventListener('drop', function (event) {
event.preventDefault();
}, false);
var dropCounter = 0;
$('#load_files').bind({
dragenter: function (event) {
event.preventDefault();
dropCounter++;
$(this).addClass('hasFileHover');
},
dragleave: function (event) {
dropCounter--;
if (dropCounter === 0) {
$(this).removeClass('hasFileHover');
}
},
drop: function (event) {
dropCounter = 0;
$(this).removeClass('hasFileHover');
}
});
siofu.addEventListener('start', function (event) {
event.file.meta.path = $('#headerTableRow').attr('data-currentdir');
event.file.meta.identifier = Math.random().toString(36).slice(2);
$('#append_files_to').append('<tr id="file-upload-' + event.file.meta.identifier +'"> \
<td><i class="fa fa-file-text-o" style="margin-left: 2px;"></i></td> \
<td>' + event.file.name + '</td> \
<td colspan=2">&nbsp;</td> \
</tr><tr> \
<td colspan="4" class="has-progress"> \
<div class="progress progress-table-bottom active"> \
<div class="progress-bar progress-bar-info prog-bar-' + event.file.meta.identifier +'" style="width: 0%"></div> \
</div> \
</td> \
</tr>\
');
});
siofu.addEventListener('progress', function(event) {
var percent = event.bytesLoaded / event.file.size * 100;
if (percent >= 100) {
$('.prog-bar-' + event.file.meta.identifier).css('width', '100%').removeClass('progress-bar-info').addClass('progress-bar-success').parent().removeClass('active');
} else {
$('.prog-bar-' + event.file.meta.identifier).css('width', percent + '%');
}
});
// Do something when a file is uploaded:
siofu.addEventListener('complete', function(event){
if (!event.success) {
$('.prog-bar-' + event.file.meta.identifier).css('width', '100%').removeClass('progress-bar-info').addClass('progress-bar-danger');
$.notify({
message: 'An error was encountered while attempting to upload this file.'
}, {
type: 'danger',
delay: 5000
});
}
});
siofu.addEventListener('error', function(event){
console.error(event);
$('.prog-bar-' + event.file.meta.identifier).css('width', '100%').removeClass('progress-bar-info').addClass('progress-bar-danger');
$.notify({
message: 'An error was encountered while attempting to upload this file: <strong>' + event.message + '.</strong>',
}, {
type: 'danger',
delay: 8000
});
});
})();