Hi,
Please find the attached patch to fix below issues:
1. #2963 - Backup database, Restore database and Maintenance Database
failed for é object
2. #3157 - Process viewer doesn't show complete command executed.
Test cases are not included for these fixes as we don't have test cases for
these modules (backup, restore, maintenance).
I will create one separate RM for the same which will cover this.
Thanks,
Khushboo
On Fri, Jan 12, 2018 at 3:24 PM, Dave Page <[email protected]> wrote:
> Hi
>
> On Wed, Jan 10, 2018 at 6:59 AM, Khushboo Vashi <
> [email protected]> wrote:
>
>>
>>
>> On Wed, Jan 3, 2018 at 8:54 PM, Dave Page <[email protected]> wrote:
>>
>>> Hi
>>>
>>> On Mon, Dec 25, 2017 at 11:03 AM, Khushboo Vashi <
>>> [email protected]> wrote:
>>>
>>>> Hi,
>>>>
>>>> Please find the attached patch to fix RM #2963: Backup database,
>>>> Restore database and Maintenance Database failed for é object.
>>>>
>>>
>>> With the patch applied, I get:
>>>
>>> 2018-01-03 15:23:00,110: INFO pgadmin: Executing the process executor
>>> with the arguments: ['/Users/dpage/.virtualenvs/pgadmin4/bin/python',
>>> '/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/process_executor.py',
>>> '/usr/local/pgsql/bin/pg_dump', u'--file', u'/Users/dpage/e.sql',
>>> u'--host', u'localhost', u'--port', '5432', u'--username', u'postgres',
>>> u'--no-password', u'--verbose', u'--format=c', u'--blobs', u'\xe9']
>>> 2018-01-03 15:23:00,117: INFO werkzeug: 127.0.0.1 - - [03/Jan/2018
>>> 15:23:00] "POST /backup/job/1/object HTTP/1.1" 200 -
>>> Exception in thread Thread-6:
>>> Traceback (most recent call last):
>>> File
>>> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py",
>>> line 810, in __bootstrap_inner
>>> self.run()
>>> File
>>> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py",
>>> line 763, in run
>>> self.__target(*self.__args, **self.__kwargs)
>>> File
>>> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py",
>>> line 602, in process_request_thread
>>> self.handle_error(request, client_address)
>>> File
>>> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py",
>>> line 599, in process_request_thread
>>> self.finish_request(request, client_address)
>>> File
>>> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py",
>>> line 334, in finish_request
>>> self.RequestHandlerClass(request, client_address, self)
>>> File
>>> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py",
>>> line 655, in __init__
>>> self.handle()
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/serving.py",
>>> line 200, in handle
>>> rv = BaseHTTPRequestHandler.handle(self)
>>> File "/System/Library/Frameworks/Python.framework/Versions/2.7/li
>>> b/python2.7/BaseHTTPServer.py", line 340, in handle
>>> self.handle_one_request()
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/serving.py",
>>> line 235, in handle_one_request
>>> return self.run_wsgi()
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/serving.py",
>>> line 177, in run_wsgi
>>> execute(self.server.app)
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/werkzeug/serving.py",
>>> line 165, in execute
>>> application_iter = app(environ, start_response)
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>> line 2000, in __call__
>>> return self.wsgi_app(environ, start_response)
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>> line 1991, in wsgi_app
>>> response = self.make_response(self.handle_exception(e))
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>> line 1567, in handle_exception
>>> reraise(exc_type, exc_value, tb)
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>> line 1988, in wsgi_app
>>> response = self.full_dispatch_request()
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>> line 1641, in full_dispatch_request
>>> rv = self.handle_user_exception(e)
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>> line 1544, in handle_user_exception
>>> reraise(exc_type, exc_value, tb)
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>> line 1639, in full_dispatch_request
>>> rv = self.dispatch_request()
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask/app.py",
>>> line 1625, in dispatch_request
>>> return self.view_functions[rule.endpoint](**req.view_args)
>>> File
>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python2.7/site-packages/flask_login.py",
>>> line 792, in decorated_view
>>> return func(*args, **kwargs)
>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/__init__.py",
>>> line 62, in index
>>> return make_response(response=BatchProcess.list())
>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/misc/bgprocess/processes.py",
>>> line 512, in list
>>> desc = loads(p.desc)
>>> File
>>> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py",
>>> line 1381, in loads
>>> file = StringIO(str)
>>> UnicodeEncodeError: 'ascii' codec can't encode character u'\ufffd' in
>>> position 138: ordinal not in range(128)
>>>
>>> Fixed. Please find the attached updated patch.
>>
>>>
> That's getting further, but still not right. Please see the attached
> screenshot - the beginning of the executed command has been lost.
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>
diff --git a/web/pgadmin/misc/bgprocess/processes.py b/web/pgadmin/misc/bgprocess/processes.py
index 02b953d..385b7bd 100644
--- a/web/pgadmin/misc/bgprocess/processes.py
+++ b/web/pgadmin/misc/bgprocess/processes.py
@@ -78,10 +78,20 @@ class BatchProcess(object):
_("Could not find a process with the specified ID.")
)
+ try:
+ tmp_desc = loads(p.desc.encode('latin-1')) if \
+ IS_PY2 and hasattr(p.desc, 'encode') else loads(p.desc)
+ except UnicodeDecodeError:
+ tmp_desc = loads(p.desc.encode('utf-8')) if \
+ IS_PY2 and hasattr(p.desc, 'encode') else loads(p.desc)
+ except Exception as e:
+ tmp_desc = loads(p.desc.encode('utf-8', 'ignore')) if \
+ IS_PY2 and hasattr(p.desc, 'encode') else loads(p.desc)
+
# ID
self.id = _id
# Description
- self.desc = loads(p.desc)
+ self.desc = tmp_desc
# Status Acknowledged time
self.atime = p.acknowledge
# Command
@@ -171,6 +181,16 @@ class BatchProcess(object):
csv_writer.writerow(_args)
args_val = args_csv_io.getvalue().strip(str('\r\n'))
+ tmp_desc = dumps(self.desc)
+ try:
+ tmp_desc =tmp_desc.decode('utf-8') if\
+ IS_PY2 and hasattr(tmp_desc, 'decode') else tmp_desc
+ except UnicodeDecodeError:
+ tmp_desc = tmp_desc.decode('latin-1') if \
+ IS_PY2 and hasattr(tmp_desc, 'decode') else tmp_desc
+ except Exception:
+ tmp_desc = tmp_desc.decode('utf-8', 'ignore') if \
+ IS_PY2 and hasattr(tmp_desc, 'decode') else tmp_desc
j = Process(
pid=int(id),
@@ -178,7 +198,7 @@ class BatchProcess(object):
arguments=args_val.decode('utf-8', 'replace')
if IS_PY2 and hasattr(args_val, 'decode') else args_val,
logdir=log_dir,
- desc=dumps(self.desc),
+ desc=tmp_desc,
user_id=current_user.id
)
db.session.add(j)
@@ -534,7 +554,17 @@ class BatchProcess(object):
etime = parser.parse(p.end_time or get_current_time())
execution_time = (etime - stime).total_seconds()
- desc = loads(p.desc)
+ desc = ""
+ try:
+ desc = loads(p.desc.encode('latin-1')) if \
+ IS_PY2 and hasattr(p.desc, 'encode') else loads(p.desc)
+ except UnicodeDecodeError:
+ desc = loads(p.desc.encode('utf-8')) if \
+ IS_PY2 and hasattr(p.desc, 'encode') else loads(p.desc)
+ except Exception:
+ desc = loads(p.desc.encode('utf-8', 'ignore')) if \
+ IS_PY2 and hasattr(p.desc, 'encode') else loads(p.desc)
+
details = desc
if isinstance(desc, IProcessDesc):
diff --git a/web/pgadmin/misc/bgprocess/static/js/bgprocess.js b/web/pgadmin/misc/bgprocess/static/js/bgprocess.js
index 5e30590..8ad2c65 100644
--- a/web/pgadmin/misc/bgprocess/static/js/bgprocess.js
+++ b/web/pgadmin/misc/bgprocess/static/js/bgprocess.js
@@ -248,7 +248,7 @@ define('misc.bgprocess', [
if (!self.notifier) {
var header = $('<div></div>', {
class: 'h5 pg-bg-notify-header',
- }).append($('<span></span>').text(self.desc)),
+ }).append($('<span></span>').text(_.escape(self.desc))),
content = $('<div class="pg-bg-bgprocess row"></div>').append(
header
).append(
@@ -366,7 +366,7 @@ define('misc.bgprocess', [
self.logs[0].scrollTop = self.logs[0].scrollHeight;
});
// set bgprocess detailed description
- $header.find('.bg-detailed-desc').html(self.detailed_desc);
+ $header.find('.bg-detailed-desc').html(_.unescape(self.detailed_desc));
}
// set bgprocess start time
@@ -562,4 +562,4 @@ define('misc.bgprocess', [
});
return pgBrowser.BackgroundProcessObsorver;
-});
\ No newline at end of file
+});
diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py
index 715ff6e..9e70c4f 100644
--- a/web/pgadmin/tools/backup/__init__.py
+++ b/web/pgadmin/tools/backup/__init__.py
@@ -97,11 +97,9 @@ class BackupMessage(IProcessDesc):
def cmdArg(x):
if x:
- # x = html.safe_str(x)
x = x.replace('\\', '\\\\')
x = x.replace('"', '\\"')
x = x.replace('""', '\\"')
-
return ' "' + x + '"'
return ''
@@ -111,6 +109,7 @@ class BackupMessage(IProcessDesc):
else:
self.cmd += cmdArg(arg)
+
@property
def message(self):
# Fetch the server details like hostname, port, roles etc
@@ -189,7 +188,7 @@ class BackupMessage(IProcessDesc):
res += '</div><div class="h5">'
res += _("Running command:")
res += '</b><br><span class="pg-bg-cmd enable-selection">'
- res += html.safe_str(self.cmd)
+ res += html.safe_str(cmd + self.cmd)
res += '</span></div>'
return res