diff --git a/media/css/seahub.css b/media/css/seahub.css index d82359b462..3c6079aaf7 100644 --- a/media/css/seahub.css +++ b/media/css/seahub.css @@ -4332,6 +4332,28 @@ img.thumbnail { .date-custom-form .submit { margin-left:5px; } +.traffic-chart { + margin:0 0 20px; +} +.traffic-tab-nav { + margin:10px 0 16px; +} +.traffic-tab-nav .tab { + display:inline-block; + margin-right:.7em; +} +.traffic-tab-nav .a { + color:#8a948f; + font-weight:normal; + padding:.3em 0; + border-bottom:2px solid transparent; +} +.traffic-tab-nav .tab-cur .a, +.traffic-tab-nav .tab .a:hover { + color:#eb8205; + text-decoration:none; + border-bottom-color:#eb8205; +} /* system info */ .license-file-upload { diff --git a/seahub/api2/endpoints/admin/org_stats.py b/seahub/api2/endpoints/admin/org_stats.py new file mode 100644 index 0000000000..e4746e1180 --- /dev/null +++ b/seahub/api2/endpoints/admin/org_stats.py @@ -0,0 +1,43 @@ +# Copyright (c) 2012-2016 Seafile Ltd. +from rest_framework.authentication import SessionAuthentication +from rest_framework.permissions import IsAdminUser +from rest_framework.response import Response +from rest_framework.views import APIView + +from seahub.api2.authentication import TokenAuthentication +from seahub.api2.throttling import UserRateThrottle +from seahub.api2.endpoints.admin.statistics import ( + check_parameter, get_init_data, get_time_offset +) +from seahub.utils import get_org_traffic_by_day +from seahub.utils.timeutils import datetime_to_isoformat_timestr + + +class AdminOrgStatsTraffic(APIView): + authentication_classes = (TokenAuthentication, SessionAuthentication) + throttle_classes = (UserRateThrottle,) + permission_classes = (IsAdminUser,) + + @check_parameter + def get(self, request, start_time, end_time, *args, **kwargs): + org_id = kwargs['org_id'] + + op_type_list = ['web-file-upload', 'web-file-download', + 'sync-file-download', 'sync-file-upload', + 'link-file-upload', 'link-file-download'] + init_count = [0] * 6 + init_data = get_init_data(start_time, end_time, + dict(zip(op_type_list, init_count))) + + for e in get_org_traffic_by_day(org_id, start_time, end_time, + get_time_offset()): + dt, op_type, count = e + init_data[dt].update({op_type: count}) + + res_data = [] + for k, v in init_data.items(): + res = {'datetime': datetime_to_isoformat_timestr(k)} + res.update(v) + res_data.append(res) + + return Response(sorted(res_data, key=lambda x: x['datetime'])) diff --git a/seahub/api2/endpoints/admin/share_links.py b/seahub/api2/endpoints/admin/share_links.py index 9117038082..b4c10a7f9c 100644 --- a/seahub/api2/endpoints/admin/share_links.py +++ b/seahub/api2/endpoints/admin/share_links.py @@ -218,7 +218,7 @@ class AdminShareLinkDownload(APIView): try: # `username` parameter only used for encrypted repo download_token = seafile_api.get_fileserver_access_token(repo_id, - obj_id, 'download', sharelink.username, use_onetime=False) + obj_id, 'download-link', sharelink.username, use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' @@ -261,7 +261,7 @@ class AdminShareLinkDownload(APIView): try: download_token = seafile_api.get_fileserver_access_token(repo_id, - real_obj_id, 'download', sharelink.username, use_onetime=False) + real_obj_id, 'download-link', sharelink.username, use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' @@ -305,7 +305,7 @@ class AdminShareLinkDownload(APIView): try: zip_token = seafile_api.get_fileserver_access_token(repo_id, - json.dumps(fake_obj_id), 'download-dir', + json.dumps(fake_obj_id), 'download-dir-link', sharelink.username, use_onetime=False) except Exception as e: logger.error(e) @@ -315,9 +315,6 @@ class AdminShareLinkDownload(APIView): try: # used for file audit send_file_access_msg(request, repo, real_path, 'share-link') - # used for traffic - seaserv.send_message('seahub.stats', 'dir-download\t%s\t%s\t%s\t%s' % - (repo_id, sharelink.username, real_obj_id, dir_size)) except Exception as e: logger.error(e) diff --git a/seahub/api2/endpoints/admin/statistics.py b/seahub/api2/endpoints/admin/statistics.py index 486d31bc52..cfe5e894d5 100644 --- a/seahub/api2/endpoints/admin/statistics.py +++ b/seahub/api2/endpoints/admin/statistics.py @@ -11,7 +11,7 @@ from django.utils import timezone from seahub.utils import get_file_ops_stats_by_day, \ get_total_storage_stats_by_day, get_user_activity_stats_by_day, \ - is_pro_version, EVENTS_ENABLED + is_pro_version, EVENTS_ENABLED, get_system_traffic_by_day from seahub.utils.timeutils import datetime_to_isoformat_timestr from seahub.api2.authentication import TokenAuthentication @@ -44,7 +44,7 @@ def check_parameter(func): error_msg = "End time %s invalid" % end_time return api_error(status.HTTP_400_BAD_REQUEST, error_msg) - return func(view, request, start_time, end_time) + return func(view, request, start_time, end_time, *args, **kwargs) return _decorated @@ -129,7 +129,35 @@ class ActiveUsersView(APIView): return Response(sorted(res_data, key=lambda x: x['datetime'])) -def get_init_data(start_time, end_time): +class SystemTrafficView(APIView): + authentication_classes = (TokenAuthentication, SessionAuthentication) + throttle_classes = (UserRateThrottle,) + permission_classes = (IsAdminUser,) + + @check_parameter + def get(self, request, start_time, end_time): + op_type_list = ['web-file-upload', 'web-file-download', + 'sync-file-download', 'sync-file-upload', + 'link-file-upload', 'link-file-download'] + init_count = [0] * 6 + init_data = get_init_data(start_time, end_time, + dict(zip(op_type_list, init_count))) + + for e in get_system_traffic_by_day(start_time, end_time, + get_time_offset()): + dt, op_type, count = e + init_data[dt].update({op_type: count}) + + res_data = [] + for k, v in init_data.items(): + res = {'datetime': datetime_to_isoformat_timestr(k)} + res.update(v) + res_data.append(res) + + return Response(sorted(res_data, key=lambda x: x['datetime'])) + + +def get_init_data(start_time, end_time, init_data=0): res = {} start_time = start_time.replace(hour=0).replace(minute=0).replace(second=0) end_time = end_time.replace(hour=0).replace(minute=0).replace(second=0) @@ -138,7 +166,10 @@ def get_init_data(start_time, end_time): for offset in range(date_length): offset = offset * 24 dt = start_time + datetime.timedelta(hours=offset) - res[dt] = 0 + if isinstance(init_data, dict): + res[dt] = init_data.copy() + else: + res[dt] = init_data return res def get_time_offset(): diff --git a/seahub/api2/endpoints/admin/upload_links.py b/seahub/api2/endpoints/admin/upload_links.py index 4eb2b2bef4..55b5f470fa 100644 --- a/seahub/api2/endpoints/admin/upload_links.py +++ b/seahub/api2/endpoints/admin/upload_links.py @@ -119,7 +119,7 @@ class AdminUploadLinkUpload(APIView): return api_error(status.HTTP_404_NOT_FOUND, error_msg) upload_token = seafile_api.get_fileserver_access_token(repo_id, - obj_id, 'upload', uploadlink.username, use_onetime=False) + obj_id, 'upload-link', uploadlink.username, use_onetime=False) if not upload_token: error_msg = 'Internal Server Error' diff --git a/seahub/api2/endpoints/share_link_zip_task.py b/seahub/api2/endpoints/share_link_zip_task.py index 7204dd3623..8b570a7d52 100644 --- a/seahub/api2/endpoints/share_link_zip_task.py +++ b/seahub/api2/endpoints/share_link_zip_task.py @@ -100,12 +100,6 @@ class ShareLinkZipTaskView(APIView): error_msg = _('Unable to download directory "%s": size is too large.') % dir_name return api_error(status.HTTP_400_BAD_REQUEST, error_msg) - try: - seaserv.send_message('seahub.stats', 'dir-download\t%s\t%s\t%s\t%s' % - (repo_id, fileshare.username, dir_id, dir_size)) - except Exception as e: - logger.error(e) - is_windows = 0 if is_windows_operating_system(request): is_windows = 1 @@ -116,11 +110,11 @@ class ShareLinkZipTaskView(APIView): 'is_windows': is_windows } - username = request.user.username try: zip_token = seafile_api.get_fileserver_access_token( - repo_id, json.dumps(fake_obj_id), 'download-dir', username, - use_onetime=settings.FILESERVER_TOKEN_ONCE_ONLY) + repo_id, json.dumps(fake_obj_id), 'download-dir-link', + fileshare.username, use_onetime=settings.FILESERVER_TOKEN_ONCE_ONLY + ) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' diff --git a/seahub/api2/endpoints/upload_links.py b/seahub/api2/endpoints/upload_links.py index 53c8ddead9..03777cc832 100644 --- a/seahub/api2/endpoints/upload_links.py +++ b/seahub/api2/endpoints/upload_links.py @@ -263,7 +263,7 @@ class UploadLinkUpload(APIView): return api_error(status.HTTP_403_FORBIDDEN, error_msg) token = seafile_api.get_fileserver_access_token(repo_id, - dir_id, 'upload', uls.username, use_onetime=False) + dir_id, 'upload-link', uls.username, use_onetime=False) if not token: error_msg = 'Internal Server Error' diff --git a/seahub/templates/sysadmin/snippets/sys_org_info_nav.html b/seahub/templates/sysadmin/snippets/sys_org_info_nav.html new file mode 100644 index 0000000000..7510d1afc1 --- /dev/null +++ b/seahub/templates/sysadmin/snippets/sys_org_info_nav.html @@ -0,0 +1,8 @@ +{% load i18n %} +
{% trans "Tip: the traffic only includes the traffic used by sharing links." %}