1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-05 08:53:14 +00:00

Add quota and quota usage information.

Changed pages:
* myhome
* user info admin
* org personal page
* org admin page
This commit is contained in:
killing
2012-10-26 14:27:54 +08:00
parent 0106d08911
commit 1d8ae030c2
11 changed files with 147 additions and 44 deletions

View File

@@ -215,3 +215,11 @@ class RepoPassowrdForm(forms.Form):
else:
raise forms.ValidationError(u'未知错误')
class SetUserQuotaForm(forms.Form):
"""
Form for setting user quota.
"""
email = forms.CharField(error_messages={'required': '参数错误'})
quota = forms.IntegerField(min_value=0,
error_messages={'required': '容量不能为空',
'min_value': '容量不能小于0'})

View File

@@ -3,18 +3,33 @@
{% block nav_useradmin_class %}class="cur"{% endblock %}
{% block left_panel %}
<div class="info-item">
<h3 class="info-item-top">团体已用总空间</h3>
<p class="info-item-bottom">{{ org_quota_usage|filesizeformat }} {% if org_quota > 0 %} / {{ org_quota|filesizeformat }} {% endif %}</p>
</div>
{% endblock %}
{% block right_panel %}
<h3>所有用户</h3>
<button id="org-user-add">添加用户</button>
<h3>所有成员</h3>
<button id="org-user-add">添加成员</button>
<table>
<tr>
<th width="80%">邮箱</th>
<th width="60%">邮箱</th>
<th width="20%">已用空间</th>
<th width="20%">操作</th>
</tr>
{% for user in users %}
<tr>
<td><a href="{% url 'user_profile' user.email %}" target="_blank">{{ user.props.email }}</a></td>
<td>
{% if user.quota_usage >= 0 %}
{{ user.quota_usage|filesizeformat }}
{% endif %}
</td>
<td>
{% if not user.is_self %}
<a href="#" class="remove-user-btn op" data="{% url 'org_user_remove' request.user.org.url_prefix user.email %}">删除</a>

View File

@@ -21,6 +21,12 @@
{% endif %}
</div>
</div>
<div class="info-item">
<h3 class="info-item-top">我已用的团体空间</h3>
<p class="info-item-bottom">{{ quota_usage|filesizeformat }}</p>
</div>
<!-- 我的群组 -->
{% include "snippets/my_groups.html" %}
{% endblock %}

View File

