mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Added support to download utility files at the client-side. Fixes #3318
This commit is contained in:
committed by
Akshay Joshi
parent
7573fac29f
commit
c2ad97d0ab
@@ -22,7 +22,7 @@ from subprocess import Popen, PIPE
|
||||
import logging
|
||||
|
||||
from pgadmin.utils import u_encode, file_quote, fs_encoding, \
|
||||
get_complete_file_path
|
||||
get_complete_file_path, get_storage_directory, IS_WIN
|
||||
|
||||
import pytz
|
||||
from dateutil import parser
|
||||
@@ -59,6 +59,48 @@ class IProcessDesc(object, metaclass=ABCMeta):
|
||||
def details(self, cmd, args):
|
||||
pass
|
||||
|
||||
@property
|
||||
def current_storage_dir(self):
|
||||
|
||||
if config.SERVER_MODE:
|
||||
|
||||
file = self.bfile
|
||||
try:
|
||||
# check if file name is encoded with UTF-8
|
||||
file = self.bfile.decode('utf-8')
|
||||
except Exception as e:
|
||||
str(e)
|
||||
# do nothing if bfile is not encoded.
|
||||
|
||||
path = get_complete_file_path(file)
|
||||
path = file if path is None else path
|
||||
|
||||
if IS_WIN:
|
||||
path = os.path.realpath(path)
|
||||
|
||||
storage_directory = os.path.basename(get_storage_directory())
|
||||
|
||||
if storage_directory in path:
|
||||
start = path.index(storage_directory)
|
||||
end = start + (len(storage_directory))
|
||||
last_dir = os.path.dirname(path[end:])
|
||||
else:
|
||||
last_dir = file
|
||||
|
||||
if IS_WIN:
|
||||
if '\\' in last_dir:
|
||||
if len(last_dir) == 1:
|
||||
last_dir = last_dir.replace('\\', '\\\\')
|
||||
else:
|
||||
last_dir = last_dir.replace('\\', '/')
|
||||
else:
|
||||
last_dir = last_dir.replace('\\', '/')
|
||||
|
||||
return None if hasattr(self, 'is_import') and self.is_import \
|
||||
else last_dir
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class BatchProcess(object):
|
||||
def __init__(self, **kwargs):
|
||||
@@ -543,8 +585,12 @@ class BatchProcess(object):
|
||||
desc = loads(p.desc)
|
||||
details = desc
|
||||
type_desc = ''
|
||||
current_storage_dir = None
|
||||
|
||||
if isinstance(desc, IProcessDesc):
|
||||
|
||||
from pgadmin.tools.backup import BackupMessage
|
||||
from pgadmin.tools.import_export import IEMessage
|
||||
args = []
|
||||
args_csv = StringIO(
|
||||
p.arguments.encode('utf-8')
|
||||
@@ -555,9 +601,11 @@ class BatchProcess(object):
|
||||
args = args + arg
|
||||
details = desc.details(p.command, args)
|
||||
type_desc = desc.type_desc
|
||||
if isinstance(desc, (BackupMessage, IEMessage)):
|
||||
current_storage_dir = desc.current_storage_dir
|
||||
desc = desc.message
|
||||
|
||||
return desc, details, type_desc
|
||||
return desc, details, type_desc, current_storage_dir
|
||||
|
||||
@staticmethod
|
||||
def list():
|
||||
@@ -584,7 +632,8 @@ class BatchProcess(object):
|
||||
|
||||
execution_time = BatchProcess.total_seconds(etime - stime)
|
||||
|
||||
desc, details, type_desc = BatchProcess._check_process_desc(p)
|
||||
desc, details, type_desc, current_storage_dir = BatchProcess.\
|
||||
_check_process_desc(p)
|
||||
|
||||
res.append({
|
||||
'id': p.pid,
|
||||
@@ -596,7 +645,8 @@ class BatchProcess(object):
|
||||
'exit_code': p.exit_code,
|
||||
'acknowledge': p.acknowledge,
|
||||
'execution_time': execution_time,
|
||||
'process_state': p.process_state
|
||||
'process_state': p.process_state,
|
||||
'current_storage_dir': current_storage_dir,
|
||||
})
|
||||
|
||||
if changed:
|
||||
|
||||
@@ -57,3 +57,7 @@ ol.pg-bg-process-logs {
|
||||
.pg-bg-bgprocess:hover .bg-close {
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.icon-storage-manager:before {
|
||||
font-icon: url('../img/storage_manager.svg');
|
||||
}
|
||||
|
||||
13
web/pgadmin/misc/bgprocess/static/img/storage_manager.svg
Normal file
13
web/pgadmin/misc/bgprocess/static/img/storage_manager.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M4.3,5.3h8.8V4c0-0.7-0.6-1.3-1.3-1.3H7.5L5.8,1H1.5C0.8,1,0.2,1.6,0.2,2.3v7.4L2,6.5C2.6,5.8,3.4,5.3,4.3,5.3z"/>
|
||||
<path d="M7.5,8.9c0-1.2,0.7-2.3,1.6-2.8H4.3C3.7,6.1,3.1,6.4,2.8,7l-1.9,3.3c-0.2,0.4,0.1,1,0.6,1h7C7.8,10.7,7.5,9.8,7.5,8.9z"/>
|
||||
<path d="M15,6.1h-2.6c1,0.6,1.6,1.6,1.6,2.8c0,0.3-0.1,0.6-0.1,0.9L15.5,7C15.8,6.7,15.5,6.1,15,6.1z"/>
|
||||
<circle cx="10.8" cy="8.9" r="2.8"/>
|
||||
</g>
|
||||
<path d="M14,11.8l-1.2-0.3c-1.3,0.9-2.9,0.8-3.8,0l-1.2,0.3C7,12,6.5,12.7,6.5,13.5v0.7c0,0.4,0.3,0.9,0.9,0.9h2.3l1.1-2.4l1.3,2.4
|
||||
h2.4c0.4,0,0.9-0.3,0.9-0.9v-0.8C15.2,12.6,14.8,11.9,14,11.8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 944 B |
@@ -20,6 +20,8 @@ define('misc.bgprocess', [
|
||||
return pgBrowser.BackgroundProcessObsorver;
|
||||
}
|
||||
|
||||
var isServerMode = (function() { return pgAdmin.server_mode == 'True'; })();
|
||||
|
||||
var wcDocker = window.wcDocker;
|
||||
|
||||
var BGProcess = function(info, notify) {
|
||||
@@ -61,6 +63,7 @@ define('misc.bgprocess', [
|
||||
curr_status: null,
|
||||
state: 0, // 0: NOT Started, 1: Started, 2: Finished, 3: Terminated
|
||||
completed: false,
|
||||
current_storage_dir: null,
|
||||
|
||||
id: info['id'],
|
||||
type_desc: null,
|
||||
@@ -161,6 +164,9 @@ define('misc.bgprocess', [
|
||||
if ('process_state' in data)
|
||||
self.state = data.process_state;
|
||||
|
||||
if ('current_storage_dir' in data)
|
||||
self.current_storage_dir = data.current_storage_dir;
|
||||
|
||||
if ('out' in data) {
|
||||
self.out = data.out && data.out.pos;
|
||||
|
||||
@@ -325,8 +331,8 @@ define('misc.bgprocess', [
|
||||
</div>
|
||||
<div class="pg-bg-etime my-auto mr-2"></div>
|
||||
<div class="ml-auto">
|
||||
<button class="btn btn-secondary pg-bg-more-details"><span class="fa fa-info-circle" role="img"></span> ` + gettext('More details...') + `</button>
|
||||
<button class="btn btn-danger bg-process-stop" disabled><span class="fa fa-times-circle" role="img"></span> ` + gettext('Stop Process') + `</button>
|
||||
<button class="btn btn-secondary pg-bg-more-details" title="More Details"><span class="fa fa-info-circle" role="img"></span> ` + gettext('More details...') + `</button>
|
||||
<button class="btn btn-danger bg-process-stop" disabled><span class="fa fa-times-circle" role="img" title="Stop the operation"></span> ` + gettext('Stop Process') + `</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pg-bg-status py-1">
|
||||
@@ -387,6 +393,7 @@ define('misc.bgprocess', [
|
||||
var $status_bar = $(self.container.find('.pg-bg-status'));
|
||||
$status_bar.html(self.curr_status);
|
||||
var $btn_stop_process = $(self.container.find('.bg-process-stop'));
|
||||
|
||||
// Enable Stop Process button only when process is running
|
||||
if (parseInt(self.state) === 1) {
|
||||
$btn_stop_process.attr('disabled', false);
|
||||
@@ -415,7 +422,27 @@ define('misc.bgprocess', [
|
||||
$logs = container.find('.bg-process-watcher'),
|
||||
$header = container.find('.bg-process-details'),
|
||||
$footer = container.find('.bg-process-footer'),
|
||||
$btn_stop_process = container.find('.bg-process-stop');
|
||||
$btn_stop_process = container.find('.bg-process-stop'),
|
||||
$btn_storage_manager = container.find('.bg-process-storage-manager');
|
||||
|
||||
if(self.current_storage_dir && isServerMode) { //for backup & exports with server mode, operate over storage manager
|
||||
|
||||
if($btn_storage_manager.length == 0) {
|
||||
var str_storage_manager_btn = '<button id="bg-process-storage-manager" class="btn btn-secondary bg-process-storage-manager" title="Click to open file location" aria-label="Storage Manager" tabindex="0" disabled><span class="pg-font-icon icon-storage-manager" role="img"></span></button> ';
|
||||
container.find('.bg-process-details .bg-btn-section').prepend(str_storage_manager_btn);
|
||||
$btn_storage_manager = container.find('.bg-process-storage-manager');
|
||||
}
|
||||
|
||||
// Disable storage manager button only when process is running
|
||||
if (parseInt(self.state) === 1) {
|
||||
$btn_storage_manager.attr('disabled', true);
|
||||
}
|
||||
else {
|
||||
$btn_storage_manager.attr('disabled', false);
|
||||
}
|
||||
// On Click event for storage manager button.
|
||||
$btn_storage_manager.off('click').on('click', self.storage_manager.bind(this));
|
||||
}
|
||||
|
||||
// Enable Stop Process button only when process is running
|
||||
if (parseInt(self.state) === 1) {
|
||||
@@ -526,6 +553,15 @@ define('misc.bgprocess', [
|
||||
});
|
||||
},
|
||||
|
||||
storage_manager: function() {
|
||||
|
||||
var self = this;
|
||||
if(self.current_storage_dir) {
|
||||
pgBrowser.Events.trigger(
|
||||
'pgadmin:tools:storage_manager', self.current_storage_dir
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
_.extend(
|
||||
@@ -634,7 +670,7 @@ define('misc.bgprocess', [
|
||||
'<span>' + gettext('Start time') + ': <span class="bgprocess-start-time"></span>' +
|
||||
'</span>'+
|
||||
'</div>' +
|
||||
'<div class="ml-auto">' +
|
||||
'<div class="ml-auto bg-btn-section">' +
|
||||
'<button type="button" class="btn btn-danger bg-process-stop" disabled><span class="fa fa-times-circle" role="img"></span> ' + gettext('Stop Process') + '</button>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
|
||||
Reference in New Issue
Block a user