mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-17 01:58:07 +00:00
Add some basic subscriptions statistics
Move the statistics to a specific Library Show some subscriptions charts in the admin panel Inject the browser user agent to the database if available Split statistics in different view (day/week/month) Install cron scripts Update the dependencies
This commit is contained in:
parent
e832eae21e
commit
4f11deeaf9
26 changed files with 601 additions and 7 deletions
1
Makefile
1
Makefile
|
|
@ -28,6 +28,7 @@ package-common:
|
|||
# General
|
||||
cp README.md $(OUTPUT_DIR)/flexisip-account-manager/
|
||||
cp -R httpd/ $(OUTPUT_DIR)/flexisip-account-manager/
|
||||
cp -R cron/ $(OUTPUT_DIR)/flexisip-account-manager/
|
||||
cp flexisip-account-manager.spec $(OUTPUT_DIR)/rpmbuild/SPECS/
|
||||
|
||||
tar cvf flexisip-account-manager.tar.gz -C $(OUTPUT_DIR) flexisip-account-manager
|
||||
|
|
|
|||
6
cron/flexiapi.debian
Normal file
6
cron/flexiapi.debian
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd /opt/belledonne-communications/share/flexisip-account-manager/flexiapi/
|
||||
sudo -su www-data && php artisan digest:expired-nonces-clear 60
|
||||
sudo -su www-data && php artisan accounts:clear-accounts-tombstones 7 --apply
|
||||
sudo -su www-data && php artisan accounts:clear-unconfirmed 30 --apply
|
||||
6
cron/flexiapi.redhat
Normal file
6
cron/flexiapi.redhat
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
cd /opt/belledonne-communications/share/flexisip-account-manager/flexiapi/
|
||||
scl enable rh-php73 "php artisan digest:expired-nonces-clear 60"
|
||||
scl enable rh-php73 "php artisan accounts:clear-accounts-tombstones 7 --apply"
|
||||
scl enable rh-php73 "php artisan accounts:clear-unconfirmed 30 --apply"
|
||||
|
|
@ -58,6 +58,12 @@ class Utils
|
|||
return mt_rand(1000, 9999);
|
||||
}
|
||||
|
||||
public static function percent($value, $max)
|
||||
{
|
||||
if ($max == 0) $max = 1;
|
||||
return round(($value*100)/$max, 2);
|
||||
}
|
||||
|
||||
public static function markdownDocumentationView($view)
|
||||
{
|
||||
$environment = Environment::createCommonMarkEnvironment();
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class RegisterController extends Controller
|
|||
$account->domain = config('app.sip_domain');
|
||||
$account->ip_address = $request->ip();
|
||||
$account->creation_time = Carbon::now();
|
||||
$account->user_agent = config('app.name');
|
||||
$account->user_agent = $request->header('User-Agent') ?? config('app.name');
|
||||
$account->save();
|
||||
|
||||
$account->confirmation_key = Str::random($this->emailCodeSize);
|
||||
|
|
@ -143,7 +143,7 @@ class RegisterController extends Controller
|
|||
$account->domain = config('app.sip_domain');
|
||||
$account->ip_address = $request->ip();
|
||||
$account->creation_time = Carbon::now();
|
||||
$account->user_agent = config('app.name');
|
||||
$account->user_agent = $request->header('User-Agent') ?? config('app.name');
|
||||
$account->save();
|
||||
|
||||
$alias = new Alias;
|
||||
|
|
|
|||
53
flexiapi/app/Http/Controllers/Admin/StatisticsController.php
Normal file
53
flexiapi/app/Http/Controllers/Admin/StatisticsController.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Libraries\StatisticsCruncher;
|
||||
|
||||
class StatisticsController extends Controller
|
||||
{
|
||||
public function showDay(Request $request)
|
||||
{
|
||||
$day = StatisticsCruncher::day();
|
||||
$maxDay = 0;
|
||||
foreach ($day as $hour) {
|
||||
if ($maxDay < $hour['all']) $maxDay = $hour['all'];
|
||||
}
|
||||
|
||||
return view('admin.statistics.show_day', [
|
||||
'day' => $day,
|
||||
'max_day' => $maxDay,
|
||||
]);
|
||||
}
|
||||
|
||||
public function showWeek(Request $request)
|
||||
{
|
||||
$week = StatisticsCruncher::week();
|
||||
$maxWeek = 0;
|
||||
foreach ($week as $day) {
|
||||
if ($maxWeek < $day['all']) $maxWeek = $day['all'];
|
||||
}
|
||||
|
||||
return view('admin.statistics.show_week', [
|
||||
'week' => $week,
|
||||
'max_week' => $maxWeek,
|
||||
]);
|
||||
}
|
||||
|
||||
public function showMonth(Request $request)
|
||||
{
|
||||
$month = StatisticsCruncher::month();
|
||||
$maxMonth = 0;
|
||||
foreach ($month as $day) {
|
||||
if ($maxMonth < $day['all']) $maxMonth = $day['all'];
|
||||
}
|
||||
|
||||
return view('admin.statistics.show_month', [
|
||||
'month' => $month,
|
||||
'max_month' => $maxMonth,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ class AccountController extends Controller
|
|||
$account->domain = $request->has('domain') && config('app.everyone_is_admin')
|
||||
? $request->get('domain')
|
||||
: config('app.sip_domain');
|
||||
$account->user_agent = config('app.name');
|
||||
$account->user_agent = $request->header('User-Agent') ?? config('app.name');
|
||||
|
||||
if (!$request->has('activated') || !(bool)$request->get('activated')) {
|
||||
$account->confirmation_key = Str::random(WebAuthenticateController::$emailCodeSize);
|
||||
|
|
|
|||
43
flexiapi/app/Http/Controllers/Api/StatisticController.php
Normal file
43
flexiapi/app/Http/Controllers/Api/StatisticController.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2021 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Libraries\StatisticsCruncher;
|
||||
|
||||
class StatisticController extends Controller
|
||||
{
|
||||
public function month(Request $request)
|
||||
{
|
||||
return StatisticsCruncher::month();
|
||||
}
|
||||
|
||||
public function week(Request $request)
|
||||
{
|
||||
return StatisticsCruncher::week();
|
||||
}
|
||||
|
||||
public function day(Request $request)
|
||||
{
|
||||
return StatisticsCruncher::day();
|
||||
}
|
||||
}
|
||||
197
flexiapi/app/Libraries/StatisticsCruncher.php
Normal file
197
flexiapi/app/Libraries/StatisticsCruncher.php
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2020 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Libraries;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonPeriod;
|
||||
use Carbon\CarbonInterval;
|
||||
|
||||
use App\Account;
|
||||
|
||||
|
||||
class StatisticsCruncher
|
||||
{
|
||||
public static function month()
|
||||
{
|
||||
$data = self::getAccountFrom(Carbon::now()->subMonth())
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
$dataAliases = self::getAccountFrom(Carbon::now()->subMonth())
|
||||
->whereIn('id', function($query) {
|
||||
$query->select('account_id')
|
||||
->from('aliases');
|
||||
})
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
$dataActivated = self::getAccountFrom(Carbon::now()->subMonth())
|
||||
->where('activated', true)
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
$dataAliasesActivated = self::getAccountFrom(Carbon::now()->subMonth())
|
||||
->where('activated', true)
|
||||
->whereIn('id', function($query) {
|
||||
$query->select('account_id')
|
||||
->from('aliases');
|
||||
})
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
return self::compileStatistics(
|
||||
collect(CarbonPeriod::create(Carbon::now()->subMonth(), Carbon::now()))->map->format('Y-m-d'),
|
||||
$data,
|
||||
$dataAliases,
|
||||
$dataActivated,
|
||||
$dataAliasesActivated
|
||||
);
|
||||
}
|
||||
|
||||
public static function week()
|
||||
{
|
||||
$data = self::getAccountFrom(Carbon::now()->subWeek())
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
$dataAliases = self::getAccountFrom(Carbon::now()->subWeek())
|
||||
->whereIn('id', function($query) {
|
||||
$query->select('account_id')
|
||||
->from('aliases');
|
||||
})
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
$dataActivated = self::getAccountFrom(Carbon::now()->subWeek())
|
||||
->where('activated', true)
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
$dataAliasesActivated = self::getAccountFrom(Carbon::now()->subWeek())
|
||||
->where('activated', true)
|
||||
->whereIn('id', function($query) {
|
||||
$query->select('account_id')
|
||||
->from('aliases');
|
||||
})
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
return self::compileStatistics(
|
||||
collect(CarbonPeriod::create(Carbon::now()->subWeek(), Carbon::now()))->map->format('Y-m-d'),
|
||||
$data,
|
||||
$dataAliases,
|
||||
$dataActivated,
|
||||
$dataAliasesActivated
|
||||
);
|
||||
}
|
||||
|
||||
public static function day()
|
||||
{
|
||||
$data = self::getAccountFrom(Carbon::now()->subDay())
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d %H') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
$dataAliases = self::getAccountFrom(Carbon::now()->subDay())
|
||||
->whereIn('id', function($query) {
|
||||
$query->select('account_id')
|
||||
->from('aliases');
|
||||
})
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d %H') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
$dataActivated = self::getAccountFrom(Carbon::now()->subDay())
|
||||
->where('activated', true)
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d %H') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
$dataAliasesActivated = self::getAccountFrom(Carbon::now()->subDay())
|
||||
->where('activated', true)
|
||||
->whereIn('id', function($query) {
|
||||
$query->select('account_id')
|
||||
->from('aliases');
|
||||
})
|
||||
->get(array(
|
||||
DB::raw("date_format(creation_time,'%Y-%m-%d %H') as moment"),
|
||||
DB::raw('COUNT(*) as "count"')
|
||||
))->each->setAppends([])->pluck('count', 'moment');
|
||||
|
||||
return self::compileStatistics(
|
||||
collect(CarbonInterval::hour()->toPeriod(Carbon::now()->subDay(), Carbon::now()))->map->format('Y-m-d H'),
|
||||
$data,
|
||||
$dataAliases,
|
||||
$dataActivated,
|
||||
$dataAliasesActivated
|
||||
);
|
||||
}
|
||||
|
||||
private static function getAccountFrom($date)
|
||||
{
|
||||
return Account::where('creation_time', '>=', $date)
|
||||
->groupBy('moment')
|
||||
->orderBy('moment', 'DESC')
|
||||
->setEagerLoads([]);
|
||||
}
|
||||
|
||||
private static function compileStatistics($period, $data, $dataAliases, $dataActivated, $dataAliasesActivated)
|
||||
{
|
||||
$stats = [];
|
||||
|
||||
foreach ($period as $moment) {
|
||||
$all = $data[$moment] ?? 0;
|
||||
$aliases = $dataAliases[$moment] ?? 0;
|
||||
$activated = $dataActivated[$moment] ?? 0;
|
||||
$activatedAliases = $dataAliasesActivated[$moment] ?? 0;
|
||||
|
||||
$stats[$moment] = [
|
||||
'all' => $all,
|
||||
'phone' => $aliases,
|
||||
'email' => $all - $aliases,
|
||||
'activated_phone' => $activatedAliases,
|
||||
'activated_email' => $activated - $activatedAliases
|
||||
];
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
|
@ -257,9 +257,9 @@ return [
|
|||
'Storage' => Illuminate\Support\Facades\Storage::class,
|
||||
'Str' => Illuminate\Support\Str::class,
|
||||
'URL' => Illuminate\Support\Facades\URL::class,
|
||||
'Utils' => App\Helpers\Utils::class,
|
||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,21 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2020 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,21 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2020 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
|
|
|||
77
flexiapi/public/css/charts.css
vendored
Normal file
77
flexiapi/public/css/charts.css
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
.legend {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.legend div:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
vertical-align: middle;
|
||||
background-color: gray;
|
||||
margin: 0 0.5rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.columns {
|
||||
display: flex;
|
||||
height: 600px;
|
||||
align-items: stretch;
|
||||
border: 1px solid #CCC;
|
||||
margin-bottom: 10rem;
|
||||
}
|
||||
|
||||
.columns .column {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
justify-content: flex-end;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.columns .column .bar {
|
||||
border-right: 1px solid white;
|
||||
font-size: 0.5rem;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.columns .column::after {
|
||||
display: block;
|
||||
content: attr(data-value);
|
||||
position: absolute;
|
||||
top: calc(100% + 1rem);
|
||||
writing-mode: vertical-rl;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.columns .column .bar.activated,
|
||||
.legend div.activated:before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.columns .column .bar.first,
|
||||
.legend .first:before {
|
||||
background-color: salmon;
|
||||
}
|
||||
|
||||
.columns .column .bar.second,
|
||||
.legend .second:before {
|
||||
background-color: seagreen;
|
||||
}
|
||||
|
||||
.columns .column .bar::after {
|
||||
display: block;
|
||||
content: attr(data-value);
|
||||
color: white;
|
||||
position: absolute;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1rem;
|
||||
left: 0rem;
|
||||
top: calc(50% - 0.5rem);
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -84,6 +84,14 @@ Finally the account page allows you to provision the account, using a QR Code or
|
|||
|
||||
The provisioning link can be generated and refreshed from this page as well.
|
||||
|
||||
### Create and edit an account
|
||||
|
||||
Administrators can create and edit accounts directly from the admin panel.
|
||||
|
||||
### Delete an account
|
||||
|
||||
The deletion of an account is definitive, all the database related data (password, aliases…) will be destroyed after the deletion.
|
||||
The deletion of an account is definitive, all the database related data (password, aliases…) will be destroyed after the deletion.
|
||||
|
||||
## Statistics
|
||||
|
||||
The statistics panel show registrations statistics based on their type (mobile and email based registration) and their activations states.
|
||||
|
|
@ -54,6 +54,12 @@
|
|||
</div>
|
||||
<p class="mb-1">Manage the Flexisip accounts</p>
|
||||
</a>
|
||||
<a href="{{ route('admin.statistics.show.day') }}" class="list-group-item list-group-item-action">
|
||||
<div class="d-flex w-100 justify-content-between">
|
||||
<h5 class="mb-1">Statistics</h5>
|
||||
</div>
|
||||
<p class="mb-1">Show some registration statistics</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h5>API Key</h5>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
<div class="bar first" style="flex-basis: {{ Utils::percent($slice['phone'] - $slice['activated_phone'], $max) }}%"
|
||||
data-value="{{ $slice['phone'] - $slice['activated_phone'] }}"
|
||||
title="Unactivated phone: {{ $slice['phone'] - $slice['activated_phone'] }}"></div>
|
||||
<div class="bar first activated" style="flex-basis: {{ Utils::percent($slice['activated_phone'], $max) }}%"
|
||||
data-value="{{ $slice['activated_phone'] }}"
|
||||
title="Activated phone: {{ $slice['activated_phone'] }}"></div>
|
||||
<div class="bar second" style="flex-basis: {{ Utils::percent($slice['email'] - $slice['activated_email'], $max) }}%"
|
||||
data-value="{{ $slice['email'] - $slice['activated_email'] }}"
|
||||
title="Unactivated email: {{ $slice['email'] - $slice['activated_email'] }}"></div>
|
||||
<div class="bar second activated" style="flex-basis: {{ Utils::percent($slice['activated_email'], $max) }}%"
|
||||
data-value="{{ $slice['activated_email'] }}"
|
||||
title="Activated email: {{ $slice['activated_email'] }}"></div>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<div class="legend">
|
||||
<div class="first">Unactivated phones</div>
|
||||
<div class="first activated">Activated phones</div>
|
||||
<div class="second">Unactivated emails</div>
|
||||
<div class="second activated">Activated emails</div>
|
||||
</div>
|
||||
37
flexiapi/resources/views/admin/statistics/show_day.blade.php
Normal file
37
flexiapi/resources/views/admin/statistics/show_day.blade.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
@extends('layouts.account')
|
||||
|
||||
@section('breadcrumb')
|
||||
<li class="breadcrumb-item active" aria-current="page">
|
||||
Statistics
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
|
||||
<ul class="nav justify-content-center">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link disabled" href="#">Day</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.statistics.show.week') }}">Week</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.statistics.show.month') }}">Month</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Statistics</h2>
|
||||
|
||||
@include('admin.statistics.parts.legend')
|
||||
|
||||
<h3>Day</h3>
|
||||
|
||||
<div class="columns">
|
||||
@foreach ($day as $key => $hour)
|
||||
<div class="column" data-value="{{ substr($key, -2, 2) }}:00">
|
||||
@include('admin.statistics.parts.columns', ['slice' => $hour, 'max' => $max_day])
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
@extends('layouts.account')
|
||||
|
||||
@section('breadcrumb')
|
||||
<li class="breadcrumb-item active" aria-current="page">
|
||||
Statistics
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
|
||||
<ul class="nav justify-content-center">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.statistics.show.day') }}">Day</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.statistics.show.week') }}">Week</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link disabled" href="#">Month</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Statistics</h2>
|
||||
|
||||
@include('admin.statistics.parts.legend')
|
||||
|
||||
<h3>Month</h3>
|
||||
|
||||
<div class="columns">
|
||||
@foreach ($month as $key => $day)
|
||||
<div class="column" data-value="{{ $key }}">
|
||||
@include('admin.statistics.parts.columns', ['slice' => $day, 'max' => $max_month])
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
@extends('layouts.account')
|
||||
|
||||
@section('breadcrumb')
|
||||
<li class="breadcrumb-item active" aria-current="page">
|
||||
Statistics
|
||||
</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
|
||||
<ul class="nav justify-content-center">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.statistics.show.day') }}">Day</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link disabled" href="#">Week</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ route('admin.statistics.show.month') }}">Month</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Statistics</h2>
|
||||
|
||||
@include('admin.statistics.parts.legend')
|
||||
|
||||
<h3>Week</h3>
|
||||
|
||||
<div class="columns">
|
||||
@foreach ($week as $key => $day)
|
||||
<div class="column" data-value="{{ $key }}">
|
||||
@include('admin.statistics.parts.columns', ['slice' => $day, 'max' => $max_week])
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
|
@ -186,6 +186,17 @@ Activate an account.
|
|||
#### `GET /accounts/{id}/deactivate`
|
||||
Deactivate an account.
|
||||
|
||||
### Statistics
|
||||
|
||||
#### `GET /statistics/day`
|
||||
Retrieve registrations statistics for 24 hours.
|
||||
|
||||
#### `GET /statistics/week`
|
||||
Retrieve registrations statistics for a week.
|
||||
|
||||
#### `GET /statistics/month`
|
||||
Retrieve registrations statistics for a month.
|
||||
|
||||
# Provisioning
|
||||
|
||||
When an account is having an available `confirmation_key` it can be provisioned using the two following URL.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
@else
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset('css/style.css') }}" >
|
||||
@endif
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset('css/charts.css') }}" >
|
||||
@endif
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ Route::post('accounts/{sip}/activate/email', 'Api\AccountController@activateEmai
|
|||
Route::post('accounts/{sip}/activate/phone', 'Api\AccountController@activatePhone');
|
||||
|
||||
Route::group(['middleware' => ['auth.digest_or_key']], function () {
|
||||
Route::get('statistic/month', 'Api\StatisticController@month');
|
||||
Route::get('statistic/week', 'Api\StatisticController@week');
|
||||
Route::get('statistic/day', 'Api\StatisticController@day');
|
||||
|
||||
Route::get('accounts/me', 'Api\AccountController@show');
|
||||
Route::delete('accounts/me', 'Api\AccountController@delete');
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ Route::group(['middleware' => 'auth'], function () {
|
|||
Route::group(['middleware' => 'auth.admin'], function () {
|
||||
Route::post('admin/api_key', 'Admin\AccountController@generateApiKey')->name('admin.api_key.generate');
|
||||
|
||||
Route::get('admin/statistics/day', 'Admin\StatisticsController@showDay')->name('admin.statistics.show.day');
|
||||
Route::get('admin/statistics/week', 'Admin\StatisticsController@showWeek')->name('admin.statistics.show.week');
|
||||
Route::get('admin/statistics/month', 'Admin\StatisticsController@showMonth')->name('admin.statistics.show.month');
|
||||
|
||||
Route::get('admin/accounts/{account}/show', 'Admin\AccountController@show')->name('admin.account.show');
|
||||
|
||||
Route::get('admin/accounts/{account}/activate', 'Admin\AccountController@activate')->name('admin.account.activate');
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#%define _datadir %{_datarootdir}
|
||||
#%define _docdir %{_datadir}/doc
|
||||
|
||||
%define build_number 105
|
||||
%define build_number 106
|
||||
%define var_dir /var/opt/belledonne-communications
|
||||
%define opt_dir /opt/belledonne-communications/share/flexisip-account-manager
|
||||
|
||||
|
|
@ -64,12 +64,16 @@ cp README* "$RPM_BUILD_ROOT%{opt_dir}/"
|
|||
mkdir -p "$RPM_BUILD_ROOT/etc/flexisip-account-manager"
|
||||
cp -R conf/* "$RPM_BUILD_ROOT/etc/flexisip-account-manager/"
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/cron.daily
|
||||
|
||||
%if %{with deb}
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/apache2/conf-available
|
||||
cp httpd/flexisip-account-manager.conf "$RPM_BUILD_ROOT/etc/apache2/conf-available/"
|
||||
cp cron/flexiapi.debian "$RPM_BUILD_ROOT/etc/cron.daily/"
|
||||
%else
|
||||
mkdir -p $RPM_BUILD_ROOT/opt/rh/httpd24/root/etc/httpd/conf.d
|
||||
cp httpd/flexisip-account-manager.conf "$RPM_BUILD_ROOT/opt/rh/httpd24/root/etc/httpd/conf.d/"
|
||||
cp cron/flexiapi.redhat "$RPM_BUILD_ROOT/etc/cron.daily/"
|
||||
%endif
|
||||
|
||||
# POST INSTALLATION
|
||||
|
|
@ -168,15 +172,19 @@ fi
|
|||
|
||||
%if %{with deb}
|
||||
%config(noreplace) /etc/apache2/conf-available/flexisip-account-manager.conf
|
||||
%config(noreplace) /etc/cron.daily/flexiapi.debian
|
||||
%else
|
||||
%config(noreplace) /opt/rh/httpd24/root/etc/httpd/conf.d/flexisip-account-manager.conf
|
||||
%config(noreplace) /etc/cron.daily/flexiapi.redhat
|
||||
%endif
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%changelog
|
||||
* Tue Jan 5 2020 Timothée Jaussoin <timothee.jaussoin@belledonne-communications.com>
|
||||
* Tue Sep 28 2021 Timothée Jaussoin <timothee.jaussoin@belledonne-communications.com>
|
||||
- Install cron scripts
|
||||
* Sun Jan 5 2020 Timothée Jaussoin <timothee.jaussoin@belledonne-communications.com>
|
||||
- Import and configure the new API package
|
||||
* Thu Jul 4 2019 Sylvain Berfini <sylvain.berfini@belledonne-communications.com>
|
||||
- New files layout
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue