1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-21 19:37:28 +00:00

Use GB instead of GiB in filesizeformat and quota calculation

This commit is contained in:
zhengxie
2016-02-23 17:20:02 +08:00
parent fa24c0c5d1
commit acb1a5e51e
15 changed files with 121 additions and 33 deletions

View File

@@ -75,6 +75,7 @@ from seahub.utils import gen_file_get_url, gen_token, gen_file_upload_url, \
from seahub.utils.repo import get_sub_repo_abbrev_origin_path 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
from seahub.utils.file_types import IMAGE, DOCUMENT from seahub.utils.file_types import IMAGE, DOCUMENT
from seahub.utils.file_size import get_file_size_unit
from seahub.utils.timeutils import utc_to_local from seahub.utils.timeutils import utc_to_local
from seahub.views import validate_owner, is_registered_user, check_file_lock, \ from seahub.views import validate_owner, is_registered_user, check_file_lock, \
group_events_data, get_diff, create_default_library, get_owned_repo_list, \ group_events_data, get_diff, create_default_library, get_owned_repo_list, \
@@ -4585,7 +4586,7 @@ class OrganizationView(APIView):
OrgMemberQuota.objects.set_quota(new_org.org_id, member_limit) OrgMemberQuota.objects.set_quota(new_org.org_id, member_limit)
# set quota # set quota
quota = quota_mb * (1 << 20) quota = quota_mb * get_file_size_unit('MB')
seafserv_threaded_rpc.set_org_quota(new_org.org_id, quota) seafserv_threaded_rpc.set_org_quota(new_org.org_id, quota)
return Response('success', status=status.HTTP_201_CREATED) return Response('success', status=status.HTTP_201_CREATED)

View File

@@ -7,10 +7,10 @@ import time
from django import template from django import template
from django.core.cache import cache from django.core.cache import cache
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils import translation from django.utils import translation, formats
from django.utils.dateformat import DateFormat from django.utils.dateformat import DateFormat
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.translation import ungettext from django.utils.translation import ugettext, ungettext
from django.utils.translation import pgettext from django.utils.translation import pgettext
from django.utils.html import escape from django.utils.html import escape
@@ -22,6 +22,8 @@ from seahub.cconvert import CConvert
from seahub.po import TRANSLATION_MAP from seahub.po import TRANSLATION_MAP
from seahub.shortcuts import get_first_object_or_none from seahub.shortcuts import get_first_object_or_none
from seahub.utils import normalize_cache_key, CMMT_DESC_PATT from seahub.utils import normalize_cache_key, CMMT_DESC_PATT
from seahub.utils.html import avoid_wrapping
from seahub.utils.file_size import get_file_size_unit
register = template.Library() register = template.Library()
@@ -468,3 +470,38 @@ def trim(value, length):
@register.filter(name='strip_slash') @register.filter(name='strip_slash')
def strip_slash(value): def strip_slash(value):
return value.strip('/') return value.strip('/')
@register.filter(is_safe=True)
def seahub_filesizeformat(bytes):
"""
Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB,
102 bytes, etc).
"""
try:
bytes = float(bytes)
except (TypeError, ValueError, UnicodeDecodeError):
value = ungettext("%(size)d byte", "%(size)d bytes", 0) % {'size': 0}
return avoid_wrapping(value)
filesize_number_format = lambda value: formats.number_format(round(value, 1), 1)
KB = get_file_size_unit('KB')
MB = get_file_size_unit('MB')
GB = get_file_size_unit('GB')
TB = get_file_size_unit('TB')
PB = get_file_size_unit('PB')
if bytes < KB:
value = ungettext("%(size)d byte", "%(size)d bytes", bytes) % {'size': bytes}
elif bytes < MB:
value = ugettext("%s KB") % filesize_number_format(bytes / KB)
elif bytes < GB:
value = ugettext("%s MB") % filesize_number_format(bytes / MB)
elif bytes < TB:
value = ugettext("%s GB") % filesize_number_format(bytes / GB)
elif bytes < PB:
value = ugettext("%s TB") % filesize_number_format(bytes / TB)
else:
value = ugettext("%s PB") % filesize_number_format(bytes / PB)
return avoid_wrapping(value)

View File

