1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-01 23:38:37 +00:00

Merge pull request #1020 from haiwen/default-repo

update admin repo view page
This commit is contained in:
Daniel Pan 2016-02-23 10:33:06 +08:00
commit 08813c6ee6
19 changed files with 371 additions and 3373 deletions

View File

@ -146,9 +146,6 @@ class RepoPassowrdForm(forms.Form):
except SearpcError, e:
if e.msg == 'Bad arguments':
raise forms.ValidationError(_(u'Bad url format'))
# elif e.msg == 'Repo is not encrypted':
# return HttpResponseRedirect(reverse('repo',
# args=[self.repo_id]))
elif e.msg == 'Incorrect password':
raise forms.ValidationError(_(u'Wrong password'))
elif e.msg == 'Internal server error':

View File

@ -124,7 +124,7 @@ class Command(BaseCommand):
if repo is None:
notice.delete()
notice.repo_url = reverse('repo', args=[repo.id])
notice.repo_url = reverse("view_common_lib_dir", args=[repo_id, '/'])
notice.notice_from = escape(email2nickname(d['share_from']))
notice.repo_name = repo.name
notice.avatar_src = self.get_avatar_src(d['share_from'])
@ -138,7 +138,7 @@ class Command(BaseCommand):
uploaded_to = d['uploaded_to'].rstrip('/')
file_path = uploaded_to + '/' + file_name
file_link = reverse('view_lib_file', args=[repo_id, urlquote(file_path)])
folder_link = reverse('repo', args=[repo_id]) + '?p=' + urlquote(uploaded_to)
folder_link = reverse('view_common_lib_dir', args=[repo_id, urlquote(uploaded_to).strip('/')])
folder_name = os.path.basename(uploaded_to)
notice.file_link = file_link

View File

@ -716,88 +716,6 @@ def share_permission_admin(request):
else:
return HttpResponse(json.dumps({'success': False}), status=400,
content_type=content_type)
# 2 views for anonymous share:
# - anonymous_share records share infomation to db and sends the mail
# - anonymous_share_confirm checks the link use clicked and
# adds token to client COOKIE, then redirect client to repo page
# def anonymous_share(request, email_template_name='repo/anonymous_share_email.html', **kwargs):
# repo_id = kwargs['repo_id']
# repo_owner = kwargs['repo_owner']
# anon_email = kwargs['anon_email']
# is_encrypted = kwargs['is_encrypted']
# # Encrypt repo can not be shared to unregistered user.
# if is_encrypted:
# msg = _(u'Failed to share to %s, as encrypted libraries cannot be shared to emails outside the site.') % anon_email
# messages.error(request, msg)
# return
# token = anon_share_token_generator.make_token()
# anon_share = AnonymousShare()
# anon_share.repo_owner = repo_owner
# anon_share.repo_id = repo_id
# anon_share.anonymous_email = anon_email
# anon_share.token = token
# try:
# anon_share.save()
# except:
# msg = _(u'Failed to share to %s.') % anon_email
# messages.add_message(request, messages.ERROR, msg)
# else:
# # send mail
# use_https = request.is_secure()
# site_name = domain = RequestSite(request).domain
# t = loader.get_template(email_template_name)
# c = {
# 'email': repo_owner,
# 'anon_email': anon_email,
# 'domain': domain,
# 'site_name': site_name,
# 'token': token,
# 'protocol': use_https and 'https' or 'http',
# }
# try:
# send_mail(_(u'You are shared with a library in Seafile'), t.render(Context(c)), None,
# [anon_email], fail_silently=False)
# except:
# AnonymousShare.objects.filter(token=token).delete()
# msg = _(u'Failed to share to %s.') % anon_email
# messages.add_message(request, messages.ERROR, msg)
# else:
# msg = _(u'Shared to %(email)s successfully, go check it at <a href="%(share)s">Share</a>.') % \
# {'email':anon_email, 'share':reverse('share_admin')}
# messages.add_message(request, messages.INFO, msg)
# def anonymous_share_confirm(request, token=None):
# assert token is not None # checked by URLconf
# # Check whether token in db
# try:
# anon_share = AnonymousShare.objects.get(token=token)
# except AnonymousShare.DoesNotExist:
# raise Http404
# else:
# res = HttpResponseRedirect(reverse('repo', args=[anon_share.repo_id]))
# res.set_cookie("anontoken", token,
# max_age=ANONYMOUS_SHARE_COOKIE_TIMEOUT)
# return res
# def remove_anonymous_share(request, token):
# AnonymousShare.objects.filter(token=token).delete()
# next = request.META.get('HTTP_REFERER', None)
# if not next:
# next = reverse('share_admin')
# messages.add_message(request, messages.INFO, _(u'Deleted successfully.'))
# return HttpResponseRedirect(next)
########## share link
@login_required_ajax

File diff suppressed because it is too large Load Diff

View File

@ -1,161 +0,0 @@
{% load i18n %}
{% load url from future %}
// set 'side toolbar' & 'groups' popup position
function setToolbarPos() {
var toolbar = $('#side-toolbar');
// set toolbar pos
toolbar.css({'top': ($(window).height() - toolbar.outerHeight())/2});
// set 'groups' popup position
$('#to-group').css({'top': parseInt(toolbar.css('top')) + 59});
}
$(window).load(function() {
var to_top = $('<ul class="side-toolbar hide" style="margin-top:3px;"><li class="item" title="{% trans "Back to top" %}"><img src="{{MEDIA_URL}}img/top.png" alt="{% trans "top" %}" /></li></ul>');
to_top.click(function() {
$(window).scrollTop(0);
}).appendTo($('#side-toolbar'));
$(window).scroll(function() {
if ($(window).scrollTop() > 0) {
to_top.show();
} else {
to_top.hide();
}
});
setToolbarPos();
}).resize(setToolbarPos);
{% if groups %}
function getAndHandleDiscussions(data_html) {
$('#discussions-to-grp').html(data_html).css({'max-height': parseInt($(window).height() * 0.8 - $('#discuss-to-group-form').outerHeight())}).removeClass('hide'); // 'parseInt' to fix '.msg-main top border missing when the ul's max-height is xxx.5px'
var popup = $('#discuss-to-group');
popup.css({'top':($(window).height() - popup.outerHeight())/2});
{% include 'group/msg_js.html' %}
}
$('#discuss').click(function() {
var popup = $('#discuss-to-group'),
form = $('#discuss-to-group-form'),
path = '{{ path }}';
// for repo.html: when get dir data with ajax
if ($('#repo-file-list').length > 0) {
path = cur_path;
$('[name="path"]', form).val(path);
// modify attachment dir name
$('.att-name', form).html($('#cur-dir-name').html());
}
if (popup.hasClass('hide')) {
$.ajax({
url: form.attr('action'),
dataType: 'json',
data: {
'repo_id': '{{ repo.id }}',
'path': path
},
success: function(data) {
getAndHandleDiscussions(data['html']);
popup.removeClass('hide');
},
error: function(jqXHR, textStatus, errorThrown) {
var err_str = '';
if (jqXHR.responseText) {
err_str = $.parseJSON(jqXHR.responseText).error;
feedback(err_str, 'error');
}
}
});
} else {
popup.addClass('hide');
}
});
// click 'close' to close discuss popup
$('#discuss-to-group .close').click(function () {
$('#discuss-to-group').addClass('hide');
});
$(document).click(function(e) {
var target = e.target || event.srcElement;
if (!$('#discuss, #discuss-to-group').is(target) && !($('#discuss, #discuss-to-group').find('*').is(target))) {
$('#discuss-to-group').addClass('hide');
}
});
$('#discuss-submit').click(function() {
var form = $('#discuss-to-group-form'),
form_id = form.attr('id');
if (form.find('.checkbox-checked').length == 0) {
apply_form_error(form_id, "{% trans "Please select at least 1 group." %}");
return false;
}
if (!$.trim($('#discuss-to-group-form .input').val())) {
apply_form_error(form_id, "{% trans "Please input a discussion." %}");
return false;
}
form.find('.error').addClass('hide');
var groups = [];
form.find('.checkbox-checked .checkbox-orig').each(function() {
groups.push($(this).val());
});
$.ajax({
url: form.attr('action'),
type: 'POST',
dataType: 'json',
beforeSend: prepareCSRFToken,
traditional: true,
data: {
'groups': groups,
'message': $('[name="message"]', form).val(),
'repo_id': '{{ repo.id }}',
'path': $('[name="path"]', form).val(),
'attach_type': $('[name="attach_type"]', form).val()
},
success: function(data) {
if(data['success']) {
feedback(data['success'], 'success');
getAndHandleDiscussions(data['html']);
form.find('.input').val('');
}
if(data['error']) {
feedback(data['error'], 'error');
}
},
error: function(jqXHR, textStatus, errorThrown) {
var err_str = '';
if (jqXHR.responseText) {
err_str = $.parseJSON(jqXHR.responseText).error;
} else {
err_str = "{% trans "Failed. Please check the network." %}";
}
apply_form_error(form_id, err_str);
}
});
return false;
});
$('#click-into-group').click(function() {
{% if groups|length == 1 %}
// only one group, just turn to group page
{% for group in groups %}
location.href= "{% url 'group_info' group.id %}";
{% endfor %}
{% else %}
// more than one group, then let user choose
$('#to-group').toggleClass('hide');
{% endif %}
});
$(document).click(function(e) {
var target = e.target || event.srcElement;
if (!$('#click-into-group, #to-group').is(target) && !($('#click-into-group, #to-group').find('*').is(target))) {
$('#to-group').addClass('hide');
}
});
{% endif %}

