mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Allow direct navigation (i.e. typing of paths) in the file manager. Fixes #1911
This commit is contained in:
committed by
Dave Page
parent
687a793383
commit
4ef26a528b
@@ -16,6 +16,7 @@ import string
|
||||
import sys
|
||||
import time
|
||||
from sys import platform as _platform
|
||||
import config
|
||||
|
||||
import simplejson as json
|
||||
from flask import render_template, Response, session, request as req, url_for
|
||||
@@ -241,6 +242,7 @@ def delete_trans_id(trans_id):
|
||||
data={'status': True}
|
||||
)
|
||||
|
||||
|
||||
@blueprint.route("/save_last_dir/<int:trans_id>", methods=["POST"])
|
||||
@login_required
|
||||
def save_last_directory_visited(trans_id):
|
||||
@@ -259,12 +261,12 @@ class Filemanager(object):
|
||||
{
|
||||
'Error': gettext('No permission to operate on \
|
||||
specified path.'),
|
||||
'Code': -1
|
||||
'Code': 0
|
||||
}
|
||||
)
|
||||
self.dir = get_storage_directory()
|
||||
|
||||
if (self.dir is not None and isinstance(self.dir, list)):
|
||||
if self.dir is not None and isinstance(self.dir, list):
|
||||
self.dir = ""
|
||||
|
||||
@staticmethod
|
||||
@@ -312,31 +314,40 @@ class Filemanager(object):
|
||||
folders_only = False
|
||||
title = "Storage Manager"
|
||||
|
||||
# get last visited directory, if not present then traverse in reverse order
|
||||
# to find closest parent directory
|
||||
# get last visited directory, if not present then traverse in reverse
|
||||
# order to find closest parent directory
|
||||
last_dir = blueprint.last_directory_visited.get()
|
||||
if storage_dir is None:
|
||||
if last_dir is None:
|
||||
last_dir = "/"
|
||||
else:
|
||||
if last_dir is not None:
|
||||
if len(last_dir) > 1 and last_dir.endswith('/'):
|
||||
if len(last_dir) > 1 and \
|
||||
(last_dir.endswith('/') or last_dir.endswith('\\')):
|
||||
last_dir = last_dir[:-1]
|
||||
while last_dir:
|
||||
if os.path.exists(storage_dir + last_dir):
|
||||
break;
|
||||
index = last_dir.rfind('/')
|
||||
break
|
||||
if _platform == 'win32':
|
||||
index = max(last_dir.rfind('\\'), last_dir.rfind('/'))
|
||||
else:
|
||||
index = last_dir.rfind('/')
|
||||
last_dir = last_dir[0:index]
|
||||
if not last_dir:
|
||||
last_dir = "/"
|
||||
if not last_dir.endswith('/'):
|
||||
last_dir += "/"
|
||||
last_dir = u"/"
|
||||
|
||||
if _platform == 'win32':
|
||||
if not (last_dir.endswith('\\') or last_dir.endswith('/')):
|
||||
last_dir += u"\\"
|
||||
else:
|
||||
if not last_dir.endswith('/'):
|
||||
last_dir += u"/"
|
||||
else:
|
||||
last_dir = "/"
|
||||
last_dir = u"/"
|
||||
|
||||
# create configs using above configs
|
||||
configs = {
|
||||
"fileroot": last_dir,
|
||||
"fileroot": last_dir.replace('\\', '\\\\'), # for JS json compatibility
|
||||
"dialog_type": fm_type,
|
||||
"title": title,
|
||||
"upload": {
|
||||
@@ -426,13 +437,13 @@ class Filemanager(object):
|
||||
bitmask >>= 1
|
||||
if (drive_name != '' and drive_name is not None and
|
||||
drive_name in drives):
|
||||
return "{0}{1}".format(drive_name, ':/')
|
||||
return u"{0}{1}".format(drive_name, ':')
|
||||
else:
|
||||
return drives # return drives if no argument is passed
|
||||
except Exception:
|
||||
return ['C:/']
|
||||
return ['C:']
|
||||
else:
|
||||
return '/'
|
||||
return u'/'
|
||||
|
||||
@staticmethod
|
||||
def list_filesystem(dir, path, trans_data, file_type):
|
||||
@@ -443,12 +454,24 @@ class Filemanager(object):
|
||||
path = unquote(path)
|
||||
if hasattr(str, 'decode'):
|
||||
path = unquote(path).encode('utf-8').decode('utf-8')
|
||||
|
||||
try:
|
||||
Filemanager.check_access_permission(dir, path)
|
||||
except Exception as e:
|
||||
err_msg = u"Error: {0}".format(e)
|
||||
files = {
|
||||
'Code': 0,
|
||||
'Error': err_msg
|
||||
}
|
||||
return files
|
||||
|
||||
files = {}
|
||||
if (_platform == "win32" and path == '/') and dir is None:
|
||||
if (_platform == "win32" and (path == '/' or path == '\\'))\
|
||||
and dir is None:
|
||||
drives = Filemanager._get_drives()
|
||||
for drive in drives:
|
||||
protected = 0
|
||||
path = file_name = "{0}:/".format(drive)
|
||||
path = file_name = u"{0}:".format(drive)
|
||||
try:
|
||||
drive_size = getDriveSize(path)
|
||||
drive_size_in_units = sizeof_fmt(drive_size)
|
||||
@@ -470,7 +493,14 @@ class Filemanager(object):
|
||||
|
||||
if dir is None:
|
||||
dir = ""
|
||||
orig_path = u"{0}{1}".format(dir, path)
|
||||
orig_path = Filemanager.get_abs_path(dir, path)
|
||||
|
||||
if not path_exists(orig_path):
|
||||
return {
|
||||
'Code': 0,
|
||||
'Error': gettext(u"'{}' file does not exist.".format(path))
|
||||
}
|
||||
|
||||
user_dir = path
|
||||
folders_only = trans_data['folders_only'] if 'folders_only' in \
|
||||
trans_data else ''
|
||||
@@ -487,13 +517,10 @@ class Filemanager(object):
|
||||
system_path = os.path.join(os.path.join(orig_path, f))
|
||||
|
||||
# continue if file/folder is hidden
|
||||
if (is_folder_hidden(system_path) or f.startswith('.')):
|
||||
if is_folder_hidden(system_path) or f.startswith('.'):
|
||||
continue
|
||||
|
||||
if hasattr(str, 'decode'):
|
||||
user_path = os.path.join(os.path.join(user_dir, f)).encode('utf-8')
|
||||
else:
|
||||
user_path = os.path.join(os.path.join(user_dir, f))
|
||||
user_path = os.path.join(os.path.join(user_dir, f))
|
||||
created = time.ctime(os.path.getctime(system_path))
|
||||
modified = time.ctime(os.path.getmtime(system_path))
|
||||
file_extension = str(splitext(system_path))
|
||||
@@ -507,8 +534,8 @@ class Filemanager(object):
|
||||
if os.path.isdir(system_path):
|
||||
if files_only == 'true':
|
||||
continue
|
||||
file_extension = str('dir')
|
||||
user_path = "{0}/".format(user_path)
|
||||
file_extension = u"dir"
|
||||
user_path = u"{0}/".format(user_path)
|
||||
else:
|
||||
# filter files based on file_type
|
||||
if file_type is not None and file_type != "*":
|
||||
@@ -532,15 +559,72 @@ class Filemanager(object):
|
||||
except Exception as e:
|
||||
if (hasattr(e, 'strerror') and
|
||||
e.strerror == gettext('Permission denied')):
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
err_msg = u"Error: {0}".format(e.strerror)
|
||||
else:
|
||||
err_msg = "Error: {0}".format(e)
|
||||
err_msg = u"Error: {0}".format(e)
|
||||
files = {
|
||||
'Code': 0,
|
||||
'err_msg': err_msg
|
||||
'Error': err_msg
|
||||
}
|
||||
return files
|
||||
|
||||
@staticmethod
|
||||
def check_access_permission(dir, path):
|
||||
|
||||
if not config.SERVER_MODE:
|
||||
return True
|
||||
|
||||
if dir is None:
|
||||
dir = ""
|
||||
orig_path = Filemanager.get_abs_path(dir, path)
|
||||
|
||||
# This translates path with relative path notations like ./ and ../ to
|
||||
# absolute path.
|
||||
orig_path = os.path.abspath(orig_path)
|
||||
|
||||
if _platform == 'win32':
|
||||
if dir[-1] == '\\' or dir[-1] == '/':
|
||||
dir = dir[:-1]
|
||||
else:
|
||||
if dir[-1] == '/':
|
||||
dir = dir[:-1]
|
||||
|
||||
# Do not allow user to access outside his storage dir in server mode.
|
||||
if not orig_path.startswith(dir):
|
||||
raise Exception(
|
||||
gettext(u"Access denied ({})".format(path)))
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def get_abs_path(dir, path):
|
||||
|
||||
if (path.startswith('\\\\') and _platform == 'win32')\
|
||||
or config.SERVER_MODE is False:
|
||||
return u"{}".format(path)
|
||||
|
||||
if path == '/' or path == '\\':
|
||||
if _platform == 'win32':
|
||||
if dir.endswith('\\') or dir.endswith('/'):
|
||||
return u"{}".format(dir)
|
||||
else:
|
||||
return u"{}{}".format(dir, '\\')
|
||||
else:
|
||||
if dir.endswith('/'):
|
||||
return u"{}".format(dir)
|
||||
else:
|
||||
return u"{}{}".format(dir, '/')
|
||||
|
||||
if dir.endswith('/') or dir.endswith('\\'):
|
||||
if path.startswith('/') or path.startswith('\\'):
|
||||
return u"{}{}".format(dir[:-1], path)
|
||||
else:
|
||||
return u"{}/{}".format(dir, path)
|
||||
else:
|
||||
if path.startswith('/') or path.startswith('\\'):
|
||||
return u"{}{}".format(dir, path)
|
||||
else:
|
||||
return u"{}/{}".format(dir, path)
|
||||
|
||||
def validate_request(self, capability):
|
||||
"""
|
||||
It validates the capability with the capabilities
|
||||
@@ -560,13 +644,35 @@ class Filemanager(object):
|
||||
if self.dir is None:
|
||||
self.dir = ""
|
||||
orig_path = u"{0}{1}".format(self.dir, path)
|
||||
|
||||
try:
|
||||
Filemanager.check_access_permission(self.dir, path)
|
||||
except Exception as e:
|
||||
thefile = {
|
||||
'Filename': split_path(path)[-1],
|
||||
'FileType': '',
|
||||
'Path': path,
|
||||
'Error': gettext(u"Error: {0}".format(e)),
|
||||
'Code': 0,
|
||||
'Info': '',
|
||||
'Properties': {
|
||||
'Date Created': '',
|
||||
'Date Modified': '',
|
||||
'Width': '',
|
||||
'Height': '',
|
||||
'Size': ''
|
||||
}
|
||||
}
|
||||
return thefile
|
||||
|
||||
user_dir = path
|
||||
thefile = {
|
||||
'Filename': split_path(orig_path)[-1],
|
||||
'File Type': '',
|
||||
'FileType': '',
|
||||
'Path': user_dir,
|
||||
'Error': '',
|
||||
'Code': 0,
|
||||
'Code': 1,
|
||||
'Info': '',
|
||||
'Properties': {
|
||||
'Date Created': '',
|
||||
'Date Modified': '',
|
||||
@@ -577,13 +683,16 @@ class Filemanager(object):
|
||||
}
|
||||
|
||||
if not path_exists(orig_path):
|
||||
thefile['Error'] = gettext('File does not exist.')
|
||||
return (encode_json(thefile), None, 'application/json')
|
||||
thefile['Error'] = gettext(u"'{}' file does not exist.".format(
|
||||
path))
|
||||
thefile['Code'] = -1
|
||||
return thefile
|
||||
|
||||
if split_path(user_dir)[-1] == '/':
|
||||
thefile['File Type'] = 'Directory'
|
||||
if split_path(user_dir)[-1] == '/'\
|
||||
or os.path.isfile(orig_path) is False:
|
||||
thefile['FileType'] = 'Directory'
|
||||
else:
|
||||
thefile['File Type'] = splitext(user_dir)
|
||||
thefile['FileType'] = splitext(user_dir)
|
||||
|
||||
created = time.ctime(os.path.getctime(orig_path))
|
||||
modified = time.ctime(os.path.getmtime(orig_path))
|
||||
@@ -599,9 +708,11 @@ class Filemanager(object):
|
||||
Returns files and folders in give path
|
||||
"""
|
||||
trans_data = Filemanager.get_trasaction_selection(self.trans_id)
|
||||
dir = self.dir if self.dir is not None else ''
|
||||
if not dir.endswith('/'):
|
||||
dir += '/';
|
||||
dir = None
|
||||
if config.SERVER_MODE:
|
||||
dir = self.dir if self.dir is not None else ''
|
||||
if not dir.endswith('/'):
|
||||
dir += u'/'
|
||||
|
||||
filelist = self.list_filesystem(dir, path, trans_data, file_type)
|
||||
return filelist
|
||||
@@ -613,10 +724,21 @@ class Filemanager(object):
|
||||
if not self.validate_request('rename'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 1
|
||||
'Code': 0
|
||||
}
|
||||
|
||||
dir = self.dir if self.dir is not None else ''
|
||||
|
||||
try:
|
||||
Filemanager.check_access_permission(dir, old)
|
||||
Filemanager.check_access_permission(dir, new)
|
||||
except Exception as e:
|
||||
res = {
|
||||
'Error': gettext(u"Error: {0}".format(e)),
|
||||
'Code': 0
|
||||
}
|
||||
return res
|
||||
|
||||
# check if it's dir
|
||||
if old[-1] == '/':
|
||||
old = old[:-1]
|
||||
@@ -629,9 +751,8 @@ class Filemanager(object):
|
||||
path = split_path(path)[0] # extract path
|
||||
|
||||
if not path[-1] == '/':
|
||||
path += '/'
|
||||
path += u'/'
|
||||
|
||||
# newname = encode_urlpath(new)
|
||||
newname = new
|
||||
if hasattr(str, 'decode'):
|
||||
newname = new.encode('utf-8').decode('utf-8')
|
||||
@@ -641,15 +762,14 @@ class Filemanager(object):
|
||||
oldpath_sys = u"{0}{1}".format(dir, old)
|
||||
newpath_sys = u"{0}{1}".format(dir, newpath)
|
||||
|
||||
error_msg = gettext('Renamed successfully.')
|
||||
error_msg = gettext(u'Renamed successfully.')
|
||||
code = 1
|
||||
try:
|
||||
os.rename(oldpath_sys, newpath_sys)
|
||||
code = 0
|
||||
except Exception as e:
|
||||
error_msg = "{0} {1}".format(
|
||||
gettext('There was an error renaming the file:'),
|
||||
str(e))
|
||||
code = 0
|
||||
error_msg = u"{0} {1}".format(
|
||||
gettext(u'There was an error renaming the file:'), e)
|
||||
|
||||
result = {
|
||||
'Old Path': old,
|
||||
@@ -669,24 +789,32 @@ class Filemanager(object):
|
||||
if not self.validate_request('delete'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 1
|
||||
'Code': 0
|
||||
}
|
||||
|
||||
dir = self.dir if self.dir is not None else ''
|
||||
path = path.encode('utf-8').decode('utf-8') if hasattr(str, 'decode') else path
|
||||
orig_path = u"{0}{1}".format(dir, path)
|
||||
|
||||
try:
|
||||
Filemanager.check_access_permission(dir, path)
|
||||
except Exception as e:
|
||||
res = {
|
||||
'Error': gettext(u"Error: {0}".format(e)),
|
||||
'Code': 0
|
||||
}
|
||||
return res
|
||||
|
||||
err_msg = ''
|
||||
code = 1
|
||||
try:
|
||||
if os.path.isdir(orig_path):
|
||||
os.rmdir(orig_path)
|
||||
code = 0
|
||||
else:
|
||||
os.remove(orig_path)
|
||||
code = 0
|
||||
except Exception as e:
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
code = 0
|
||||
err_msg = u"Error: {0}".format(e.strerror)
|
||||
|
||||
result = {
|
||||
'Path': path,
|
||||
@@ -703,7 +831,7 @@ class Filemanager(object):
|
||||
if not self.validate_request('upload'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 1
|
||||
'Code': 0
|
||||
}
|
||||
|
||||
dir = self.dir if self.dir is not None else ''
|
||||
@@ -718,13 +846,22 @@ class Filemanager(object):
|
||||
path = req.form.get('currentpath').encode('utf-8').decode('utf-8')
|
||||
file_name = file_obj.filename.encode('utf-8').decode('utf-8')
|
||||
orig_path = u"{0}{1}".format(dir, path)
|
||||
newName = u'{0}{1}'.format(orig_path, file_name)
|
||||
newName = u"{0}{1}".format(orig_path, file_name)
|
||||
|
||||
with open(newName, 'wb') as f:
|
||||
f.write(file_obj.read())
|
||||
code = 0
|
||||
except Exception as e:
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
code = 0
|
||||
err_msg = u"Error: {0}".format(e.strerror)
|
||||
|
||||
try:
|
||||
Filemanager.check_access_permission(dir, path)
|
||||
except Exception as e:
|
||||
res = {
|
||||
'Error': gettext(u"Error: {0}".format(e)),
|
||||
'Code': 0
|
||||
}
|
||||
return res
|
||||
|
||||
result = {
|
||||
'Path': path,
|
||||
@@ -745,17 +882,21 @@ class Filemanager(object):
|
||||
name = unquote(name)
|
||||
path = unquote(path)
|
||||
if hasattr(str, 'decode'):
|
||||
name = unquote(name).encode('utf-8')
|
||||
path = unquote(path).encode('utf-8')
|
||||
name = name.encode('utf-8').decode('utf-8')
|
||||
path = path.encode('utf-8').decode('utf-8')
|
||||
try:
|
||||
orig_path = "{0}{1}".format(dir, path)
|
||||
newName = '{0}{1}'.format(orig_path, name)
|
||||
if os.path.exists(newName):
|
||||
orig_path = u"{0}{1}".format(dir, path)
|
||||
Filemanager.check_access_permission(dir, u"{}{}".format(path, name))
|
||||
|
||||
newName = u"{0}{1}".format(orig_path, name)
|
||||
if not os.path.exists(newName):
|
||||
code = 0
|
||||
else:
|
||||
code = 1
|
||||
except Exception as e:
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
code = 0
|
||||
if hasattr(e, 'strerror'):
|
||||
err_msg = u"Error: {0}".format(e.strerror)
|
||||
else:
|
||||
err_msg = u"Error: {0}".format(e)
|
||||
|
||||
result = {
|
||||
'Path': path,
|
||||
@@ -773,12 +914,12 @@ class Filemanager(object):
|
||||
with same name already exists
|
||||
"""
|
||||
last_char = newName[-1]
|
||||
tnewPath = dir + '/' + path + newName + '_' + str(count)
|
||||
tnewPath = u"{}/{}{}_{}".format(dir, path, newName, count)
|
||||
if last_char == 'r' and not path_exists(tnewPath):
|
||||
return tnewPath, newName
|
||||
else:
|
||||
last_char = int(tnewPath[-1]) + 1
|
||||
newPath = dir + '/' + path + newName + '_' + str(last_char)
|
||||
newPath = u"{}/{}{}_{}".format(dir, path, newName, last_char)
|
||||
if path_exists(newPath):
|
||||
count += 1
|
||||
return Filemanager.getNewName(dir, path, newName, count)
|
||||
@@ -792,40 +933,42 @@ class Filemanager(object):
|
||||
if not self.validate_request('create'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 1
|
||||
'Code': 0
|
||||
}
|
||||
|
||||
dir = self.dir if self.dir is not None else ''
|
||||
newName = name
|
||||
if hasattr(str, 'decode'):
|
||||
newName = name.encode('utf-8')
|
||||
|
||||
try:
|
||||
Filemanager.check_access_permission(dir, u"{}{}".format(
|
||||
path, name))
|
||||
except Exception as e:
|
||||
res = {
|
||||
'Error': gettext(u"Error: {0}".format(e)),
|
||||
'Code': 0
|
||||
}
|
||||
return res
|
||||
|
||||
if dir != "":
|
||||
if hasattr(str, 'decode'):
|
||||
newPath = dir + '/' + path + newName.decode('utf-8') + '/'
|
||||
else:
|
||||
newPath = dir + '/' + path + newName + '/'
|
||||
newPath = u"{}/{}{}/".format(dir, path, name)
|
||||
else:
|
||||
if hasattr(str, 'decode'):
|
||||
newPath = path + newName.decode('utf-8') + '/'
|
||||
else:
|
||||
newPath = path + newName + '/'
|
||||
newPath = u"{}{}/".format(path, name)
|
||||
|
||||
err_msg = ''
|
||||
code = 1
|
||||
newName = name
|
||||
if not path_exists(newPath):
|
||||
try:
|
||||
os.mkdir(newPath)
|
||||
code = 0
|
||||
except Exception as e:
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
code = 0
|
||||
err_msg = u"Error: {0}".format(e.strerror)
|
||||
else:
|
||||
newPath, newName = self.getNewName(dir, path, newName)
|
||||
newPath, newName = self.getNewName(dir, path, name)
|
||||
try:
|
||||
os.mkdir(newPath)
|
||||
code = 0
|
||||
except Exception as e:
|
||||
err_msg = "Error: {0}".format(e.strerror)
|
||||
code = 0
|
||||
err_msg = u"Error: {0}".format(e.strerror)
|
||||
|
||||
result = {
|
||||
'Parent': path,
|
||||
@@ -843,21 +986,42 @@ class Filemanager(object):
|
||||
if not self.validate_request('download'):
|
||||
return {
|
||||
'Error': gettext('Not allowed'),
|
||||
'Code': 1
|
||||
'Code': 0
|
||||
}
|
||||
|
||||
dir = self.dir if self.dir is not None else ''
|
||||
|
||||
if hasattr(str, 'decode'):
|
||||
path = path.encode('utf-8')
|
||||
orig_path = u"{0}{1}".format(dir, path.decode('utf-8'))
|
||||
else:
|
||||
orig_path = "{0}{1}".format(dir, path)
|
||||
orig_path = u"{0}{1}".format(dir, path)
|
||||
|
||||
try:
|
||||
Filemanager.check_access_permission(dir, u"{}{}".format(
|
||||
path, path))
|
||||
except Exception as e:
|
||||
resp = Response(gettext(u"Error: {0}".format(e)))
|
||||
resp.headers['Content-Disposition'] = 'attachment; filename=' + name
|
||||
return resp
|
||||
|
||||
name = path.split('/')[-1]
|
||||
content = open(orig_path, 'rb')
|
||||
resp = Response(content)
|
||||
resp.headers['Content-Disposition'] = 'attachment; filename=' + name
|
||||
return resp
|
||||
|
||||
def permission(self, path=None, req=None):
|
||||
dir = self.dir if self.dir is not None else ''
|
||||
res = {'Code': 1}
|
||||
try:
|
||||
Filemanager.check_access_permission(dir, path)
|
||||
except Exception as e:
|
||||
err_msg = u"Error: {0}".format(e)
|
||||
res['Code'] = 0
|
||||
res['Error'] = err_msg
|
||||
return res
|
||||
|
||||
|
||||
@blueprint.route("/filemanager/<int:trans_id>/", methods=["GET", "POST"])
|
||||
@login_required
|
||||
|
@@ -15,19 +15,17 @@
|
||||
top: 35px;
|
||||
}
|
||||
|
||||
#uploader h1 {
|
||||
#uploader .input-path {
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
margin-left: 5px;
|
||||
padding: 0;
|
||||
display: block;
|
||||
float: left;
|
||||
text-align: left;
|
||||
line-height:1.9em;
|
||||
max-width: 367px;
|
||||
line-height:1.6em;
|
||||
width: calc(100% - 72px);
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#uploader h1 b {
|
||||
|
@@ -5,13 +5,14 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="file_manager">
|
||||
<form id="uploader" method="post" class='col-xs-12'>
|
||||
<div id="uploader" class='col-xs-12'>
|
||||
<div class="btn-group filemanager-path-group col-sm-7 col-xs-12" role="group">
|
||||
<button name="home" type="button" value="Home" title="Home" class="fa fa-home btn home"><span></span>
|
||||
</button>
|
||||
<button name="level-up" type="button" title="Back" value="LevelUp" class="btn fa fa-level-up level-up"
|
||||
disabled><span></span></button>
|
||||
<h1 title=''></h1>
|
||||
<input class='input-path' title='' type="text"/>
|
||||
|
||||
</div>
|
||||
<div class="btn-group filemanager-btn-group" role="group">
|
||||
<div class="uploadresponse"></div>
|
||||
@@ -29,7 +30,7 @@
|
||||
<button class="ON fa fa-th btn grid" type="button" title="View as grid"><span></span></button>
|
||||
<button type="button" class="btn fa fa-list list" title="View as Table"><span></span></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="fileinfo">
|
||||
<span class="activity">
|
||||
<img src="{{ url_for('browser.static', filename='css/aciTree/image/load-root.gif') }}">
|
||||
|
@@ -47,9 +47,9 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
var set_last_traversed_dir = function(path, _url) {
|
||||
var set_last_traversed_dir = function(path, trans_id) {
|
||||
return $.ajax({
|
||||
url: _url,
|
||||
url: "{{ url_for('file_manager.index') }}save_last_dir/" + trans_id,
|
||||
type: 'POST',
|
||||
data: JSON.stringify(path),
|
||||
contentType: 'application/json'
|
||||
@@ -90,6 +90,7 @@ define([
|
||||
return {
|
||||
main: function(params) {
|
||||
// Set title and button name
|
||||
var self = this;
|
||||
if (_.isUndefined(params['dialog_title'])) {
|
||||
params['dialog_title'] = 'Storage manager';
|
||||
}
|
||||
@@ -105,6 +106,11 @@ define([
|
||||
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
|
||||
@@ -127,7 +133,7 @@ define([
|
||||
return {
|
||||
buttons:[
|
||||
{
|
||||
text: "{{ _('Select') }}", key: 13, className: "btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled"
|
||||
text: "{{ _('Select') }}", className: "btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled"
|
||||
},
|
||||
{
|
||||
text: "{{ _('Cancel') }}", className: "btn btn-danger fa fa-times pg-alertify-button"
|
||||
@@ -142,25 +148,21 @@ define([
|
||||
},
|
||||
callback: function(closeEvent) {
|
||||
if (closeEvent.button.text == "{{ _('Select') }}") {
|
||||
if($('.fileinfo').data('view') == 'grid') {
|
||||
sel_file = $('.fileinfo').find('#contents li.selected p span').attr('title');
|
||||
} else {
|
||||
sel_file = $('.fileinfo tbody tr.selected td p span').attr('title');
|
||||
}
|
||||
var newFile = $('.currentpath').val() + sel_file;
|
||||
var newFile = $('.storage_dialog #uploader .input-path').val(),
|
||||
file_data = {'path': $('.currentpath').val()};
|
||||
|
||||
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:storage_dialog', newFile);
|
||||
|
||||
var _Url = "{{ url_for('file_manager.index') }}" + "save_last_dir/" + trans_id;
|
||||
var file_data = {
|
||||
'path': $('.currentpath').val()
|
||||
};
|
||||
set_last_traversed_dir(file_data, _Url);
|
||||
set_last_traversed_dir(file_data, trans_id);
|
||||
var innerbody = $(this.elements.body).find('.storage_content')
|
||||
$(innerbody).find('*').off();
|
||||
innerbody.remove();
|
||||
removeTransId(trans_id);
|
||||
} else if (closeEvent.button.text == "{{ _('Cancel') }}") {
|
||||
if (removeTransId(trans_id)) {
|
||||
this.destroy();
|
||||
return;
|
||||
}
|
||||
var innerbody = $(this.elements.body).find('.storage_content')
|
||||
$(innerbody).find('*').off();
|
||||
innerbody.remove();
|
||||
removeTransId(trans_id);
|
||||
}
|
||||
},
|
||||
build: function() {
|
||||
@@ -210,6 +212,7 @@ define([
|
||||
return {
|
||||
main: function(params) {
|
||||
// Set title and button name
|
||||
var self = this;
|
||||
if (_.isUndefined(params['dialog_title'])) {
|
||||
params['dialog_title'] = 'Select file';
|
||||
}
|
||||
@@ -225,6 +228,11 @@ define([
|
||||
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
|
||||
@@ -247,7 +255,7 @@ define([
|
||||
return {
|
||||
buttons:[
|
||||
{
|
||||
text: "{{ _('Select') }}", key: 13, className: "btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled"
|
||||
text: "{{ _('Select') }}", className: "btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled"
|
||||
},
|
||||
{
|
||||
text: "{{ _('Cancel') }}", key: 27, className: "btn btn-danger fa fa-times pg-alertify-button"
|
||||
@@ -264,26 +272,22 @@ define([
|
||||
},
|
||||
callback: function(closeEvent) {
|
||||
if (closeEvent.button.text == "{{ _('Select') }}") {
|
||||
if($('.fileinfo').data('view') == 'grid') {
|
||||
sel_file = $('.fileinfo').find('#contents li.selected p span').attr('title');
|
||||
} else {
|
||||
sel_file = $('.fileinfo tbody tr.selected td p span').attr('title');
|
||||
}
|
||||
var newFile = $('.currentpath').val() + sel_file;
|
||||
var newFile = $('.storage_dialog #uploader .input-path').val(),
|
||||
file_data = {'path': $('.currentpath').val()};
|
||||
|
||||
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:select_file', newFile);
|
||||
var 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
|
||||
var _Url = "{{ url_for('file_manager.index') }}" + "save_last_dir/" + trans_id;
|
||||
var file_data = {
|
||||
'path': $('.currentpath').val()
|
||||
};
|
||||
set_last_traversed_dir(file_data, _Url);
|
||||
|
||||
set_last_traversed_dir(file_data, trans_id);
|
||||
} else if (closeEvent.button.text == "{{ _('Cancel') }}") {
|
||||
if (removeTransId(trans_id)) {
|
||||
this.destroy();
|
||||
return;
|
||||
}
|
||||
var innerbody = $(this.elements.body).find('.storage_content')
|
||||
$(innerbody).find('*').off();
|
||||
innerbody.remove();
|
||||
removeTransId(trans_id);
|
||||
}
|
||||
},
|
||||
build: function() {
|
||||
@@ -332,6 +336,7 @@ define([
|
||||
// Dialog property
|
||||
return {
|
||||
main: function(params) {
|
||||
var self = this;
|
||||
// Set title and button name
|
||||
if (_.isUndefined(params['dialog_title'])) {
|
||||
params['dialog_title'] = 'Select folder';
|
||||
@@ -348,6 +353,11 @@ define([
|
||||
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
|
||||
@@ -370,7 +380,7 @@ define([
|
||||
return {
|
||||
buttons:[
|
||||
{
|
||||
text: "{{ _('Select') }}", key: 13, className: "btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled"
|
||||
text: "{{ _('Select') }}", className: "btn btn-primary fa fa-file file_manager_ok pg-alertify-button disabled"
|
||||
},
|
||||
{
|
||||
text: "{{ _('Cancel') }}", key: 27, className: "btn btn-danger fa fa-times pg-alertify-button"
|
||||
@@ -387,26 +397,20 @@ define([
|
||||
},
|
||||
callback: function(closeEvent) {
|
||||
if (closeEvent.button.text == "{{ _('Select') }}") {
|
||||
if($('.fileinfo').data('view') == 'grid') {
|
||||
sel_file = $('.fileinfo').find('#contents li.selected p span').attr('title');
|
||||
} else {
|
||||
sel_file = $('.fileinfo tbody tr.selected td p span').attr('title');
|
||||
}
|
||||
var newFile = $('.currentpath').val() + sel_file;
|
||||
|
||||
var newFile = $('.storage_dialog #uploader .input-path').val(),
|
||||
file_data = {'path': $('.currentpath').val()};
|
||||
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:select_folder', newFile);
|
||||
var 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
|
||||
var _Url = "{{ url_for('file_manager.index') }}" + "save_last_dir/" + trans_id;
|
||||
var file_data = {
|
||||
'path': $('.currentpath').val()
|
||||
};
|
||||
set_last_traversed_dir(file_data, _Url);
|
||||
set_last_traversed_dir(file_data, trans_id);
|
||||
} else if (closeEvent.button.text == "{{ _('Cancel') }}") {
|
||||
if (removeTransId(trans_id)) {
|
||||
this.destroy();
|
||||
return;
|
||||
}
|
||||
var innerbody = $(this.elements.body).find('.storage_content')
|
||||
$(innerbody).find('*').off();
|
||||
innerbody.remove();
|
||||
removeTransId(trans_id);
|
||||
}
|
||||
},
|
||||
build: function() {
|
||||
@@ -454,7 +458,8 @@ define([
|
||||
// Dialog property
|
||||
return {
|
||||
main: function(params) {
|
||||
var trans_id;
|
||||
var self = this,
|
||||
trans_id;
|
||||
// Set title and button name
|
||||
if (_.isUndefined(params['dialog_title'])) {
|
||||
params['dialog_title'] = 'Create file';
|
||||
@@ -471,6 +476,11 @@ define([
|
||||
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
|
||||
@@ -493,7 +503,7 @@ define([
|
||||
return {
|
||||
buttons:[
|
||||
{
|
||||
text: "{{ _('Create') }}", key: 13, className: "btn btn-primary fa fa-file file_manager_create file_manager_ok pg-alertify-button disabled"
|
||||
text: "{{ _('Create') }}", className: "btn btn-primary fa fa-file file_manager_create file_manager_ok pg-alertify-button disabled"
|
||||
},
|
||||
{
|
||||
text: "{{ _('Cancel') }}", key: 27, className: "btn btn-danger fa fa-times file_manager_create_cancel pg-alertify-button"
|
||||
@@ -509,25 +519,41 @@ define([
|
||||
};
|
||||
},
|
||||
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();
|
||||
$('.replace_file .btn_yes').click(function(self) {
|
||||
|
||||
$yesBtn.click(function(e) {
|
||||
$('.replace_file, .fm_dimmer').hide();
|
||||
var selected_item = $('.allowed_file_types .create_input input[type="text"]').val(),
|
||||
newFile = $('.currentpath').val() + selected_item;
|
||||
$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');
|
||||
});
|
||||
$('.replace_file .btn_no').click(function() {
|
||||
|
||||
$noBtn.click(function(e) {
|
||||
$('.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 selected_item = $('.allowed_file_types .create_input input[type="text"]').val(),
|
||||
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': $('.currentpath').val(),
|
||||
'path': path,
|
||||
'name': selected_item,
|
||||
'mode': 'is_file_exist'
|
||||
};
|
||||
@@ -541,7 +567,7 @@ define([
|
||||
async: false,
|
||||
success: function(resp) {
|
||||
data = resp.data.result;
|
||||
if(data['Code'] === 0) {
|
||||
if(data['Code'] === 1) {
|
||||
is_exist = true;
|
||||
} else {
|
||||
is_exist = false;
|
||||
@@ -550,30 +576,63 @@ define([
|
||||
});
|
||||
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: fileConnector + 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('{{ _('Error occurred while checking access permission.') }}');
|
||||
}
|
||||
});
|
||||
return permission;
|
||||
},
|
||||
callback: function(closeEvent) {
|
||||
if (closeEvent.button.text == "{{ _('Create') }}") {
|
||||
var selected_item = $('.allowed_file_types .create_input input[type="text"]').val();
|
||||
var newFile = $('.currentpath').val() + selected_item;
|
||||
var newFile = $('.storage_dialog #uploader .input-path').val(),
|
||||
file_data = {'path': $('.currentpath').val()};
|
||||
|
||||
if(!_.isUndefined(selected_item) && selected_item !== '' && this.is_file_exist()) {
|
||||
if (!this.check_permission(newFile)) {
|
||||
closeEvent.cancel = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!_.isUndefined(newFile) && newFile !== '' && this.is_file_exist()) {
|
||||
this.replace_file();
|
||||
closeEvent.cancel = true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pgAdmin.Browser.Events.trigger('pgadmin-storage:finish_btn:create_file', newFile);
|
||||
var innerbody = $(this.elements.body).find('.storage_content');
|
||||
$(innerbody).find('*').off();
|
||||
innerbody.remove();
|
||||
removeTransId(trans_id);
|
||||
}
|
||||
|
||||
var _Url = "{{ url_for('file_manager.index') }}" + "save_last_dir/" + trans_id;
|
||||
var file_data = {
|
||||
'path': $('.currentpath').val()
|
||||
};
|
||||
set_last_traversed_dir(file_data, _Url);
|
||||
set_last_traversed_dir(file_data, trans_id);
|
||||
} else if (closeEvent.button.text == "{{ _('Cancel') }}") {
|
||||
if (removeTransId(trans_id)) {
|
||||
this.destroy();
|
||||
return;
|
||||
}
|
||||
var innerbody = $(this.elements.body).find('.storage_content')
|
||||
$(innerbody).find('*').off();
|
||||
innerbody.remove();
|
||||
removeTransId(trans_id);
|
||||
}
|
||||
},
|
||||
build: function() {
|
||||
|
@@ -159,37 +159,42 @@ var setUploader = function(path) {
|
||||
$('.storage_dialog #uploader').find('a').remove();
|
||||
$('.storage_dialog #uploader').find('b').remove();
|
||||
|
||||
path = decodeURI(path);
|
||||
|
||||
var display_string = path,
|
||||
file_path = '';
|
||||
|
||||
// split path
|
||||
var split_path = display_string.split('/');
|
||||
split_path = split_path.filter(function(e) {return e;});
|
||||
|
||||
// set empty path if it is windows
|
||||
if (config.options.platform_type === "win32" && config.options.show_volumes) {
|
||||
file_path = "";
|
||||
} else if (split_path.length === 0) {
|
||||
file_path = '/';
|
||||
if(config.options.platform_type === "win32") {
|
||||
path = path.replace(/\//g, '\\')
|
||||
} else {
|
||||
file_path = '/';
|
||||
path = path.replace(/\\/g, '/')
|
||||
}
|
||||
|
||||
Object.keys(split_path).forEach(function (i) {
|
||||
file_path += split_path[i] + '/';
|
||||
});
|
||||
$('.storage_dialog #uploader h1').html(file_path);
|
||||
path = decodeURI(path);
|
||||
if (config.options.platform_type === "win32") {
|
||||
if (config.options.show_volumes && path == '\\') {
|
||||
$('.storage_dialog #uploader .input-path').val('');
|
||||
} else {
|
||||
$('.storage_dialog #uploader .input-path').val(path);
|
||||
}
|
||||
} else if (!config.options.platform_type === "win32" &&
|
||||
(path == '' || !path.startsWith('/'))) {
|
||||
path = '/' + path;
|
||||
$('.storage_dialog #uploader .input-path').val(path);
|
||||
} else {
|
||||
$('.storage_dialog #uploader .input-path').val(path);
|
||||
}
|
||||
|
||||
if( path.lastIndexOf('\\') == -1 && path.lastIndexOf('/') == -1) {
|
||||
$('.currentpath').val(path);
|
||||
} else if(path.lastIndexOf('/') > path.lastIndexOf('\\')) {
|
||||
$('.currentpath').val(path.substr(0, path.lastIndexOf('/') + 1));
|
||||
} else {
|
||||
$('.currentpath').val(path.substr(0, path.lastIndexOf('\\') + 1));
|
||||
}
|
||||
|
||||
$('.currentpath').val(path);
|
||||
enab_dis_level_up();
|
||||
if ($('.storage_dialog #uploader h1 span').length === 0) {
|
||||
$('<span>'+lg.current_folder+'</span>').appendTo($('.storage_dialog #uploader h1'));
|
||||
}
|
||||
|
||||
$('.storage_dialog #uploader h1').attr('title', display_string);
|
||||
$('.storage_dialog #uploader h1').attr('data-path', display_string);
|
||||
$('.storage_dialog #uploader .input-path').attr('title', path);
|
||||
$('.storage_dialog #uploader .input-path').attr('data-path', path);
|
||||
|
||||
// create new folder
|
||||
$('.create').unbind().click(function() {
|
||||
@@ -288,7 +293,7 @@ var setUploader = function(path) {
|
||||
var d = new Date(); // to prevent IE cache issues
|
||||
$.getJSON(fileConnector + '?mode=addfolder&path=' + $('.currentpath').val() + '&name=' + foldername, function(resp) {
|
||||
var result = resp.data.result;
|
||||
if (result.Code === 0) {
|
||||
if (result.Code === 1) {
|
||||
alertify.success(lg.successful_added_folder);
|
||||
getFolderInfo(result.Parent);
|
||||
} else {
|
||||
@@ -382,7 +387,6 @@ var enable_disable_btn = function() {
|
||||
$('.file_manager').find('button.download').prop('disabled', true);
|
||||
$('.file_manager').find('button.rename').prop('disabled', true);
|
||||
if ($grid_file.length > 0) {
|
||||
$('.create_input input[type="text"]').val('');
|
||||
$('.file_manager_ok').addClass('disabled');
|
||||
}
|
||||
} else {
|
||||
@@ -392,14 +396,13 @@ var enable_disable_btn = function() {
|
||||
$('.file_manager').find('button.download').prop('disabled', true);
|
||||
$('.file_manager').find('button.rename').prop('disabled', true);
|
||||
if ($list_file.length > 0) {
|
||||
$('.create_input input[type="text"]').val('');
|
||||
$('.file_manager_ok').addClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
$('.delete_item').hide();
|
||||
// clear address bar
|
||||
$('.file_manager #uploader h1').show();
|
||||
$('.file_manager #uploader .input-path').show();
|
||||
$('.file_manager #uploader .show_selected_file').remove();
|
||||
};
|
||||
|
||||
@@ -436,7 +439,7 @@ var renameItem = function(data) {
|
||||
async: false,
|
||||
success: function(resp) {
|
||||
var result = resp.data.result;
|
||||
if (result.Code === 0) {
|
||||
if (result.Code === 1) {
|
||||
var newPath = result['New Path'],
|
||||
newName = result['New Name'],
|
||||
title = $("#preview h1").attr("title");
|
||||
@@ -500,7 +503,7 @@ var deleteItem = function(data) {
|
||||
async: false,
|
||||
success: function(resp) {
|
||||
var result = resp.data.result;
|
||||
if (result.Code === 0) {
|
||||
if (result.Code === 1) {
|
||||
isDeleted = true;
|
||||
if (isDeleted) {
|
||||
alertify.success(lg.successful_delete);
|
||||
@@ -529,7 +532,7 @@ var deleteItem = function(data) {
|
||||
* the path provided.
|
||||
*/
|
||||
var getDetailView = function(path) {
|
||||
if (path.lastIndexOf('/') == path.length - 1) {
|
||||
if (path.lastIndexOf('/') == path.length - 1 || path.lastIndexOf('\\') == path.length - 1) {
|
||||
var allowed_types = config.options.allowed_file_types;
|
||||
var set_type = allowed_types[0];
|
||||
if (allowed_types[0] == "*") {
|
||||
@@ -548,11 +551,11 @@ var getDetailView = function(path) {
|
||||
*/
|
||||
var getFileInfo = function(file) {
|
||||
// Update location for status, upload, & new folder functions.
|
||||
var currentpath = file.substr(0, file.lastIndexOf('/') + 1);
|
||||
setUploader(currentpath);
|
||||
setUploader(file);
|
||||
|
||||
// Retrieve the data & populate the template.
|
||||
var d = new Date(); // to prevent IE cache issues
|
||||
var d = new Date(), // to prevent IE cache issues
|
||||
is_file_valid = false;
|
||||
var post_data = {
|
||||
'path': file,
|
||||
'mode': 'getinfo'
|
||||
@@ -567,8 +570,8 @@ var getFileInfo = function(file) {
|
||||
async: false,
|
||||
success: function(resp) {
|
||||
var data = resp.data.result;
|
||||
|
||||
if (data.Code === 0) {
|
||||
if (data.Code === 1) {
|
||||
$('.file_manager_ok').removeClass('disabled');
|
||||
var properties = '';
|
||||
if (
|
||||
data.Properties.Size || parseInt(data.Properties.Size)==0
|
||||
@@ -579,18 +582,69 @@ var getFileInfo = function(file) {
|
||||
}
|
||||
data.Capabilities = capabilities;
|
||||
bindToolbar(data);
|
||||
if (data.FileType == 'Directory') {
|
||||
// Enable/Disable level up button
|
||||
enab_dis_level_up();
|
||||
$('.file_manager_ok').addClass('disabled');
|
||||
|
||||
$('.file_manager button.delete, .file_manager button.rename').attr('disabled', 'disabled');
|
||||
$('.file_manager button.download').attr('disabled', 'disabled');
|
||||
|
||||
if (file.charAt(file.length - 1) != '/' && file.charAt(file.length - 1) != '\\') {
|
||||
file += '/';
|
||||
}
|
||||
getFolderInfo(file);
|
||||
} else {
|
||||
is_file_valid = true;
|
||||
}
|
||||
} else {
|
||||
$('.file_manager_ok').addClass('disabled');
|
||||
alertify.error(data.Error);
|
||||
}
|
||||
}
|
||||
});
|
||||
return is_file_valid;
|
||||
};
|
||||
|
||||
var checkPermission = function(path) {
|
||||
var permission = false,
|
||||
post_data = {
|
||||
'path': path,
|
||||
'mode': 'permission'
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
data: JSON.stringify(post_data),
|
||||
url: fileConnector,
|
||||
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('{{ _('Error occurred while checking access permission.') }}');
|
||||
}
|
||||
});
|
||||
return permission;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Retrieves data for all items within the given folder and
|
||||
* creates a list view.
|
||||
*/
|
||||
var getFolderInfo = function(path, file_type) {
|
||||
$('.storage_dialog #uploader .input-path').prop('disabled', true);
|
||||
if (!file_type) {
|
||||
file_type = '';
|
||||
}
|
||||
@@ -640,16 +694,16 @@ var getFolderInfo = function(path, file_type) {
|
||||
contentType: "application/json; charset=utf-8",
|
||||
async: false,
|
||||
success: function(resp) {
|
||||
$('.storage_dialog #uploader .input-path').prop('disabled', false);
|
||||
var result = '',
|
||||
data = resp.data.result;
|
||||
|
||||
// hide activity indicator
|
||||
$('.fileinfo').find('span.activity').hide();
|
||||
if (data.Code === 0) {
|
||||
alertify.error(data.err_msg);
|
||||
alertify.error(data.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
// generate HTML for files/folder and render into container
|
||||
if (!_.isEmpty(data)) {
|
||||
if ($('.fileinfo').data('view') == 'grid') {
|
||||
@@ -918,7 +972,7 @@ var getFolderInfo = function(path, file_type) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
} else if (e.type=="focusout") {
|
||||
if ($(this).css('display')=="inline-block") {
|
||||
if ($(this).css('display')=="inline-block" || $(this).css('display')=="inline") {
|
||||
var full_name = decodeURI(
|
||||
$(this).val()
|
||||
) + (last !== ''? '.' + last: '');
|
||||
@@ -951,7 +1005,6 @@ var getFolderInfo = function(path, file_type) {
|
||||
var old_name = decodeURI($(this).siblings('span').attr('title')),
|
||||
newvalue = old_name.substring(0, old_name.indexOf('.')),
|
||||
last = getFileExtension(old_name);
|
||||
|
||||
if (old_name.indexOf('.') == 0) {
|
||||
last = '';
|
||||
}
|
||||
@@ -961,7 +1014,7 @@ var getFolderInfo = function(path, file_type) {
|
||||
}
|
||||
|
||||
if (e.type=="focusout") {
|
||||
if ($(this).css('display')=="inline-block") {
|
||||
if ($(this).css('display')=="inline-block" || $(this).css('display')=="inline") {
|
||||
var full_name = decodeURI($(this).val()) + (
|
||||
last !== ''? '.' + last: ''
|
||||
);
|
||||
@@ -997,24 +1050,19 @@ var getFolderInfo = function(path, file_type) {
|
||||
// Get into folder on dblclick
|
||||
$('.fileinfo').find('#contents li').dblclick(function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
// Enable/Disable level up button
|
||||
enab_dis_level_up();
|
||||
|
||||
var path = decodeURI($(this).find('span').attr('data-alt'));
|
||||
|
||||
if (path.lastIndexOf("/") == path.length - 1) {
|
||||
if (path.lastIndexOf("/") == path.length - 1 || path.lastIndexOf("\\") == path.length - 1) {
|
||||
$('.file_manager_ok').addClass('disabled');
|
||||
|
||||
var $create_input = $('.create_input input[type="text"]');
|
||||
|
||||
$('.file_manager button.delete, .file_manager button.rename').attr('disabled', 'disabled');
|
||||
$('.file_manager button.download').attr('disabled', 'disabled');
|
||||
|
||||
getFolderInfo(path);
|
||||
if ($create_input.length != 0 && $create_input.val() != '') {
|
||||
$('.file_manager_ok').removeClass('disabled');
|
||||
}
|
||||
|
||||
} else {
|
||||
getFileInfo(path);
|
||||
}
|
||||
@@ -1028,7 +1076,7 @@ var getFolderInfo = function(path, file_type) {
|
||||
'.clip span.fm_lock_icon'
|
||||
).attr('data-protected');
|
||||
|
||||
if (path.lastIndexOf('/') == path.length - 1) {
|
||||
if (path.lastIndexOf('/') == path.length - 1 || path.lastIndexOf('\\') == path.length - 1) {
|
||||
if (
|
||||
has_capability(data_cap, 'select_folder') &&
|
||||
is_protected == undefined
|
||||
@@ -1044,7 +1092,7 @@ var getFolderInfo = function(path, file_type) {
|
||||
'disabled', 'disabled'
|
||||
);
|
||||
// set selected folder name in breadcrums
|
||||
$('.file_manager #uploader h1').hide();
|
||||
$('.file_manager #uploader .input-path').hide();
|
||||
$('.file_manager #uploader .show_selected_file').remove();
|
||||
$('<span class="show_selected_file">'+path+'</span>').appendTo(
|
||||
'.file_manager #uploader .filemanager-path-group'
|
||||
@@ -1065,13 +1113,6 @@ var getFolderInfo = function(path, file_type) {
|
||||
$('.file_manager #uploader .show_selected_file').remove();
|
||||
}
|
||||
|
||||
if (
|
||||
config.options.dialog_type == 'create_file' &&
|
||||
is_protected == undefined
|
||||
) {
|
||||
$('.create_input input[type="text"]').val(decodeURI(file_name));
|
||||
$('.file_manager_ok, .file_manager_create').removeClass('disabled');
|
||||
}
|
||||
getFileInfo(path);
|
||||
}
|
||||
});
|
||||
@@ -1086,7 +1127,7 @@ var getFolderInfo = function(path, file_type) {
|
||||
'i.tbl_lock_icon'
|
||||
).attr('data-protected');
|
||||
|
||||
if (path.lastIndexOf('/') == path.length - 1) {
|
||||
if (path.lastIndexOf('/') == path.length - 1 || path.lastIndexOf('\\') == path.length - 1) {
|
||||
if (has_capability(data_cap, 'select_folder') && is_protected == undefined) {
|
||||
$(this).parent().find('tr.selected').removeClass('selected');
|
||||
$('td:first-child', this).parent().addClass('selected');
|
||||
@@ -1095,7 +1136,7 @@ var getFolderInfo = function(path, file_type) {
|
||||
$('.file_manager button.delete, .file_manager button.rename').removeAttr('disabled');
|
||||
|
||||
// set selected folder name in breadcrums
|
||||
$('.file_manager #uploader h1').hide();
|
||||
$('.file_manager #uploader .input-path').hide();
|
||||
$('.file_manager #uploader .show_selected_file').remove();
|
||||
$('<span class="show_selected_file">'+path+'</span>').appendTo(
|
||||
'.file_manager #uploader .filemanager-path-group'
|
||||
@@ -1105,33 +1146,24 @@ var getFolderInfo = function(path, file_type) {
|
||||
if (has_capability(data_cap, 'select_file') && is_protected == undefined) {
|
||||
$(this).parent().find('tr.selected').removeClass('selected');
|
||||
$('td:first-child', this).parent().addClass('selected');
|
||||
$('.file_manager_ok').removeClass('disabled');
|
||||
$('.file_manager button.delete, .file_manager button.download, .file_manager button.rename').removeAttr(
|
||||
'disabled'
|
||||
);
|
||||
// set selected folder name in breadcrums
|
||||
$('.file_manager #uploader .show_selected_file').remove();
|
||||
}
|
||||
if (
|
||||
config.options.dialog_type == 'create_file' &&
|
||||
is_protected == undefined
|
||||
) {
|
||||
$('.create_input input[type="text"]').val(file_name);
|
||||
$('.file_manager_ok, .file_manager_create').removeClass('disabled');
|
||||
}
|
||||
|
||||
getFileInfo(path);
|
||||
}
|
||||
});
|
||||
|
||||
$('.fileinfo table#contents tbody tr').on('dblclick', function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
// Enable/Disable level up button
|
||||
enab_dis_level_up();
|
||||
|
||||
var path = $('td:first-child', this).attr('title');
|
||||
|
||||
if (path.lastIndexOf('/') == path.length - 1) {
|
||||
if (path.lastIndexOf('/') == path.length - 1 || path.lastIndexOf('\\') == path.length - 1) {
|
||||
$('.file_manager_ok').removeClass('disabled');
|
||||
$('.file_manager button.download').attr('disabled', 'disabled');
|
||||
$('.file_manager button.delete, .file_manager button.rename').attr('disabled', 'disabled');
|
||||
@@ -1142,13 +1174,17 @@ var getFolderInfo = function(path, file_type) {
|
||||
});
|
||||
|
||||
}
|
||||
input_object.set_cap(data_cap);
|
||||
},
|
||||
error: function() {
|
||||
$('.storage_dialog #uploader .input-path').prop('disabled', false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Enable/Disable level up button
|
||||
var enab_dis_level_up = function() {
|
||||
$('.file_manager #uploader h1').show();
|
||||
$('.file_manager #uploader .input-path').show();
|
||||
$('.show_selected_file').remove();
|
||||
|
||||
setTimeout(function() {
|
||||
@@ -1182,7 +1218,6 @@ if (transId.readyState == 4) {
|
||||
t_res = JSON.parse(transId.responseText);
|
||||
}
|
||||
t_id = t_res.data.fileTransId;
|
||||
|
||||
var root_url = '{{ url_for("file_manager.index") }}',
|
||||
file_manager_config_json = root_url+t_id+'/file_manager_config.json',
|
||||
file_manager_config_js = root_url+'file_manager_config.js',
|
||||
@@ -1203,6 +1238,7 @@ var fileRoot = config.options.fileRoot,
|
||||
* Get localized messages from file
|
||||
* through culture var or from URL
|
||||
*/
|
||||
|
||||
var lg = [],
|
||||
enjs = '{{ url_for("file_manager.index") }}' + "en.js",
|
||||
lgf = loadData(enjs);
|
||||
@@ -1260,39 +1296,26 @@ if (
|
||||
});
|
||||
}
|
||||
|
||||
if (config.options.dialog_type == 'create_file') {
|
||||
var create_file_html = '<div class="create_input">'+
|
||||
'<span>Filename:</span>'+
|
||||
'<input type="text" name="new_filename" class="fm_create_input form-control" />'+
|
||||
'</div>';
|
||||
|
||||
$('.create_mode_dlg').find('.allowed_file_types').prepend(create_file_html);
|
||||
$('.create_input input[type="text"]').on('keypress, keydown', function() {
|
||||
var input_text_len = $(this).val().length;
|
||||
if (input_text_len > 0 ) {
|
||||
$('.file_manager_ok').removeClass('disabled');
|
||||
} else {
|
||||
$('.file_manager_ok').addClass('disabled');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------
|
||||
Item Actions - Object events
|
||||
---------------------------------------------------------*/
|
||||
|
||||
// switch to folder view
|
||||
$('.file_manager .fileinfo').on('click', function(e) {
|
||||
$('.file_manager #uploader .input-path').val($('.currentpath').val())
|
||||
enable_disable_btn();
|
||||
});
|
||||
|
||||
// refresh current directory
|
||||
$('.file_manager .refresh').on('click', function(e) {
|
||||
enable_disable_btn();
|
||||
var curr_path = $('.currentpath').val(),
|
||||
path = curr_path.substring(
|
||||
0, curr_path.lastIndexOf("/")
|
||||
) + "/";
|
||||
var curr_path = $('.currentpath').val();
|
||||
$('.file_manager #uploader .input-path').val(curr_path);
|
||||
if(curr_path.endsWith("/")) {
|
||||
var path = curr_path.substring(0, curr_path.lastIndexOf("/")) + "/";
|
||||
} else {
|
||||
var path = curr_path.substring(0, curr_path.lastIndexOf("\\")) + "\\";
|
||||
}
|
||||
getFolderInfo(path);
|
||||
});
|
||||
|
||||
@@ -1345,12 +1368,20 @@ $('.file_manager .home').click(function() {
|
||||
// Go one directory back
|
||||
$(".file_manager .level-up").click(function() {
|
||||
var b = $('.currentpath').val();
|
||||
|
||||
// Enable/Disable level up button
|
||||
enab_dis_level_up();
|
||||
|
||||
if (b.endsWith('\\') || b.endsWith('/')) {
|
||||
b = b.substring(0, b.length - 1)
|
||||
}
|
||||
|
||||
if (b != '/') {
|
||||
parent = b.substring(0, b.slice(0, -1).lastIndexOf("/")) + "/";
|
||||
if(b.lastIndexOf('/') > b.lastIndexOf('\\')) {
|
||||
var parent = b.substring(0, b.slice(0, -1).lastIndexOf("/")) + "/";
|
||||
} else {
|
||||
var parent = b.substring(0, b.slice(0, -1).lastIndexOf("\\")) + "\\";
|
||||
}
|
||||
|
||||
var d = $(".fileinfo").data("view");
|
||||
$(".fileinfo").data("view", d);
|
||||
getFolderInfo(parent);
|
||||
@@ -1376,12 +1407,110 @@ $('.file_manager .list').click(function() {
|
||||
// Provide initial values for upload form, status, etc.
|
||||
setUploader(fileRoot);
|
||||
|
||||
$('#uploader').attr('action', fileConnector);
|
||||
|
||||
var data = {
|
||||
'Capabilities': capabilities
|
||||
};
|
||||
|
||||
function InputObject() {
|
||||
this.init= function(cap) {
|
||||
var self = this,
|
||||
check_obj = function(path, check) {
|
||||
|
||||
var path = decodeURI(path);
|
||||
|
||||
if (path.lastIndexOf('/') == path.length - 1 || path.lastIndexOf('\\') == path.length - 1) {
|
||||
if (
|
||||
has_capability(self.data_cap, 'select_folder')
|
||||
) {
|
||||
$('.file_manager_ok').removeClass('disabled');
|
||||
$('.file_manager button.delete, .file_manager button.rename').removeAttr(
|
||||
'disabled', 'disabled'
|
||||
);
|
||||
$('.file_manager button.download').attr(
|
||||
'disabled', 'disabled'
|
||||
);
|
||||
// set selected folder name in breadcrums
|
||||
$('.file_manager #uploader .input-path').hide();
|
||||
$('.file_manager #uploader .show_selected_file').remove();
|
||||
$('<span class="show_selected_file">'+path+'</span>').appendTo(
|
||||
'.file_manager #uploader .filemanager-path-group'
|
||||
);
|
||||
} else {
|
||||
$('.file_manager_ok').addClass('disabled');
|
||||
if(check) {
|
||||
// Enable/Disable level up button
|
||||
enab_dis_level_up();
|
||||
|
||||
$('.file_manager button.delete, .file_manager button.rename').attr('disabled', 'disabled');
|
||||
$('.file_manager button.download').attr('disabled', 'disabled');
|
||||
getFolderInfo(path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
has_capability(self.data_cap, 'select_file')
|
||||
) {
|
||||
$('.file_manager_ok').removeClass('disabled');
|
||||
$('.file_manager button.delete, .file_manager button.download, .file_manager button.rename').removeAttr(
|
||||
'disabled'
|
||||
);
|
||||
// set selected folder name in breadcrums
|
||||
$('.file_manager #uploader .show_selected_file').remove();
|
||||
}
|
||||
|
||||
if(check) {
|
||||
if (config.options.dialog_type == 'create_file') {
|
||||
var status = checkPermission(path)
|
||||
if (status) {
|
||||
$('.file_manager').trigger('enter-key');
|
||||
}
|
||||
} else if(config.options.dialog_type == 'select_file') {
|
||||
var file_status = getFileInfo(path);
|
||||
if (file_status) {
|
||||
$('.file_manager').trigger('enter-key');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.data_cap = cap;
|
||||
|
||||
$('.storage_dialog #uploader .input-path').keyup(function(e) {
|
||||
if(e.keyCode == 13) {
|
||||
e.stopPropagation();
|
||||
var path = $(this).val();
|
||||
if(path == '') {
|
||||
path = '/';
|
||||
}
|
||||
|
||||
if(config.options.platform_type === "win32") {
|
||||
path = path.replace(/\//g, '\\')
|
||||
} else {
|
||||
path = path.replace(/\\/g, '/')
|
||||
if (!path.startsWith('/')) {
|
||||
path = '/' + path;
|
||||
}
|
||||
}
|
||||
|
||||
$(this).val(path);
|
||||
setTimeout(function() {
|
||||
check_obj(path, true);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
check_obj($(this).val(), false);
|
||||
});
|
||||
}
|
||||
this.set_cap = function(cap) {
|
||||
this.data_cap = cap;
|
||||
}
|
||||
}
|
||||
|
||||
var input_object = new InputObject()
|
||||
input_object.init(data);
|
||||
|
||||
// Upload file
|
||||
if (has_capability(data, 'upload')) {
|
||||
Dropzone.autoDiscover = false;
|
||||
@@ -1463,7 +1592,7 @@ if (has_capability(data, 'upload')) {
|
||||
var data = response.data.result,
|
||||
$this = $(file.previewTemplate);
|
||||
|
||||
if (data.Code == 0) {
|
||||
if (data.Code == 1) {
|
||||
setTimeout(function() {
|
||||
$this.find(".dz-upload").addClass("success");
|
||||
}, 1000);
|
||||
|
@@ -8,8 +8,6 @@
|
||||
##########################################################################
|
||||
|
||||
"""A blueprint module implementing the sqleditor frame."""
|
||||
MODULE_NAME = 'sqleditor'
|
||||
|
||||
import simplejson as json
|
||||
import os
|
||||
import pickle
|
||||
@@ -25,8 +23,12 @@ from pgadmin.utils.ajax import make_json_response, bad_request, \
|
||||
success_return, internal_server_error
|
||||
from pgadmin.utils.driver import get_driver
|
||||
from pgadmin.utils.sqlautocomplete.autocomplete import SQLAutoComplete
|
||||
from pgadmin.misc.file_manager import Filemanager
|
||||
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
|
||||
from config import PG_DEFAULT_DRIVER, SERVER_MODE
|
||||
|
||||
MODULE_NAME = 'sqleditor'
|
||||
|
||||
# import unquote from urlib for python2.x and python3.x
|
||||
try:
|
||||
@@ -1203,7 +1205,7 @@ def load_file():
|
||||
# generate full path of file
|
||||
file_path = os.path.join(
|
||||
storage_manager_path,
|
||||
file_path.lstrip('/')
|
||||
file_path.lstrip('/').lstrip('\\')
|
||||
)
|
||||
|
||||
file_data = None
|
||||
@@ -1268,10 +1270,16 @@ def save_file():
|
||||
file_path = unquote(
|
||||
file_data['file_name']
|
||||
).encode('utf-8').decode('utf-8')
|
||||
|
||||
try:
|
||||
Filemanager.check_access_permission(storage_manager_path, file_path)
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
if storage_manager_path is not None:
|
||||
file_path = os.path.join(
|
||||
storage_manager_path,
|
||||
file_path.lstrip('/')
|
||||
file_path.lstrip('/').lstrip('\\')
|
||||
)
|
||||
|
||||
if hasattr(str, 'decode'):
|
||||
@@ -1281,7 +1289,7 @@ def save_file():
|
||||
|
||||
# write to file
|
||||
try:
|
||||
with open(file_path, 'wb') as output_file:
|
||||
with open(file_path, 'wb+') as output_file:
|
||||
if hasattr(str, 'decode'):
|
||||
output_file.write(file_content.encode('utf-8'))
|
||||
else:
|
||||
|
@@ -197,7 +197,7 @@ class _Preference(object):
|
||||
)
|
||||
db.session.add(pref)
|
||||
else:
|
||||
pref.value = str(value)
|
||||
pref.value = u"{}".format(value)
|
||||
db.session.commit()
|
||||
|
||||
return True, None
|
||||
|
Reference in New Issue
Block a user