diff --git a/.env.example b/.env.example index adc4dd9..c5186bb 100644 --- a/.env.example +++ b/.env.example @@ -6,4 +6,5 @@ DB_PORT=3306 SESSION_SECRET=secretkeyhere ADMIN_USERNAME=admin ADMIN_PASSWORD=admin -INTERNAL_PORT=3000 \ No newline at end of file +INTERNAL_PORT=3000 +MC_API_KEY=mailcowapikeyhere \ No newline at end of file diff --git a/README.md b/README.md index 91128c8..74de823 100644 --- a/README.md +++ b/README.md @@ -65,3 +65,4 @@ You will now have a fully functioning Node.js Express server, which will be runn # To-Do - [ ] Port to NextJS? - [ ] Hovering effects for buttons +- [ ] Statistics animation \ No newline at end of file diff --git a/app.js b/app.js index 0774168..085983b 100644 --- a/app.js +++ b/app.js @@ -4,6 +4,9 @@ const path = require('path'); const fs = require('fs'); const session = require('express-session'); const { Sequelize, DataTypes } = require('sequelize'); +const axios = require('axios'); +const NodeCache = require('node-cache'); +const cache = new NodeCache({ stdTTL: 1800 }); require('dotenv').config(); const app = express(); @@ -40,11 +43,44 @@ const Request = sequelize.define('Request', { } }); +async function fetchDomainData() { + const cachedData = cache.get('domainData'); + if (cachedData) { + console.log(domainData); + return cachedData; + } + + try { + const response = await axios.get('https://user.p0ntus.com/api/v1/get/domain/all', { + headers: { + 'accept': 'application/json', + 'X-API-Key': process.env.MC_API_KEY + } + }); + const domainData = response.data; + cache.set('domainData', domainData); + return domainData; + } catch (error) { + console.error('Error fetching domain data:', error); + return []; + } +} + // Sync DB models sequelize.sync(); -app.get('/', (req, res) => { - res.render('index', { currentPage: 'home' }); +app.get('/', async (req, res) => { + const domainData = await fetchDomainData(); + const domainCount = Array.isArray(domainData) ? domainData.length : 0; + const accountCount = Array.isArray(domainData) ? domainData.reduce((acc, domain) => acc + domain.mboxes_in_domain, 0) : 0; + const totalData = Array.isArray(domainData) ? domainData.reduce((acc, domain) => acc + parseInt(domain.bytes_total), 0) / (1024 * 1024) : 0; + + res.render('index', { + currentPage: 'home', + domainCount, + accountCount, + totalData: totalData.toFixed(2) // Round to 2 decimal places + }); }); app.get('/services', (req, res) => { diff --git a/package.json b/package.json index 74cdbff..80242e2 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "author": "ihatenodejs", "license": "CC0-1.0", "dependencies": { + "axios": "^1.7.9", "body-parser": "^1.20.3", "dotenv": "^16.4.7", "ejs": "^3.1.10", @@ -17,6 +18,7 @@ "express-session": "^1.18.1", "mariadb": "^3.4.0", "mysql2": "^3.11.5", + "node-cache": "^5.1.2", "sequelize": "^6.37.5", "winston": "^3.17.0" }, diff --git a/src/index.ejs b/src/index.ejs index 688c9f6..019b741 100644 --- a/src/index.ejs +++ b/src/index.ejs @@ -21,5 +21,21 @@ Guides + Statistics +
+
+
+

<%= domainCount %>

+

Domains Hosted

+
+
+

<%= accountCount %>

+

Accounts

+
+
+

<%= totalData %>

+

Total Data (MB)

+
+
<%- include('shards/footer') %> \ No newline at end of file