Skip to content

Commit

Permalink
localization
Browse files Browse the repository at this point in the history
  • Loading branch information
wardviaene committed Aug 25, 2024
1 parent 94467aa commit 820078e
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 28 deletions.
59 changes: 43 additions & 16 deletions pkg/rest/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ func (c *Context) userStatsHandler(w http.ResponseWriter, r *http.Request) {
case "GB":
unitAdjustment = 1024 * 1024 * 1024
}
offset := 0
if r.FormValue("offset") != "" {
i, err := strconv.Atoi(r.FormValue("offset"))
if err == nil {
offset = i
}
}
// get all users
users := c.UserStore.ListUsers()
userMap := make(map[string]string)
Expand All @@ -43,22 +50,24 @@ func (c *Context) userStatsHandler(w http.ResponseWriter, r *http.Request) {
}
// calculate stats
var userStatsResponse UserStatsResponse
statsFile := c.Storage.Client.ConfigPath(path.Join(wireguard.VPN_STATS_DIR, "user-"+date.Format("2006-01-02")+".log"))
if !c.Storage.Client.FileExists(statsFile) { // file does not exist so just return empty response
out, err := json.Marshal(userStatsResponse)
if err != nil {
c.returnError(w, fmt.Errorf("user stats response marshal error: %s", err), http.StatusBadRequest)
return
}
c.write(w, out)
return
statsFiles := []string{
c.Storage.Client.ConfigPath(path.Join(wireguard.VPN_STATS_DIR, "user-"+date.AddDate(0, 0, -1).Format("2006-01-02")+".log")),
c.Storage.Client.ConfigPath(path.Join(wireguard.VPN_STATS_DIR, "user-"+date.Format("2006-01-02")+".log")),
c.Storage.Client.ConfigPath(path.Join(wireguard.VPN_STATS_DIR, "user-"+date.AddDate(0, 0, 1).Format("2006-01-02")+".log")),
}
logData, err := c.Storage.Client.ReadFile(statsFile)
if err != nil {
c.returnError(w, fmt.Errorf("readfile error: %s", err), http.StatusBadRequest)
return
logData := bytes.NewBuffer([]byte{})
for _, statsFile := range statsFiles {
if c.Storage.Client.FileExists(statsFile) {
fileLogData, err := c.Storage.Client.ReadFile(statsFile)
if err != nil {
c.returnError(w, fmt.Errorf("readfile error: %s", err), http.StatusBadRequest)
return
}
logData.Write(fileLogData)
}
}
scanner := bufio.NewScanner(bytes.NewReader(logData))

scanner := bufio.NewScanner(logData)

receiveBytesLast := make(map[string]int64)
transmitBytesLast := make(map[string]int64)
Expand Down Expand Up @@ -89,15 +98,27 @@ func (c *Context) userStatsHandler(w http.ResponseWriter, r *http.Request) {
receiveBytesData[userID] = []UserStatsDataPoint{}
}
value := math.Round(float64((receiveBytes-receiveBytesLast[userID])/unitAdjustment*100)) / 100
receiveBytesData[userID] = append(receiveBytesData[userID], UserStatsDataPoint{X: inputSplit[0], Y: value})
timestamp, err := time.Parse(wireguard.TIMESTAMP_FORMAT, inputSplit[0])
if err == nil {
timestamp = timestamp.Add(time.Duration(offset) * time.Minute)
if dateEqual(timestamp, date) {
receiveBytesData[userID] = append(receiveBytesData[userID], UserStatsDataPoint{X: timestamp.Format(wireguard.TIMESTAMP_FORMAT), Y: value})
}
}
}
transmitBytes, err := strconv.ParseInt(inputSplit[4], 10, 64)
if err == nil {
if _, ok := transmitBytesData[userID]; !ok {
transmitBytesData[userID] = []UserStatsDataPoint{}
}
value := math.Round(float64((transmitBytes-transmitBytesLast[userID])/unitAdjustment*100)) / 100
transmitBytesData[userID] = append(transmitBytesData[userID], UserStatsDataPoint{X: inputSplit[0], Y: value})
timestamp, err := time.Parse(wireguard.TIMESTAMP_FORMAT, inputSplit[0])
if err == nil {
timestamp = timestamp.Add(time.Duration(offset) * time.Minute)
if dateEqual(timestamp, date) {
transmitBytesData[userID] = append(transmitBytesData[userID], UserStatsDataPoint{X: timestamp.Format(wireguard.TIMESTAMP_FORMAT), Y: value})
}
}
}
receiveBytesLast[userID] = receiveBytes
transmitBytesLast[userID] = transmitBytes
Expand Down Expand Up @@ -161,3 +182,9 @@ func getColor(i int) string {
}
return colors[i%len(colors)]
}

