diff --git a/app.ts b/app.ts index 149099b..a5bdc18 100644 --- a/app.ts +++ b/app.ts @@ -5,7 +5,8 @@ import * as dotenv from 'dotenv'; import {partyPlanerRouter} from './src/models/partyplaner/PartyPlaner.router'; import {highlightMarkerRouter} from './src/models/twitch-highlight-marker/HighlightMarker.router'; import {dhbwServiceRouter} from './src/models/dhbw-service/DHBWService.router'; -import logger from "./src/middleware/logger"; +import logger from './src/middleware/logger'; +import {dhbwRaPlaChangesRouter} from './src/models/dhbw-rapla-changes/DHBWRaPlaChanges.router'; dotenv.config(); @@ -26,6 +27,7 @@ app.use(express.json()); app.use('/dhbw-service', dhbwServiceRouter); app.use('/twitch-highlight-marker', highlightMarkerRouter); app.use('/partyplaner', partyPlanerRouter); +app.use('/raplachanges', dhbwRaPlaChangesRouter); // this is a simple route to make sure everything is working properly app.get('/', (req: express.Request, res: express.Response) => { diff --git a/src/models/dhbw-rapla-changes/DHBWRaPlaChanges.router.ts b/src/models/dhbw-rapla-changes/DHBWRaPlaChanges.router.ts new file mode 100644 index 0000000..705d28c --- /dev/null +++ b/src/models/dhbw-rapla-changes/DHBWRaPlaChanges.router.ts @@ -0,0 +1,30 @@ +/** + * Required External Modules and Interfaces + */ +import express, {Request, Response} from 'express'; +import logger from '../../middleware/logger'; +import {Guid} from 'guid-typescript'; +import * as ChangeService from './changes/changes.service'; + +/** + * Router Definition + */ +export const dhbwRaPlaChangesRouter = express.Router(); + +dhbwRaPlaChangesRouter.get('/', async (req: Request, res: Response) => { + try { + let week = (req.query.week ?? '').toString(); + + let changes = await ChangeService.getChanges('TINF19B4', week); + + res.status(200).send(changes); + } catch (e) { + let errorGuid = Guid.create().toString(); + logger.error('Error handling a request: ' + e.message, {reference: errorGuid}); + res.status(500).send({ + 'status': 'PROCESSING_ERROR', + 'message': 'Internal Server Error. Try again later.', + 'reference': errorGuid + }); + } +}); diff --git a/src/models/dhbw-rapla-changes/changes/Change.interface.ts b/src/models/dhbw-rapla-changes/changes/Change.interface.ts new file mode 100644 index 0000000..1b09280 --- /dev/null +++ b/src/models/dhbw-rapla-changes/changes/Change.interface.ts @@ -0,0 +1,16 @@ +export interface Change { + change_id: string; + event_id: string; + change_timestamp: Date; + is_deleted: boolean; + new_summary: string; + new_description: string; + new_start: Date; + new_end: Date; + new_last_modified: Date; + new_created: Date; + new_location: string; + new_organizer: string; + new_categories: string; + new_recurring: string; +} diff --git a/src/models/dhbw-rapla-changes/changes/Event.interface.ts b/src/models/dhbw-rapla-changes/changes/Event.interface.ts new file mode 100644 index 0000000..15d4bc2 --- /dev/null +++ b/src/models/dhbw-rapla-changes/changes/Event.interface.ts @@ -0,0 +1,9 @@ +import {Change} from './Change.interface'; + +export interface Event { + event_id: string; + event_uid: string; + latest_event_summary: string; + latest_start_date: Date; + changes: Change[]; +} diff --git a/src/models/dhbw-rapla-changes/changes/changes.service.ts b/src/models/dhbw-rapla-changes/changes/changes.service.ts new file mode 100644 index 0000000..b58ace1 --- /dev/null +++ b/src/models/dhbw-rapla-changes/changes/changes.service.ts @@ -0,0 +1,79 @@ +import * as dotenv from 'dotenv'; +import {Event} from './Event.interface'; +import {Change} from './Change.interface'; + +dotenv.config(); + +const mariadb = require('mariadb'); +const pool = mariadb.createPool({ + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASSWORD, + database: process.env.RAPLACHANGES_DATABASE, + connectionLimit: 5 +}); + +export const getChanges = async (course: string, week: string): Promise => { + let conn; + try { + conn = await pool.getConnection(); + + let relevantEventsRows = await conn.query('SELECT DISTINCT(entry_id) FROM rapla_changes WHERE new_start > ? AND new_start < DATE_ADD(?, INTERVAL 7 DAY)', [week, week]); + + let relevantEventIds: string[] = []; + relevantEventsRows.forEach((row: { entry_id: string; }) => { + relevantEventIds.push(row.entry_id); + }); + + let rows = await conn.query('SELECT c.change_id, c.entry_id, c.change_timestamp, c.isDeleted, c.new_summary, c.new_description, c.new_start, c.new_last_modified, c.new_end, c.new_created, c.new_location, c.new_organizer, c.new_categories, e.uid FROM rapla_changes c LEFT OUTER JOIN rapla_entries e ON c.entry_id = e.entry_id WHERE c.entry_id IN (?) ORDER BY c.change_id', [relevantEventIds]); + + let eventsMap = new Map(); + + for (let row of rows) { + let change: Change = { + change_id: row.change_id, + event_id: row.event_id, + change_timestamp: row.change_timestamp, + is_deleted: row.isDeleted, + new_summary: row.new_summary, + new_description: row.new_description, + new_start: row.new_start, + new_end: row.new_end, + new_last_modified: row.new_last_modified, + new_created: row.new_created, + new_location: row.new_location, + new_organizer: row.new_organizer, + new_categories: row.new_categories, + new_recurring: row.new_recurring + }; + + if (eventsMap.has(row.entry_id)) { + let event = eventsMap.get(row.entry_id); + + event.latest_event_summary = row.new_summary; + event.latest_start_date = row.new_start; + event.changes.push(change); + + eventsMap.set(row.entry_id, event); + } else { + let event: Event = { + event_id: row.event_id, + event_uid: row.uid, + latest_event_summary: row.event_summary, + latest_start_date: row.new_start, + changes: [change] + }; + + eventsMap.set(row.entry_id, event); + } + } + + return Array.from(eventsMap.values()) as Event[]; + } catch (err) { + throw err; + } finally { + if (conn) { + conn.end(); + } + } +};