View File

@ -1,15 +0,0 @@
{% load seahub_tags avatar_tags i18n %}
<span class="commit-msg vam" data-cmtid="{{ current_commit.id }}">
{{ info_commit.props.desc|translate_commit_desc }}
<a class="lsch" href="#" data-url="{% url 'repo_history_changes' repo.id %}?commit_id={{ info_commit.id }}" data-time="{{ info_commit.props.ctime|tsstr_sec }}">{% trans "Details"%}</a>
</span>
<span class="meta-info split">
{% if info_commit.props.creator_name %}
{% avatar info_commit.props.creator_name 20 %}
<a class="vam" href="{% url 'user_profile' info_commit.creator_name %}">{{ info_commit.creator_name|email2nickname }}</a>
{% else %}
<span class="vam">{% trans "Unknown"%}</span>
{% endif %}
<span class="time vam">{{ info_commit.props.ctime|translate_seahub_time }}</span>
</span>
<a href="{% url 'seahub.views.repo_history' repo.id %}" class="more vam split">{% trans "History"%}</a>

View File

@ -1,37 +0,0 @@
{% load seahub_tags i18n %}
{% load url from future %}
<div id="discuss-to-group" class="hide">
<form action="{% url 'group_recommend' %}" method="post" id="discuss-to-group-form">{% csrf_token %}
<h3>{% trans "Post a discussion to group" %}</h3>
<div class="groups">
{% for group in groups %}
<label for="{{ group.id }}" class="checkbox-label">
<span class="checkbox{% if forloop.first and forloop.last %} checkbox-checked{% endif %}"><input type="checkbox" name="groups" value="{{ group.id }}" id="{{ group.id }}" {% if forloop.first and forloop.last %}checked="checked"{% endif %} class="checkbox-orig"></span>
<span class="checkbox-option">{{ group.group_name }}</span>
</label>
{% endfor %}
</div>
<textarea name="message" placeholder="{% trans 'discussion' %}" class="input"></textarea>
<input type="hidden" name="repo_id" value="{{ repo.id }}" />
<input type="hidden" name="path" value="{{ path }}" />
<input type="hidden" name="attach_type" value="{{ attach_type }}" />
<p class="error hide"></p>
<input type="submit" id="discuss-submit" class="submit" value="{% trans "Submit"%}" />
<span class="attachment">
{% if attach_type == 'dir' %}
<img src="{{ MEDIA_URL }}img/folder-icon-24.png" alt="{% trans 'Directory icon' %}" height="20" class="vam" />
{% endif %}
{% for name,link in zipped %}
{% if forloop.last %}
{% if attach_type == 'file' %}
<img src="{{ MEDIA_URL }}img/file/{{ name|file_icon_filter }}" alt="{% trans 'File' %}" height="18" class="vam" />
{% endif %}
<span class="att-name vam">{{ name }}</span>
{% endif %}
{% endfor %}
</span>
</form>
<ul id="discussions-to-grp" class="hide"></ul>
<img src="{{MEDIA_URL}}img/del.png" alt="{% trans "close" %}" class="close" />
</div>

View File

@ -1,73 +0,0 @@
{% load seahub_tags i18n %}
<div class="repo-file-list-topbar">
<p class="path fleft">
{% for name, link in zipped %}
{% if forloop.first or not forloop.last %}
<a href="{{ SITE_ROOT }}repo/{{ repo.id }}/?p={{ link|urlencode }}" class="dir-link normal">{{ name }}</a> /
{% else %}
<span id="cur-dir-name" data-name="{{ name }}">{{ name }}</span> /
{% endif %}
{% endfor %}
</p>
<div class="repo-op fright">
{% if user_perm == 'rw' %}
{% if repo.encrypted and repo.enc_version == 2 and not server_crypto %}
<button id="upload-file" class="op-btn"><span class="icon-upload-alt"></span>{% trans "Upload"%}</button>
{% else %}
{% if no_quota %}
<button id="upload-file" class="op-btn"><span class="icon-upload-alt"></span>{% trans "Upload"%}</button>
{% else %}
<div id="upload-file" class="op-btn upload-file-btn">
<span class="icon-upload-alt"></span><span>{% trans "Upload"%}</span>
<input type="file" name="file" multiple />
</div>
{% if enable_upload_folder %}
<ul id="upload-menu" class="hide">
<li class="item">
<span>{% trans "Upload Files" %}</span>
<input type="file" name="file" multiple />
</li>
<li class="item">
<span>{% trans "Upload Folder" %}</span>
<input type="file" name="file" multiple directory webkitdirectory />
</li>
</ul>
{% endif %}
{% endif %}
{% endif %}
<button id="add-new-dir" class="op-btn"><span class="icon-plus-sign-alt"></span>{% trans "New Directory"%}</button>
{% if repo.encrypted and repo.enc_version == 2 and not server_crypto %}
{% else %}
<button id="add-new-file" class="op-btn"><span class="icon-plus-sign-alt"></span>{% trans "New File"%}</button>
{% endif %}
{% endif %}
{% if path != '/' %}
{% if not repo.encrypted %}
<button data-link="{{ dir_shared_link }}" data-token="{{fileshare.token}}" data-upload-link="{{ dir_shared_upload_link }}" data-upload-token="{{ uploadlink.token }}" class="op-btn" id="share-cur-dir"><span class="sf-icon-share"></span>{% trans "Share"%}</button>
{% endif %}
{% endif %}
</div>
<div id="repo-latest-commit" class="clear">
{% include 'snippets/current_commit.html' %}
</div>
</div>
<table class="repo-file-list">
<tr>
<th class="select">
<span class="checkbox"><input type="checkbox" class="checkbox-orig" /></span>
</th>
<th class="star"></th>
<th class="dirent-icon"></th>
<th><span class="dirent-name">{% trans "Name"%} <span id="name-down" class="icon-caret-up cspt"></span> <span id="name-up" class="icon-caret-down cspt hide"></span></span></th>
<th class="dirent-size">{% trans "Size"%}</th>
<th class="dirent-update">{% trans "Last Update" %} <span id="time-up" class="icon-caret-up cspt hide"></span> <span id="time-down" class="icon-caret-down cspt"></span></th>
<th class="dirent-op">{% trans "Operations"%}</th>
</tr>
{% include 'snippets/repo_dirents.html' %}
</table>
{% if dirent_more %}
<span class="dirent-more loading-icon loading-tip" data-start="{{more_start}}"></span>
{% endif %}

View File