func dateEqual(date1, date2 time.Time) bool {
y1, m1, d1 := date1.Date()
y2, m2, d2 := date2.Date()
return y1 == y2 && m1 == m2 && d1 == d2
}
3 changes: 3 additions & 0 deletions pkg/wireguard/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@ PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACC
const ACTION_ADD = "add"
const ACTION_DELETE = "delete"
const ACTION_CLEANUP = "cleanup"

// stats
const TIMESTAMP_FORMAT = "2006-01-02T15:04:05"
1 change: 0 additions & 1 deletion pkg/wireguard/stats_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
)

const RUN_STATS_INTERVAL = 5
const TIMESTAMP_FORMAT = "2006-01-02T15:04:05"

func RunStats(storage storage.Iface) {
err := storage.EnsurePath(storage.ConfigPath(VPN_STATS_DIR))
Expand Down
21 changes: 10 additions & 11 deletions webapp/src/Routes/Home/UserStats.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Card, Center, Divider, Grid, Select, Text } from "@mantine/core";
import { Card, Center, Grid, Select, Text } from "@mantine/core";
import { DatePickerInput } from '@mantine/dates';
import { useQuery } from "@tanstack/react-query";
import { useAuthContext } from "../../Auth/Auth";
Expand All @@ -8,18 +8,17 @@ import { Chart } from 'react-chartjs-2';
import 'chartjs-adapter-date-fns';
import { Chart as ChartJS, LineController, LineElement, PointElement, LinearScale, Title, CategoryScale, TimeScale, ChartOptions, Legend } from 'chart.js';
import { useState } from "react";


export function UserStats() {
ChartJS.register(LineController, LineElement, PointElement, LinearScale, Title, CategoryScale, TimeScale, Legend);

const timezoneOffset = new Date().getTimezoneOffset() * -1
const {authInfo} = useAuthContext()
const [statsDate, setStatsDate] = useState<Date | null>(new Date());
const [unit, setUnit] = useState<string>("MB")
const { isPending, error, data } = useQuery({
queryKey: ['userstats', statsDate, unit],
queryFn: () =>
fetch(AppSettings.url + '/stats/user/' + format(statsDate === null ? new Date() : statsDate, "yyyy-MM-dd") + "?unit=" +unit, {
fetch(AppSettings.url + '/stats/user/' + format(statsDate === null ? new Date() : statsDate, "yyyy-MM-dd") + "?offset="+timezoneOffset+"&unit=" +unit, {
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + authInfo.token
Expand All @@ -43,12 +42,6 @@ export function UserStats() {
scales: {
x: {
type: 'time',
min: '00:00:00',
/*time: {
displayFormats: {
quarter: 'HHHH MM'
}
}*/
},
y: {
min: 0
Expand All @@ -58,7 +51,13 @@ export function UserStats() {

if (isPending) return ''
if (error) return 'cannot retrieve licensed users'


if(data.receivedBytes.datasets === null) {
data.receivedBytes.datasets = [{ data: [0], label: "no data"}]
}
if(data.transmitBytes.datasets === null) {
data.transmitBytes.datasets = [{ data: [0], label: "no data"}]
}

return (
<>
Expand Down

0 comments on commit 820078e

Please sign in to comment.