Skip to content

Commit

Permalink
Merge pull request #180 from GDSC-PKNU-Official/feat/#179
Browse files Browse the repository at this point in the history
Feat: 건물 정보 api 라우팅 추가
  • Loading branch information
hwinkr authored Feb 2, 2024
2 parents 8f104c6 + 584fb7c commit 264039f
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 1 deletion.
18 changes: 18 additions & 0 deletions src/apis/building-info/controllers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import express, { Request, Response } from 'express';

import fetchBuildingInfo from './service';

const router = express.Router();

router.get('/', async (req: Request, res: Response) => {
const code = req.query.code;

try {
const buildingInfo = await fetchBuildingInfo(code as string);
res.json(buildingInfo);
} catch (err) {
console.log(err);
}
});

export default router;
99 changes: 99 additions & 0 deletions src/apis/building-info/service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import axios, { AxiosResponse } from 'axios';
import notificationToSlack from 'src/hooks/notificateToSlack';

type Floor = 'basement' | 'ground' | 'rooftop';

interface Room {
roomNumber: string;
roomName: string;
}

interface FormattedInfo extends Room {
floor: number;
floorType: Floor;
}

type TotalInfo = {
[key in Floor]: {
[key in string]: Room[];
};
};

const configPaylod = (code: string) => {
const payload = new URLSearchParams();
payload.append('code', code);
payload.append('stat', 'D');

return payload;
};

const handleLayerType = (layerType: string) => {
if (layerType === '0') return 'ground';
if (layerType === '1') return 'basement';
if (layerType === '2') return 'rooftop';
};

const formatTotalInfo = (formattedInfo: FormattedInfo[]) => {
const totalInfo: TotalInfo = {
basement: {},
ground: {},
rooftop: {},
};

formattedInfo.forEach(({ roomNumber, roomName, floor, floorType }) => {
const type = floorType as Floor;

if (!Object.prototype.hasOwnProperty.call(totalInfo[type], floor)) {
totalInfo[type][floor] = [{ roomNumber, roomName }];
return;
}

totalInfo[type][floor].push({ roomNumber, roomName });
});

return totalInfo;
};

const formatFetchedInfo = (data: AxiosResponse['data']) => {
const formattedData: FormattedInfo[] = data.response.deps2.reduce(
(accData: FormattedInfo[], curr: any) => {
const item = {
roomNumber: curr.roomNo,
roomName: curr.roomName,
floor: curr.layer,
floorType: handleLayerType(curr.layerTyp),
};

return [...accData, item];
},
[] as FormattedInfo[],
);

const formattedInfo = formatTotalInfo(formattedData);

return formattedInfo;
};

const fetchBuildingInfo = async (code: string) => {
const REQUEST_URL = 'https://www.pknu.ac.kr/buildingInfoAjax.do';
const HEADERS = {
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
};
const payload = configPaylod(code);

try {
const response = await axios.post(REQUEST_URL, payload.toString(), {
headers: HEADERS,
});

const formattedInfo = formatFetchedInfo(response.data);

return formattedInfo;
} catch (error) {
notificationToSlack('건물 정보 요청에 문제가 발생했습니다.');
console.log(error);
}
};

export default fetchBuildingInfo;
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import buildingInfoRouter from '@apis/building-info/controllers';
import graduationRouter from '@apis/graduation/controller';
import majorRouter from '@apis/majorDecision/controller';
import noticeRouter from '@apis/notice/controller';
import subscriptionRouter from '@apis/subscribe/controller';
import suggestionRouter from '@apis/suggestion/controller';
import env from '@config';
import { saveMajorNoticeToDB } from '@db/data/noticeHandler';
import { corsOptions } from '@middlewares/cors';
import errorHandler from '@middlewares/error-handler';
import cors from 'cors';
Expand All @@ -30,6 +30,7 @@ app.use('/api/majorDecision', majorRouter);
app.use('/api/announcement', noticeRouter);
app.use('/api/graduation', graduationRouter);
app.use('/api/subscription', subscriptionRouter);
app.use('/api/buildingInfo', buildingInfoRouter);

app.get('/test', (req: Request, res: Response) => {
console.log('test');
Expand Down

0 comments on commit 264039f

Please sign in to comment.