@ -1,98 +0,0 @@
{% load seahub_tags i18n %}
{% for dirent in dir_list %}
<tr class="dir-item" data-name="{{dirent.obj_name}}" data-time="{% if dirent.last_modified %}{{ dirent.last_modified }}{%else %}0{% endif %}">
<td class="select">
<span class="checkbox"><input type="checkbox" class="checkbox-orig" /></span>
</td>
<td class="star"></td>
{% if dirent.permission = 'r' %}
<td class="dirent-icon"><img src="{{ MEDIA_URL }}img/folder-read-only-24.png" alt="{% trans "Directory icon"%}" /></td>
{% else %}
<td class="dirent-icon"><img src="{{ MEDIA_URL }}img/folder-24.png" alt="{% trans "Directory icon"%}" /></td>
{% endif %}
<td>
<span class="dirent-name"><a href="{{dirent.view_link}}" class="dir-link">{{ dirent.obj_name }}</a></span>
</td>
<td class="dirent-size"></td>
<td class="dirent-update">
{{ dirent.last_modified|translate_seahub_time }}
</td>
<td class="dirent-op">
<div class="repo-file-op vh">
<div class="displayed-op">
<a class="op dir-download" href="{{dirent.dl_link}}" title="{% trans "Download" %}">
<img src="{{MEDIA_URL}}img/download.png" alt="" />
</a>
{% if not repo.encrypted %}
<a class="op dir-share" href="#" data-link="{{ dirent.sharelink }}" data-token="{{ dirent.sharetoken }}" data-upload-link="{{ dirent.uploadlink }}" data-upload-token="{{ dirent.uploadtoken }}" title="{% trans "Share" %}">
<img src="{{MEDIA_URL}}img/share_20.png" alt="" />
</a>
{% endif %}
</div>
{% if user_perm == 'rw' %}
<img src="{{ MEDIA_URL }}img/dropdown-arrow.png" title="{% trans 'More operations'%}" alt="{% trans 'More operations'%}" class="more-op-icon cspt" data="no-popup" />
<ul class="hidden-op hide">
<li><a class="op dir-del" href="#">{% trans "Delete"%}</a></li>
<li><a class="op dir-rename" href="#">{% trans "Rename"%}</a></li>
<li><a class="op dir-mv" href="#">{% trans "Move"%}</a></li>
<li><a class="op dir-cp" href="#">{% trans "Copy"%}</a></li>
</ul>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
{% for dirent in file_list %}
<tr class="file-item" data-name="{{dirent.obj_name}}" data-time="{% if dirent.last_modified %}{{ dirent.last_modified }}{% else %}0{% endif %}">
<td class="select">
<span class="checkbox"><input type="checkbox" class="checkbox-orig" /></span>
</td>
<td class="star alc">
{% if dirent.starred %}
<span title="{% trans 'starred' %}" class="icon-star file-star" data-status="starred"></span>
{% else %}
<span title="{% trans 'unstarred' %}" class="icon-star-empty file-star" data-status="unstarred"></span>
{% endif %}
</td>
<td class="dirent-icon">
<img src="{{ MEDIA_URL }}img/file/{{ dirent.obj_name|file_icon_filter }}" alt="{% trans "File"%}" />
</td>
<td>
{% if repo.encrypted and repo.enc_version == 2 and not server_crypto %}
<span class="dirent-name">{{ dirent.obj_name }}</span>
{% else %}
<span class="dirent-name"><a class="normal" href="{{dirent.view_link}}" target="_blank">{{ dirent.obj_name }}</a></span>
{% endif %}
</td>
<td class="dirent-size">{{ dirent.file_size|filesizeformat }}</td>
<td class="dirent-update">
{{ dirent.last_modified|translate_seahub_time }}
</td>
<td class="dirent-op">
<div class="repo-file-op vh">
<div class="displayed-op">
<a class="op file-download" href="{{dirent.dl_link}}" data-fileid="{{ dirent.props.obj_id }}" title="{% trans "Download"%}">
<img src="{{MEDIA_URL}}img/download.png" alt="" />
</a>
{% if not repo.encrypted %}
<a class="op file-share" href="#" data-link="{{ dirent.sharelink }}" data-token="{{ dirent.sharetoken }}" title="{% trans "Share" %}">
<img src="{{MEDIA_URL}}img/share_20.png" alt="" />
</a>
{% endif %}
</div>
{% if user_perm == 'rw' %}
<img src="{{ MEDIA_URL }}img/dropdown-arrow.png" title="{% trans "More Operations"%}" alt="{% trans "More Operations"%}" class="more-op-icon cspt" data="no-popup" />
<ul class="hidden-op hide">
<li><a class="op file-del" href="#">{% trans "Delete"%}</a></li>
<li><a class="op file-update" href="#">{% trans "Update"%}</a></li>
<li><a class="op file-rename" href="#">{% trans "Rename" %}</a></li>
<li><a class="op file-mv" href="#">{% trans "Move" %}</a></li>
<li><a class="op file-cp" href="#">{% trans "Copy" %}</a></li>
<li><a class="op file-history" href="{{dirent.history_link}}" target="_blank">{% trans "History" %}</a></li>
</ul>
{% endif %}
</div>
</td>
</tr>
{% endfor %}

View File

@ -1,9 +0,0 @@
{% load url from future %}
{% autoescape off %}
<ul>
{% for group in groups %}
<li><a href="{% url 'group_info' group.id %}">{{ group.group_name }}</a></li>
{% endfor %}
</ul>
{% endautoescape %}

View File

