Properly support backups in Directory format. Fixes #3309

This commit is contained in:
Khushboo Vashi 2018-06-29 15:14:37 +01:00 committed by Dave Page
parent c85ced4c6b
commit fb1ef9ac0b
15 changed files with 504 additions and 714 deletions

View File

@ -16,4 +16,4 @@ Features
Bug fixes
*********
| `Bug #???? <https://redmine.postgresql.org/issues/????>`_ - Fix foo!
| `Bug #3309 <https://redmine.postgresql.org/issues/3309>`_ - Fix Directory format support for backups.

View File

@ -0,0 +1,162 @@
import gettext from 'sources/gettext';
import url_for from 'sources/url_for';
import $ from 'jquery';
import Alertify from 'pgadmin.alertifyjs';
import pgAdmin from 'sources/pgadmin';
import {removeTransId, set_last_traversed_dir} from './helpers';
// Declare the Create mode dialog
module.exports = Alertify.dialog('createModeDlg', function() {
// Dialog property
return {
setup: function() {
return {
buttons: [{
text: gettext('Create'),
key: 13,
className: 'btn btn-primary fa fa-file file_manager_create file_manager_ok pg-alertify-button disabled',
},
{
text: gettext('Cancel'),
key: 27,
className: 'btn btn-danger fa fa-times file_manager_create_cancel pg-alertify-button',
},
],
focus: {
element: 0,
},
options: {
closableByDimmer: false,
maximizable: false,
closable: false,
movable: true,
},
};
},
replace_file: function() {
var $yesBtn = $('.replace_file .btn_yes'),
$noBtn = $('.replace_file .btn_no');
$('.storage_dialog #uploader .input-path').attr('disabled', true);
$('.file_manager_ok').addClass('disabled');
$('.replace_file, .fm_dimmer').show();
$yesBtn.on('click',() => {
$('.replace_file, .fm_dimmer').hide();
$yesBtn.off();
$noBtn.off();
var newFile = $('.storage_dialog #uploader .input-path').val();
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:create_file', newFile);
$('.file_manager_create_cancel').trigger('click');
$('.storage_dialog #uploader .input-path').attr('disabled', false);
$('.file_manager_ok').removeClass('disabled');
});
$noBtn.on('click',() => {
$('.replace_file, .fm_dimmer').hide();
$yesBtn.off();
$noBtn.off();
$('.storage_dialog #uploader .input-path').attr('disabled', false);
$('.file_manager_ok').removeClass('disabled');
});
},
is_file_exist: function() {
var full_path = $('.storage_dialog #uploader .input-path').val(),
path = full_path.substr(0, full_path.lastIndexOf('/') + 1),
selected_item = full_path.substr(full_path.lastIndexOf('/') + 1),
is_exist = false;
var file_data = {
'path': path,
'name': selected_item,
'mode': 'is_file_exist',
};
$.ajax({
type: 'POST',
data: JSON.stringify(file_data),
url: url_for('file_manager.filemanager', {
'trans_id': this.trans_id,
}),
dataType: 'json',
contentType: 'application/x-download; charset=utf-8',
async: false,
success: function(resp) {
var data = resp.data.result;
if (data['Code'] === 1) {
is_exist = true;
} else {
is_exist = false;
}
},
});
return is_exist;
},
check_permission: function(path) {
var permission = false,
post_data = {
'path': path,
'mode': 'permission',
};
$.ajax({
type: 'POST',
data: JSON.stringify(post_data),
url: url_for('file_manager.filemanager', {
'trans_id': this.trans_id,
}),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
async: false,
success: function(resp) {
var data = resp.data.result;
if (data.Code === 1) {
permission = true;
} else {
$('.file_manager_ok').addClass('disabled');
Alertify.error(data.Error);
}
},
error: function() {
$('.file_manager_ok').addClass('disabled');
Alertify.error(gettext('Error occurred while checking access permission.'));
},
});
return permission;
},
callback: function(closeEvent) {
if (closeEvent.button.text == gettext('Create')) {
var newFile = $('.storage_dialog #uploader .input-path').val(),
file_data = {
'path': $('.currentpath').val(),
},
innerbody;
if (!this.check_permission(newFile)) {
closeEvent.cancel = true;
return;
}
if (!_.isUndefined(newFile) && newFile !== '' && this.is_file_exist()) {
this.replace_file();
closeEvent.cancel = true;
} else {
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:create_file', newFile);
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(this.trans_id);
}
set_last_traversed_dir(file_data, this.trans_id);
} else if (closeEvent.button.text == gettext('Cancel')) {
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(this.trans_id);
pgAdmin.Browser.Events.trigger('pgadmin-storage:cancel_btn:create_file');
}
},
};
}, true, 'fileSelectionDlg');

