// Import necessary modules const express = require('express'); const http = require('http'); const fs = require('fs'); const fetch = require('isomorphic-fetch'); const path = require('path'); const cors = require('cors'); require('dotenv').config(); // Import custom modules const msGraphHelper = require('./msGraphHelper'); const settings = require('./settings'); // Set the port const HTTP_PORT = process.env.HTTP_PORT || 8080; // Initialize Express app const app = express(); const slideshowDir = path.join(__dirname, 'slideshow'); // Middleware configurations app.use(express.static(path.join(__dirname, 'public'))); app.use(cors({ origin: 'http://localhost:5173', })); app.use(express.json()); // Initialize Microsoft Graph API for App Only Auth msGraphHelper.initializeGraphForAppOnlyAuth(settings); // Read resource UPNs once at startup const data = fs.readFileSync('./resourceUPNs.json', 'utf8'); const resourceUPNs = JSON.parse(data); // Cache quotes to avoid reading the file on every request let quotesCache = []; const quotesFilePath = path.join(__dirname, 'quotes.json'); fs.readFile(quotesFilePath, 'utf8', (err, data) => { if (err) { console.error('Error reading quotes:', err.message); } else { try { const parsedData = JSON.parse(data); if (Array.isArray(parsedData) && parsedData.length > 0) { quotesCache = parsedData; console.log('Quotes loaded into cache.'); } else { console.error('Quotes file is empty or malformed.'); } } catch (parseError) { console.error('Error parsing quotes:', parseError.message); } } }); // API endpoint to get events app.get('/api/events', async (req, res) => { try { const now = new Date(); const startDateTime = new Date(now); const endDateTime = new Date(now); endDateTime.setHours(20, 0, 0, 0); if (startDateTime > endDateTime) { // No relevant events to display return res.json({}); } const events = {}; for (const resource of resourceUPNs) { try { const data = await msGraphHelper.getCalendarView( resource, startDateTime.toISOString(), endDateTime.toISOString() ); events[resource] = data; } catch (error) { console.error(`Error fetching events for ${resource}:`, error); } } res.json(events); } catch (err) { res.status(500).json({ message: err.message }); } }); // API endpoint to get weather information app.get('/api/weather', async (req, res) => { try { const lat = 45.49; const lon = -73.58; const appId = process.env.OPENWEATHER_APPID; const url = `https://api.openweathermap.org/data/2.5/weather?units=metric&lat=${lat}&lon=${lon}&appid=${appId}`; const response = await fetch(url); if (response.ok) { const json = await response.json(); res.json(json); } else { res.status(500).json({ message: 'Error fetching weather data' }); } } catch (err) { res.status(500).json({ message: err.message }); } }); // API endpoint to get a random quote app.get('/api/quotes', (req, res) => { try { if (quotesCache.length === 0) { return res.status(500).json({ message: 'No quotes available' }); } const randomIndex = Math.floor(Math.random() * quotesCache.length); const randomQuote = quotesCache[randomIndex]; res.json(randomQuote); // Send only one quote } catch (err) { res.status(500).json({ message: 'Error retrieving quote' }); } }); // Serve slideshow images app.use('/slideshow', express.static(slideshowDir)); // API endpoint to get slideshow images app.get('/api/slideshow', (req, res) => { fs.readdir(slideshowDir, (err, files) => { if (err) { console.error('Failed to list slideshow images:', err.message); res.status(500).json({ message: err.message }); return; } const imagePaths = files .filter(file => /\.(jpg|jpeg|png|gif)$/i.test(file)) .map(file => `slideshow/${file}`); res.json(imagePaths); }); }); // Create and start the HTTP server const httpServer = http.createServer(app); httpServer.listen(HTTP_PORT, () => { console.log(`HTTP Server listening on http://localhost:${HTTP_PORT}`); });