From dfdcb6ac437dbfa28bc080d23d2baa3d86c0fbba Mon Sep 17 00:00:00 2001 From: Itamar Oren Date: Wed, 22 Feb 2023 14:09:40 -0500 Subject: [PATCH] migrated to express.js --- CSS/calendar.css | 38 ++++++++++ CSS/main.css | 4 ++ CSS/navbar.css | 31 ++++++++ html/calendar.html | 24 +++++++ html/index.html | 26 +++++++ main.js | 172 +++++++++++++++++++++++++++------------------ 6 files changed, 226 insertions(+), 69 deletions(-) create mode 100644 CSS/calendar.css create mode 100644 CSS/main.css create mode 100644 CSS/navbar.css create mode 100644 html/calendar.html create mode 100644 html/index.html diff --git a/CSS/calendar.css b/CSS/calendar.css new file mode 100644 index 0000000..8d48ced --- /dev/null +++ b/CSS/calendar.css @@ -0,0 +1,38 @@ +.calDownload { + color: #e7e5e5; + background-color: #2d63c8; + font-size: 19px; + border: 1px solid #2d63c8; + padding: 15px 50px; + cursor: pointer; +} + + +.calDownload:hover { + color: #2d63c8; + background-color: #e7e5e5; +} + + +.ogCal { + color: #e7e5e5; + background-color: #c82d31; + font-size: 20px; + border: 1px solid #2d63c8; + padding: 10px 45px; + letter-spacing: 1px; + cursor: pointer; +} + + +.ogCal:hover { + color: #c82d31; + background-color: #e7e5e5; +} + +h1 { + text-align: center; + color: #ffffff; + font-weight: 120; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} \ No newline at end of file diff --git a/CSS/main.css b/CSS/main.css new file mode 100644 index 0000000..0a22d3d --- /dev/null +++ b/CSS/main.css @@ -0,0 +1,4 @@ +body { + /* color: rgb(148, 0, 0); */ + color: rgb(252, 252, 252); +} \ No newline at end of file diff --git a/CSS/navbar.css b/CSS/navbar.css new file mode 100644 index 0000000..1fdf1d9 --- /dev/null +++ b/CSS/navbar.css @@ -0,0 +1,31 @@ +body { + margin: 0; + background-color: rgb(110, 110, 110) +} + +.topnav { + overflow: hidden; + background-color: #333; + text-align: center; + align-items: center; + height: 40px; + } + +.topnav a { + /* float: left; */ + color: #f2f2f2; + text-align: center; + padding: 20px 20px; + text-decoration: none; + font-size: 20px; +} + +.topnav a:hover { + background-color: #ddd; + color: black; +} + +.topnav a.active { + background-color: #aa0404; + color: white; +} \ No newline at end of file diff --git a/html/calendar.html b/html/calendar.html new file mode 100644 index 0000000..be1f65c --- /dev/null +++ b/html/calendar.html @@ -0,0 +1,24 @@ + + + + + + + + + RPI Academic Calendar to ics + + +
+ Home + Calendar +
+ +

Academic Calendar

+
+ Download ICS file +
+ RPI Web Page +
+ + \ No newline at end of file diff --git a/html/index.html b/html/index.html new file mode 100644 index 0000000..b1398dd --- /dev/null +++ b/html/index.html @@ -0,0 +1,26 @@ + + + + + + + + + + RPI Utils Website + + +
+ Home + Calendar +
+ +
+

Welcome to RPI Utils!

+

The place with the tools to withstand RPI's terrible online presence!

+ +
+ +
+ + \ No newline at end of file diff --git a/main.js b/main.js index 0c7a38b..1ddf953 100644 --- a/main.js +++ b/main.js @@ -2,89 +2,123 @@ const axios = require('axios'); const cheerio = require('cheerio'); const ics = require('ics'); const fs = require('fs'); +const express = require('express'); - +const app = express(); +app.use('/CSS', express.static('./CSS')); +app.use('/HTML', express.static('./HTML')); const url = "https://info.rpi.edu/registrar/academic-calendar"; -const m = new Map(); -async function main() { - // const data = await fetch(url); - // console.log(await data.text()); - await axios.get(url) - .then(res => { - const $ = cheerio.load(res.data) - const calendar = $('#academicCalendar'); - for (child of calendar.get(0).children) { - if (child.name) { - // if (child.attributes) - var tag; - const c = new Map(); - for (sub of child.children) { - if (sub.name == 'thead') { - tag = sub.children[0].children[0].children[0].data; - } else { - for (tr of sub.children) { - const tchildren = tr.children; - const d = tchildren.find((c) => (c.attribs.class == "date")); - const a = tchildren.find((c) => (c.attribs.class != "date")); - const txt = a.children[0].children[0].data; - const href = a.children[0].attribs.href; - c.set(d.children[0].data, new Map([['txt', txt], ['href', href]])); +async function createIcs() { + return new Promise(async (resolve) => { + const m = new Map(); + + await axios.get(url) + .then(res => { + const $ = cheerio.load(res.data) + const calendar = $('#academicCalendar'); + for (child of calendar.get(0).children) { + if (child.name) { + // if (child.attributes) + var tag; + const c = new Map(); + for (sub of child.children) { + if (sub.name == 'thead') { + tag = sub.children[0].children[0].children[0].data; + } else { + for (tr of sub.children) { + const tchildren = tr.children; + const d = tchildren.find((c) => (c.attribs.class == "date")); + const a = tchildren.find((c) => (c.attribs.class != "date")); + const txt = a.children[0].children[0].data; + const href = a.children[0].attribs.href; + c.set(d.children[0].data, new Map([['txt', txt], ['href', href]])); + } } } + + m.set(tag, c); + } + } + }); + + + const events = []; + const unused = []; + for (const i of m) { + for (const j of i[1]) { + const key = j[0]; + const val = j[1]; + var startDate; + var endDate; + + if (key.indexOf("-") != -1) { + const keySplit = key.split(" - "); + startDate = new Date(keySplit[0]); + endDate = new Date(keySplit[1]); + } else { + startDate = new Date(key); + endDate = new Date(key); + endDate.setDate(startDate.getDate() + 1); } - m.set(tag, c); + const timesStart = [startDate.getFullYear(), startDate.getMonth() + 1, startDate.getDate(), 0, 0]; + const timesEnd = [endDate.getFullYear(), endDate.getMonth() + 1, endDate.getDate(), 0, 0]; + + events.push({ + calName: "RPI Academic Calendar", + title: val.get("txt"), + url: val.get("href"), + location: val.get('href'), + start: timesStart, + end: timesEnd + }); } } + + ics.createEvents(events, (error, value) => { + if (error) { + console.log(error) + } + + // console.log(value); + resolve(value); + // fs.writeFileSync(`${__dirname}/rpievents.ics`, value) + }) }); - - const events = []; - const unused = []; - for (const i of m) { - for (const j of i[1]) { - const key = j[0]; - const val = j[1]; - var startDate; - var endDate; - - if (key.indexOf("-") != -1) { - const keySplit = key.split(" - "); - startDate = new Date(keySplit[0]); - endDate = new Date(keySplit[1]); - } else { - startDate = new Date(key); - endDate = new Date(key); - endDate.setDate(startDate.getDate() + 1); - } - - const timesStart = [startDate.getFullYear(), startDate.getMonth() + 1, startDate.getDate(), 0, 0]; - const timesEnd = [endDate.getFullYear(), endDate.getMonth() + 1, endDate.getDate(), 0, 0]; - - events.push({ - calName: "RPI Academic Calendar", - title: val.get("txt"), - url: val.get("href"), - location: val.get('href'), - start: timesStart, - end: timesEnd - }); - } - } - - ics.createEvents(events, (error, value) => { - if (error) { - console.log(error) - } - - fs.writeFileSync(`${__dirname}/rpievents.ics`, value) - }) - // console.log(m.entries().next()); } -main(); + +app.get('/', (req, res) => { + res.sendFile('index.html', {root: 'HTML'}); +}); + +app.get('/calendar', (req, res) => { + res.sendFile('calendar.html', {root: 'HTML'}); +}) + + +app.get('/calendar.css', (req, res) => { + return res.sendFile('calendar.css', { root: 'CSS' }); +}); + +app.get('/main.css', (req, res) => { + return res.sendFile('main.css', { root: 'CSS' }); +}); + +app.get('/navbar.css', (req, res) => { + return res.sendFile('navbar.css', { root: 'CSS' }); +}); + + +app.get('/createCalendar', async (req, res) => { + res.set({'Content-Disposition': 'attachment; rpievents.ics','Content-Type': 'text/ics'}); + res.send(await createIcs()) +}); + +app.listen(5000); \ No newline at end of file