View File

@ -1,3 +1,6 @@
import './select_dialogue';
import './create_dialogue';
define('misc.file_manager', [
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
'sources/pgadmin', 'pgadmin.alertifyjs',
@ -22,708 +25,13 @@ define('misc.file_manager', [
this.initialized = true;
// Send a request to get transaction id
var getTransId = function(configs) {
return $.ajax({
data: configs,
type: 'POST',
async: false,
url: url_for('file_manager.get_trans_id'),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
});
};
// Function to remove trans id from session
var removeTransId = function(trans_id) {
return $.ajax({
type: 'GET',
async: false,
url: url_for('file_manager.delete_trans_id', {
'trans_id': trans_id,
}),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
});
};
var set_last_traversed_dir = function(path, trans_id) {
return $.ajax({
url: url_for('file_manager.save_last_dir', {
'trans_id': trans_id,
}),
type: 'POST',
data: JSON.stringify(path),
contentType: 'application/json',
});
};
// Declare the Storage dialog
Alertify.dialog('storageManagerDlg', function() {
// Dialog containter
var $container = $('<div class=\'storage_dialog\'></div>'),
trans_id;
/*
* Function: renderStoragePanel
*
* Renders the FileManager in the content div based on the given
* configuration parameters.
*/
var renderStoragePanel = function(params) {
/*
* Clear the existing html in the storage content
*/
var content = $container.find('.storage_content');
content.empty();
$.get(url_for('file_manager.index'), function(data) {
content.append(data);
});
var transId = getTransId(params);
var t_res;
if (transId.readyState == 4) {
t_res = JSON.parse(transId.responseText);
}
trans_id = t_res.data.fileTransId;
};
// Dialog property
return {
main: function(params) {
// Set title and button name
var self = this;
if (_.isUndefined(params['dialog_title'])) {
params['dialog_title'] = 'Storage manager';
}
this.set('title', params['dialog_title']);
if (_.isUndefined(params['btn_primary'])) {
params['btn_primary'] = 'Select';
}
this.set('label', params['btn_primary']);
params = JSON.stringify(params);
$container.find('.storage_content').remove();
$container.append('<div class=\'storage_content\'></div>');
renderStoragePanel(params);
this.elements.dialog.style.minWidth = '630px';
this.show();
setTimeout(function() {
$($container.find('.file_manager')).on('enter-key', function() {
$($(self.elements.footer).find('.file_manager_ok')).trigger('click');
});
}, 200);
},
settings: {
label: undefined,
},
settingUpdated: function(key, oldValue, newValue) {
switch (key) {
case 'message':
this.setMessage(newValue);
break;
case 'label':
if (this.__internal.buttons[0].element) {
this.__internal.buttons[0].element.innerHTML = newValue;
}
break;
default:
break;
}
},
prepare: function() {
this.__internal.buttons[0].element.disabled = true;
},
setup: function() {
return {
buttons: [{
text: gettext('Select'),
className: 'btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled',
},
{
text: gettext('Cancel'),
className: 'btn btn-danger fa fa-times pg-alertify-button',
},
],
focus: {
element: 0,
},
options: {
closableByDimmer: false,
},
};
},
callback: function(closeEvent) {
var innerbody;
if (closeEvent.button.text == gettext('Select')) {
var newFile = $('.storage_dialog #uploader .input-path').val(),
file_data = {
'path': $('.currentpath').val(),
};
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:storage_dialog', newFile);
set_last_traversed_dir(file_data, trans_id);
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(trans_id);
} else if (closeEvent.button.text == gettext('Cancel')) {
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(trans_id);
pgAdmin.Browser.Events.trigger('pgadmin-storage:cancel_btn:storage_dialog');
}
},
build: function() {
this.elements.content.appendChild($container.get(0));
},
hooks: {
onshow: function() {
$(this.elements.body).addClass('pgadmin-storage-body');
},
},
};
});
// Declare the Selection dialog
Alertify.dialog('fileSelectionDlg', function() {
// Dialog containter
var $container =
$('<div class=\'storage_dialog file_selection_dlg\'></div>'),
trans_id;
// Send a request to get transaction id
/*
* Function: renderStoragePanel
*
* Renders the FileManager in the content div based on the given
* configuration parameters.
*/
var renderStoragePanel = function(configs) {
/*
* Clear the existing html in the storage content
*/
var content = $container.find('.storage_content');
content.empty();
$.get(url_for('file_manager.index'), function(data) {
content.append(data);
});
var transId = getTransId(configs);
var t_res;
if (transId.readyState == 4) {
t_res = JSON.parse(transId.responseText);
}
trans_id = t_res.data.fileTransId;
};
// Dialog property
return {
main: function(params) {
// Set title and button name
var self = this;
if (_.isUndefined(params['dialog_title'])) {
params['dialog_title'] = 'Select file';
}
this.set('title', params['dialog_title']);
if (_.isUndefined(params['btn_primary'])) {
params['btn_primary'] = 'Select';
}
this.set('label', params['btn_primary']);
params = JSON.stringify(params);
$container.find('.storage_content').remove();
$container.append('<div class=\'storage_content\'></div>');
renderStoragePanel(params);
this.elements.dialog.style.minWidth = '630px';
this.show();
setTimeout(function() {
$($container.find('.file_manager')).on('enter-key', function() {
$($(self.elements.footer).find('.file_manager_ok')).trigger('click');
});
}, 200);
},
settings: {
label: undefined,
},
settingUpdated: function(key, oldValue, newValue) {
switch (key) {
case 'message':
this.setMessage(newValue);
break;
case 'label':
if (this.__internal.buttons[0].element) {
this.__internal.buttons[0].element.innerHTML = newValue;
}
break;
default:
break;
}
},
prepare: function() {
this.__internal.buttons[0].element.disabled = true;
},
setup: function() {
return {
buttons: [{
text: gettext('Select'),
key: 13,
className: 'btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled',
},
{
text: gettext('Cancel'),
key: 27,
className: 'btn btn-danger fa fa-times pg-alertify-button',
},
],
focus: {
element: 0,
},
options: {
closableByDimmer: false,
maximizable: false,
closable: false,
movable: true,
},
};
},
callback: function(closeEvent) {
var innerbody;
if (closeEvent.button.text == gettext('Select')) {
var newFile = $('.storage_dialog #uploader .input-path').val(),
file_data = {
'path': $('.currentpath').val(),
};
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:select_file', newFile);
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(trans_id);
// Ajax call to store the last directory visited once user press select button
set_last_traversed_dir(file_data, trans_id);
} else if (closeEvent.button.text == gettext('Cancel')) {
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(trans_id);
pgAdmin.Browser.Events.trigger('pgadmin-storage:cancel_btn:select_file');
}
},
build: function() {
this.elements.content.appendChild($container.get(0));
},
hooks: {
onshow: function() {
$(this.elements.body).addClass('pgadmin-storage-body');
},
},
};
});
// Declare the Folder Selection dialog
Alertify.dialog('folderSelectionDlg', function() {
// Dialog containter
var $container =
$('<div class=\'storage_dialog folder_selection_dlg\'></div>'),
trans_id;
// send a request to get transaction id
/*
* Function: renderStoragePanel
*
* Renders the FileManager in the content div based on the given
* configuration parameters.
*/
var renderStoragePanel = function(params) {
/*
* Clear the existing html in the storage content
*/
var content = $container.find('.storage_content');
content.empty();
$.get(url_for('file_manager.index'), function(data) {
content.append(data);
});
var transId = getTransId(params);
var t_res;
if (transId.readyState == 4) {
t_res = JSON.parse(transId.responseText);
}
trans_id = t_res.data.fileTransId;
};
// Dialog property
return {
main: function(params) {
var self = this;
// Set title and button name
if (_.isUndefined(params['dialog_title'])) {
params['dialog_title'] = 'Select folder';
}
this.set('title', params['dialog_title']);
if (_.isUndefined(params['btn_primary'])) {
params['btn_primary'] = 'Select';
}
this.set('label', params['btn_primary']);
params = JSON.stringify(params);
$container.find('.storage_content').remove();
$container.append('<div class=\'storage_content\'></div>');
renderStoragePanel(params);
this.elements.dialog.style.minWidth = '630px';
this.show();
setTimeout(function() {
$($container.find('.file_manager')).on('enter-key', function() {
$($(self.elements.footer).find('.file_manager_ok')).trigger('click');
});
}, 200);
},
settings: {
label: undefined,
},
settingUpdated: function(key, oldValue, newValue) {
switch (key) {
case 'message':
this.setMessage(newValue);
break;
case 'label':
if (this.__internal.buttons[0].element) {
this.__internal.buttons[0].element.innerHTML = newValue;
}
break;
default:
break;
}
},
prepare: function() {
this.__internal.buttons[0].element.disabled = true;
},
setup: function() {
return {
buttons: [{
text: gettext('Select'),
key: 13,
className: 'btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled',
},
{
text: gettext('Cancel'),
key: 27,
className: 'btn btn-danger fa fa-times pg-alertify-button',
},
],
focus: {
element: 0,
},
options: {
closableByDimmer: false,
maximizable: false,
closable: false,
movable: true,
},
};
},
callback: function(closeEvent) {
var innerbody;
if (closeEvent.button.text == gettext('Select')) {
var newFile = $('.storage_dialog #uploader .input-path').val(),
file_data = {
'path': $('.currentpath').val(),
};
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:select_folder', newFile);
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(trans_id);
// Ajax call to store the last directory visited once user press select button
set_last_traversed_dir(file_data, trans_id);
} else if (closeEvent.button.text == gettext('Cancel')) {
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(trans_id);
pgAdmin.Browser.Events.trigger('pgadmin-storage:cancel_btn:select_folder');
}
},
build: function() {
this.elements.content.appendChild($container.get(0));
},
hooks: {
onshow: function() {
$(this.elements.body).addClass('pgadmin-storage-body');
},
},
};
});
// Declare the Create mode dialog
Alertify.dialog('createModeDlg', function() {
// Dialog containter
var $container =
$('<div class=\'storage_dialog create_mode_dlg\'></div>'),
trans_id;
/*
* Function: renderStoragePanel
*
* Renders the FileManager in the content div based on the given
* configuration parameters.
*/
var renderStoragePanel = function(params) {
/*
* Clear the existing html in the storage content
*/
var content = $container.find('.storage_content');
content.empty();
$.get(url_for('file_manager.index'), function(data) {
content.append(data);
});
var transId = getTransId(params);
var t_res;
if (transId.readyState == 4) {
t_res = JSON.parse(transId.responseText);
}
trans_id = t_res.data.fileTransId;
};
// Dialog property
return {
main: function(params) {
var self = this;
// Set title and button name
if (_.isUndefined(params['dialog_title'])) {
params['dialog_title'] = 'Create file';
}
this.set('title', params['dialog_title']);
if (_.isUndefined(params['btn_primary'])) {
params['btn_primary'] = 'Create';
}
this.set('label', params['btn_primary']);
params = JSON.stringify(params);
$container.find('.storage_content').remove();
$container.append('<div class=\'storage_content\'></div>');
renderStoragePanel(params);
this.elements.dialog.style.minWidth = '630px';
this.show();
setTimeout(function() {
$($container.find('.file_manager')).on('enter-key', function() {
$($(self.elements.footer).find('.file_manager_ok')).trigger('click');
});
}, 200);
},
settings: {
label: undefined,
},
settingUpdated: function(key, oldValue, newValue) {
switch (key) {
case 'message':
this.setMessage(newValue);
break;
case 'label':
if (this.__internal.buttons[0].element) {
this.__internal.buttons[0].element.innerHTML = newValue;
}
break;
default:
break;
}
},
prepare: function() {
this.__internal.buttons[0].element.disabled = true;
},
setup: function() {
return {
buttons: [{
text: gettext('Create'),
key: 13,
className: 'btn btn-primary fa fa-file file_manager_create file_manager_ok pg-alertify-button disabled',
},
{
text: gettext('Cancel'),
key: 27,
className: 'btn btn-danger fa fa-times file_manager_create_cancel pg-alertify-button',
},
],
focus: {
element: 0,
},
options: {
closableByDimmer: false,
maximizable: false,
closable: false,
movable: true,
},
};
},
replace_file: function() {
var $yesBtn = $('.replace_file .btn_yes'),
$noBtn = $('.replace_file .btn_no');
$('.storage_dialog #uploader .input-path').attr('disabled', true);
$('.file_manager_ok').addClass('disabled');
$('.replace_file, .fm_dimmer').show();
$yesBtn.on('click',() => {
$('.replace_file, .fm_dimmer').hide();
$yesBtn.off();
$noBtn.off();
var newFile = $('.storage_dialog #uploader .input-path').val();
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:create_file', newFile);
$('.file_manager_create_cancel').trigger('click');
$('.storage_dialog #uploader .input-path').attr('disabled', false);
$('.file_manager_ok').removeClass('disabled');
});
$noBtn.on('click',() => {
$('.replace_file, .fm_dimmer').hide();
$yesBtn.off();
$noBtn.off();
$('.storage_dialog #uploader .input-path').attr('disabled', false);
$('.file_manager_ok').removeClass('disabled');
});
},
is_file_exist: function() {
var full_path = $('.storage_dialog #uploader .input-path').val(),
path = full_path.substr(0, full_path.lastIndexOf('/') + 1),
selected_item = full_path.substr(full_path.lastIndexOf('/') + 1),
is_exist = false;
var file_data = {
'path': path,
'name': selected_item,
'mode': 'is_file_exist',
};
$.ajax({
type: 'POST',
data: JSON.stringify(file_data),
url: url_for('file_manager.filemanager', {
'trans_id': trans_id,
}),
dataType: 'json',
contentType: 'application/x-download; charset=utf-8',
async: false,
success: function(resp) {
var data = resp.data.result;
if (data['Code'] === 1) {
is_exist = true;
} else {
is_exist = false;
}
},
});
return is_exist;
},
check_permission: function(path) {
var permission = false,
post_data = {
'path': path,
'mode': 'permission',
};
$.ajax({
type: 'POST',
data: JSON.stringify(post_data),
url: url_for('file_manager.filemanager', {
'trans_id': trans_id,
}),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
async: false,
success: function(resp) {
var data = resp.data.result;
if (data.Code === 1) {
permission = true;
} else {
$('.file_manager_ok').addClass('disabled');
Alertify.error(data.Error);
}
},
error: function() {
$('.file_manager_ok').addClass('disabled');
Alertify.error(gettext('Error occurred while checking access permission.'));
},
});
return permission;
},
callback: function(closeEvent) {
if (closeEvent.button.text == gettext('Create')) {
var newFile = $('.storage_dialog #uploader .input-path').val(),
file_data = {
'path': $('.currentpath').val(),
},
innerbody;
if (!this.check_permission(newFile)) {
closeEvent.cancel = true;
return;
}
if (!_.isUndefined(newFile) && newFile !== '' && this.is_file_exist()) {
this.replace_file();
closeEvent.cancel = true;
} else {
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:create_file', newFile);
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(trans_id);
}
set_last_traversed_dir(file_data, trans_id);
} else if (closeEvent.button.text == gettext('Cancel')) {
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(trans_id);
pgAdmin.Browser.Events.trigger('pgadmin-storage:cancel_btn:create_file');
}
},
build: function() {
this.elements.content.appendChild($container.get(0));
},
hooks: {
onshow: function() {
$(this.elements.body).addClass('pgadmin-storage-body');
},
},
};
});
},
show_storage_dlg: function(params) {
Alertify.storageManagerDlg(params).resizeTo('60%', '80%');
},
show_file_selection: function(params) {
Alertify.fileSelectionDlg(params).resizeTo('60%', '80%');
},
show_folder_selection: function(params) {
Alertify.folderSelectionDlg(params).resizeTo('60%', '80%');
},
show_create_dlg: function(params) {
Alertify.createModeDlg(params).resizeTo('60%', '80%');
},
// Call dialogs subject to dialog_type param
show_dialog: function(params) {
if (params.dialog_type == 'select_file') {
this.show_file_selection(params);
} else if (params.dialog_type == 'select_folder') {
this.show_folder_selection(params);
} else if (params.dialog_type == 'create_file') {
this.show_create_dlg(params);
if (params.dialog_type == 'create_file') {
Alertify.createModeDlg(params).resizeTo('60%', '80%');
} else {
this.show_storage_dlg(params);
Alertify.fileSelectionDlg(params).resizeTo('60%', '80%');
}
},
};

View File

@ -0,0 +1,38 @@
import url_for from 'sources/url_for';
import $ from 'jquery';
// Send a request to get transaction id
export function getTransId(configs) {
return $.ajax({
data: configs,
type: 'POST',
async: false,
url: url_for('file_manager.get_trans_id'),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
});
}
// Function to remove trans id from session
export function removeTransId(trans_id) {
return $.ajax({
type: 'GET',
async: false,
url: url_for('file_manager.delete_trans_id', {
'trans_id': trans_id,
}),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
});
}
export function set_last_traversed_dir(path, trans_id) {
return $.ajax({
url: url_for('file_manager.save_last_dir', {
'trans_id': trans_id,
}),
type: 'POST',
data: JSON.stringify(path),
contentType: 'application/json',
});
}

View File

@ -0,0 +1,134 @@
import gettext from 'sources/gettext';
import url_for from 'sources/url_for';
import $ from 'jquery';
import Alertify from 'pgadmin.alertifyjs';
import pgAdmin from 'sources/pgadmin';
import {getTransId, removeTransId, set_last_traversed_dir} from './helpers';
// Declare the Selection dialog
module.exports = Alertify.dialog('fileSelectionDlg', function() {
// Dialog property
return {
main: function(params) {
// Set title and button name
var self = this;
if (_.isUndefined(params['dialog_title'])) {
params['dialog_title'] = 'Select file';
}
self.dialog_type = params['dialog_type'];
this.set('title', params['dialog_title']);
if (_.isUndefined(params['btn_primary'])) {
params['btn_primary'] = 'Select';
}
this.set('label', params['btn_primary']);
this.params = JSON.stringify(params);
this.elements.dialog.style.minWidth = '630px';
this.show();
},
settings: {
label: undefined,
},
settingUpdated: function(key, oldValue, newValue) {
switch (key) {
case 'message':
this.setMessage(newValue);
break;
case 'label':
if (this.__internal.buttons[0].element) {
this.__internal.buttons[0].element.innerHTML = newValue;
}
break;
default:
break;
}
},
prepare: function() {
var self = this;
self.$container.find('.storage_content').remove();
self.$container.append('<div class=\'storage_content\'></div>');
var content = self.$container.find('.storage_content');
content.empty();
$.get(url_for('file_manager.index'), function(data) {
content.append(data);
});
var transId = getTransId(self.params);
var t_res;
if (transId.readyState == 4) {
t_res = JSON.parse(transId.responseText);
}
self.trans_id = t_res.data.fileTransId;
setTimeout(function() {
$(self.$container.find('.file_manager')).on('enter-key', function() {
$($(self.elements.footer).find('.file_manager_ok')).trigger('click');
});
}, 200);
self.__internal.buttons[0].element.disabled = true;
},
setup: function() {
return {
buttons: [{
text: gettext('Select'),
key: 13,
className: 'btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled',
},
{
text: gettext('Cancel'),
key: 27,
className: 'btn btn-danger fa fa-times pg-alertify-button',
},
],
focus: {
element: 0,
},
options: {
closableByDimmer: false,
maximizable: false,
closable: false,
movable: true,
},
};
},
callback: function(closeEvent) {
var innerbody;
if (closeEvent.button.text == gettext('Select')) {
var newFile = $('.storage_dialog #uploader .input-path').val(),
file_data = {
'path': $('.currentpath').val(),
};
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:' + this.dialog_type, newFile);
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(this.trans_id);
// Ajax call to store the last directory visited once user press select button
set_last_traversed_dir(file_data, this.trans_id);
} else if (closeEvent.button.text == gettext('Cancel')) {
innerbody = $(this.elements.body).find('.storage_content');
$(innerbody).find('*').off();
innerbody.remove();
removeTransId(this.trans_id);
pgAdmin.Browser.Events.trigger('pgadmin-storage:cancel_btn:' + this.dialog_type);
}
},
build: function() {
this.$container = $('<div class="storage_dialog file_selection_dlg"></div>');
this.elements.content.appendChild(this.$container.get(0));
},
hooks: {
onshow: function() {
$(this.elements.body).addClass('pgadmin-storage-body');
},
},
};
});

View File

@ -36,7 +36,7 @@ define([
async: false,
cache: false,
url: url,
dataType: 'jsonp',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
});
};
@ -169,7 +169,7 @@ define([
if (!has_capability(data, 'download') || pgAdmin.FileUtils.hideButtons()) {
$('.file_manager').find('button.download').hide();
} else {
$('.file_manager').find('button.download').off().on('click',() => {
$('.file_manager').find('button.download').off().on('click', function() {
var path;
if ($('.fileinfo').data('view') == 'grid') {
path = $('.fileinfo li.selected').find('.clip span').attr('data-alt');
@ -879,7 +879,7 @@ define([
}
});
$('.fileinfo').find('#contents li').on('click',(e) => {
$('.fileinfo').find('#contents li').on('click', function(e) {
e.stopPropagation();
var path = decodeURI($(this).find('.clip span').attr('data-alt')),
is_protected = $(this).find(
@ -909,6 +909,7 @@ define([
'.file_manager #uploader .filemanager-path-group'
);
}
pgAdmin.FileUtils.setUploader(path);
} else {
if (
has_capability(data_cap, 'select_file') &&
@ -952,6 +953,7 @@ define([
'.file_manager #uploader .filemanager-path-group'
);
}
pgAdmin.FileUtils.setUploader(path);
} else {
if (has_capability(data_cap, 'select_file') && is_protected == undefined) {
$(this).parent().find('tr.selected').removeClass('selected');
@ -1229,7 +1231,7 @@ define([
});
// re-render the home view
$('.file_manager .home').on('click',() => {
$('.file_manager .home').on('click', function() {
var currentViewMode = $('.fileinfo').data('view');
$('.fileinfo').data('view', currentViewMode);
getFolderInfo('/');
@ -1237,7 +1239,7 @@ define([
});
// Go one directory back
$('.file_manager .level-up').on('click',() => {
$('.file_manager .level-up').on('click', function() {
var b = $('.currentpath').val();
// Enable/Disable level up button
enab_dis_level_up();
@ -1395,7 +1397,7 @@ define([
$('.upload').remove();
$('.create').before('<button value="Upload" type="button" title="Upload File" name="upload" id="upload" class="btn fa fa-upload upload" tabindex="6"><span></span></button> ');
$('#uploader .upload').off().on('click',() => {
$('#uploader .upload').off().on('click', function() {
// we create prompt
var msg = '<div id="dropzone-container">' +
'<button class="fa fa-times dz_cross_btn" tabindex="7"></button>' +
@ -1541,7 +1543,7 @@ define([
$('.storage_dialog #uploader .input-path').attr('data-path', path);
// create new folder
$('.create').off().on('click',() => {
$('.create').off().on('click', function() {
var foldername = lg.new_folder;
var $file_element,
$file_element_list,

View File

@ -2269,6 +2269,12 @@ define([
// Introduce a new class to fix the error icon placement on the control
this.$el.addClass('pgadmin-file-has-error');
},
disable_button: function() {
this.$el.find('button.select_item').attr('disabled', 'disabled');
},
enable_button: function() {
this.$el.find('button.select_item').removeAttr('disabled');
},
});
Backform.DatetimepickerControl =

View File

@ -221,10 +221,11 @@ def script():
)
def filename_with_file_manager_path(_file):
def filename_with_file_manager_path(_file, create_file=True):
"""
Args:
file: File name returned from client file manager
create_file: Set flag to False when file creation doesn't required
Returns:
Filename to use for backup with full path taken from preference
@ -237,9 +238,10 @@ def filename_with_file_manager_path(_file):
elif not os.path.isabs(_file):
_file = os.path.join(document_dir(), _file)
# Touch the file to get the short path of the file on windows.
with open(_file, 'a'):
pass
if create_file:
# Touch the file to get the short path of the file on windows.
with open(_file, 'a'):
pass
return fs_short_path(_file)
@ -385,7 +387,10 @@ def create_backup_objects_job(sid):
data.pop("ratio")
try:
backup_file = filename_with_file_manager_path(data['file'])
if data['format'] == 'directory':
backup_file = filename_with_file_manager_path(data['file'], False)
else:
backup_file = filename_with_file_manager_path(data['file'])
except Exception as e:
return bad_request(errormsg=str(e))

View File

@ -139,9 +139,23 @@ define([
label: gettext('Filename'),
type: 'text',
disabled: false,
control: Backform.FileControl,
control: Backform.FileControl.extend({
render: function() {
var attributes = this.model.toJSON();
if (attributes.format == 'directory') {
this.field.attributes.dialog_type = 'select_folder';
}
else {
this.field.attributes.dialog_type = 'create_file';
}
Backform.InputControl.prototype.render.apply(this, arguments);
return this;
},
}),
dialog_type: 'create_file',
supp_types: ['*', 'sql', 'backup'],
deps: ['format'],
}, {
id: 'format',
label: gettext('Format'),

View File

@ -52,6 +52,31 @@ class BackupCreateJobTest(BaseTestGenerator):
not_expected_cmd_opts=[],
expected_exit_code=[0, None]
)),
('When backup object with format directory',
dict(
class_params=dict(
sid=1,
name='test_backup_server',
port=5444,
host='localhost',
database='postgres',
bfile='test_backup',
username='postgres'
),
params=dict(
file='test_backup_folder',
format='directory',
verbose=True,
blobs=False,
schemas=[],
tables=[],
database='postgres'
),
url='/backup/job/{0}/object',
expected_cmd_opts=['--verbose', '--format=d'],
not_expected_cmd_opts=[],
expected_exit_code=[0, None]
)),
('When backup the object with option sections to all data',
dict(
class_params=dict(

View File

@ -168,7 +168,7 @@ def filename_with_file_manager_path(_file):
elif not os.path.isabs(_file):
_file = os.path.join(document_dir(), _file)
if not os.path.isfile(_file):
if not os.path.isfile(_file) and not os.path.exists(_file):
return None
return fs_short_path(_file)

View File

@ -112,9 +112,23 @@ commonUtils, menuUtils, supportedNodes, restoreDialog
label: gettext('Filename'),
type: 'text',
disabled: false,
control: Backform.FileControl,
control: Backform.FileControl.extend({
render: function() {
var attributes = this.model.toJSON();
if (attributes.format == 'directory') {
this.field.attributes.dialog_type = 'select_folder';
}
else {
this.field.attributes.dialog_type = 'select_file';
}
Backform.InputControl.prototype.render.apply(this, arguments);
return this;
},
}),
dialog_type: 'select_file',
supp_types: ['*', 'backup', 'sql', 'patch'],
deps: ['format'],
}, {
id: 'no_of_jobs',
label: gettext('Number of jobs'),

View File

@ -51,6 +51,32 @@ class RestoreCreateJobTest(BaseTestGenerator):
not_expected_cmd_opts=[],
expected_exit_code=[0, None]
)),
('When restore object with format directory',
dict(
class_params=dict(
sid=1,
name='test_restore_server',
port=5444,
host='localhost',
database='postgres',
bfile='test_restore',
username='postgres'
),
params=dict(
file='test_restore_file',
format='directory',
custom=False,
verbose=True,
blobs=False,
schemas=[],
tables=[],
database='postgres'
),
url='/restore/job/{0}',
expected_cmd_opts=['--verbose', '--format=d'],
not_expected_cmd_opts=[],
expected_exit_code=[0, None]
)),
('When restore object with the sections options',
dict(
class_params=dict(

View File

@ -244,6 +244,7 @@ class PgadminPage:
tab = self.find_by_xpath("//*[contains(@class,'wcTabTop')]//"
"*[contains(@class,'wcPanelTab') "
"and contains(.,'" + tab_name + "')]")
self.click_element(tab)
def wait_for_input_field_content(self, field_name, content):

View File

@ -0,0 +1,55 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import pgAdmin from 'sources/pgadmin';
import Alertify from 'pgadmin.alertifyjs';
import '../../../pgadmin/misc/file_manager/static/js/file_manager';
import '../../../pgadmin/misc/file_manager/static/js/select_dialogue.js';
describe('fileSelectDialog', function () {
let params;
describe('When dialog is called for select file', () => {
it('Select file dialog', function() {
params = {
'dialog_title': 'Select file',
'dialog_type': 'select_file',
};
spyOn(Alertify, 'fileSelectionDlg').and.callFake(function() {
this.resizeTo = function() {};
return this;
});
pgAdmin.FileManager.show_dialog(params);
expect(Alertify.fileSelectionDlg).toHaveBeenCalled();
});
});
describe('When dialog is called for create file', () => {
it('Select file dialog', function() {
params = {
'dialog_title': 'Create file',
'dialog_type': 'create_file',
};
spyOn(Alertify, 'createModeDlg').and.callFake(function() {
this.resizeTo = function() {};
return this;
});
pgAdmin.FileManager.show_dialog(params);
expect(Alertify.createModeDlg).toHaveBeenCalled();
});
});
});