Skip to content

Commit

Permalink
split features into separate folders and implement new code replace f…
Browse files Browse the repository at this point in the history
…unction
  • Loading branch information
AAP9002 committed Nov 1, 2023
1 parent 1bb5025 commit 9456595
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 70 deletions.
21 changes: 21 additions & 0 deletions server/features/_new_feature_doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@


```js
// your feature
// @author : your github username
// @date : the date you created this file
// @description : a short description of what your feature does
// @params : any parameters your feature needs
// @returns : what your feature returns
// @notes : any notes you want to add

function run(cal) {
// your code

return cal
}

module.exports = {
run,
};
```
36 changes: 36 additions & 0 deletions server/features/forcedBreakPoint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Forcing calenders to update events once a day
// @author : aap9002
// @date : 01/11/2023
// @description : once a day between 01:00 and 04:00, force a refresh of the events to restyle any new formatting
// @params : the calender in string format
// @returns : the calender in string format
// @notes : Be aware the time is based on the server time not UTC

const regex = /^LAST-MODIFIED:.*/gm;

/**
* Force events to update format once a day
* @param {string} cal
* @returns cal with last modified date time set
*/
function run(cal) {
// once a day between 01:00 and 04:00, force a refresh of the events to restyle any new formatting
// this is as modifications to the event will not be recognised and updated unless the UoM event changes on the timetabling system itself
// so this will manual set the last modified each day to force an update in the calender app
// NB. it will stop doing this at 4 am so any changes in the day will be recognised and updated live
// NB. 3 hour window set as the ICS is set to refresh evert 2 hours, so this should affect all users
const date = new Date();
const hour = date.getHours();
if (hour >= 1 && hour <= 4) {
datestr = date.toISOString().split('T')[0];
datestr = datestr.split('-').join('');
datestr = "LAST-MODIFIED:" + datestr + "T000000";
cal = cal.replace(regex, datestr);
}

return cal;
}

module.exports = {
run,
};
81 changes: 81 additions & 0 deletions server/features/replaceCodeName.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Replace course codes
// @author : aap9002
// @date : 01/11/2023
// @description : Find and replace course codes with [course names] or [course code and course name]
// @params : the calender in string format
// @returns : the calender in string format


const pattern = /SUMMARY:[^\/]*\//g // REGEX to search the ICAL for the course code

/**
* List unique course names in the string
* @param {string} cal
* @returns List of unique course codes
*/
function parseCourseCodes(cal) {
const uniqueMatches = new Set();

let match;
while ((match = pattern.exec(cal)) !== null) {
//console.log(match[0].split(':')[1].split('/')[0]);
uniqueMatches.add(match[0].split(':')[1].split('/')[0]);
}
const uniqueCourseCodesArray = Array.from(uniqueMatches);
return uniqueCourseCodesArray;
}

/**
* Replace course codes with full course names
* @param {string} cal
* @returns cal with replacements
*/
function replaceCourseCodesWithNames(cal, courses) {
// get unique course codes
let uniqueCourseCodesArray = parseCourseCodes(cal);

// replace course codes with names
for (let i = 0; i < uniqueCourseCodesArray.length; i++) {
const courseCode = uniqueCourseCodesArray[i];
try {
const courseName = courses.find(course => course.split(' ')[0] === courseCode).split(' ').slice(1).join(' ');
cal = cal.split(courseCode).join(courseName);
}
catch (e) {
// if the course code is not found in the allCourses.md file, log it
console.log(courseCode + " not found in allCourses.md");
}
}

return cal;
}

/**
* Replace course codes with code and full course names
* @param {string} cal
* @returns cal with replacements
*/
function replaceCourseCodesWithCodeAndNames(cal, courses) {
// get unique course codes
let uniqueCourseCodesArray = parseCourseCodes(cal);

// replace course codes with names
for (let i = 0; i < uniqueCourseCodesArray.length; i++) {
const courseCode = uniqueCourseCodesArray[i];
try {
const courseName = courses.find(course => course.split(' ')[0] === courseCode).split(' ').slice(1).join(' ');
cal = cal.split(courseCode).join(courseCode + " " + courseName);
}
catch (e) {
// if the course code is not found in the allCourses.md file, log it
console.log(courseCode + " not found in allCourses.md");
}
}

return cal;
}

