1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-25 14:50:29 +00:00

[repo] refactor multi-dirents mv/cp, improved file/dir mv/cp

* when mv/cp multi-dirents to other library, mv/cp dirent one by one
This commit is contained in:
llj
2014-08-22 18:44:01 +08:00
parent 327a6675b9
commit fc62b92bd3
3 changed files with 234 additions and 222 deletions

View File

@@ -546,156 +546,158 @@ $('#mv-dirents, #cp-dirents').click(function() {
return false; return false;
} }
if (op == 'mv') {
url_main = '{% url 'mv_dirents' repo.id %}';
} else {
url_main = '{% url 'cp_dirents' repo.id %}';
}
disable($('[type="submit"]', form)); disable($('[type="submit"]', form));
form.append('<p style="color:red;">' + "{% trans "Processing..." %}" + '</p>'); form.append('<p style="color:red;">' + "{% trans "Processing..." %}" + '</p>');
$.ajax({
url: url_main + '?parent_dir=' + e(cur_path),
type: 'POST',
dataType: 'json',
beforeSend: prepareCSRFToken,
traditional: true,
data: {
'file_names': file_names,
'dir_names': dir_names,
'dst_repo': dst_repo,
'dst_path': dst_path
},
success: function(data) {
var success_len = data['success'].length,
msg_s, msg_f,
view_url = data['url'];
var task_ids = data['task_ids'], if (dst_repo == '{{repo.id }}') {
task_ids_len = task_ids.length; // when mv/cp in current lib, files/dirs can be handled in batch, and no need to show progress
url_main = op == 'mv' ? '{% url 'mv_dirents' repo.id %}':'{% url 'cp_dirents' repo.id %}';
$.ajax({
url: url_main + '?parent_dir=' + e(cur_path),
type: 'POST',
dataType: 'json',
beforeSend: prepareCSRFToken,
traditional: true,
data: {
'file_names': file_names,
'dir_names': dir_names,
'dst_repo': dst_repo,
'dst_path': dst_path
},
success: function(data) {
var success_len = data['success'].length,
msg_s, msg_f,
view_url = data['url'];
$.modal.close(); $.modal.close();
$('#dirents-op').addClass('hide'); $('#dirents-op').addClass('hide');
$('th.select .checkbox').removeClass('checkbox-checked'); $('th.select .checkbox').removeClass('checkbox-checked');
var success_without_tasks = function() { if (success_len > 0) {
if (success_len > 0) {
if (op == 'mv') {
if (success_len == files.length + dirs.length) {
files.remove();
dirs.remove();
} else {
files.each(function() {
if ($(this).data('name') in data['success']) {
$(this).remove();
}
});
dirs.each(function() {
if ($(this).data('name') in data['success']) {
$(this).remove();
}
});
}
if (data['success'].length > 1) {
msg_s = "{% trans "Successfully moved %(name)s and %(amount)s other items." %}";
} else {
msg_s = "{% trans "Successfully moved %(name)s." %}";
}
} else {
$('.checkbox').removeClass('checkbox-checked');
if (data['success'].length > 1) {
msg_s = "{% trans "Successfully copied %(name)s and %(amount)s other items." %}";
} else {
msg_s = "{% trans "Successfully copied %(name)s." %}";
}
}
msg_s = msg_s.replace('%(name)s', data['success'][0]).replace('%(amount)s', data['success'].length - 1);
msg_s += ' <a href="' + view_url + '">' + "{% trans "View" %}" + '</a>';
feedback(msg_s, 'success');
updateCmt();
}
if (data['failed'].length > 0) {
if (op == 'mv') {
if (data['failed'].length > 1) {
msg_f = "{% trans "Internal error. Failed to move %(name)s and %(amount)s other items." %}";
} else {
msg_f = "{% trans "Internal error. Failed to move %(name)s." %}";
}
} else {
if (data['failed'].length > 1) {
msg_f = "{% trans "Internal error. Failed to copy %(name)s and %(amount)s other items." %}";
} else {
msg_f = "{% trans "Internal error. Failed to copy %(name)s." %}";
}
}
msg_f = msg_f.replace('%(name)s', data['failed'][0]).replace('%(amount)s', data['failed'].length - 1);
feedback(msg_f, 'error');
}
}; // 'success_without_tasks' ends
if (task_ids_len == 0) {
success_without_tasks();
} else {
var details = $('#mv-details'),
other_info = $('#mv-other-info');
$('#cancel-mv').addClass('hide');
setTimeout(function () {
$('#mv-progress-popup').modal({containerCss: {
width: 300,
height: 150,
paddingTop: 50
}, focus:false});
if (op == 'mv') { if (op == 'mv') {
details.html("{% trans "Moving..." %}"); if (success_len == files.length + dirs.length) {
} else { files.remove();
details.html("{% trans "Copying..." %}"); dirs.remove();
} } else {
$('#mv-progress').progressbar(); files.each(function() {
req_progress(); if ($(this).data('name') in data['success']) {
}, 100); $(this).remove();
var req_progress = function() { }
$.ajax({ });
url: '{% url 'get_multi_cp_progress' %}', dirs.each(function() {
dataType: 'json', if ($(this).data('name') in data['success']) {
data: { task_ids: task_ids }, $(this).remove();
traditional: true, }
success: function(data) { });
var success_num = data['success'], }
fail_num = data['fail']; if (success_len == 1) {
var bar = $('.ui-progressbar-value', $('#mv-progress')).show(); msg_s = "{% trans "Successfully moved %(name)s." %}";
bar.css('width', parseInt(success_num/task_ids_len*100, 10) + '%'); } else if (success_len == 2) {
if (task_ids_len == success_num + fail_num) { msg_s = "{% trans "Successfully moved %(name)s and 1 other item." %}";
setTimeout(function() {$.modal.close();}, 100); } else {
var msg; msg_s = "{% trans "Successfully moved %(name)s and %(amount)s other items." %}";
if (success_num > 0) { }
if (op == 'mv') { } else { // cp
if (success_num == files.length + dirs.length) { $('.checkbox').removeClass('checkbox-checked');
files.remove(); if (success_len == 1) {
dirs.remove(); msg_s = "{% trans "Successfully copied %(name)s." %}";
} else { } else if (success_len == 2) {
reqDirData('{% url 'repo_dir_data' repo.id %}?p=' + e(cur_path)); msg_s = "{% trans "Successfully copied %(name)s and 1 other item." %}";
} } else {
msg = "{% trans "Successfully moved %(s_num)s items." %}"; msg_s = "{% trans "Successfully copied %(name)s and %(amount)s other items." %}";
if (fail_num > 0) { }
msg += "{% trans "Failed to move %(f_num)s items." %}"; }
} msg_s = msg_s.replace('%(name)s', data['success'][0]).replace('%(amount)s', data['success'].length - 1);
} else { msg_s += ' <a href="' + view_url + '">' + "{% trans "View" %}" + '</a>';
msg = "{% trans "Successfully copied %(s_num)s items." %}"; feedback(msg_s, 'success');
if (fail_num > 0) { updateCmt();
msg += "{% trans "Failed to copy %(f_num)s items." %}"; }
}
$('.checkbox').removeClass('checkbox-checked'); if (data['failed'].length > 0) {
} if (op == 'mv') {
msg = msg.replace('%(s_num)s', success_num).replace('%(f_num)s', fail_num); if (data['failed'].length > 1) {
msg += ' <a href="' + view_url + '">' + "{% trans "View" %}" + '</a>'; msg_f = "{% trans "Internal error. Failed to move %(name)s and %(amount)s other items." %}";
feedback(msg, 'success'); } else {
updateCmt(); msg_f = "{% trans "Internal error. Failed to move %(name)s." %}";
} else { }
feedback("{% trans "Failed" %}", 'error'); } else {
if (data['failed'].length > 1) {
msg_f = "{% trans "Internal error. Failed to copy %(name)s and %(amount)s other items." %}";
} else {
msg_f = "{% trans "Internal error. Failed to copy %(name)s." %}";
}
}
msg_f = msg_f.replace('%(name)s', data['failed'][0]).replace('%(amount)s', data['failed'].length - 1);
feedback(msg_f, 'error');
}
},
error: function(xhr, textStatus, errorThrown) {
$.modal.close();
ajaxErrorHandler(xhr, textStatus, errorThrown);
}
});
} else {
// when mv/cp to another lib, files/dirs should be handled one by one, and need to show progress
var op_objs = $('.checkbox-checked').parents('tr'),
i = 0;
// progress popup
var details = $('#mv-details'),
cancel_btn = $('#cancel-mv'),
other_info = $('#mv-other-info');
var mvcpDirent = function () {
var op_obj = $(op_objs[i]),
obj_type = op_obj.hasClass('dir-item') ? 'dir':'file',
obj_name = op_obj.attr('data-name'),
post_url;
if (op == 'mv') {
post_url = obj_type == 'dir' ? '{% url 'mv_dir' repo.id %}':'{% url 'mv_file' repo.id %}';
} else {
post_url = obj_type == 'dir' ? '{% url 'cp_dir' repo.id %}':'{% url 'cp_file' repo.id %}';
}
post_url += '?path=' + e(cur_path) + '&obj_name=' + e(obj_name);
post_data = {
'dst_repo': dst_repo,
'dst_path': dst_path
};
var after_op_success = function (data) {
cancel_btn.removeClass('hide');
var det_text = op == 'mv' ? "{% trans "Moving %(name)s" %}": "{% trans "Copying %(name)s" %}";
details.html(det_text.replace('%(name)s', trimFilename(obj_name, 20)));
var req_progress = function () {
var task_id = data['task_id'];
var msg = data['msg'];
cancel_btn.data('task_id', task_id);
$.ajax({
url: '{% url "get_cp_progress" %}?task_id=' + e(task_id),
dataType: 'json',
success: function(data) {
var bar = $('.ui-progressbar-value', $('#mv-progress'));
if (!data['failed'] && !data['canceled'] && !data['successful']) {
bar.css('width', parseInt(data['done']/data['total']*100, 10) + '%').show();
if (data['done'] == data['total']) {
details.addClass('vh');
cancel_btn.addClass('hide');
other_info.html("{% trans "Saving..." %}").removeClass('hide');
} }
} else {
setTimeout(req_progress, 1000); setTimeout(req_progress, 1000);
} else {
if (data['successful']) {
if (op=='mv') {
op_obj.remove();
updateCmt();
} else {
$('.checkbox', op_obj).removeClass('checkbox-checked');
}
feedback(msg, 'success');
} else { // failed or canceled
details.addClass('vh');
var other_msg = data['failed'] ? "{% trans "Failed." %}" : "{% trans "Canceled." %}";
other_info.html(other_msg).removeClass('hide');
cancel_btn.addClass('hide');
}
endOrContinue();
} }
}, },
error: function(xhr, textStatus, errorThrown) { error: function(xhr, textStatus, errorThrown) {
@@ -707,18 +709,69 @@ $('#mv-dirents, #cp-dirents').click(function() {
} }
details.addClass('vh') details.addClass('vh')
other_info.html(error).removeClass('hide'); other_info.html(error).removeClass('hide');
setTimeout(function () {$.modal.close();}, 1000); cancel_btn.addClass('hide');
endOrContinue();
} }
}); });
}; // 'req_progress' ends
if (i == 0) {
$.modal.close();
$('#dirents-op').addClass('hide');
$('th.select .checkbox').removeClass('checkbox-checked');
setTimeout(function () {
$('#mv-progress-popup').modal({containerCss: {
width: 300,
height: 150,
paddingTop: 50
}, focus:false});
$('#mv-progress').progressbar();
req_progress();
}, 100);
} else {
req_progress();
} }
}; // 'after_op_success' ends
ajaxPost({
'form': form,
'post_url': post_url,
'post_data': post_data,
'after_op_success': after_op_success,
'form_id': form.attr('id')
});
}; // 'mvcpDirent' ends
var endOrContinue = function () {
if (i == op_objs.length - 1) {
setTimeout(function () { $.modal.close(); }, 500);
} else {
mvcpDirent(++i);
} }
};
}, mvcpDirent();
error: function(xhr, textStatus, errorThrown) { cancel_btn.click(function() {
$.modal.close(); disable(cancel_btn);
ajaxErrorHandler(xhr, textStatus, errorThrown); var task_id = $(this).data('task_id');
} $.ajax({
}); url: '{% url "cancel_cp" %}?task_id=' + e(task_id),
dataType: 'json',
success: function(data) {
details.addClass('vh')
other_info.html("{% trans "Canceled." %}").removeClass('hide');
cancel_btn.addClass('hide');
endOrContinue();
},
error: function(xhr, textStatus, errorThrown) {
var error;
if (xhr.responseText) {
error = $.parseJSON(xhr.responseText).error;
} else {
error = "{% trans "Failed. Please check the network." %}";
}
other_info.html(error).removeClass('hide');
enable(cancel_btn);
}
});
});
}
return false; return false;
}); });
}); });
@@ -1678,18 +1731,11 @@ $('#add-new-file-form, #add-new-dir-form, #rename-form, #mv-form').submit(functi
return false; return false;
} }
if (op == 'mv') { if (op == 'mv') {
if (obj_type == 'dir') { // move dir post_url = obj_type == 'dir' ? '{% url 'mv_dir' repo.id %}':'{% url 'mv_file' repo.id %}';
post_url = '{% url 'mv_dir' repo.id%}?path=' + e(path) + '&obj_name=' + e(obj_name);
} else { // move file
post_url = '{% url 'mv_file' repo.id%}?path=' + e(path) + '&obj_name=' + e(obj_name);
}
} else { } else {
if (obj_type == 'dir') { // copy dir post_url = obj_type == 'dir' ? '{% url 'cp_dir' repo.id %}':'{% url 'cp_file' repo.id %}';
post_url = '{% url 'cp_dir' repo.id%}?path=' + e(path) + '&obj_name=' + e(obj_name);
} else { // copy file
post_url = '{% url 'cp_file' repo.id%}?path=' + e(path) + '&obj_name=' + e(obj_name);
}
} }
post_url += '?path=' + e(path) + '&obj_name=' + e(obj_name);
post_data = { post_data = {
'dst_repo': dst_repo, 'dst_repo': dst_repo,
'dst_path': dst_path 'dst_path': dst_path
@@ -1697,7 +1743,7 @@ $('#add-new-file-form, #add-new-dir-form, #rename-form, #mv-form').submit(functi
after_op_success = function(data) { after_op_success = function(data) {
$.modal.close(); $.modal.close();
msg = data['msg']; msg = data['msg'];
if (!data['task_id']) { // don not show progress if (!data['task_id']) { // no progress
if (op=='mv') { if (op=='mv') {
op_obj.remove(); op_obj.remove();
} }
@@ -1714,11 +1760,8 @@ $('#add-new-file-form, #add-new-dir-form, #rename-form, #mv-form').submit(functi
height: 150, height: 150,
paddingTop: 50 paddingTop: 50
}, focus:false}); }, focus:false});
if (op == 'mv') { var det_text = op == 'mv' ? "{% trans "Moving %(name)s" %}": "{% trans "Copying %(name)s" %}";
details.html("{% trans "Moving..." %}"); details.html(det_text.replace('%(name)s', trimFilename(obj_name, 20)));
} else {
details.html("{% trans "Copying..." %}");
}
$('#mv-progress').progressbar(); $('#mv-progress').progressbar();
req_progress(); req_progress();
}, 100); }, 100);
@@ -1729,35 +1772,26 @@ $('#add-new-file-form, #add-new-dir-form, #rename-form, #mv-form').submit(functi
success: function(data) { success: function(data) {
var bar = $('.ui-progressbar-value', $('#mv-progress')); var bar = $('.ui-progressbar-value', $('#mv-progress'));
if (!data['failed'] && !data['canceled'] && !data['successful']) { if (!data['failed'] && !data['canceled'] && !data['successful']) {
bar.show(); bar.css('width', parseInt(data['done']/data['total']*100, 10) + '%').show();
if (data['done'] == data['total']) { if (data['done'] == data['total']) {
bar.width('100%');
details.addClass('vh'); details.addClass('vh');
cancel_btn.addClass('hide'); cancel_btn.addClass('hide');
other_info.html("{% trans "Saving..." %}").removeClass('hide'); other_info.html("{% trans "Saving..." %}").removeClass('hide');
setTimeout(req_progress, 1000);
} else {
bar.css('width', parseInt(data['done']/data['total']*100, 10) + '%');
setTimeout(req_progress, 1000);
} }
setTimeout(req_progress, 1000);
} else if (data['successful']) { } else if (data['successful']) {
$.modal.close(); $.modal.close();
if (op=='mv') { if (op=='mv') {
op_obj.remove(); op_obj.remove();
updateCmt();
} }
updateCmt();
feedback(msg, 'success'); feedback(msg, 'success');
} else { // failed or canceled } else { // failed or canceled
var other_msg;
details.addClass('vh'); details.addClass('vh');
if (data['failed']) { var other_msg = data['failed'] ? "{% trans "Failed." %}" : "{% trans "Canceled." %}";
other_msg = "{% trans "Failed." %}";
} else {
other_msg = "{% trans "Canceled." %}";
}
other_info.html(other_msg).removeClass('hide'); other_info.html(other_msg).removeClass('hide');
cancel_btn.addClass('hide'); cancel_btn.addClass('hide');
setTimeout(function () {$.modal.close();}, 1000); setTimeout(function () { $.modal.close(); }, 1000);
} }
}, },
error: function(xhr, textStatus, errorThrown) { error: function(xhr, textStatus, errorThrown) {
@@ -1770,7 +1804,7 @@ $('#add-new-file-form, #add-new-dir-form, #rename-form, #mv-form').submit(functi
details.addClass('vh') details.addClass('vh')
other_info.html(error).removeClass('hide'); other_info.html(error).removeClass('hide');
cancel_btn.addClass('hide'); cancel_btn.addClass('hide');
setTimeout(function () {$.modal.close();}, 1000); setTimeout(function () { $.modal.close(); }, 1000);
} }
}); });
}; };
@@ -1801,6 +1835,22 @@ $('#add-new-file-form, #add-new-dir-form, #rename-form, #mv-form').submit(functi
} }
} }
ajaxPost({
'form': form,
'post_url': post_url,
'post_data': post_data,
'after_op_success': after_op_success,
'form_id': form_id
});
return false;
});
function ajaxPost(params) { // params: {}
var form = params.form,
post_url = params.post_url,
post_data = params.post_data,
after_op_success = params.after_op_success,
form_id = params.form_id;
var submit_btn = form.children('input[type="submit"]'); var submit_btn = form.children('input[type="submit"]');
disable(submit_btn); disable(submit_btn);
$.ajax({ $.ajax({
@@ -1825,8 +1875,7 @@ $('#add-new-file-form, #add-new-dir-form, #rename-form, #mv-form').submit(functi
enable(submit_btn); enable(submit_btn);
} }
}); });
return false; }
});
$('#mv-dir-list .hd').click(function() { $('#mv-dir-list .hd').click(function() {
var span = $('span', $(this)), var span = $('span', $(this)),

View File

@@ -124,7 +124,6 @@ urlpatterns = patterns('',
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/cp/$', cp_dir, name='cp_dir'), url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/cp/$', cp_dir, name='cp_dir'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/sub_repo/$', sub_repo, name='sub_repo'), url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/sub_repo/$', sub_repo, name='sub_repo'),
url(r'^ajax/cp_progress/$', get_cp_progress, name='get_cp_progress'), url(r'^ajax/cp_progress/$', get_cp_progress, name='get_cp_progress'),
url(r'^ajax/multi_cp_progress/$', get_multi_cp_progress, name='get_multi_cp_progress'),
url(r'^ajax/cancel_cp/$', cancel_cp, name='cancel_cp'), url(r'^ajax/cancel_cp/$', cancel_cp, name='cancel_cp'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/file/new/$', new_file, name='new_file'), url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/file/new/$', new_file, name='new_file'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/file/rename/$', rename_dirent, name='rename_file'), url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/file/rename/$', rename_dirent, name='rename_file'),

View File

@@ -848,7 +848,6 @@ def mv_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj
success = [] success = []
failed = [] failed = []
url = None url = None
task_ids = []
for obj_name in obj_file_names + obj_dir_names: for obj_name in obj_file_names + obj_dir_names:
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name) new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
try: try:
@@ -861,13 +860,11 @@ def mv_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj
failed.append(obj_name) failed.append(obj_name)
else: else:
success.append(obj_name) success.append(obj_name)
if res.background:
task_ids.append(res.task_id)
if len(success) > 0: if len(success) > 0:
url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path) url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
result = {'success': success, 'failed': failed, 'url': url, 'task_ids': task_ids} result = {'success': success, 'failed': failed, 'url': url}
return HttpResponse(json.dumps(result), content_type=content_type) return HttpResponse(json.dumps(result), content_type=content_type)
@login_required_ajax @login_required_ajax
@@ -887,7 +884,6 @@ def cp_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj
success = [] success = []
failed = [] failed = []
url = None url = None
task_ids = []
for obj_name in obj_file_names + obj_dir_names: for obj_name in obj_file_names + obj_dir_names:
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name) new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
try: try:
@@ -900,13 +896,11 @@ def cp_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj
failed.append(obj_name) failed.append(obj_name)
else: else:
success.append(obj_name) success.append(obj_name)
if res.background:
task_ids.append(res.task_id)
if len(success) > 0: if len(success) > 0:
url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path) url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
result = {'success': success, 'failed': failed, 'url': url, 'task_ids': task_ids} result = {'success': success, 'failed': failed, 'url': url}
return HttpResponse(json.dumps(result), content_type=content_type) return HttpResponse(json.dumps(result), content_type=content_type)
@login_required_ajax @login_required_ajax
@@ -938,36 +932,6 @@ def get_cp_progress(request):
return HttpResponse(json.dumps(result), content_type=content_type) return HttpResponse(json.dumps(result), content_type=content_type)
@login_required_ajax
def get_multi_cp_progress(request):
'''
Fetch progress of multi files/dirs mv/cp.
'''
content_type = 'application/json; charset=utf-8'
result = {}
task_ids = request.GET.getlist('task_ids')
if not task_ids:
result['error'] = _(u'Argument missing')
return HttpResponse(json.dumps(result), status=400,
content_type=content_type)
success = 0
fail = 0
for task_id in task_ids:
res = seafile_api.get_copy_task(task_id)
if not res:
fail += 1
else:
if res.failed:
fail += 1
elif res.successful:
success += 1
result['success'] = success
result['fail'] = fail
return HttpResponse(json.dumps(result), content_type=content_type)
@login_required_ajax @login_required_ajax
def cancel_cp(request): def cancel_cp(request):
''' '''