mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-11 03:41:12 +00:00
export user traffic by month to excel
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
# Copyright (c) 2012-2016 Seafile Ltd.
|
# Copyright (c) 2012-2016 Seafile Ltd.
|
||||||
import datetime
|
import datetime
|
||||||
import pytz
|
import pytz
|
||||||
|
import logging
|
||||||
|
|
||||||
from rest_framework.authentication import SessionAuthentication
|
from rest_framework.authentication import SessionAuthentication
|
||||||
from rest_framework.permissions import IsAdminUser
|
from rest_framework.permissions import IsAdminUser
|
||||||
@@ -8,16 +9,21 @@ from rest_framework.response import Response
|
|||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.http import HttpResponse
|
||||||
|
|
||||||
from seahub.utils import get_file_ops_stats_by_day, \
|
from seahub.utils import get_file_ops_stats_by_day, \
|
||||||
get_total_storage_stats_by_day, get_user_activity_stats_by_day, \
|
get_total_storage_stats_by_day, get_user_activity_stats_by_day, \
|
||||||
is_pro_version, EVENTS_ENABLED, get_system_traffic_by_day
|
is_pro_version, EVENTS_ENABLED, get_system_traffic_by_day, \
|
||||||
|
get_all_users_traffic_by_month
|
||||||
from seahub.utils.timeutils import datetime_to_isoformat_timestr
|
from seahub.utils.timeutils import datetime_to_isoformat_timestr
|
||||||
|
from seahub.utils.ms_excel import write_xls
|
||||||
|
|
||||||
from seahub.api2.authentication import TokenAuthentication
|
from seahub.api2.authentication import TokenAuthentication
|
||||||
from seahub.api2.throttling import UserRateThrottle
|
from seahub.api2.throttling import UserRateThrottle
|
||||||
from seahub.api2.utils import api_error
|
from seahub.api2.utils import api_error
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
def check_parameter(func):
|
def check_parameter(func):
|
||||||
def _decorated(view, request, *args, **kwargs):
|
def _decorated(view, request, *args, **kwargs):
|
||||||
@@ -176,3 +182,66 @@ def get_time_offset():
|
|||||||
timezone_name = timezone.get_current_timezone_name()
|
timezone_name = timezone.get_current_timezone_name()
|
||||||
offset = pytz.timezone(timezone_name).localize(datetime.datetime.now()).strftime('%z')
|
offset = pytz.timezone(timezone_name).localize(datetime.datetime.now()).strftime('%z')
|
||||||
return offset[:3] + ':' + offset[3:]
|
return offset[:3] + ':' + offset[3:]
|
||||||
|
|
||||||
|
class SystemUsersTrafficExcelView(APIView):
|
||||||
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||||
|
throttle_classes = (UserRateThrottle,)
|
||||||
|
permission_classes = (IsAdminUser,)
|
||||||
|
|
||||||
|
def byte_to_mb(self, byte):
|
||||||
|
|
||||||
|
return round(float(byte)/1000/1000, 2)
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
|
||||||
|
month = request.GET.get("month", "")
|
||||||
|
if not month:
|
||||||
|
error_msg = "month invalid."
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
try:
|
||||||
|
month_obj = datetime.datetime.strptime(month, "%Y-%m")
|
||||||
|
except:
|
||||||
|
error_msg = "Month %s invalid" % month
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
try:
|
||||||
|
res_data = get_all_users_traffic_by_month(month_obj)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
|
data_list = []
|
||||||
|
head = [_("Time"), _("User"), _("Web Download") + ('(MB)'), \
|
||||||
|
_("Sync Download") + ('(MB)'), _("Link Download") + ('(MB)'), \
|
||||||
|
_("Web Upload") + ('(MB)'), _("Sync Upload") + ('(MB)'), \
|
||||||
|
_("Link Upload") + ('(MB)')]
|
||||||
|
|
||||||
|
for data in res_data:
|
||||||
|
web_download = self.byte_to_mb(data['web_file_download'])
|
||||||
|
sync_download = self.byte_to_mb(data['sync_file_download'])
|
||||||
|
link_download = self.byte_to_mb(data['link_file_download'])
|
||||||
|
web_upload = self.byte_to_mb(data['web_file_upload'])
|
||||||
|
sync_upload = self.byte_to_mb(data['sync_file_upload'])
|
||||||
|
link_upload = self.byte_to_mb(data['link_file_upload'])
|
||||||
|
|
||||||
|
row = [month, data['user'], web_download, sync_download, \
|
||||||
|
link_download, web_upload, sync_upload, link_upload]
|
||||||
|
|
||||||
|
data_list.append(row)
|
||||||
|
|
||||||
|
excel_name = _("User Traffic %s" % month)
|
||||||
|
|
||||||
|
try:
|
||||||
|
wb = write_xls(excel_name, head, data_list)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
|
response = HttpResponse(content_type='application/ms-excel')
|
||||||
|
response['Content-Disposition'] = 'attachment; filename=%s.xlsx' % excel_name
|
||||||
|
wb.save(response)
|
||||||
|
|
||||||
|
return response
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
<li class="tabnav-tab"><a href="{% url 'sys_statistic_storage' %}">{% trans "Storage" %}</a></li>
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_storage' %}">{% trans "Storage" %}</a></li>
|
||||||
<li class="tabnav-tab"><a href="{% url 'sys_statistic_user' %}">{% trans "Users" %}</a></li>
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_user' %}">{% trans "Users" %}</a></li>
|
||||||
<li class="tabnav-tab"><a href="{% url 'sys_statistic_traffic' %}">{% trans "Traffic" %}</a></li>
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_traffic' %}">{% trans "Traffic" %}</a></li>
|
||||||
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_reports' %}">{% trans "Reports" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
71
seahub/templates/sysadmin/sys_statistic_reports.html
Normal file
71
seahub/templates/sysadmin/sys_statistic_reports.html
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
{% extends "sysadmin/base.html" %}
|
||||||
|
{% load seahub_tags i18n staticfiles %}
|
||||||
|
|
||||||
|
{% block extra_style %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{MEDIA_URL}}css/jquery-ui.datepicker.min.css" />
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block cur_statistic %}tab-cur{% endblock %}
|
||||||
|
|
||||||
|
{% block right_panel %}
|
||||||
|
<div class="tabnav ovhd">
|
||||||
|
<ul class="tabnav-tabs fleft">
|
||||||
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_file' %}">{% trans "File" %}</a></li>
|
||||||
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_storage' %}">{% trans "Storage" %}</a></li>
|
||||||
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_user' %}">{% trans "Users" %}</a></li>
|
||||||
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_traffic' %}">{% trans "Traffic" %}</a></li>
|
||||||
|
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_statistic_reports' %}">{% trans "Reports" %}</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="system-statistic-time-range ovhd">
|
||||||
|
<h3>{% trans "Get a detailed user traffic report of a month." %}</h3>
|
||||||
|
<form action="" class="fleft date-custom-form">
|
||||||
|
<input type="text" name="month" class="input" placeholder="yyyy-mm" />
|
||||||
|
<button type="submit" class="submit">{% trans "Create Report" %}</button>
|
||||||
|
<span class="error hide"></span>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_script %}
|
||||||
|
<script type="text/javascript" src="{% static "scripts/lib/jquery-ui.min.js" %}"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
// date picker for date-custom
|
||||||
|
$.datepicker.setDefaults({
|
||||||
|
changeMonth: true,
|
||||||
|
changeYear: true,
|
||||||
|
hideIfNoPrevNext: true,
|
||||||
|
maxDate: 0, // today (The maximum selectable date)
|
||||||
|
dateFormat: 'yy-mm'
|
||||||
|
});
|
||||||
|
$('.date-custom-form .input').datepicker();
|
||||||
|
|
||||||
|
// custom time range
|
||||||
|
$('.date-custom-form').on('submit', function() {
|
||||||
|
var $form = $(this);
|
||||||
|
var $month= $('[name="month"]', $form);
|
||||||
|
var $error = $('.error', $form);
|
||||||
|
|
||||||
|
var month = $month.val();
|
||||||
|
|
||||||
|
if (!month) {
|
||||||
|
$error.html("{% trans "Month is required." %}").removeClass('hide');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'date' can be picked from datepicker, also directly input
|
||||||
|
var date_pattern = /^([012]\d{3})\-(0[1-9]|1[012])$/;
|
||||||
|
if (!date_pattern.test(month)) {
|
||||||
|
$error.html("{% trans "Invalid month, should be yyyy-mm" %}").removeClass('hide');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$error.addClass('hide');
|
||||||
|
location.href = "{% url 'api-v2.1-admin-statistics-system-users-traffic-excel' %}" + "?month=" + month;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
@@ -14,6 +14,7 @@
|
|||||||
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_statistic_storage' %}">{% trans "Storage" %}</a></li>
|
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_statistic_storage' %}">{% trans "Storage" %}</a></li>
|
||||||
<li class="tabnav-tab"><a href="{% url 'sys_statistic_user' %}">{% trans "Users" %}</a></li>
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_user' %}">{% trans "Users" %}</a></li>
|
||||||
<li class="tabnav-tab"><a href="{% url 'sys_statistic_traffic' %}">{% trans "Traffic" %}</a></li>
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_traffic' %}">{% trans "Traffic" %}</a></li>
|
||||||
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_reports' %}">{% trans "Reports" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
<li class="tabnav-tab"><a href="{% url 'sys_statistic_storage' %}">{% trans "Storage" %}</a></li>
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_storage' %}">{% trans "Storage" %}</a></li>
|
||||||
<li class="tabnav-tab"><a href="{% url 'sys_statistic_user' %}">{% trans "Users" %}</a></li>
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_user' %}">{% trans "Users" %}</a></li>
|
||||||
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_statistic_traffic' %}">{% trans "Traffic" %}</a></li>
|
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_statistic_traffic' %}">{% trans "Traffic" %}</a></li>
|
||||||
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_reports' %}">{% trans "Reports" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
<li class="tabnav-tab"><a href="{% url 'sys_statistic_storage' %}">{% trans "Storage" %}</a></li>
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_storage' %}">{% trans "Storage" %}</a></li>
|
||||||
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_statistic_user' %}">{% trans "Users" %}</a></li>
|
<li class="tabnav-tab tabnav-tab-cur"><a href="{% url 'sys_statistic_user' %}">{% trans "Users" %}</a></li>
|
||||||
<li class="tabnav-tab"><a href="{% url 'sys_statistic_traffic' %}">{% trans "Traffic" %}</a></li>
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_traffic' %}">{% trans "Traffic" %}</a></li>
|
||||||
|
<li class="tabnav-tab"><a href="{% url 'sys_statistic_reports' %}">{% trans "Reports" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -78,7 +78,8 @@ from seahub.api2.endpoints.admin.file_update import FileUpdate
|
|||||||
from seahub.api2.endpoints.admin.perm_audit import PermAudit
|
from seahub.api2.endpoints.admin.perm_audit import PermAudit
|
||||||
from seahub.api2.endpoints.admin.sysinfo import SysInfo
|
from seahub.api2.endpoints.admin.sysinfo import SysInfo
|
||||||
from seahub.api2.endpoints.admin.statistics import (
|
from seahub.api2.endpoints.admin.statistics import (
|
||||||
FileOperationsView, TotalStorageView, ActiveUsersView, SystemTrafficView
|
FileOperationsView, TotalStorageView, ActiveUsersView, SystemTrafficView, \
|
||||||
|
SystemUsersTrafficExcelView
|
||||||
)
|
)
|
||||||
from seahub.api2.endpoints.admin.devices import AdminDevices
|
from seahub.api2.endpoints.admin.devices import AdminDevices
|
||||||
from seahub.api2.endpoints.admin.device_errors import AdminDeviceErrors
|
from seahub.api2.endpoints.admin.device_errors import AdminDeviceErrors
|
||||||
@@ -324,7 +325,7 @@ urlpatterns = [
|
|||||||
url(r'^api/v2.1/admin/statistics/total-storage/$', TotalStorageView.as_view(), name='api-v2.1-admin-statistics-total-storage'),
|
url(r'^api/v2.1/admin/statistics/total-storage/$', TotalStorageView.as_view(), name='api-v2.1-admin-statistics-total-storage'),
|
||||||
url(r'^api/v2.1/admin/statistics/active-users/$', ActiveUsersView.as_view(), name='api-v2.1-admin-statistics-active-users'),
|
url(r'^api/v2.1/admin/statistics/active-users/$', ActiveUsersView.as_view(), name='api-v2.1-admin-statistics-active-users'),
|
||||||
url(r'^api/v2.1/admin/statistics/system-traffic/$', SystemTrafficView.as_view(), name='api-v2.1-admin-statistics-system-traffic'),
|
url(r'^api/v2.1/admin/statistics/system-traffic/$', SystemTrafficView.as_view(), name='api-v2.1-admin-statistics-system-traffic'),
|
||||||
|
url(r'^api/v2.1/admin/statistics/system-users-traffic/excel/$', SystemUsersTrafficExcelView.as_view(), name='api-v2.1-admin-statistics-system-users-traffic-excel'),
|
||||||
## admin::users
|
## admin::users
|
||||||
url(r'^api/v2.1/admin/users/$', AdminUsers.as_view(), name='api-v2.1-admin-users'),
|
url(r'^api/v2.1/admin/users/$', AdminUsers.as_view(), name='api-v2.1-admin-users'),
|
||||||
# [^...] Matches any single character not in brackets
|
# [^...] Matches any single character not in brackets
|
||||||
@@ -434,6 +435,8 @@ urlpatterns = [
|
|||||||
url(r'^sys/statistic/storage/$', sys_statistic_storage, name='sys_statistic_storage'),
|
url(r'^sys/statistic/storage/$', sys_statistic_storage, name='sys_statistic_storage'),
|
||||||
url(r'^sys/statistic/user/$', sys_statistic_user, name='sys_statistic_user'),
|
url(r'^sys/statistic/user/$', sys_statistic_user, name='sys_statistic_user'),
|
||||||
url(r'^sys/statistic/traffic/$', sys_statistic_traffic, name='sys_statistic_traffic'),
|
url(r'^sys/statistic/traffic/$', sys_statistic_traffic, name='sys_statistic_traffic'),
|
||||||
|
url(r'^sys/statistic/reports/$', sys_statistic_reports, name='sys_statistic_reports'),
|
||||||
|
|
||||||
url(r'^sysadmin/#all-libs/$', fake_view, name='sys_repo_admin'),
|
url(r'^sysadmin/#all-libs/$', fake_view, name='sys_repo_admin'),
|
||||||
url(r'^sysadmin/#libs/(?P<repo_id>[-0-9a-f]{36})/$', fake_view, name='sys_admin_repo'),
|
url(r'^sysadmin/#libs/(?P<repo_id>[-0-9a-f]{36})/$', fake_view, name='sys_admin_repo'),
|
||||||
url(r'^sysadmin/#system-lib/$', fake_view, name='sys_list_system'),
|
url(r'^sysadmin/#system-lib/$', fake_view, name='sys_list_system'),
|
||||||
|
@@ -40,6 +40,8 @@ try:
|
|||||||
from seahub.settings import EVENTS_CONFIG_FILE
|
from seahub.settings import EVENTS_CONFIG_FILE
|
||||||
except ImportError:
|
except ImportError:
|
||||||
EVENTS_CONFIG_FILE = None
|
EVENTS_CONFIG_FILE = None
|
||||||
|
from seafevents import seafevents_api
|
||||||
|
seafevents_api.init(EVENTS_CONFIG_FILE)
|
||||||
try:
|
try:
|
||||||
from seahub.settings import EMAIL_HOST
|
from seahub.settings import EMAIL_HOST
|
||||||
IS_EMAIL_CONFIGURED = True
|
IS_EMAIL_CONFIGURED = True
|
||||||
@@ -722,6 +724,11 @@ if EVENTS_CONFIG_FILE:
|
|||||||
res = seafevents.get_system_traffic_by_day(session, start, end, offset, op_type)
|
res = seafevents.get_system_traffic_by_day(session, start, end, offset, op_type)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def get_all_users_traffic_by_month(datetime, start=-1, limit=-1):
|
||||||
|
|
||||||
|
res = seafevents_api.get_all_users_traffic_by_month(datetime, start, limit)
|
||||||
|
return res
|
||||||
|
|
||||||
def get_org_traffic_by_day(org_id, start, end, offset, op_type='all'):
|
def get_org_traffic_by_day(org_id, start, end, offset, op_type='all'):
|
||||||
with _get_seafevents_session() as session:
|
with _get_seafevents_session() as session:
|
||||||
res = seafevents.get_org_traffic_by_day(session, org_id, start, end, offset, op_type)
|
res = seafevents.get_org_traffic_by_day(session, org_id, start, end, offset, op_type)
|
||||||
@@ -788,6 +795,8 @@ else:
|
|||||||
pass
|
pass
|
||||||
def get_system_traffic_by_day():
|
def get_system_traffic_by_day():
|
||||||
pass
|
pass
|
||||||
|
def get_all_users_traffic_by_month():
|
||||||
|
pass
|
||||||
def get_org_traffic_by_day():
|
def get_org_traffic_by_day():
|
||||||
pass
|
pass
|
||||||
def get_file_update_events():
|
def get_file_update_events():
|
||||||
|
@@ -201,6 +201,13 @@ def sys_statistic_traffic(request):
|
|||||||
'page_next': page_next,
|
'page_next': page_next,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@sys_staff_required
|
||||||
|
def sys_statistic_reports(request):
|
||||||
|
|
||||||
|
return render(request, 'sysadmin/sys_statistic_reports.html', {
|
||||||
|
})
|
||||||
|
|
||||||
def can_view_sys_admin_repo(repo):
|
def can_view_sys_admin_repo(repo):
|
||||||
default_repo_id = get_system_default_repo_id()
|
default_repo_id = get_system_default_repo_id()
|
||||||
is_default_repo = True if repo.id == default_repo_id else False
|
is_default_repo = True if repo.id == default_repo_id else False
|
||||||
|
Reference in New Issue
Block a user