@ -25,8 +25,16 @@
{% endif %}
{% endfor %}
</p>
<div id="repo-latest-commit" class="clear">
{% if is_default_repo %}
<div class="repo-op fright">
<div id="upload-file" class="op-btn upload-file-btn">
<span class="icon-upload-alt"></span><span>{% trans "Upload"%}</span>
<input type="file" name="file" multiple />
</div>
<button id="add-new-dir" class="op-btn"><span class="icon-plus-sign-alt"></span>{% trans "New Directory"%}</button>
</div>
{% endif %}
<div class="clear"></div>
</div>
<table class="repo-file-list">
@ -49,6 +57,15 @@
{{ dirent.last_modified|translate_seahub_time }}
</td>
<td class="dirent-op">
{% if is_default_repo %}
<div class="repo-file-op vh">
<div class="displayed-op">
<a href="#" class="op dirent-del" data-url="{% url 'delete_dir' repo.id %}?parent_dir={{path|urlencode}}&name={{ dirent.obj_name|urlencode }}" title="{% trans "Delete" %}">
<img src="{{MEDIA_URL}}img/rm.png" alt="" />
</a>
</div>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
@ -67,6 +84,11 @@
<td class="dirent-op">
<div class="repo-file-op vh">
<div class="displayed-op">
{% if is_default_repo %}
<a href="#" class="op dirent-del" data-url="{% url 'delete_file' repo.id %}?parent_dir={{path|urlencode}}&name={{ dirent.obj_name|urlencode }}" title="{% trans "Delete" %}">
<img src="{{MEDIA_URL}}img/rm.png" alt="" />
</a>
{% endif %}
<a class="op file-download" href="{% url 'sys_admin_repo_download_file' repo.id %}?p={{path|urlencode}}{{ dirent.obj_name|urlencode }}" title="{% trans "Download"%}">
<img src="{{MEDIA_URL}}img/download.png" alt="" />
</a>
@ -78,9 +100,41 @@
</table>
</div>
{% if is_default_repo %}
<form id="add-new-dir-form" action="" method="post" class="hide">{% csrf_token %}
<h3>{% trans "New Directory" %}</h3>
<label>{% trans "Directory Name" %}</label><br /><!-- <br/> for ie 7 -->
<input type="text" name="name" value="" class="input" maxlength="{{max_file_name}}"/><br />
<p class="error hide"></p>
<button type="submit" class="submit">{% trans "Submit" %}</button>
<button class="simplemodal-close">{% trans "Cancel" %}</button>
</form>
<div id="upload-file-dialog" class="hide">
<h3 class="hd"><span class="status">{% trans "File Upload" %}</span> <span class="total-progress hide"></span></h3>
<div class="ops">
<img src="{{MEDIA_URL}}img/minus.png" alt="" class="fold-switch cspt" />
<img src="{{MEDIA_URL}}img/close.png" alt="close" title="{% trans "close" %}" class="close cspt hide" />
</div>
<div class="con">
<div class="row fileupload-buttonbar">
<button type="button" class="cancel cspt fright">{% trans "Cancel All" %}</button>
</div>
<p class="saving-tip alc clear hide">
<span class="loading-icon vam"></span>
<span class="vam">{% trans "Saving..." %}</span>
</p>
<table class="table table-striped"><tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody></table>
</div>
</div>
{% endif %}
{% endblock %}
{% block extra_script %}
{% if is_default_repo %}
{% upload_js %}
{% endif %}
<script type="text/javascript">
$('.dir-item, .file-item').unbind().hover( // remove previously binded hover handler at first
function() {
@ -90,5 +144,217 @@ $('.dir-item, .file-item').unbind().hover( // remove previously binded hover han
$(this).removeClass('hl').find('.repo-file-op').addClass('vh');
}
);
{% if is_default_repo %}
var cur_path = "{{path|escapejs}}";
$(function() {
$.getScript('{{ MEDIA_URL }}js/jquery.fileupload.min.js', function () {
var popup = $('#upload-file-dialog').addClass('fixed-upload-file-dialog');;
var popup_height = '200px';
popup.css({'height': popup_height}).data('height', popup_height);
var fu_status = $('.status', popup),
total_progress = $('.total-progress', popup),
cancel_all_btn = $('.fileupload-buttonbar .cancel', popup),
close_icon = $('.close', popup),
saving_tip = $('.saving-tip', popup);
var fu_status_ = {
'uploading': "{% trans "File Uploading..." %}",
'complete': "{% trans "File Upload complete" %}",
'canceled': "{% trans "File Upload canceled" %}",
'failed': "{% trans "File Upload failed" %}"
};
popup.fileupload({
formData: {'parent_dir': cur_path},
fileInput: $('#upload-file input'),
paramName: 'file',
// customize it for 'done'
getFilesFromResponse: function (data) {
if (data.result) {
return data.result;
}
},
autoUpload:true,
{% if max_upload_file_size %}
maxFileSize: {{ max_upload_file_size }}, // in bytes
{% endif %}
maxNumberOfFiles: 500,
sequentialUploads: true
})
.bind('fileuploadadd', function(e, data) {
popup.removeClass('hide');
cancel_all_btn.removeClass('hide');
close_icon.addClass('hide');
})
.bind('fileuploadstart', function() {
fu_status.html(fu_status_.uploading);
})
.bind('fileuploadsubmit', function(e, data) {
if (data.files.length == 0) {
return false;
}
var file = data.files[0];
// get url(token) for every file
if (!file.error) {
$.ajax({
url: '{% url 'get_file_op_url' repo.id %}',
cache: false,
data: {
'op_type': 'upload',
'path': cur_path
},
dataType: 'json',
success: function(ret) {
data.url = ret['url'];
data.jqXHR = popup.fileupload('send', data);
},
error: function() {
file.error = "{% trans "Failed to get upload url" %}";
}
});
return false;
}
})
.bind('fileuploadprogressall', function (e, data) {
total_progress.html(parseInt(data.loaded / data.total * 100, 10) + '% ' + '<span style="font-size:14px;color:#555;">(' + $(this).data('blueimp-fileupload')._formatBitrate(data.bitrate) + ')</span>').removeClass('hide');
if (data.loaded > 0 && data.loaded == data.total) {
saving_tip.show();
}
})
.bind('fileuploadstop', function() {
setTimeout(function() { location.reload(true); }, 1000);
})
// after tpl has rendered
.bind('fileuploadcompleted', function() { // 'done'
if ($('.files .cancel', popup).length == 0) {
saving_tip.hide();
total_progress.addClass('hide');
fu_status.html(fu_status_.complete);
}
})
.bind('fileuploadfailed', function(e, data) { // 'fail'
if ($('.files .cancel', popup).length == 0) {
cancel_all_btn.addClass('hide');
close_icon.removeClass('hide');
total_progress.addClass('hide');
saving_tip.hide();
if (data.errorThrown == 'abort') { // 'cancel'
fu_status.html(fu_status_.canceled);
} else { // 'error'
fu_status.html(fu_status_.failed);
}
}
});
// Enable iframe cross-domain access via redirect option:
popup.fileupload(
'option',
'redirect',
window.location.href.replace(/\/repo\/[-a-z0-9]{36}\/.*/, '{{ MEDIA_URL }}cors/result.html?%s')
);
});
});
// fold/unfold the dialog
$('#upload-file-dialog .fold-switch').click(function() {
var popup = $('#upload-file-dialog');
var full_ht = parseInt(popup.data('height'));
var main_con = $('.fileupload-buttonbar, .table', popup);
if (popup.height() == full_ht) {
popup.height($('.hd', popup).outerHeight(true));
main_con.addClass('hide');
} else {
popup.height(full_ht);
main_con.removeClass('hide');
}
});
$('#upload-file-dialog .close').click(function() {
$('#upload-file-dialog').addClass('hide');
$('#upload-file-dialog .files').empty();
});
window.locale = {
"fileupload": {
"errors": {
"maxFileSize": "{% trans "File is too big" %}",
"minFileSize": "{% trans "File is too small" %}",
"acceptFileTypes": "{% trans "Filetype not allowed" %}",
"maxNumberOfFiles": "{% trans "Max number of files exceeded" %}",
"uploadedBytes": "{% trans "Uploaded bytes exceed file size" %}",
"emptyResult": "{% trans "Empty file upload result" %}"
},
"error": "{% trans "Error" %}",
"uploaded": "{% trans "uploaded" %}",
"canceled": "{% trans "canceled" %}",
"start": "{% trans "Start" %}",
"cancel": "{% trans "Cancel" %}",
"destroy": "{% trans "Delete" %}"
}
};
$('#add-new-dir').click(function () {
$('#add-new-dir-form').modal({appendTo:'#main'});
$('#simplemodal-container').css({'height':'auto'});
});
$('#add-new-dir-form').submit(function() {
var form = $(this),
form_id = form.attr('id'),
dirent_name = $.trim($('[name="name"]', form).val()),
submit_btn = $('[type="submit"]', form);
if (!dirent_name) {
apply_form_error(form_id, "{% trans "It is required." %}");
return false;
}
disable(submit_btn);
$.ajax({
url: '{% url 'new_dir' repo.id %}?parent_dir=' + e(cur_path),
type: 'POST',
dataType: 'json',
beforeSend: prepareCSRFToken,
data: {'dirent_name': dirent_name},
success: function(data) {
location.reload(true);
},
error: function(xhr, textStatus, errorThrown) {
var err;
if (xhr.responseText) {
err = $.parseJSON(xhr.responseText).error;
} else {
err = "{% trans "Failed. Please check the network." %}";
}
apply_form_error(form_id, err);
enable(submit_btn);
}
});
return false;
});
$('.dirent-del').click(function() {
var dirent = $(this).parents('tr'),
url = $(this).attr('data-url');
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
beforeSend: prepareCSRFToken,
success: function(data) {
if (data['success']) {
dirent.remove();
feedback("{% trans "Delete succeeded." %}", 'success');
}
},
error: ajaxErrorHandler
});
return false;
});
{% endif %}
</script>
{% endblock %}

View File

@ -15,9 +15,7 @@
<td>{{ repo.props.name }}</td>
{% else %}
<td><img src="{{MEDIA_URL}}img/sync-folder-20.png?t=1387267140" title="{% trans "Read-Write"%}" alt="{% trans "directory icon" %}" /></td>
{% if repo.is_default_repo %}
<td><a href="{% url 'repo' repo.id %}">{{ repo.props.name }}</a></td>
{% elif enable_sys_admin_view_repo and is_pro_version %}
{% if enable_sys_admin_view_repo and is_pro_version %}
<td><a href="{% url 'sys_admin_repo' repo.id %}">{{ repo.props.name }}</a></td>
{% else %}
<td>{{ repo.props.name }}</td>

View File