@@ -1,10 +1,10 @@
{% load i18n %} {% load seahub_tags i18n %}
<div class="item"> <div class="item">
<p>{% trans "Used:" %} {{ space_usage|filesizeformat }} {% if space_quota > 0 %}/ {{ space_quota|filesizeformat }} {% endif %}</p> <p>{% trans "Used:" %} {{ space_usage|seahub_filesizeformat }} {% if space_quota > 0 %}/ {{ space_quota|seahub_filesizeformat }} {% endif %}</p>
{% if not org %} {% if not org %}
{% if CALC_SHARE_USAGE %} {% if CALC_SHARE_USAGE %}
<p>{% trans "Sharing:" %} {{ share_usage|filesizeformat }} {% if share_quota > 0 %}/ {{ share_quota|filesizeformat }} {% endif %}</p> <p>{% trans "Sharing:" %} {{ share_usage|seahub_filesizeformat }} {% if share_quota > 0 %}/ {{ share_quota|seahub_filesizeformat }} {% endif %}</p>
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@@ -17,7 +17,7 @@
</td> </td>
<td><a href="{% url 'user_info' org.creator %}">{{ org.creator }}</a></td> <td><a href="{% url 'user_info' org.creator %}">{{ org.creator }}</a></td>
<td> <td>
{{ org.quota_usage|filesizeformat }} {% if org.total_quota > 0 %} / {{ org.total_quota|filesizeformat }} {% endif %} {{ org.quota_usage|seahub_filesizeformat }} {% if org.total_quota > 0 %} / {{ org.total_quota|seahub_filesizeformat }} {% endif %}
</td> </td>
<td>{{ org.ctime|tsstr_sec }} <br/> <td>{{ org.ctime|tsstr_sec }} <br/>
<span class="{% if org.is_expired %}error{% endif %}">{% if org.expiration %}{{ org.expiration|date:'Y-m-d H:i:s' }}{% else %}--{% endif %}</span> <span class="{% if org.is_expired %}error{% endif %}">{% if org.expiration %}{{ org.expiration|date:'Y-m-d H:i:s' }}{% else %}--{% endif %}</span>

View File

@@ -1,6 +1,5 @@
{% extends "admin_base.html" %} {% extends "admin_base.html" %}
{% load i18n seahub_tags %} {% load i18n seahub_tags %}
{% load url from future %}
{% block nav_orgadmin_class %}class="cur"{% endblock %} {% block nav_orgadmin_class %}class="cur"{% endblock %}
@@ -25,7 +24,7 @@
</dl> </dl>
<h3 class="hd">{% trans "Space Used" %}</h3> <h3 class="hd">{% trans "Space Used" %}</h3>
<p>{{ quota_usage|filesizeformat }} {% if total_quota > 0 %}/ {{ total_quota|filesizeformat }} {% endif %}</p> <p>{{ quota_usage|seahub_filesizeformat }} {% if total_quota > 0 %}/ {{ total_quota|seahub_filesizeformat }} {% endif %}</p>
<a href="#" id="set-quota">{% trans "Set Quota" %}</a> <a href="#" id="set-quota">{% trans "Set Quota" %}</a>
</div> </div>
<form id="set-quota-form" method="post" class="hide">{% csrf_token %} <form id="set-quota-form" method="post" class="hide">{% csrf_token %}

View File

@@ -1,6 +1,5 @@
{% extends "sysadmin/sys_org_info_base.html" %} {% extends "sysadmin/sys_org_info_base.html" %}
{% load i18n seahub_tags %} {% load i18n seahub_tags %}
{% load url from future %}
{% block right_panel %} {% block right_panel %}
<div class="tabnav"> <div class="tabnav">
@@ -40,9 +39,9 @@
</td> </td>
<td> <td>
{% if CALC_SHARE_USAGE %} {% if CALC_SHARE_USAGE %}
{{ user.self_usage|filesizeformat }} + {{ user.share_usage|filesizeformat }} {% if user.quota > 0 %} / {{ user.quota|filesizeformat }} {% endif %} {{ user.self_usage|seahub_filesizeformat }} + {{ user.share_usage|seahub_filesizeformat }} {% if user.quota > 0 %} / {{ user.quota|seahub_filesizeformat }} {% endif %}
{% else %} {% else %}
{{ user.self_usage|filesizeformat }} {% if user.quota > 0 %} / {{ user.quota|filesizeformat }} {% endif %} {{ user.self_usage|seahub_filesizeformat }} {% if user.quota > 0 %} / {{ user.quota|seahub_filesizeformat }} {% endif %}
{% endif %} {% endif %}
</td> </td>
<td style="font-size:11px;"> <td style="font-size:11px;">

View File

@@ -49,12 +49,7 @@
</select> </select>
</td> </td>
<td style="font-size:11px;"> <td style="font-size:11px;">
<p> {{ user.space_usage|filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|filesizeformat }} {% endif %} </p> <p> {{ user.space_usage|seahub_filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|seahub_filesizeformat }} {% endif %} </p>
{% if not user.org %}
{% if CALC_SHARE_USAGE %}
<p> {{ user.share_usage|filesizeformat }} {% if user.share_quota > 0 %} / {{ user.share_quota|filesizeformat }} {% endif %} </p>
{% endif %}
{% endif %}
</td> </td>
<td> <td>
{% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %} {% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %}

