-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
52 additions
and
501 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,10 +2,8 @@ const express = require('express'); | |
const mongoose = require("mongoose"); | ||
const moment = require('moment'); | ||
const path = require('path'); | ||
const { updateLeaderboard } = require('./fetcher'); | ||
|
||
moment().format(); | ||
require('dotenv').config(); | ||
|
||
const app = express(); | ||
const port = process.env.PORT || 3000; | ||
|
@@ -20,34 +18,19 @@ app.use(express.json()); | |
console.log('Current directory:', __dirname); | ||
console.log('Views directory:', path.join(__dirname, 'views')); | ||
|
||
const mongoURI = process.env.MONGODB_URI; | ||
if (!mongoURI) { | ||
console.error('MONGODB_URI environment variable is not set'); | ||
process.exit(1); | ||
} | ||
const mongoURI = process.env.MONGODB_URI || "mongodb+srv://kanishkranjan17:[email protected]/leaderboard"; | ||
|
||
// Connect to MongoDB with connection pooling | ||
// Connect to MongoDB | ||
const connectDB = async () => { | ||
try { | ||
if (mongoose.connection.readyState === 1) { | ||
console.log('MongoDB already connected'); | ||
return mongoose.connection; | ||
} | ||
|
||
if (!global.mongoConnection) { | ||
global.mongoConnection = await mongoose.connect(mongoURI, { | ||
useNewUrlParser: true, | ||
useUnifiedTopology: true, | ||
serverSelectionTimeoutMS: 5000, | ||
bufferCommands: false, | ||
maxPoolSize: 10 | ||
}); | ||
console.log("Connected to MongoDB!"); | ||
} | ||
return global.mongoConnection; | ||
await mongoose.connect(mongoURI, { | ||
useNewUrlParser: true, | ||
useUnifiedTopology: true | ||
}); | ||
console.log("Connected to MongoDB!"); | ||
} catch (error) { | ||
console.error("MongoDB connection error:", error); | ||
throw error; | ||
process.exit(1); | ||
} | ||
}; | ||
|
||
|
@@ -56,88 +39,65 @@ const User = mongoose.model("User", new mongoose.Schema({ | |
username: String, | ||
solved: Object, | ||
streak: Number, | ||
questionSolved: Number, | ||
lastUpdated: Date | ||
}), "CSES"); | ||
questionSolved: Number | ||
}, { strict: false }), "CSES"); | ||
|
||
// Routes | ||
app.get("/", async (req, res, next) => { | ||
app.get("/", async (req, res) => { | ||
try { | ||
await connectDB(); | ||
const users = await User.find().lean(); | ||
const users = await User.find(); | ||
const usersData = users.map(userData => { | ||
const timeline = Array(7).fill(false); | ||
const noOfDaysInWeek = 7; | ||
|
||
for (let index = 0; index < noOfDaysInWeek; index++) { | ||
const reqDate = moment().subtract(index, 'days').format('DD/MM/YYYY'); | ||
const prevDate = moment().subtract(index + 1, 'days').format('DD/MM/YYYY'); | ||
const reqDate = moment("2024-12-08", "YYYY-MM-DD") | ||
.subtract(index, 'days') | ||
.format('DD/MM/YYYY'); | ||
const prevDate = moment("2024-12-08", "YYYY-MM-DD") | ||
.subtract(index + 1, 'days') | ||
.format('DD/MM/YYYY'); | ||
|
||
timeline[noOfDaysInWeek - index - 1] = parseInt(userData.solved?.[reqDate] || 0) > parseInt(userData.solved?.[prevDate] || 0); | ||
if (userData.solved && | ||
userData.solved[reqDate] !== undefined && | ||
userData.solved[prevDate] !== undefined) { | ||
timeline[noOfDaysInWeek - index - 1] = | ||
parseInt(userData.solved[reqDate]) > parseInt(userData.solved[prevDate]); | ||
} | ||
} | ||
|
||
return { | ||
name: userData.username, | ||
timeline: timeline, | ||
streak: userData.streak || 0, | ||
questionSolved: userData.questionSolved || 0, | ||
lastUpdated: userData.lastUpdated | ||
questionSolved: userData.questionSolved || 0 | ||
}; | ||
}); | ||
|
||
// Sort users by questionSolved in descending order | ||
usersData.sort((a, b) => b.questionSolved - a.questionSolved); | ||
|
||
res.render("index", { data: usersData }); | ||
} catch (error) { | ||
next(error); | ||
} | ||
}); | ||
|
||
// Manual update endpoint (protected) | ||
app.post("/update", async (req, res, next) => { | ||
try { | ||
const apiKey = req.headers['x-api-key']; | ||
if (apiKey !== process.env.API_KEY) { | ||
return res.status(401).json({ error: "Unauthorized" }); | ||
} | ||
|
||
await connectDB(); | ||
await updateLeaderboard(); | ||
res.json({ status: "success" }); | ||
} catch (error) { | ||
next(error); | ||
console.error("Error fetching data:", error); | ||
res.status(500).json({ error: "Error fetching data", details: error.message }); | ||
} | ||
}); | ||
|
||
// Health check endpoint | ||
app.get("/health", (req, res) => { | ||
res.json({ status: "healthy" }); | ||
}); | ||
|
||
// Error handling middleware | ||
app.use((err, req, res, next) => { | ||
console.error('Error:', err); | ||
const statusCode = err.statusCode || 500; | ||
const message = err.message || 'Internal Server Error'; | ||
res.status(statusCode).json({ error: message }); | ||
console.error(err.stack); | ||
res.status(500).json({ error: "Something broke!", details: err.message }); | ||
}); | ||
|
||
// For local development | ||
if (process.env.NODE_ENV !== 'production') { | ||
const startServer = async () => { | ||
try { | ||
await connectDB(); | ||
app.listen(port, () => { | ||
console.log(`Server is running on port ${port}`); | ||
}); | ||
} catch (error) { | ||
console.error('Failed to start server:', error); | ||
process.exit(1); | ||
} | ||
}; | ||
|
||
startServer(); | ||
} | ||
// Start server | ||
const startServer = async () => { | ||
try { | ||
await connectDB(); | ||
app.listen(port, () => { | ||
console.log(`Server running on http://localhost:${port}`); | ||
}); | ||
} catch (error) { | ||
console.error("Server startup error:", error); | ||
process.exit(1); | ||
} | ||
}; | ||
|
||
module.exports = app; | ||
startServer(); |
Oops, something went wrong.