module.exports = {
replaceCourseCodesWithNames,
replaceCourseCodesWithCodeAndNames
};
86 changes: 16 additions & 70 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,22 @@ const app = express();
const axios = require('axios');
var fs = require('fs');

/////////////////////////////////////////////// IMPORT FEATURES ////////////////////////////////////////////////

const syncForcedBreakpoint = require('./features/forcedBreakPoint.js')
const replaceTitle = require('./features/replaceCodeName.js')


///////////////////////////////////////////// IMPORT FEATURES END //////////////////////////////////////////////


/////////////////////////////////////////////////// SETUP /////////////////////////////////////////////////////

// This displays message that the server running and listening to specified port
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Listening on port ${port}`));

var courses = []; // Predefined courses from allCourses.md
const pattern = /SUMMARY:[^\/]*\//g // REGEX to search the ICAL for the course code
const validUrlPATTERN = /^https:\/\/scientia-eu-v4-api-d3-02\.azurewebsites\.net\/\/api\/ical\/[0-9a-fA-F-]+\/[0-9a-fA-F-]+\/timetable\.ics$/g; // REGEX for valid uom ics uri


Expand All @@ -23,6 +33,7 @@ try {
console.log('Error:', e.stack);
}

////////////////////////////////////////////////// SETUP END ///////////////////////////////////////////////////

/////////////////////////////////////////////////// API V1 /////////////////////////////////////////////////////
app.get('/api/v1/:uniqueAPI/tt.ics', function (req, res) {
Expand All @@ -41,9 +52,10 @@ app.get('/api/v1/:uniqueAPI/tt.ics', function (req, res) {
getTimetable(rebuild).then(cal => {
if (cal != null) {

// modification steps
cal = replaceCourseCodesWithNames(cal);
cal = syncForcedBreakpoint(cal);
////// modification steps //////
cal = replaceTitle.replaceCourseCodesWithNames(cal, courses);
cal = syncForcedBreakpoint.run(cal);
//// modification steps end ////

res.writeHead(200, {
"Content-Type": "text/calendar",
Expand Down Expand Up @@ -109,70 +121,4 @@ async function getTimetable(timetableUri) {
}
}

/**
* List unique course names in the string
* @param {string} cal
* @returns List of unique course codes
*/
function parseCourseCodes(cal) {
const uniqueMatches = new Set();

let match;
while ((match = pattern.exec(cal)) !== null) {
//console.log(match[0].split(':')[1].split('/')[0]);
uniqueMatches.add(match[0].split(':')[1].split('/')[0]);
}
const uniqueCourseCodesArray = Array.from(uniqueMatches);
return uniqueCourseCodesArray;
}

/**
* Replace course codes with full course names
* @param {string} cal
* @returns cal with replacements
*/
function replaceCourseCodesWithNames(cal) {
// get unique course codes
let uniqueCourseCodesArray = parseCourseCodes(cal);

// replace course codes with names
for (let i = 0; i < uniqueCourseCodesArray.length; i++) {
const courseCode = uniqueCourseCodesArray[i];
try {
const courseName = courses.find(course => course.split(' ')[0] === courseCode).split(' ').slice(1).join(' ');
cal = cal.split(courseCode).join(courseName);
}
catch (e) {
// if the course code is not found in the allCourses.md file, log it
console.log(courseCode + " not found in allCourses.md");
}
}

return cal;
}

/**
* Force events to update format once a day
* @param {string} cal
* @returns cal with last modified date time set
*/
function syncForcedBreakpoint(cal) {
// once a day between 01:00 and 04:00, force a refresh of the events to restyle any new formatting
// this is as modifications to the event will not be recognised and updated unless the UoM event changes on the timetabling system itself
// so this will manual set the last modified each day to force an update in the calender app
// NB. it will stop doing this at 4 am so any changes in the day will be recognised and updated live
// NB. 3 hour window set as the ICS is set to refresh evert 2 hours, so this should affect all users
const date = new Date();
const hour = date.getHours();
if (hour >= 1 && hour <= 4) {
datestr = date.toISOString().split('T')[0];
datestr = datestr.split('-').join('');
datestr = "LAST-MODIFIED:" + datestr + "T000000";
const regex = /^LAST-MODIFIED:.*/gm;
cal = cal.replace(regex, datestr);
}

return cal;
}

////////////////////////////////////////////// FUNDAMENTAL METHODS END //////////////////////////////////////////////

0 comments on commit 9456595

Please sign in to comment.