View File

@@ -32,12 +32,7 @@
<td style="font-size:11px;"> -- / {% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %} <td style="font-size:11px;"> -- / {% if user.last_login %}{{user.last_login|translate_seahub_time}} {% else %} -- {% endif %}
</td> </td>
<td style="font-size:11px;"> <td style="font-size:11px;">
<p> {{ user.space_usage|filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|filesizeformat }} {% endif %} </p> <p> {{ user.space_usage|seahub_filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|seahub_filesizeformat }} {% endif %} </p>
{% if not user.org %}
{% if CALC_SHARE_USAGE %}
<p> {{ user.share_usage|filesizeformat }} {% if user.share_quota > 0 %} / {{ user.share_quota|filesizeformat }} {% endif %} </p>
{% endif %}
{% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -62,10 +62,10 @@
{% endif %} {% endif %}
<td style="font-size:11px;"> <td style="font-size:11px;">
<p> {{ user.space_usage|filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|filesizeformat }} {% endif %} </p> <p> {{ user.space_usage|seahub_filesizeformat }} {% if user.space_quota > 0 %} / {{ user.space_quota|seahub_filesizeformat }} {% endif %} </p>
{% if not user.org %} {% if not user.org %}
{% if CALC_SHARE_USAGE %} {% if CALC_SHARE_USAGE %}
<p> {{ user.share_usage|filesizeformat }} {% if user.share_quota > 0 %} / {{ user.share_quota|filesizeformat }} {% endif %} </p> <p> {{ user.share_usage|seahub_filesizeformat }} {% if user.share_quota > 0 %} / {{ user.share_quota|seahub_filesizeformat }} {% endif %} </p>
{% endif %} {% endif %}
{% endif %} {% endif %}
</td> </td>

View File

@@ -43,10 +43,10 @@
</dl> </dl>
<h3 class="hd">{% trans "Space Used" %}</h3> <h3 class="hd">{% trans "Space Used" %}</h3>
<p>{% trans "Used" %}: {{ space_usage|filesizeformat }} {% if space_quota > 0 %} / {{ space_quota|filesizeformat }} {% endif %}</p> <p>{% trans "Used" %}: {{ space_usage|seahub_filesizeformat }} {% if space_quota > 0 %} / {{ space_quota|seahub_filesizeformat }} {% endif %}</p>
{% if CALC_SHARE_USAGE %} {% if CALC_SHARE_USAGE %}
<p>{% trans "Sharing" %}: {{ share_usage|filesizeformat }} {% if share_quota > 0 %} / {{ share_quota|filesizeformat }} {% endif %}</p> <p>{% trans "Sharing" %}: {{ share_usage|seahub_filesizeformat }} {% if share_quota > 0 %} / {{ share_quota|seahub_filesizeformat }} {% endif %}</p>
{% endif %} {% endif %}
<a href="#" id="set-quota">{% trans "Set Quota" %}</a> <a href="#" id="set-quota">{% trans "Set Quota" %}</a>

24
seahub/utils/file_size.py Normal file
View File

@@ -0,0 +1,24 @@
def get_file_size_unit(unit_type):
"""
File size unit according to https://en.wikipedia.org/wiki/Kibibyte.
"""
table = {
# decimal
'kb': 10 ** 3,
'mb': 10 ** 6,
'gb': 10 ** 9,
'tb': 10 ** 12,
'pb': 10 ** 15,
# binary
'kib': 1 << 10,
'mib': 1 << 20,
'gib': 1 << 30,
'tib': 1 << 40,
'pib': 1 << 50,
}
unit_type = unit_type.lower()
if unit_type not in table.keys():
raise TypeError('Invalid unit type')
return table.get(unit_type)

8
seahub/utils/html.py Normal file
View File

@@ -0,0 +1,8 @@
from __future__ import unicode_literals
def avoid_wrapping(value):
"""
Avoid text wrapping in the middle of a phrase by adding non-breaking
spaces where there previously were normal spaces.
"""
return value.replace(" ", "\xa0")

View File

@@ -38,6 +38,7 @@ from seahub.utils import IS_EMAIL_CONFIGURED, string2list, is_valid_username, \
is_pro_version, send_html_email, get_user_traffic_list, get_server_id, \ is_pro_version, send_html_email, get_user_traffic_list, get_server_id, \
clear_token, gen_file_get_url, is_org_context, handle_virus_record, \ clear_token, gen_file_get_url, is_org_context, handle_virus_record, \
get_virus_record_by_id, get_virus_record get_virus_record_by_id, get_virus_record
from seahub.utils.file_size import get_file_size_unit
from seahub.utils.rpc import mute_seafile_api from seahub.utils.rpc import mute_seafile_api
from seahub.utils.licenseparse import parse_license from seahub.utils.licenseparse import parse_license
from seahub.utils.sysinfo import get_platform_name from seahub.utils.sysinfo import get_platform_name
@@ -966,12 +967,12 @@ def user_set_quota(request, email):
if f.is_valid(): if f.is_valid():
email = f.cleaned_data['email'] email = f.cleaned_data['email']
space_quota_mb = f.cleaned_data['space_quota'] space_quota_mb = f.cleaned_data['space_quota']
space_quota = space_quota_mb * (1 << 20) space_quota = space_quota_mb * get_file_size_unit('MB')
share_quota_mb = f.cleaned_data['share_quota'] share_quota_mb = f.cleaned_data['share_quota']
share_quota = None share_quota = None
if share_quota_mb is not None: if share_quota_mb is not None:
share_quota = share_quota_mb * (1 << 20) share_quota = share_quota_mb * get_file_size_unit('MB')
org = ccnet_threaded_rpc.get_orgs_by_user(email) org = ccnet_threaded_rpc.get_orgs_by_user(email)
try: try:
@@ -981,7 +982,7 @@ def user_set_quota(request, email):
seafile_api.set_user_share_quota(email, share_quota) seafile_api.set_user_share_quota(email, share_quota)
else: else:
org_id = org[0].org_id org_id = org[0].org_id
org_quota_mb = seafserv_threaded_rpc.get_org_quota(org_id) / (1 << 20) org_quota_mb = seafserv_threaded_rpc.get_org_quota(org_id) / get_file_size_unit('MB')
if space_quota_mb > org_quota_mb: if space_quota_mb > org_quota_mb:
result['error'] = _(u'Failed to set quota: maximum quota is %d MB' % \ result['error'] = _(u'Failed to set quota: maximum quota is %d MB' % \
org_quota_mb) org_quota_mb)
@@ -1009,7 +1010,7 @@ def sys_org_set_quota(request, org_id):
org_id = int(org_id) org_id = int(org_id)
quota_mb = int(request.POST.get('quota', 0)) quota_mb = int(request.POST.get('quota', 0))
quota = quota_mb * (1 << 20) quota = quota_mb * get_file_size_unit('MB')
try: try:
seafserv_threaded_rpc.set_org_quota(org_id, quota) seafserv_threaded_rpc.set_org_quota(org_id, quota)

View File

@@ -1,6 +1,7 @@
from seahub.test_utils import BaseTestCase from seahub.test_utils import BaseTestCase
from seahub.base.templatetags.seahub_tags import email2nickname from seahub.base.templatetags.seahub_tags import email2nickname, \
seahub_filesizeformat
from seahub.profile.models import Profile from seahub.profile.models import Profile
@@ -30,3 +31,11 @@ class Email2nicknameTest(BaseTestCase):
assert Profile.objects.all()[0].nickname == ' foo bar ' assert Profile.objects.all()[0].nickname == ' foo bar '
assert email2nickname(self.user.username) == 'foo bar' assert email2nickname(self.user.username) == 'foo bar'
class SeahubFilesizeformatTest(BaseTestCase):
def test_seahub_filesizeformat(self):
assert seahub_filesizeformat(1) == u'1\xa0byte'
assert seahub_filesizeformat(1000) == u'1.0\xa0KB'
assert seahub_filesizeformat(1000000) == u'1.0\xa0MB'
assert seahub_filesizeformat(1000000000) == u'1.0\xa0GB'

View File

@@ -0,0 +1,20 @@
from seahub.test_utils import BaseTestCase
from seahub.utils.file_size import get_file_size_unit
class GetFileSizeUnitTest(BaseTestCase):
def test_invalid_type(self):
with self.assertRaises(TypeError):
get_file_size_unit('ff')
def test_valid_type(self):
assert get_file_size_unit('KB') == 1000 ** 1
assert get_file_size_unit('MB') == 1000 ** 2
assert get_file_size_unit('GB') == 1000 ** 3
assert get_file_size_unit('TB') == 1000 ** 4
assert get_file_size_unit('PB') == 1000 ** 5
assert get_file_size_unit('KiB') == 1024 ** 1
assert get_file_size_unit('MiB') == 1024 ** 2
assert get_file_size_unit('GiB') == 1024 ** 3
assert get_file_size_unit('TiB') == 1024 ** 4
assert get_file_size_unit('PiB') == 1024 ** 5