diff --git a/src/dashboard.py b/src/dashboard.py
index d52c3cbe..f7573227 100644
--- a/src/dashboard.py
+++ b/src/dashboard.py
@@ -908,6 +908,37 @@ def API_GetPeerSessions():
return ResponseObject(data=p.getSessions(startDate, endDate))
return ResponseObject(False, "Peer does not exist")
+@app.get(f'{APP_PREFIX}/api/getPeerTraffics')
+def API_GetPeerTraffics():
+ configurationName = request.args.get("configurationName")
+ id = request.args.get('id')
+ try:
+ interval = request.args.get('interval', 30)
+ startDate = request.args.get('startDate', None)
+ endDate = request.args.get('endDate', None)
+
+ if type(interval) is str:
+ if not interval.isdigit():
+ return ResponseObject(False, "Interval must be integers in minutes")
+ interval = int(interval)
+
+ if startDate is None:
+ endDate = None
+ else:
+ startDate = datetime.strptime(startDate, "%Y-%m-%d")
+ if endDate:
+ endDate = datetime.strptime(endDate, "%Y-%m-%d")
+ if startDate > endDate:
+ return ResponseObject(False, "startDate must be smaller than endDate")
+ except Exception as e:
+ return ResponseObject(False, "Dates are invalid" + e)
+ if not configurationName or not id:
+ return ResponseObject(False, "Please provide configurationName and id")
+ fp, p = WireguardConfigurations.get(configurationName).searchPeer(id)
+ if fp:
+ return ResponseObject(data=p.getTraffics(interval, startDate, endDate))
+ return ResponseObject(False, "Peer does not exist")
+
@app.get(f'{APP_PREFIX}/api/getDashboardTheme')
def API_getDashboardTheme():
return ResponseObject(data=DashboardConfig.GetConfig("Server", "dashboard_theme")[1])
diff --git a/src/modules/Peer.py b/src/modules/Peer.py
index 14b47eee..926056e4 100644
--- a/src/modules/Peer.py
+++ b/src/modules/Peer.py
@@ -236,17 +236,48 @@ class Peer:
return False
return True
+ def getTraffics(self, interval: int = 30, startDate: datetime.datetime = None, endDate: datetime.datetime = None):
+ if startDate is None and endDate is None:
+ endDate = datetime.datetime.now()
+ startDate = endDate - timedelta(minutes=interval)
+ else:
+ endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
+ startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
+
+ with self.configuration.engine.connect() as conn:
+ result = conn.execute(
+ db.select(
+ self.configuration.peersTransferTable.c.cumu_data,
+ self.configuration.peersTransferTable.c.total_data,
+ self.configuration.peersTransferTable.c.cumu_receive,
+ self.configuration.peersTransferTable.c.total_receive,
+ self.configuration.peersTransferTable.c.cumu_sent,
+ self.configuration.peersTransferTable.c.total_sent,
+ self.configuration.peersTransferTable.c.time
+ ).where(
+ db.and_(
+ self.configuration.peersTransferTable.c.id == self.id,
+ self.configuration.peersTransferTable.c.time <= endDate,
+ self.configuration.peersTransferTable.c.time >= startDate,
+ )
+ ).order_by(
+ self.configuration.peersTransferTable.c.time
+ )
+ ).mappings().fetchall()
+ return list(result)
+
+
def getSessions(self, startDate: datetime.datetime = None, endDate: datetime.datetime = None):
if endDate is None:
endDate = datetime.datetime.now()
if startDate is None:
- startDate = (endDate - datetime.timedelta(days=1))
+ startDate = endDate
endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999)
startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0)
-
+
with self.configuration.engine.connect() as conn:
result = conn.execute(
db.select(
@@ -261,23 +292,27 @@ class Peer:
self.configuration.peersTransferTable.c.time
)
).fetchall()
+ time = list(map(lambda x : x[0], result))
+ return time
# sessions = []
- # current_session = [time[0]]
+ # if len(time) > 1:
+ # current_session = [time[0]]
#
- # for ts in time[1:]:
- # if ts - current_session[-1] <= datetime.timedelta(minutes=3):
- # current_session.append(ts)
- # else:
- # sessions.append({
- # "duration": self.__duration(current_session[-1], current_session[0]),
- # "timestamps": current_session
- # })
- # current_session = [ts]
- # sessions.append({
- # "duration": self.__duration(current_session[-1], current_session[0]),
- # "timestamps": current_session
- # })
- return list(map(lambda x : x[0], result))
+ # for ts in time[1:]:
+ # if ts - current_session[-1] <= datetime.timedelta(minutes=3):
+ # current_session.append(ts)
+ # else:
+ # sessions.append({
+ # "duration": self.__duration(current_session[-1], current_session[0]),
+ # "timestamps": current_session
+ # })
+ # current_session = [ts]
+ # sessions.append({
+ # "duration": self.__duration(current_session[-1], current_session[0]),
+ # "timestamps": current_session
+ # })
+ # print(sessions)
+ # return sessions
def __duration(self, t1: datetime.datetime, t2: datetime.datetime):
delta = t1 - t2
diff --git a/src/static/app/src/components/configurationComponents/peer.vue b/src/static/app/src/components/configurationComponents/peer.vue
index 74d6a9b8..b514463b 100644
--- a/src/static/app/src/components/configurationComponents/peer.vue
+++ b/src/static/app/src/components/configurationComponents/peer.vue
@@ -16,9 +16,6 @@ export default {
},
props: {
Peer: Object, ConfigurationInfo: Object, order: Number, searchPeersLength: Number
- },
- mounted() {
-
},
setup(){
const target = ref(null);
@@ -136,7 +133,12 @@ export default {
-
+
+
diff --git a/src/static/app/src/components/configurationComponents/peerDetailsModal.vue b/src/static/app/src/components/configurationComponents/peerDetailsModal.vue
new file mode 100644
index 00000000..6b4a6f4f
--- /dev/null
+++ b/src/static/app/src/components/configurationComponents/peerDetailsModal.vue
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/static/app/src/components/configurationComponents/peerList.vue b/src/static/app/src/components/configurationComponents/peerList.vue
index d0f8192c..3b943c94 100644
--- a/src/static/app/src/components/configurationComponents/peerList.vue
+++ b/src/static/app/src/components/configurationComponents/peerList.vue
@@ -1,5 +1,5 @@
@@ -393,8 +395,10 @@ watch(() => route.query.id, (newValue) => {
:searchPeersLength="searchPeers.length"
:order="order"
:ConfigurationInfo="configurationInfo"
+ @details="configurationModals.peerDetails.modalOpen = true; configurationModalSelectedPeer = peer"
@share="configurationModals.peerShare.modalOpen = true; configurationModalSelectedPeer = peer"
@refresh="fetchPeerList()"
+
@jobs="configurationModals.peerScheduleJobs.modalOpen = true; configurationModalSelectedPeer = peer"
@setting="configurationModals.peerSetting.modalOpen = true; configurationModalSelectedPeer = peer"
@qrcode="configurationModalSelectedPeer = peer; configurationModals.peerQRCode.modalOpen = true;"
@@ -456,6 +460,13 @@ watch(() => route.query.id, (newValue) => {
:configurationPeers="configurationPeers"
@close="configurationModals.selectPeers.modalOpen = false"
>
+
+
{
labels: [...historySentData.value.timestamp],
datasets: [
{
- label: 'Data Sent',
+ label: GetLocale('Data Sent'),
data: [...historySentData.value.data],
- fill: false,
+ fill: 'start',
borderColor: '#198754',
- backgroundColor: '#198754',
- tension: 0
+ backgroundColor: '#19875490',
+ tension: 0,
+ pointRadius: 2,
+ borderWidth: 1,
},
],
}
@@ -139,12 +144,14 @@ const peersRealtimeReceivedData = computed(() => {
labels: [...historyReceivedData.value.timestamp],
datasets: [
{
- label: 'Data Received',
+ label: GetLocale('Data Received'),
data: [...historyReceivedData.value.data],
- fill: false,
+ fill: 'start',
borderColor: '#0d6efd',
- backgroundColor: '#0d6efd',
- tension: 0
+ backgroundColor: '#0d6efd90',
+ tension: 0,
+ pointRadius: 2,
+ borderWidth: 1,
},
],
}
diff --git a/src/static/app/src/components/configurationComponents/peerListComponents/peerListModals.vue b/src/static/app/src/components/configurationComponents/peerListComponents/peerListModals.vue
index 7383bd07..16e19a02 100644
--- a/src/static/app/src/components/configurationComponents/peerListComponents/peerListModals.vue
+++ b/src/static/app/src/components/configurationComponents/peerListComponents/peerListModals.vue
@@ -12,6 +12,8 @@ const PeerJobsModal = defineAsyncComponent(() => import("@/components/configurat
const PeerQRCodeModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerQRCode.vue"))
const PeerConfigurationFileModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerConfigurationFile.vue"))
const PeerSettingsModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerSettings.vue"))
+const PeerDetailsModal = defineAsyncComponent(() => import("@/components/configurationComponents/peerDetailsModal.vue"))
+
@@ -43,14 +45,17 @@ const PeerSettingsModal = defineAsyncComponent(() => import("@/components/config
:selectedPeer="configurationModalSelectedPeer">
+
diff --git a/src/static/app/src/components/peerDetailsModalComponents/peerSession.vue b/src/static/app/src/components/peerDetailsModalComponents/peerSession.vue
new file mode 100644
index 00000000..2234d440
--- /dev/null
+++ b/src/static/app/src/components/peerDetailsModalComponents/peerSession.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/static/app/src/components/peerDetailsModalComponents/peerSessionCalendarDay.vue b/src/static/app/src/components/peerDetailsModalComponents/peerSessionCalendarDay.vue
new file mode 100644
index 00000000..be8fe009
--- /dev/null
+++ b/src/static/app/src/components/peerDetailsModalComponents/peerSessionCalendarDay.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+ {{ s.timestamps[0].format("HH:mm:ss") }}{{ s.timestamps[s.timestamps.length - 1].format("HH:mm:ss") }}
+
+
+ {{ s.duration.format('HH:mm:ss')}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/static/app/src/components/peerDetailsModalComponents/peerSessionCalendarView.vue b/src/static/app/src/components/peerDetailsModalComponents/peerSessionCalendarView.vue
new file mode 100644
index 00000000..91f1df47
--- /dev/null
+++ b/src/static/app/src/components/peerDetailsModalComponents/peerSessionCalendarView.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+ {{ day.isSame(day.startOf('month')) ? day.format("MMM") : '' }} {{ day.format('D')}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/static/app/src/components/peerDetailsModalComponents/peerSessions.vue b/src/static/app/src/components/peerDetailsModalComponents/peerSessions.vue
new file mode 100644
index 00000000..0a879082
--- /dev/null
+++ b/src/static/app/src/components/peerDetailsModalComponents/peerSessions.vue
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ day.format('D')}}
+
+
+
{dayDetailsData = {day: day, details: args}; dayDetails = true}"
+ :sessions="sessions"
+ :day="day" :key="day">
+
+
+
+
+
+
+
+ {{ dayDetailsData.day.format("YYYY-MM-DD") }}
+
+
+
+
+
+
+
+
+
+
+ {{ s.timestamps[0].format("HH:mm:ss") }}{{ s.timestamps[s.timestamps.length - 1].format("HH:mm:ss") }}
+
+
+ {{ s.duration.format('HH:mm:ss')}}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/static/app/src/components/peerDetailsModalComponents/peerTraffics.vue b/src/static/app/src/components/peerDetailsModalComponents/peerTraffics.vue
new file mode 100644
index 00000000..3fb1e69d
--- /dev/null
+++ b/src/static/app/src/components/peerDetailsModalComponents/peerTraffics.vue
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/static/app/src/components/settingsComponent/dashboardAPIKeysComponents/newDashboardAPIKey.vue b/src/static/app/src/components/settingsComponent/dashboardAPIKeysComponents/newDashboardAPIKey.vue
index 53c8c280..d14d3d54 100644
--- a/src/static/app/src/components/settingsComponent/dashboardAPIKeysComponents/newDashboardAPIKey.vue
+++ b/src/static/app/src/components/settingsComponent/dashboardAPIKeysComponents/newDashboardAPIKey.vue
@@ -56,7 +56,7 @@ export default {
+ style="background-color: #00000060; backdrop-filter: blur(3px); z-index: 9999">