mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-10 03:11:07 +00:00
export user traffic by month to excel
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Copyright (c) 2012-2016 Seafile Ltd.
|
||||
import datetime
|
||||
import pytz
|
||||
import logging
|
||||
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
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 import status
|
||||
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, \
|
||||
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.ms_excel import write_xls
|
||||
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.api2.utils import api_error
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def check_parameter(func):
|
||||
def _decorated(view, request, *args, **kwargs):
|
||||
@@ -176,3 +182,66 @@ def get_time_offset():
|
||||
timezone_name = timezone.get_current_timezone_name()
|
||||
offset = pytz.timezone(timezone_name).localize(datetime.datetime.now()).strftime('%z')
|
||||
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_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_reports' %}">{% trans "Reports" %}</a></li>
|
||||
</ul>
|
||||
</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"><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_reports' %}">{% trans "Reports" %}</a></li>
|
||||
</ul>
|
||||
</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_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"><a href="{% url 'sys_statistic_reports' %}">{% trans "Reports" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
@@ -14,6 +14,7 @@
|
||||
<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"><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>
|
||||
</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.sysinfo import SysInfo
|
||||
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.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/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-users-traffic/excel/$', SystemUsersTrafficExcelView.as_view(), name='api-v2.1-admin-statistics-system-users-traffic-excel'),
|
||||
## 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
|
||||
@@ -434,6 +435,8 @@ urlpatterns = [
|
||||
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/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/#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'),
|
||||
|
@@ -40,6 +40,8 @@ try:
|
||||
from seahub.settings import EVENTS_CONFIG_FILE
|
||||
except ImportError:
|
||||
EVENTS_CONFIG_FILE = None
|
||||
from seafevents import seafevents_api
|
||||
seafevents_api.init(EVENTS_CONFIG_FILE)
|
||||
try:
|
||||
from seahub.settings import EMAIL_HOST
|
||||
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)
|
||||
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'):
|
||||
with _get_seafevents_session() as session:
|
||||
res = seafevents.get_org_traffic_by_day(session, org_id, start, end, offset, op_type)
|
||||
@@ -788,6 +795,8 @@ else:
|
||||
pass
|
||||
def get_system_traffic_by_day():
|
||||
pass
|
||||
def get_all_users_traffic_by_month():
|
||||
pass
|
||||
def get_org_traffic_by_day():
|
||||
pass
|
||||
def get_file_update_events():
|
||||
|
@@ -201,6 +201,13 @@ def sys_statistic_traffic(request):
|
||||
'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):
|
||||
default_repo_id = get_system_default_repo_id()
|
||||
is_default_repo = True if repo.id == default_repo_id else False
|
||||
|
Reference in New Issue
Block a user