|
@@ -142,12 +142,17 @@ def index(request):
|
|
|
|
|
|
|
|
return view(request, path)
|
|
return view(request, path)
|
|
|
|
|
|
|
|
|
|
+def _decode_slashes(path):
|
|
|
|
|
+ # This is a fix for some installations where the path is still having the slash (/) encoded
|
|
|
|
|
+ # as %2F while the rest of the path is actually decoded.
|
|
|
|
|
+ encoded_slash = '%2F'
|
|
|
|
|
+ if path.startswith(encoded_slash) or path.startswith('abfs:' + encoded_slash) or path.startswith('s3a:' + encoded_slash):
|
|
|
|
|
+ path = path.replace(encoded_slash, '/')
|
|
|
|
|
+
|
|
|
|
|
+ return path
|
|
|
|
|
|
|
|
def _normalize_path(path):
|
|
def _normalize_path(path):
|
|
|
- # Prevent decoding of already decoded path, every path contains a '/' which would be encoded to %2F, hence
|
|
|
|
|
- # if / is present it means that it's already been decoded.
|
|
|
|
|
- if '/' not in path:
|
|
|
|
|
- path = unquote_url(path)
|
|
|
|
|
|
|
+ path = _decode_slashes(path)
|
|
|
|
|
|
|
|
# Check if protocol missing / and add it back (e.g. Kubernetes ingress can strip double slash)
|
|
# Check if protocol missing / and add it back (e.g. Kubernetes ingress can strip double slash)
|
|
|
if path.startswith('abfs:/') and not path.startswith('abfs://'):
|
|
if path.startswith('abfs:/') and not path.startswith('abfs://'):
|
|
@@ -367,7 +372,7 @@ def save_file(request):
|
|
|
"""
|
|
"""
|
|
|
form = EditorForm(request.POST)
|
|
form = EditorForm(request.POST)
|
|
|
is_valid = form.is_valid()
|
|
is_valid = form.is_valid()
|
|
|
- path = form.cleaned_data.get('path')
|
|
|
|
|
|
|
+ path = form['path'].value()
|
|
|
|
|
|
|
|
path = _normalize_path(path)
|
|
path = _normalize_path(path)
|
|
|
|
|
|
|
@@ -406,7 +411,7 @@ def parse_breadcrumbs(path):
|
|
|
if url and not url.endswith('/'):
|
|
if url and not url.endswith('/'):
|
|
|
url += '/'
|
|
url += '/'
|
|
|
url += part
|
|
url += part
|
|
|
- breadcrumbs.append({'url': urllib_quote(url.encode('utf-8'), safe=SAFE_CHARACTERS_URI_COMPONENTS), 'label': part})
|
|
|
|
|
|
|
+ breadcrumbs.append({'url': url, 'label': part})
|
|
|
return breadcrumbs
|
|
return breadcrumbs
|
|
|
|
|
|
|
|
|
|
|
|
@@ -591,7 +596,7 @@ def listdir_paged(request, path):
|
|
|
# The following should probably be deprecated
|
|
# The following should probably be deprecated
|
|
|
'cwd_set': True,
|
|
'cwd_set': True,
|
|
|
'file_filter': 'any',
|
|
'file_filter': 'any',
|
|
|
- 'current_dir_path': urllib_quote(path.encode('utf-8'), safe=SAFE_CHARACTERS_URI),
|
|
|
|
|
|
|
+ 'current_dir_path': path,
|
|
|
'is_fs_superuser': is_fs_superuser,
|
|
'is_fs_superuser': is_fs_superuser,
|
|
|
'groups': is_fs_superuser and [str(x) for x in Group.objects.values_list('name', flat=True)] or [],
|
|
'groups': is_fs_superuser and [str(x) for x in Group.objects.values_list('name', flat=True)] or [],
|
|
|
'users': is_fs_superuser and [str(x) for x in User.objects.values_list('username', flat=True)] or [],
|
|
'users': is_fs_superuser and [str(x) for x in User.objects.values_list('username', flat=True)] or [],
|
|
@@ -1218,7 +1223,7 @@ def rename(request):
|
|
|
raise PopupException(_("Could not rename folder \"%s\" to \"%s\": Hashes are not allowed in filenames." % (src_path, dest_path)))
|
|
raise PopupException(_("Could not rename folder \"%s\" to \"%s\": Hashes are not allowed in filenames." % (src_path, dest_path)))
|
|
|
if "/" not in dest_path:
|
|
if "/" not in dest_path:
|
|
|
src_dir = os.path.dirname(src_path)
|
|
src_dir = os.path.dirname(src_path)
|
|
|
- dest_path = request.fs.join(urllib_unquote(src_dir), urllib_unquote(dest_path))
|
|
|
|
|
|
|
+ dest_path = request.fs.join(src_dir, dest_path)
|
|
|
if request.fs.exists(dest_path):
|
|
if request.fs.exists(dest_path):
|
|
|
raise PopupException(_('The destination path "%s" already exists.') % dest_path)
|
|
raise PopupException(_('The destination path "%s" already exists.') % dest_path)
|
|
|
request.fs.rename(src_path, dest_path)
|
|
request.fs.rename(src_path, dest_path)
|
|
@@ -1233,14 +1238,13 @@ def set_replication(request):
|
|
|
|
|
|
|
|
return generic_op(SetReplicationFactorForm, request, smart_set_replication, ["src_path", "replication_factor"], None)
|
|
return generic_op(SetReplicationFactorForm, request, smart_set_replication, ["src_path", "replication_factor"], None)
|
|
|
|
|
|
|
|
-
|
|
|
|
|
def mkdir(request):
|
|
def mkdir(request):
|
|
|
def smart_mkdir(path, name):
|
|
def smart_mkdir(path, name):
|
|
|
# Make sure only one directory is specified at a time.
|
|
# Make sure only one directory is specified at a time.
|
|
|
# No absolute directory specification allowed.
|
|
# No absolute directory specification allowed.
|
|
|
if posixpath.sep in name or "#" in name:
|
|
if posixpath.sep in name or "#" in name:
|
|
|
raise PopupException(_("Could not name folder \"%s\": Slashes or hashes are not allowed in filenames." % name))
|
|
raise PopupException(_("Could not name folder \"%s\": Slashes or hashes are not allowed in filenames." % name))
|
|
|
- request.fs.mkdir(request.fs.join(urllib_unquote(path), urllib_unquote(name)))
|
|
|
|
|
|
|
+ request.fs.mkdir(request.fs.join(path, name))
|
|
|
|
|
|
|
|
return generic_op(MkDirForm, request, smart_mkdir, ["path", "name"], "path")
|
|
return generic_op(MkDirForm, request, smart_mkdir, ["path", "name"], "path")
|
|
|
|
|
|
|
@@ -1252,8 +1256,8 @@ def touch(request):
|
|
|
raise PopupException(_("Could not name file \"%s\": Slashes are not allowed in filenames." % name))
|
|
raise PopupException(_("Could not name file \"%s\": Slashes are not allowed in filenames." % name))
|
|
|
request.fs.create(
|
|
request.fs.create(
|
|
|
request.fs.join(
|
|
request.fs.join(
|
|
|
- urllib_unquote(path.encode('utf-8') if not isinstance(path, str) else path),
|
|
|
|
|
- urllib_unquote(name.encode('utf-8') if not isinstance(name, str) else name)
|
|
|
|
|
|
|
+ (path.encode('utf-8') if not isinstance(path, str) else path),
|
|
|
|
|
+ (name.encode('utf-8') if not isinstance(name, str) else name)
|
|
|
)
|
|
)
|
|
|
)
|
|
)
|
|
|
|
|
|
|
@@ -1265,7 +1269,7 @@ def rmtree(request):
|
|
|
params = ["path"]
|
|
params = ["path"]
|
|
|
def bulk_rmtree(*args, **kwargs):
|
|
def bulk_rmtree(*args, **kwargs):
|
|
|
for arg in args:
|
|
for arg in args:
|
|
|
- request.fs.do_as_user(request.user, request.fs.rmtree, urllib_unquote(arg['path']), 'skip_trash' in request.GET)
|
|
|
|
|
|
|
+ request.fs.do_as_user(request.user, request.fs.rmtree, arg['path'], 'skip_trash' in request.GET)
|
|
|
return generic_op(RmTreeFormSet, request, bulk_rmtree, ["path"], None,
|
|
return generic_op(RmTreeFormSet, request, bulk_rmtree, ["path"], None,
|
|
|
data_extractor=formset_data_extractor(recurring, params),
|
|
data_extractor=formset_data_extractor(recurring, params),
|
|
|
arg_extractor=formset_arg_extractor,
|
|
arg_extractor=formset_arg_extractor,
|
|
@@ -1281,8 +1285,8 @@ def move(request):
|
|
|
if arg['src_path'] == arg['dest_path']:
|
|
if arg['src_path'] == arg['dest_path']:
|
|
|
raise PopupException(_('Source path and destination path cannot be same'))
|
|
raise PopupException(_('Source path and destination path cannot be same'))
|
|
|
request.fs.rename(
|
|
request.fs.rename(
|
|
|
- urllib_unquote(arg['src_path'].encode('utf-8') if not isinstance(arg['src_path'], str) else arg['src_path']),
|
|
|
|
|
- urllib_unquote(arg['dest_path'].encode('utf-8') if not isinstance(arg['dest_path'], str) else arg['dest_path'])
|
|
|
|
|
|
|
+ arg['src_path'].encode('utf-8') if not isinstance(arg['src_path'], str) else arg['src_path'],
|
|
|
|
|
+ arg['dest_path'].encode('utf-8') if not isinstance(arg['dest_path'], str) else arg['dest_path']
|
|
|
)
|
|
)
|
|
|
return generic_op(RenameFormSet, request, bulk_move, ["src_path", "dest_path"], None,
|
|
return generic_op(RenameFormSet, request, bulk_move, ["src_path", "dest_path"], None,
|
|
|
data_extractor=formset_data_extractor(recurring, params),
|
|
data_extractor=formset_data_extractor(recurring, params),
|
|
@@ -1298,7 +1302,7 @@ def copy(request):
|
|
|
for arg in args:
|
|
for arg in args:
|
|
|
if arg['src_path'] == arg['dest_path']:
|
|
if arg['src_path'] == arg['dest_path']:
|
|
|
raise PopupException(_('Source path and destination path cannot be same'))
|
|
raise PopupException(_('Source path and destination path cannot be same'))
|
|
|
- request.fs.copy(unquote_url(arg['src_path']), unquote_url(arg['dest_path']), recursive=True, owner=request.user)
|
|
|
|
|
|
|
+ request.fs.copy(arg['src_path'], arg['dest_path'], recursive=True, owner=request.user)
|
|
|
return generic_op(CopyFormSet, request, bulk_copy, ["src_path", "dest_path"], None,
|
|
return generic_op(CopyFormSet, request, bulk_copy, ["src_path", "dest_path"], None,
|
|
|
data_extractor=formset_data_extractor(recurring, params),
|
|
data_extractor=formset_data_extractor(recurring, params),
|
|
|
arg_extractor=formset_arg_extractor,
|
|
arg_extractor=formset_arg_extractor,
|
|
@@ -1314,7 +1318,7 @@ def chmod(request):
|
|
|
def bulk_chmod(*args, **kwargs):
|
|
def bulk_chmod(*args, **kwargs):
|
|
|
op = partial(request.fs.chmod, recursive=request.POST.get('recursive', False))
|
|
op = partial(request.fs.chmod, recursive=request.POST.get('recursive', False))
|
|
|
for arg in args:
|
|
for arg in args:
|
|
|
- op(urllib_unquote(arg['path']), arg['mode'])
|
|
|
|
|
|
|
+ op(arg['path'], arg['mode'])
|
|
|
# mode here is abused: on input, it's a string, but when retrieved,
|
|
# mode here is abused: on input, it's a string, but when retrieved,
|
|
|
# it's an int.
|
|
# it's an int.
|
|
|
return generic_op(ChmodFormSet, request, bulk_chmod, ['path', 'mode'], "path",
|
|
return generic_op(ChmodFormSet, request, bulk_chmod, ['path', 'mode'], "path",
|
|
@@ -1404,8 +1408,8 @@ def _upload_file(request):
|
|
|
|
|
|
|
|
if form.is_valid():
|
|
if form.is_valid():
|
|
|
uploaded_file = request.FILES['hdfs_file']
|
|
uploaded_file = request.FILES['hdfs_file']
|
|
|
- dest = scheme_absolute_path(unquote_url(request.GET['dest']), unquote_url(request.GET['dest']))
|
|
|
|
|
- filepath = request.fs.join(dest, unquote_url(uploaded_file.name))
|
|
|
|
|
|
|
+ dest = request.GET['dest']
|
|
|
|
|
+ filepath = request.fs.join(dest, uploaded_file.name)
|
|
|
|
|
|
|
|
if request.fs.isdir(dest) and posixpath.sep in uploaded_file.name:
|
|
if request.fs.isdir(dest) and posixpath.sep in uploaded_file.name:
|
|
|
raise PopupException(_('Sorry, no "%(sep)s" in the filename %(name)s.' % {'sep': posixpath.sep, 'name': uploaded_file.name}))
|
|
raise PopupException(_('Sorry, no "%(sep)s" in the filename %(name)s.' % {'sep': posixpath.sep, 'name': uploaded_file.name}))
|
|
@@ -1469,9 +1473,6 @@ def compress_files_using_batch_job(request):
|
|
|
|
|
|
|
|
if upload_path and file_names and archive_name:
|
|
if upload_path and file_names and archive_name:
|
|
|
try:
|
|
try:
|
|
|
- upload_path = urllib_unquote(upload_path)
|
|
|
|
|
- archive_name = urllib_unquote(archive_name)
|
|
|
|
|
- file_names = [urllib_unquote(name) for name in file_names]
|
|
|
|
|
response = compress_files_in_hdfs(request, file_names, upload_path, archive_name)
|
|
response = compress_files_in_hdfs(request, file_names, upload_path, archive_name)
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
response['message'] = _('Exception occurred while compressing files: %s' % e)
|
|
response['message'] = _('Exception occurred while compressing files: %s' % e)
|