@ -2,12 +2,6 @@
{% load i18n %}
{% block cur_repo %}tab-cur{% endblock %}
{% block left_panel %}{{block.super}}
<form action="{% url 'sys_repo_search' %}" method="get" class="side-search-form">
<input type="text" name="name" class="input" value="" placeholder="{% trans "Search libraries by name..." %}" />
</form>
{% endblock %}
{% block right_panel %}
<div class="tabnav">
<ul class="tabnav-tabs">
@ -26,7 +20,7 @@
</tr>
{% for repo in repos %}
<tr>
<td><a href="{% url 'repo' repo.id %}">{{ repo.props.name }}</a></td>
<td><a href="{% url 'sys_admin_repo' repo.id %}">{{ repo.props.name }}</a></td>
<td style="font-size:11px;">{{ repo.id }}</td>
<td>{{ repo.props.desc }}</td>
</tr>
@ -36,5 +30,4 @@
<p>{% trans "None" %}</p>
{% endif %}
{% include "sysadmin/repo_transfer_form.html" %}
{% endblock %}

View File

@ -8,7 +8,7 @@ from seahub.views.file import view_repo_file, view_history_file, view_trash_file
view_snapshot_file, file_edit, view_shared_file, view_file_via_shared_dir,\
text_diff, view_priv_shared_file, view_raw_file, view_raw_shared_file, \
download_file, view_lib_file, file_access
from seahub.views.repo import repo, repo_history_view, view_shared_dir, \
from seahub.views.repo import repo_history_view, view_shared_dir, \
view_shared_upload_link
from notifications.views import notification_list
from message.views import user_msg_list, user_msg_remove, user_received_msg_remove
@ -72,7 +72,6 @@ urlpatterns = patterns(
url(r'^repo/file_revisions/(?P<repo_id>[-0-9a-f]{36})/$', file_revisions, name='file_revisions'),
url(r'^repo/file-access/(?P<repo_id>[-0-9a-f]{36})/$', file_access, name='file_access'),
url(r'^repo/text_diff/(?P<repo_id>[-0-9a-f]{36})/$', text_diff, name='text_diff'),
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/$', repo, name='repo'),
url(r'^repo/history/(?P<repo_id>[-0-9a-f]{36})/$', repo_history, name='repo_history'),
url(r'^repo/history/view/(?P<repo_id>[-0-9a-f]{36})/$', repo_history_view, name='repo_history_view'),
url(r'^repo/recycle/(?P<repo_id>[-0-9a-f]{36})/$', repo_recycle_view, name='repo_recycle_view'),
@ -127,14 +126,11 @@ urlpatterns = patterns(
url(r'^choose_register/$', TemplateView.as_view(template_name="choose_register.html"), name="choose_register"),
### Ajax ###
url(r'^ajax/repo/create/$', repo_create, name="repo_create"),
(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/remove/$', repo_remove),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dirents/$', get_dirents, name="get_dirents"),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dirents/delete/$', delete_dirents, name='delete_dirents'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dirents/move/$', mv_dirents, name='mv_dirents'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dirents/copy/$', cp_dirents, name='cp_dirents'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/$', list_dir, name='repo_dir_data'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/more/$', list_dir_more, name='list_dir_more'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/new/$', new_dir, name='new_dir'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/rename/$', rename_dirent, name='rename_dir'),
url(r'^ajax/repo/(?P<repo_id>[-0-9a-f]{36})/dir/delete/$', delete_dirent, name='delete_dir'),

View File

@ -226,93 +226,6 @@ def get_file_download_link(repo_id, obj_id, path):
return reverse('download_file', args=[repo_id, obj_id]) + '?p=' + \
urlquote(path)
def get_repo_dirents_with_perm(request, repo, commit, path, offset=-1, limit=-1):
"""List repo dirents with perm based on commit id and path.
Use ``offset`` and ``limit`` to do paginating.
Returns: A tupple of (file_list, dir_list, dirent_more)
TODO: Some unrelated parts(file sharing, stars, modified info, etc) need
to be pulled out to multiple functions.
"""
if get_system_default_repo_id() == repo.id:
return get_repo_dirents(request, repo, commit, path, offset, limit)
dir_list = []
file_list = []
dirent_more = False
username = request.user.username
if commit.root_id == EMPTY_SHA1:
return ([], [], False) if limit == -1 else ([], [], False)
else:
try:
dir_id = seafile_api.get_dir_id_by_path(repo.id, path)
if not dir_id:
return ([], [], False)
dirs = seafserv_threaded_rpc.list_dir_with_perm(repo.id, path,
dir_id, username,
offset, limit)
except SearpcError as e:
logger.error(e)
return ([], [], False)
if limit != -1 and limit == len(dirs):
dirent_more = True
starred_files = get_dir_starred_files(username, repo.id, path)
fileshares = FileShare.objects.filter(repo_id=repo.id).filter(username=username)
uploadlinks = UploadLinkShare.objects.filter(repo_id=repo.id).filter(username=username)
view_dir_base = reverse('repo', args=[repo.id])
dl_dir_base = reverse('repo_download_dir', args=[repo.id])
view_file_base = reverse('repo_view_file', args=[repo.id])
file_history_base = reverse('file_revisions', args=[repo.id])
for dirent in dirs:
dirent.last_modified = dirent.mtime
dirent.sharelink = ''
dirent.uploadlink = ''
if stat.S_ISDIR(dirent.props.mode):
dpath = posixpath.join(path, dirent.obj_name)
if dpath[-1] != '/':
dpath += '/'
for share in fileshares:
if dpath == share.path:
dirent.sharelink = gen_dir_share_link(share.token)
dirent.sharetoken = share.token
break
for link in uploadlinks:
if dpath == link.path:
dirent.uploadlink = gen_shared_upload_link(link.token)
dirent.uploadtoken = link.token
break
p_dpath = posixpath.join(path, dirent.obj_name)
dirent.view_link = view_dir_base + '?p=' + urlquote(p_dpath)
dirent.dl_link = dl_dir_base + '?p=' + urlquote(p_dpath)
dir_list.append(dirent)
else:
file_list.append(dirent)
if repo.version == 0:
dirent.file_size = get_file_size(repo.store_id, repo.version, dirent.obj_id)
else:
dirent.file_size = dirent.size
dirent.starred = False
fpath = posixpath.join(path, dirent.obj_name)
p_fpath = posixpath.join(path, dirent.obj_name)
dirent.view_link = view_file_base + '?p=' + urlquote(p_fpath)
dirent.dl_link = get_file_download_link(repo.id, dirent.obj_id,
p_fpath)
dirent.history_link = file_history_base + '?p=' + urlquote(p_fpath)
if fpath in starred_files:
dirent.starred = True
for share in fileshares:
if fpath == share.path:
dirent.sharelink = gen_file_share_link(share.token)
dirent.sharetoken = share.token
break
return (file_list, dir_list, dirent_more)
def get_repo_dirents(request, repo, commit, path, offset=-1, limit=-1):
"""List repo dirents based on commit id and path. Use ``offset`` and
``limit`` to do paginating.
@ -347,7 +260,8 @@ def get_repo_dirents(request, repo, commit, path, offset=-1, limit=-1):
fileshares = FileShare.objects.filter(repo_id=repo.id).filter(username=username)
uploadlinks = UploadLinkShare.objects.filter(repo_id=repo.id).filter(username=username)
view_dir_base = reverse('repo', args=[repo.id])
view_dir_base = reverse("view_common_lib_dir", args=[repo.id, '/'])
dl_dir_base = reverse('repo_download_dir', args=[repo.id])
file_history_base = reverse('file_revisions', args=[repo.id])
for dirent in dirs:
@ -922,7 +836,7 @@ def repo_folder_perm(request, repo_id):
for folder_perm in user_folder_perms:
folder_path = folder_perm.path
folder_perm.folder_link = reverse('repo', args=[repo_id]) + '?p=' + urlquote(folder_path)
folder_perm.folder_link = reverse("view_common_lib_dir", args=[repo_id, urlquote(folder_path).strip('/')])
if folder_path == '/':
folder_perm.folder_name = _(u'Root Directory')
else:
@ -936,7 +850,7 @@ def repo_folder_perm(request, repo_id):
for folder_perm in group_folder_perms:
folder_path = folder_perm.path
folder_perm.folder_link = reverse('repo', args=[repo_id]) + '?p=' + urlquote(folder_path)
folder_perm.folder_link = reverse("view_common_lib_dir", args=[repo_id, urlquote(folder_path).strip('/')])
if folder_path == '/':
folder_perm.folder_name = _(u'Root Directory')
else:
@ -1054,7 +968,7 @@ def repo_history(request, repo_id):
return render_error(request, e.msg)
if not password_set:
return HttpResponseRedirect(reverse('repo', args=[repo_id]))
return HttpResponseRedirect(reverse("view_common_lib_dir", args=[repo_id, '/']))
try:
current_page = int(request.GET.get('page', '1'))
@ -1124,7 +1038,7 @@ def repo_revert_history(request, repo_id):
return render_error(request, e.msg)
if not password_set:
return HttpResponseRedirect(reverse('repo', args=[repo_id]))
return HttpResponseRedirect(reverse("view_common_lib_dir", args=[repo_id, '/']))
commit_id = request.GET.get('commit_id', '')
if not commit_id:
@ -1416,7 +1330,7 @@ def repo_set_access_property(request, repo_id):
ap = request.GET.get('ap', '')
seafserv_threaded_rpc.repo_set_access_property(repo_id, ap)
return HttpResponseRedirect(reverse('repo', args=[repo_id]))
return HttpResponseRedirect(reverse("view_common_lib_dir", args=[repo_id, '/']))
@login_required
def file_upload_progress_page(request):

View File

@ -16,11 +16,10 @@ from django.contrib import messages
from django.template.defaultfilters import filesizeformat
import seaserv
from seaserv import seafile_api, seafserv_rpc, is_passwd_set, \
from seaserv import seafile_api, is_passwd_set, \
get_related_users_by_repo, get_related_users_by_org_repo, \
CALC_SHARE_USAGE, seafserv_threaded_rpc, ccnet_threaded_rpc, \
get_user_quota_usage, get_user_share_usage, edit_repo, \
set_repo_history_limit
edit_repo, set_repo_history_limit
from pysearpc import SearpcError
from seahub.auth.decorators import login_required_ajax
@ -35,13 +34,9 @@ from seahub.message.models import UserMessage
from seahub.share.models import UploadLinkShare
from seahub.group.models import PublicGroup
from seahub.signals import upload_file_successful, repo_created, repo_deleted
from seahub.views import get_repo_dirents_with_perm, validate_owner, \
check_repo_access_permission, get_unencry_rw_repos_by_user, \
get_system_default_repo_id, get_diff, group_events_data, \
get_owned_repo_list, check_folder_permission, is_registered_user, \
check_file_lock
from seahub.views.repo import get_nav_path, get_fileshare, get_dir_share_link, \
get_uploadlink, get_dir_shared_upload_link
from seahub.views import validate_owner, check_repo_access_permission, \
get_unencry_rw_repos_by_user, get_system_default_repo_id, get_diff, group_events_data, \
get_owned_repo_list, check_folder_permission, is_registered_user
from seahub.views.modules import get_enabled_mods_by_group, \
get_available_mods_by_group, enable_mod_for_group, \
disable_mod_for_group, MOD_GROUP_WIKI, MOD_PERSONAL_WIKI, \
@ -49,7 +44,7 @@ from seahub.views.modules import get_enabled_mods_by_group, \
from seahub.group.views import is_group_staff
import seahub.settings as settings
from seahub.settings import ENABLE_THUMBNAIL, THUMBNAIL_ROOT, \
THUMBNAIL_DEFAULT_SIZE, ENABLE_SUB_LIBRARY, ENABLE_REPO_HISTORY_SETTING, \
THUMBNAIL_DEFAULT_SIZE, ENABLE_SUB_LIBRARY, \
ENABLE_FOLDER_PERM, SHOW_TRAFFIC, MEDIA_URL
from constance import config
from seahub.utils import check_filename_with_rename, EMPTY_SHA1, \
@ -59,7 +54,7 @@ from seahub.utils import check_filename_with_rename, EMPTY_SHA1, \
get_org_user_events, get_user_events, get_file_type_and_ext, \
is_valid_username, send_perm_audit_msg, get_origin_repo_info, is_pro_version
from seahub.utils.repo import get_sub_repo_abbrev_origin_path
from seahub.utils.star import star_file, unstar_file
from seahub.utils.star import star_file, unstar_file, get_dir_starred_files
from seahub.base.accounts import User
from seahub.thumbnail.utils import get_thumbnail_src
from seahub.utils.file_types import IMAGE
@ -238,165 +233,6 @@ def unenc_rw_repos(request):
repo_list.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))
return HttpResponse(json.dumps(repo_list), content_type=content_type)
@login_required_ajax
def list_dir(request, repo_id):
"""
List directory entries in AJAX.
"""
content_type = 'application/json; charset=utf-8'
repo = get_repo(repo_id)
if not repo:
err_msg = _(u'Library does not exist.')
return HttpResponse(json.dumps({'error': err_msg}),
status=400, content_type=content_type)
username = request.user.username
user_perm = check_repo_access_permission(repo.id, request.user)
if user_perm is None:
err_msg = _(u'Permission denied.')
return HttpResponse(json.dumps({'error': err_msg}),
status=403, content_type=content_type)
sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)
try:
server_crypto = UserOptions.objects.is_server_crypto(username)
except CryptoOptionNotSetError:
# Assume server_crypto is ``False`` if this option is not set.
server_crypto = False
if repo.encrypted and \
(repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
and not seafile_api.is_password_set(repo.id, username):
err_msg = _(u'Library is encrypted.')
return HttpResponse(json.dumps({'error': err_msg}),
status=403, content_type=content_type)
head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)
if not head_commit:
err_msg = _(u'Error: no head commit id')
return HttpResponse(json.dumps({'error': err_msg}),
status=500, content_type=content_type)
if new_merge_with_no_conflict(head_commit):
info_commit = get_commit_before_new_merge(head_commit)
else:
info_commit = head_commit
path = request.GET.get('p', '/')
if path[-1] != '/':
path = path + '/'
more_start = None
file_list, dir_list, dirent_more = get_repo_dirents_with_perm(request, repo,
head_commit, path,
offset=0, limit=100)
if dirent_more:
more_start = 100
zipped = get_nav_path(path, repo.name)
fileshare = get_fileshare(repo.id, username, path)
dir_shared_link = get_dir_share_link(fileshare)
uploadlink = get_uploadlink(repo.id, username, path)
dir_shared_upload_link = get_dir_shared_upload_link(uploadlink)
ctx = {
'repo': repo,
'zipped': zipped,
'user_perm': user_perm,
'path': path,
'server_crypto': server_crypto,
'fileshare': fileshare,
'dir_shared_link': dir_shared_link,
'uploadlink': uploadlink,
'dir_shared_upload_link': dir_shared_upload_link,
'dir_list': dir_list,
'file_list': file_list,
'dirent_more': dirent_more,
'more_start': more_start,
'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
'sub_lib_enabled': sub_lib_enabled,
'enable_upload_folder': settings.ENABLE_UPLOAD_FOLDER,
'current_commit': head_commit,
'info_commit': info_commit,
}
html = render_to_string('snippets/repo_dir_data.html', ctx,
context_instance=RequestContext(request))
return HttpResponse(json.dumps({'html': html, 'path': path}),
content_type=content_type)
@login_required_ajax
def list_dir_more(request, repo_id):
"""
List 'more' entries in a directory with AJAX.
"""
content_type = 'application/json; charset=utf-8'
repo = get_repo(repo_id)
if not repo:
err_msg = _(u'Library does not exist.')
return HttpResponse(json.dumps({'error': err_msg}),
status=400, content_type=content_type)
username = request.user.username
user_perm = check_repo_access_permission(repo.id, request.user)
if user_perm is None:
err_msg = _(u'Permission denied.')
return HttpResponse(json.dumps({'error': err_msg}),
status=403, content_type=content_type)
sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)
try:
server_crypto = UserOptions.objects.is_server_crypto(username)
except CryptoOptionNotSetError:
# Assume server_crypto is ``False`` if this option is not set.
server_crypto = False
if repo.encrypted and \
(repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
and not seafile_api.is_password_set(repo.id, username):
err_msg = _(u'Library is encrypted.')
return HttpResponse(json.dumps({'error': err_msg}),
status=403, content_type=content_type)
head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)
if not head_commit:
err_msg = _(u'Error: no head commit id')
return HttpResponse(json.dumps({'error': err_msg}),
status=500, content_type=content_type)
path = request.GET.get('p', '/')
if path[-1] != '/':
path = path + '/'
offset = int(request.GET.get('start'))
if not offset:
err_msg = _(u'Argument missing')
return HttpResponse(json.dumps({'error': err_msg}),
status=400, content_type=content_type)
more_start = None
file_list, dir_list, dirent_more = get_repo_dirents_with_perm(request, repo,
head_commit, path,
offset, limit=100)
if dirent_more:
more_start = offset + 100
ctx = {
'repo': repo,
'user_perm': user_perm,
'path': path,
'server_crypto': server_crypto,
'dir_list': dir_list,
'file_list': file_list,
'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
'sub_lib_enabled': sub_lib_enabled,
}
html = render_to_string('snippets/repo_dirents.html', ctx,
context_instance=RequestContext(request))
return HttpResponse(json.dumps({'html': html, 'dirent_more': dirent_more, 'more_start': more_start}),
content_type=content_type)
@login_required_ajax
def list_lib_dir(request, repo_id):
'''
@ -436,9 +272,51 @@ def list_lib_dir(request, repo_id):
status=500, content_type=content_type)
offset = int(request.GET.get('start', 0))
file_list, dir_list, dirent_more = get_repo_dirents_with_perm(request, repo, head_commit, path, offset, limit=100)
limit = 100
dir_list = []
file_list = []
dirent_more = False
try:
dir_id = seafile_api.get_dir_id_by_path(repo.id, path)
except SearpcError as e:
logger.error(e)
err_msg = 'Internal Server Error'
return HttpResponse(json.dumps({'error': err_msg}),
status=500, content_type=content_type)
if not dir_id:
err_msg = 'Folder not found.'
return HttpResponse(json.dumps({'error': err_msg}),
status=404, content_type=content_type)
dirs = seafserv_threaded_rpc.list_dir_with_perm(repo_id, path, dir_id, username, offset, limit)
starred_files = get_dir_starred_files(username, repo_id, path)
for dirent in dirs:
dirent.last_modified = dirent.mtime
if stat.S_ISDIR(dirent.mode):
dpath = posixpath.join(path, dirent.obj_name)
if dpath[-1] != '/':
dpath += '/'
dir_list.append(dirent)
else:
if repo.version == 0:
file_size = seafile_api.get_file_size(repo.store_id, repo.version, dirent.obj_id)
else:
file_size = dirent.size
dirent.file_size = file_size if file_size else 0
dirent.starred = False
fpath = posixpath.join(path, dirent.obj_name)
if fpath in starred_files:
dirent.starred = True
file_list.append(dirent)
more_start = None
if dirent_more:
if limit == len(dirs):
dirent_more = True
more_start = offset + 100
if is_org_context(request):
@ -462,8 +340,7 @@ def list_lib_dir(request, repo_id):
d_['obj_name'] = d.obj_name
d_['last_modified'] = d.last_modified
d_['last_update'] = translate_seahub_time(d.last_modified)
p_dpath = posixpath.join(path, d.obj_name)
d_['p_dpath'] = p_dpath # for 'view_link' & 'dl_link'
d_['p_dpath'] = posixpath.join(path, d.obj_name)
d_['perm'] = d.permission # perm for sub dir in current dir
dirent_list.append(d_)
@ -1072,7 +949,7 @@ def mv_dirents(request, src_repo_id, src_path, dst_repo_id, dst_path,
success.append(obj_name)
if len(success) > 0:
url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
url = reverse("view_common_lib_dir", args=[dst_repo_id, urlquote(dst_path).strip('/')])
result = {'success': success, 'failed': failed, 'url': url}
return HttpResponse(json.dumps(result), content_type=content_type)
@ -1115,7 +992,7 @@ def cp_dirents(request, src_repo_id, src_path, dst_repo_id, dst_path, obj_file_n
success.append(obj_name)
if len(success) > 0:
url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
url = reverse("view_common_lib_dir", args=[dst_repo_id, urlquote(dst_path).strip('/')])
result = {'success': success, 'failed': failed, 'url': url}
return HttpResponse(json.dumps(result), content_type=content_type)
@ -1956,69 +1833,6 @@ def _create_repo_common(request, repo_name, repo_desc, encryption,
return repo_id
@login_required_ajax
def repo_create(request):
'''
Handle ajax post to create a library.
'''
if request.method != 'POST':
return Http404
result = {}
content_type = 'application/json; charset=utf-8'
if not request.user.permissions.can_add_repo():
result['error'] = _(u"You do not have permission to create library")
return HttpResponse(json.dumps(result), status=403,
content_type=content_type)
form = RepoCreateForm(request.POST)
if not form.is_valid():
result['error'] = str(form.errors.values()[0])
return HttpResponseBadRequest(json.dumps(result),
content_type=content_type)
repo_name = form.cleaned_data['repo_name']
repo_desc = form.cleaned_data['repo_desc']
encryption = int(form.cleaned_data['encryption'])
uuid = form.cleaned_data['uuid']
magic_str = form.cleaned_data['magic_str']
encrypted_file_key = form.cleaned_data['encrypted_file_key']
repo_id = _create_repo_common(request, repo_name, repo_desc, encryption,
uuid, magic_str, encrypted_file_key)
if repo_id is None:
result['error'] = _(u"Internal Server Error")
return HttpResponse(json.dumps(result), status=500,
content_type=content_type)
username = request.user.username
try:
default_lib = (int(request.GET.get('default_lib', 0)) == 1)
except ValueError:
default_lib = False
if default_lib:
UserOptions.objects.set_default_repo(username, repo_id)
if is_org_context(request):
org_id = request.user.org.org_id
else:
org_id = -1
repo_created.send(sender=None,
org_id=org_id,
creator=username,
repo_id=repo_id,
repo_name=repo_name)
result = {
'repo_id': repo_id,
'repo_name': repo_name,
'repo_desc': repo_desc,
'repo_enc': encryption,
}
return HttpResponse(json.dumps(result), content_type=content_type)
@login_required_ajax
def public_repo_create(request):
'''

View File

@ -4,12 +4,10 @@ import posixpath
import logging
from django.core.urlresolvers import reverse
from django.contrib.sites.models import RequestSite
from django.db.models import F
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.template.loader import render_to_string
from django.utils.translation import ugettext as _
from django.utils.http import urlquote
@ -17,28 +15,21 @@ import seaserv
from seaserv import seafile_api
from seahub.auth.decorators import login_required
from seahub.avatar.templatetags.avatar_tags import avatar
from seahub.avatar.templatetags.group_avatar_tags import grp_avatar
from seahub.contacts.models import Contact
from seahub.forms import RepoPassowrdForm
from seahub.options.models import UserOptions, CryptoOptionNotSetError
from seahub.share.models import FileShare, UploadLinkShare, \
check_share_link_common
from seahub.views import gen_path_link, get_repo_dirents, \
check_repo_access_permission, get_repo_dirents_with_perm, \
get_system_default_repo_id
check_repo_access_permission
from seahub.utils import gen_file_upload_url, is_org_context, \
get_fileserver_root, gen_dir_share_link, gen_shared_upload_link, \
get_max_upload_file_size, new_merge_with_no_conflict, \
get_commit_before_new_merge, user_traffic_over_limit, render_error, \
from seahub.utils import gen_file_upload_url, gen_dir_share_link, \
gen_shared_upload_link, user_traffic_over_limit, render_error, \
get_file_type_and_ext
from seahub.settings import ENABLE_SUB_LIBRARY, FORCE_SERVER_CRYPTO, \
from seahub.settings import FORCE_SERVER_CRYPTO, \
ENABLE_UPLOAD_FOLDER, ENABLE_RESUMABLE_FILEUPLOAD, ENABLE_THUMBNAIL, \
THUMBNAIL_ROOT, THUMBNAIL_DEFAULT_SIZE, THUMBNAIL_SIZE_FOR_GRID
from seahub.utils import gen_file_get_url
from seahub.utils.file_types import IMAGE
from seahub.thumbnail.utils import get_thumbnail_src, get_share_link_thumbnail_src
from seahub.thumbnail.utils import get_share_link_thumbnail_src
# Get an instance of a logger
logger = logging.getLogger(__name__)
@ -157,157 +148,6 @@ def get_dir_shared_upload_link(uploadlink):
dir_shared_upload_link = ''
return dir_shared_upload_link
def render_repo(request, repo):
"""Steps to show repo page:
If user has permission to view repo
If repo is encrypt and password is not set on server
return decrypt repo page
If repo is not encrypt or password is set on server
Show repo direntries based on requested path
If user does not have permission to view repo
return permission deny page
"""
username = request.user.username
path = get_path_from_request(request)
user_perm = check_repo_access_permission(repo.id, request.user)
if user_perm is None:
return render_error(request, _(u'Permission denied'))
sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)
server_crypto = False
if repo.encrypted:
try:
server_crypto = UserOptions.objects.is_server_crypto(username)
except CryptoOptionNotSetError:
return render_to_response('options/set_user_options.html', {
}, context_instance=RequestContext(request))
if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
and not is_password_set(repo.id, username):
return render_to_response('decrypt_repo_form.html', {
'repo': repo,
'next': get_next_url_from_request(request) or reverse('repo', args=[repo.id]),
'force_server_crypto': FORCE_SERVER_CRYPTO,
}, context_instance=RequestContext(request))
# query context args
fileserver_root = get_fileserver_root()
max_upload_file_size = get_max_upload_file_size()
protocol = request.is_secure() and 'https' or 'http'
domain = RequestSite(request).domain
for g in request.user.joined_groups:
g.avatar = grp_avatar(g.id, 20)
head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)
if not head_commit:
raise Http404
if new_merge_with_no_conflict(head_commit):
info_commit = get_commit_before_new_merge(head_commit)
else:
info_commit = head_commit
repo_size = get_repo_size(repo.id)
no_quota = is_no_quota(repo.id)
if is_org_context(request):
repo_owner = seafile_api.get_org_repo_owner(repo.id)
else:
repo_owner = seafile_api.get_repo_owner(repo.id)
is_repo_owner = True if repo_owner == username else False
if is_repo_owner and not repo.is_virtual:
show_repo_settings = True
else:
show_repo_settings = False
file_list, dir_list, dirent_more = get_repo_dirents_with_perm(
request, repo, head_commit, path, offset=0, limit=100)
more_start = None
if dirent_more:
more_start = 100
zipped = get_nav_path(path, repo.name)
repo_groups = get_shared_groups_by_repo_and_user(repo.id, username)
if len(repo_groups) > 1:
repo_group_str = render_to_string("snippets/repo_group_list.html",
{'groups': repo_groups})
else:
repo_group_str = ''
fileshare = get_fileshare(repo.id, username, path)
dir_shared_link = get_dir_share_link(fileshare)
uploadlink = get_uploadlink(repo.id, username, path)
dir_shared_upload_link = get_dir_shared_upload_link(uploadlink)
for f in file_list:
file_type, file_ext = get_file_type_and_ext(f.obj_name)
if file_type == IMAGE:
f.is_img = True
file_path = posixpath.join(path, f.obj_name)
if os.path.exists(os.path.join(THUMBNAIL_ROOT, str(THUMBNAIL_DEFAULT_SIZE), f.obj_id)):
src = get_thumbnail_src(repo.id, THUMBNAIL_DEFAULT_SIZE, file_path)
f.encoded_thumbnail_src = urlquote(src)
return render_to_response('repo.html', {
'repo': repo,
'user_perm': user_perm,
'repo_owner': repo_owner,
'is_repo_owner': is_repo_owner,
'show_repo_settings': show_repo_settings,
'current_commit': head_commit,
'info_commit': info_commit,
'password_set': True,
'repo_size': repo_size,
'dir_list': dir_list,
'file_list': file_list,
'dirent_more': dirent_more,
'more_start': more_start,
'path': path,
'zipped': zipped,
'groups': repo_groups,
'repo_group_str': repo_group_str,
'no_quota': no_quota,
'max_upload_file_size': max_upload_file_size,
'fileserver_root': fileserver_root,
'protocol': protocol,
'domain': domain,
'fileshare': fileshare,
'dir_shared_link': dir_shared_link,
'uploadlink': uploadlink,
'dir_shared_upload_link': dir_shared_upload_link,
'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
'server_crypto': server_crypto,
'sub_lib_enabled': sub_lib_enabled,
'enable_upload_folder': ENABLE_UPLOAD_FOLDER,
'ENABLE_THUMBNAIL': ENABLE_THUMBNAIL,
}, context_instance=RequestContext(request))
@login_required
def repo(request, repo_id):
"""Show repo page and handle POST request to decrypt repo.
"""
repo = get_repo(repo_id)
if not repo:
raise Http404
if request.method == 'GET':
return render_repo(request, repo)
elif request.method == 'POST':
form = RepoPassowrdForm(request.POST)
next = get_next_url_from_request(request) or reverse('repo',
args=[repo_id])
if form.is_valid():
return HttpResponseRedirect(next)
else:
return render_to_response('decrypt_repo_form.html', {
'repo': repo,
'form': form,
'next': next,
'force_server_crypto': FORCE_SERVER_CRYPTO,
}, context_instance=RequestContext(request))
@login_required
def repo_history_view(request, repo_id):
"""View repo in history.
@ -333,13 +173,13 @@ def repo_history_view(request, repo_id):
and not is_password_set(repo.id, username):
return render_to_response('decrypt_repo_form.html', {
'repo': repo,
'next': get_next_url_from_request(request) or reverse('repo', args=[repo.id]),
'next': get_next_url_from_request(request) or reverse("view_common_lib_dir", args=[repo_id, '/']),
'force_server_crypto': FORCE_SERVER_CRYPTO,
}, context_instance=RequestContext(request))
commit_id = request.GET.get('commit_id', None)
if commit_id is None:
return HttpResponseRedirect(reverse('repo', args=[repo.id]))
return HttpResponseRedirect(reverse("view_common_lib_dir", args=[repo_id, '/']))
current_commit = get_commit(repo.id, repo.version, commit_id)
if not current_commit:
current_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)

View File

@ -163,9 +163,11 @@ def sys_repo_admin(request):
page_next = False
repos = filter(lambda r: not r.is_virtual, repos)
default_repo_id = get_system_default_repo_id()
repos = filter(lambda r: not r.repo_id == default_repo_id, repos)
for repo in repos:
repo.is_default_repo = True if repo.id == default_repo_id else False
try:
repo.owner = seafile_api.get_repo_owner(repo.id)
except:
@ -272,6 +274,8 @@ def sys_admin_repo(request, repo_id):
file_list.append(dirent)
zipped = gen_path_link(path, repo.name)
default_repo_id = get_system_default_repo_id()
is_default_repo = True if repo_id == default_repo_id else False
return render_to_response('sysadmin/admin_repo_view.html', {
'repo': repo,
@ -280,6 +284,8 @@ def sys_admin_repo(request, repo_id):
'file_list': file_list,
'path': path,
'zipped': zipped,
'is_default_repo': is_default_repo,
'max_upload_file_size': seaserv.MAX_UPLOAD_FILE_SIZE,
}, context_instance=RequestContext(request))
@login_required

View File

@ -0,0 +1,24 @@
import json
import os
from django.core.urlresolvers import reverse
from seahub.test_utils import BaseTestCase
class ListLibDirTest(BaseTestCase):
def setUp(self):
self.login_as(self.user)
self.endpoint = reverse('list_lib_dir', args=[self.repo.id])
self.folder_name = os.path.basename(self.folder)
def tearDown(self):
self.remove_repo()
def test_can_list(self):
resp = self.client.get(self.endpoint, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(200, resp.status_code)
json_resp = json.loads(resp.content)
assert len(json_resp) == 8
assert self.folder_name == json_resp['dirent_list'][0]['obj_name']
assert self.repo.name == json_resp['repo_name']