@@ -27,7 +27,7 @@ urlpatterns = patterns('',
### Org admin ###
url(r'^(?P<url_prefix>[^/]+)/seafadmin/$', org_seafadmin, name='org_seafadmin'),
url(r'^(?P<url_prefix>[^/]+)/useradmin/$', org_useradmin, name='org_useradmin'),
url(r'^(?P<url_prefix>[^/]+)/orgadmin/$', org_admin, name='org_admin'),
url(r'^(?P<url_prefix>[^/]+)/useradmin/remove/(?P<user>[^/]+)/$', org_user_remove, name='org_user_remove'),
url(r'^(?P<url_prefix>[^/]+)/groupadmin/$', org_group_admin, name='org_groupadmin'),
url(r'^(?P<url_prefix>[^/]+)/group/remove/(?P<group_id>[\d]+)/$', org_group_remove, name='org_group_remove'),

View File

@@ -140,6 +140,8 @@ def org_personal(request, url_prefix):
else:
events = None
quota_usage = seafserv_threaded_rpc.get_org_user_quota_usage(org.org_id, user)
return render_to_response('organizations/personal.html', {
'owned_repos': owned_repos,
"in_repos": in_repos,
@@ -151,6 +153,7 @@ def org_personal(request, url_prefix):
'allow_public_share': True,
'nickname': nickname,
'events': events,
'quota_usage': quota_usage,
}, context_instance=RequestContext(request))
@login_required
@@ -281,7 +284,7 @@ def send_org_user_add_mail(request, email, password, org_name):
@login_required
@org_staff_required
def org_useradmin(request, url_prefix):
def org_admin(request, url_prefix):
"""
List and add org users.
"""
@@ -334,16 +337,27 @@ def org_useradmin(request, url_prefix):
else:
page_next = False
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponseRedirect(reverse(myhome))
users = users_plus_one[:per_page]
for user in users:
if user.props.id == request.user.id:
user.is_self = True
try:
user.quota_usage = seafserv_threaded_rpc.get_org_user_quota_usage(org.org_id, user.email)
except:
user.quota_usage = -1
# My contacts
contacts = Contact.objects.filter(user_email=request.user.username)
org_quota_usage = seafserv_threaded_rpc.get_org_quota_usage(org.org_id)
org_quota = seafserv_threaded_rpc.get_org_quota(org.org_id)
return render_to_response(
'organizations/org_useradmin.html', {
'organizations/org_admin.html', {
'users': users,
'contacts': contacts,
'current_page': current_page,
@@ -351,6 +365,8 @@ def org_useradmin(request, url_prefix):
'next_page': current_page+1,
'per_page': per_page,
'page_next': page_next,
'org_quota_usage': org_quota_usage,
'org_quota': org_quota,
},
context_instance=RequestContext(request))

View File

@@ -49,7 +49,7 @@
{% endif %}
{% if org.is_staff %}
<a href="{% url 'org_useradmin' org.url_prefix %}"{% block top_bar_org_manager_class %}{% endblock %}>管理员工作台</a>
<a href="{% url 'org_admin' org.url_prefix %}"{% block top_bar_org_manager_class %}{% endblock %}>管理员工作台</a>
<a href="{% url 'org_personal' org.url_prefix %}"{% block top_bar_org_myaccount_class %}{% endblock %}>个人工作台</a>
{% endif %}
</div>

View File

@@ -42,7 +42,7 @@
<div class="info-item">
<h3 class="info-item-top">已用空间</h3>
<p class="info-item-bottom">{{ quota_usage|filesizeformat }} {% if cloud_mode %}/ 2 GB {% endif %}</p>
<p class="info-item-bottom">{{ quota_usage|filesizeformat }} {% if quota > 0 %}/ {{ quota|filesizeformat }} {% endif %}</p>
</div>
<!-- 我的群组 -->

View File

@@ -4,7 +4,7 @@
<ul class="nav">
{% if request.user.org.is_staff %}
<li>
<a href="{% url org_useradmin request.user.org.url_prefix %}" {% block nav_useradmin_class %}{% endblock %}>用户管理</a>
<a href="{% url org_admin request.user.org.url_prefix %}" {% block nav_useradmin_class %}{% endblock %}>团体概况</a>
</li>
<li>
<a href="{% url org_seafadmin request.user.org.url_prefix %}" {% block nav_seafadmin_class %}{% endblock %}>资料库管理</a>

View File

@@ -4,7 +4,7 @@
{% block nav_orgadmin_class %}class="cur"{% endblock %}
{% block right_panel %}
<h3>所有企业</h3>
<h3>所有团体</h3>
{% if orgs %}
<table>
<tr>
@@ -58,7 +58,7 @@
{% block extra_script %}
<script type="text/javascript">
addConfirmTo($('.org-remove-btn'), '确定要删除该企业');
addConfirmTo($('.org-remove-btn'), '确定要删除该团体');
</script>
{% endblock %}

View File

@@ -1,5 +1,7 @@
{% extends "admin_base.html" %}
{% load url from future %}
{% block nav_useradmin_class %}class="cur"{% endblock %}
{% block left_panel %}
<!--
@@ -7,8 +9,13 @@
<li><a href="{{ SITE_ROOT }}useradmin/add/">添加用户</a></li>
</ul>
-->
<h3>已用空间</h3>
<p>{{ quota_usage|filesizeformat }} / 2 GB</p>
<div class="info-item">
<div class="info-item-top">
<h3 class="inbl">已用空间</h3>
<a href="#" class="set-quota op">设置容量</a>
</div>
<p class="info-item-bottom">{{ quota_usage|filesizeformat }} {% if quota > 0 %} / {{ quota|filesizeformat }} {% endif %}</p>
</div>
{% endblock %}
@@ -29,7 +36,7 @@
<td><a href="{{ SITE_ROOT }}repo/{{ repo.props.id }}/">{{ repo.props.name }}</a></td>
<td>{{ repo.props.desc }}</td>
<td>
<button data="{{ SITE_ROOT }}repo/remove/{{ repo.props.id }}/?next={{ request.path }}" class="repo-delete-btn">删除</button>
<a href="#" data="{{ SITE_ROOT }}repo/remove/{{ repo.props.id }}/?next={{ request.path }}" class="remove-user-repo op">删除</a>
</td>
</tr>
{% endfor %}
@@ -61,33 +68,59 @@
<p>暂无</p>
{% endif %}
<!--
<h3>{{ email }} 的计算机</h3>
<table class="user-list">
<tr>
<th width="60%">计算机名</th>
<th width="20%">角色</th>
<th width="20%">状态</th>
</tr>
<form id="set-quota-form" method="post" class="hide">{% csrf_token %}
<label>设置该用户的存储容量上限</label><br />
<input type="hidden" name="email" value="{{ email }}" />
<input type="text" name="quota" /> MB <br />
<p class="tip">Tip: 设置为0表示重置为默认上限</p>
<p class="error hide"></p>
<input type="submit" value="提交" class="submit" />
</form>
{% for username, roles in user_dict.items %}
<tr>
{% if username %}
<td>{{ username }}</td>
{% else %}
<td>未知</td>
{% endif %}
{% if roles %}
<td>{{ roles }}</td>
<td>已验证</td>
{% else %}
<td>无</td>
<td>未验证</td>
{% endif %}
</tr>
{% endfor %}
</table>
-->
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
$('.set-quota').click(function() {
$("#set-quota-form").modal({appendTo: "#main"});
return false;
});
$('#set-quota-form .submit').click(function() {
var self = $(this);
self.attr('disabled', 'disabled');
$.ajax({
url: '{% url 'views.user_info' email %}',
type: 'POST',
dataType: 'json',
cache: 'false',
beforeSend: prepareCSRFToken,
data: {
'email': $('#set-quota-form input[name="email"]').val(),
'quota': $('#set-quota-form input[name="quota"]').val()
},
success: function(data) {
if (data['success']) {
location.reload(true);
} else {
apply_form_error('set-quota-form', data['error']);
self.removeAttr('disabled');
}
},
error: function(data, textStatus, jqXHR) {
var errors = $.parseJSON(data.responseText);
$.each(errors, function(index, value) {
apply_form_error('set-quota-form', value[0]);
});
self.removeAttr('disabled');
}
});
return false;
});
addConfirmTo($('.remove-user-repo'), '确定要删除该资料库?');
</script>
{% endblock %}

View File

@@ -60,7 +60,7 @@ from notifications.models import UserNotification
from profile.models import Profile
from forms import AddUserForm, FileLinkShareForm, RepoCreateForm, \
RepoNewDirForm, RepoNewFileForm, FileCommentForm, RepoRenameFileForm, \
RepoPassowrdForm, SharedRepoCreateForm
RepoPassowrdForm, SharedRepoCreateForm, SetUserQuotaForm
from utils import render_permission_error, render_error, list_to_string, \
get_httpserver_root, get_ccnetapplet_root, gen_token, \
calculate_repo_last_modify, valid_previewed_file, \
@@ -858,6 +858,7 @@ def myhome(request):
quota_usage = 0
email = request.user.username
quota = seafserv_threaded_rpc.get_user_quota(email)
quota_usage = seafserv_threaded_rpc.get_user_quota_usage(email)
# Personal repos that I own
@@ -921,6 +922,7 @@ def myhome(request):
return render_to_response('myhome.html', {
"nickname": nickname,
"owned_repos": owned_repos,
"quota": quota,
"quota_usage": quota_usage,
"in_repos": in_repos,
"contacts": contacts,
@@ -1825,10 +1827,32 @@ def sys_useradmin(request):
@login_required
@sys_staff_required
def user_info(request, email):
if request.method == 'POST':
result = {}
content_type = 'application/json; charset=utf-8'
f = SetUserQuotaForm(request.POST)
if f.is_valid():
email = f.cleaned_data['email']
quota_mb = f.cleaned_data['quota']
quota = quota_mb * (1 << 20)
try:
seafserv_threaded_rpc.set_user_quota(email, quota)
except:
result['error'] = u'内部错误,设置失败'
return HttpResponse(json.dumps(result), content_type=content_type)
result['success'] = True
return HttpResponse(json.dumps(result), content_type=content_type)
else:
result['error'] = str(f.errors.values()[0])
return HttpResponse(json.dumps(result), content_type=content_type)
owned_repos = []
quota_usage = 0
owned_repos = seafserv_threaded_rpc.list_owned_repos(email)
quota = seafserv_threaded_rpc.get_user_quota(email)
quota_usage = seafserv_threaded_rpc.get_user_quota_usage(email)
# Repos that are share to user
@@ -1838,6 +1862,7 @@ def user_info(request, email):
return render_to_response(
'userinfo.html', {
'owned_repos': owned_repos,
'quota': quota,
'quota_usage': quota_usage,
"in_repos": in_repos,
'email': email