server.js 9.37 KB
const mongoose = require('mongoose');
// const db = require('mongodb');
const Festival = require('./models/Festival');
const request = require('request-promise-native');

const url = 'mongodb://mongo:27017';

const ServiceKey = '3zrQDvoNwUV9Se%2BHZv8DjCCNWRGJisQ7jjHP6LsbJqoRQ2cJpQKrHUGC4uslgXSVO9Dzb06BSC3kp9BunvIPSw%3D%3D';
const ServiceKey2 ='%2FGjtI8kwZeJTzJm%2BxUxz%2Bjh15wnmV3rwFuRvrq3oRSqyklfiZfbUaqmsG0McVPJMdXSUYetGaCXl0ZkbfMI0BQ%3D%3D'
const ServiceKey3 ='%2FsBWti235XX%2Fg1%2FqBZfiNQ6A%2BJmF3WL%2FboaNqJH4v3eWic59SiHc6W5vgZKU7Hjocj%2BAntIqHfhXOpmE5CpAFw%3D%3D'

const WeatherServiceKey = '2lFkvQJYgzOOhwUKiUt8aZVNpd1PpBOf%2FfMNW17cl25DE0GUEDddeR9iGnuSUpggjUoIUgamfhcvnKQ3eH1dAw%3D%3D';
const COORDINATES = require('./coordinates')['COORDINATES'];
const DISTRICT = [
    "서울특별시", "부산광역시", "울산광역시", "대구광역시", "대전광역시",
    "인천광역시", "광주광역시", "세종특별자치시", "제주특별자치도",
    "경기도", "강원도", "충청북도", "충청남도", "경상북도",
    "경상남도", "전라북도", "전라남도"
]
const WEATHERTYPE = [
    '맑음', '비', '비/눈', '눈', '소나기'
];

function parseDistrict(addr) {
    const words = addr.split(" ");
    if( DISTRICT.includes(words[0]) ) {
        return [words[0], words[1]];
    } else {
        return [];
    }
}
function leftPad(value) { if (value >= 10) { return value; } return `0${value}`; }

writeDB()
setInterval(() => {
    writeDB();
}, 86400000);

function writeDB() {

var today = new Date();
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
let todayString = "" + (today.getFullYear())+leftPad(today.getMonth()+1)+leftPad(today.getDate());
let yesterdayString = "" + (yesterday.getFullYear())+leftPad(yesterday.getMonth()+1)+leftPad(yesterday.getDate()-1);
var todayTime = leftPad(today.getHours()) + "00";

mongoose.connect(url,(err)=>{
    if(err) {
        console.log(err);
    } else {
        mongoose.connection.db.dropCollection('festivals',function(err, result) {
            if(err) {
                console.log(err + "Reset Failed!");
            } else {
                console.log(result + "Reset Success!");

                for(let i = 1; i <= 5; i++) {
                    let options = {
                        'method': 'GET',
                        'url' : 'http://api.visitkorea.or.kr/openapi/service/rest/KorService/areaBasedList'
                            + '?ServiceKey=' + ServiceKey2
                            + '&contentTypeId=15&areaCode=&sigunguCode=&cat1=&cat2=&cat3=&listYN=Y&MobileOS=ETC&MobileApp=TourAPI3.0_Guide&arrange=C&numOfRows=12'
                            + '&pageNo='+ i
                            + '&_type=json',
                    
                        'headers': {}
                    };

                    request(options, async function (error, response, body) {
                        if (error) {
                            throw new Error(error);
                        }
                        let info = JSON.parse(body);

                        let items = info['response']['body']['items']['item'];
                        for(item of items) {
                            let Info = {
                                'public': {
                                    'method': 'GET',
                                    'url': 'http://api.visitkorea.or.kr/openapi/service/rest/KorService/detailCommon?'
                                    + 'ServiceKey=' + ServiceKey2
                                    + '&contentTypeId=' + '15'
                                    + '&contentId=' + item['contentid']
                                    + '&MobileOS=ETC&MobileApp=TourAPI3.0_Guide&defaultYN=Y&firstImageYN=Y&areacodeYN=Y&catcodeYN=Y&addrinfoYN=Y&mapinfoYN=Y&overviewYN=Y&transGuideYN=Y&_type=json',
                                    'headers': {}
                                },
                                'detail': {
                                    'method': 'GET',
                                    'url': 'http://api.visitkorea.or.kr/openapi/service/rest/KorService/detailIntro?'
                                    + 'ServiceKey=' + ServiceKey2
                                    + '&contentTypeId=' + '15'
                                    + '&contentId=' + item['contentid']
                                    + '&MobileOS=ETC&MobileApp=TourAPI3.0_Guide&introYN=Y&_type=json',
                                    'headers': {}
                                },
                                'weather': {
                                    'method': 'GET',
                                    'url': '',
                                    'headers': {}
                                }
                            };
                            await request(Info.public, async function (error, response, body) {
                                if (error) {
                                    throw new Error(error);
                                }

                                let toSave = true;
                                let pinfo = JSON.parse(body);
                                let distriction = parseDistrict(pinfo['response']['body']['items']['item']['addr1']);
                                if (distriction.length == 0) toSave = false; 

                                const newFestival = new Festival();
                                newFestival.title = pinfo['response']['body']['items']['item']['title'];
                                newFestival.contentid = pinfo['response']['body']['items']['item']['contentid'];
                                newFestival.addr = pinfo['response']['body']['items']['item']['addr1'];
                                newFestival.tel = pinfo['response']['body']['items']['item']['tel'];
                                newFestival.mapx = pinfo['response']['body']['items']['item']['mapx'];
                                newFestival.mapy = pinfo['response']['body']['items']['item']['mapy'];
                                newFestival.overview= pinfo['response']['body']['items']['item']['overview'];
                                newFestival.firstimage = pinfo['response']['body']['items']['item']['firstimage'];
                                newFestival.homepage = pinfo ['response']['body']['items']['item']['homepage'];
                                

                                await request(Info.detail, function (error, response, body) {
                                    if (error) {
                                        throw new Error(error);
                                    }
                                    let dinfo = JSON.parse(body); 
                                    newFestival.eventstartdate = dinfo['response']['body']['items']['item']['eventstartdate'];
                                    newFestival.eventenddate = dinfo['response']['body']['items']['item']['eventenddate'];

                                   if (newFestival.eventenddate < todayString) toSave = false; 
                                });
                            
                                let [nx, ny] = COORDINATES[distriction[0]][distriction[1]];
                                let curDate = ('0500' < todayTime ? todayString : yesterdayString); 

                                Info.weather.url = 'http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getVilageFcst?'
                                + 'serviceKey=' + WeatherServiceKey
                                + '&pageNo=' + '1'
                                + '&numOfRows=' + '2000'
                                + '&dataType=' + 'JSON'
                                + '&base_date=' + curDate
                                + '&base_time=' + '0500'
                                + '&nx=' + nx
                                + '&ny=' + ny;

                                await request(Info.weather, function (error, response, body) {
                                    if (error) {
                                        throw new Error(error);
                                    }
                                    let winfo = JSON.parse(body); 
                                    
                                    let weathers = {};
                                    for( let item of winfo['response']['body']['items']['item'] ) {
                                        if(item['fcstTime'] === '1200') { // 최고기온 + 날씨
                                            let fcstDate = item['fcstDate'];
                                            if(!weathers[fcstDate])  weathers[fcstDate] = {};
                                            if(item['category']=='TMP') {
                                                weathers[fcstDate]['temp'] = item['fcstValue'];
                                            } else if(item['category']=='PTY') {
                                                weathers[fcstDate]['weather'] = WEATHERTYPE[item['fcstValue']];
                                            }
                                        }
                                    }
                                    newFestival.weathers = JSON.stringify(weathers);
                                });

                                if (toSave)
                                    await newFestival.save().then((festival) => {
                                        console.log(festival, "Save success!");
                                    });
								})
							}
						});
					}
				}
			});
		}
	});
}