Junhyuyk Seo

Integrate server with apihandler

Showing 50 changed files with 741 additions and 100 deletions
node_modules
npm-debug.log
\ No newline at end of file
FROM node:14
LABEL title="TFT-APIHandler"
LABEL version="1.00"
# set working directory
WORKDIR /app
# install modules and dependencies
COPY package*.json ./
RUN npm install
# copy source codes
COPY ./ ./
#start application
CMD [ "node", "server.js" ]
\ No newline at end of file
exports.COORDINATES = {
"서울특별시" : {
"종로구" : [60, 127],
"중구" : [60, 127],
"용산구" : [60, 126],
"성동구" : [61, 127],
"광진구" : [62, 126],
"동대문구" : [61, 127],
"중랑구" : [62, 128],
"성북구" : [61, 127],
"강북구" : [61, 128],
"도봉구" : [61, 129],
"노원구" : [61, 129],
"은평구" : [59, 127],
"서대문구" : [59, 127],
"마포구" : [59, 127],
"양천구" : [58, 126],
"강서구" : [58, 126],
"구로구" : [58, 125],
"금천구" : [59, 124],
"영등포구" : [58, 126],
"동작구" : [59, 125],
"관악구" : [59, 125],
"서초구" : [61, 125],
"강남구" : [61, 126],
"송파구" : [62, 126],
"강동구" : [62, 126]
},
"부산광역시" : {
"중구" : [97, 74],
"서구" : [97, 74],
"동구" : [98, 75],
"영도구" : [98, 74],
"부산진구" : [97, 75],
"동래구" : [98, 76],
"남구" : [98, 75],
"북구" : [96, 76],
"해운대구" : [99, 75],
"사하구" : [96, 74],
"금정구" : [98, 77],
"강서구" : [96, 76],
"연제구" : [98, 76],
"수영구" : [99, 75],
"사상구" : [96, 75],
"기장군" : [100, 77]
},
"대구광역시" : {
"중구" : [89, 90],
"동구" : [90, 91],
"서구" : [88, 90],
"남구" : [89, 90],
"북구" : [89, 91],
"수성구" : [89, 90],
"달서구" : [88, 90],
"달성군" : [86, 88]
},
"인천광역시" : {
"중구" : [54, 125],
"동구" : [54, 125],
"미추홀구" : [54, 124],
"연수구" : [55, 123],
"남동구" : [56, 124],
"부평구" : [55, 125],
"계양구" : [56, 126],
"서구" : [55, 126],
"강화군" : [51, 130],
"옹진군" : [54, 124]
},
"광주광역시" : {
"동구" : [60, 74],
"서구" : [59, 74],
"남구" : [59, 73],
"북구" : [59, 75],
"광산구" : [57, 74]
},
"대전광역시" : {
"동구" : [68, 100],
"중구" : [68, 100],
"서구" : [67, 100],
"유성구" : [67, 101],
"대덕구" : [68, 100]
},
"울산광역시" : {
"중구" : [102, 84],
"남구" : [102, 84],
"동구" : [104, 83],
"북구" : [103, 85],
"울주군" : [101, 84]
},
"세종특별자치시" : {
"세종특별자치시": [66, 103]
},
"경기도" : {
"수원시" : [61, 120],
"성남시" : [63, 124],
"의정부시" : [61, 130],
"안양시" : [59, 123],
"부천시" : [56, 125],
"광명시" : [58, 125],
"평택시" : [62, 114],
"동두천시" : [61, 134],
"안산시" : [58, 121],
"고양시" : [57, 128],
"과천시" : [60, 124],
"구리시" : [62, 127],
"남양주시" : [64, 128],
"오산시" : [62, 118],
"시흥시" : [57, 123],
"군포시" : [59, 122],
"의왕시" : [60, 122],
"하남시" : [64, 126],
"용인시" : [64, 119],
"파주시" : [56, 131],
"이천시" : [68, 121],
"안성시" : [65, 115],
"김포시" : [55, 128],
"화성시" : [57, 119],
"광주시" : [65, 123],
"양주시" : [61, 131],
"포천시" : [64, 134],
"여주시" : [71, 121],
"연천군" : [61, 138],
"가평군" : [69, 133],
"양평군" : [69, 125]
},
"강원도" : {
"춘천시" : [73, 134],
"원주시" : [76, 122],
"강릉시" : [92, 131],
"동해시" : [97, 127],
"태백시" : [95, 119],
"속초시" : [87, 141],
"삼척시" : [98, 125],
"홍천군" : [75, 130],
"횡성군" : [77, 125],
"영월군" : [86, 119],
"평창군" : [84, 123],
"정선군" : [89, 123],
"철원군" : [65, 139],
"화천군" : [72, 139],
"양구군" : [77, 139],
"인제군" : [80, 138],
"고성군" : [85, 145],
"양양군" : [88, 138]
},
"충청북도" : {
"청주시" : [69, 106],
"충주시" : [76, 114],
"제천시" : [81, 118],
"보은군" : [73, 103],
"옥천군" : [71, 99],
"영동군" : [74, 97],
"증평군" : [71, 110],
"진천군" : [68, 111],
"괴산군" : [74, 111],
"음성군" : [72, 113],
"단양군" : [84, 115]
},
"충청남도" : {
"천안시" : [63, 110],
"공주시" : [63, 102],
"보령시" : [54, 100],
"아산시" : [60, 110],
"서산시" : [51, 110],
"논산시" : [62, 97],
"계룡시" : [65, 99],
"당진시" : [54, 112],
"금산군" : [69, 95],
"부여군" : [59, 99],
"서천군" : [55, 94],
"청양군" : [57, 103],
"홍성군" : [55, 106],
"예산군" : [58, 107],
"태안군" : [48, 109]
},
"전라북도" : {
"전주시" : [63, 89],
"군산시" : [56, 92],
"익산시" : [60, 91],
"정읍시" : [58, 83],
"남원시" : [68, 80],
"김제시" : [59, 88],
"완주군" : [63, 89],
"진안군" : [68, 88],
"무주군" : [72, 93],
"장수군" : [70, 85],
"임실군" : [66, 84],
"순창군" : [63, 79],
"고창군" : [56, 80],
"부안군" : [56, 87]
},
"전라남도" : {
"목포시" : [50, 67],
"여수시" : [73, 66],
"순천시" : [70, 70],
"나주시" : [56, 71],
"광양시" : [73, 70],
"담양군" : [61, 78],
"곡성군" : [66, 77],
"구례군" : [69, 75],
"고흥군" : [66, 62],
"보성군" : [62, 66],
"화순군" : [61, 72],
"장흥군" : [59, 64],
"강진군" : [57, 63],
"해남군" : [54, 61],
"영암군" : [56, 66],
"무안군" : [52, 71],
"함평군" : [52, 72],
"영광군" : [52, 77],
"장성군" : [57, 77],
"완도군" : [57, 56],
"진도군" : [48, 59],
"신안군" : [50, 66]
},
"경상북도" : {
"포항시" : [102, 94],
"경주시" : [100, 91],
"김천시" : [80, 96],
"안동시" : [91, 106],
"구미시" : [84, 96],
"영주시" : [89, 111],
"영천시" : [95, 93],
"상주시" : [81, 102],
"문경시" : [81, 106],
"경산시" : [91, 90],
"군위군" : [88, 99],
"의성군" : [90, 101],
"청송군" : [96, 103],
"영양군" : [97, 108],
"영덕군" : [102, 103],
"청도군" : [91, 86],
"고령군" : [83, 87],
"성주군" : [83, 91],
"칠곡군" : [85, 93],
"예천군" : [86, 107],
"봉화군" : [90, 113],
"울진군" : [102, 115],
"울릉군" : [127, 127]
},
"경상남도" : {
"창원시" : [90, 77],
"진주시" : [81, 75],
"통영시" : [87, 68],
"사천시" : [80, 71],
"김해시" : [95, 77],
"밀양시" : [92, 83],
"거제시" : [90, 69],
"양산시" : [97, 79],
"의령군" : [83, 78],
"함안군" : [86, 77],
"창녕군" : [87, 83],
"고성군" : [85, 71],
"남해군" : [77, 68],
"하동군" : [74, 73],
"산청군" : [76, 80],
"함양군" : [74, 82],
"거창군" : [77, 86],
"합천군" : [81, 84]
},
"제주특별자치도" : {
"제주시" : [53, 38],
"서귀포시" : [52, 33]
}
}
\ No newline at end of file
const mongoose =require('mongoose');
const { Schema } =mongoose;
const festivalSchema = new Schema({
title: String,
addr: String,
tel: String,
contentid : Number,
mapx : Number,
mapy : Number,
eventstartdate : String,
eventenddate : String,
overview : String,
firstimage : String,
homepage : String,
weathers : String
// weather : {
// date1: { weather : String, temp : Number},
// date2: { weather : String, temp : Number},
// date3: { weather : String, temp : Number},
// }
},
{
versionKey: false
});
module.exports = mongoose.model('Festival',festivalSchema);
This diff is collapsed. Click to expand it.
{
"name": "REST-API",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^10.0.0",
"mongoose": "^6.0.13",
"request": "^2.88.2",
"request-promise-native": "^1.0.9"
}
}
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!");
});
})
}
});
}
}
});
}
});
}
node_modules
npm-debug.log
\ No newline at end of file
FROM node:14
LABEL title="TFT-Webserver"
LABEL version="1.01"
LABEL version="1.00"
# set working directory
WORKDIR /app
......
......@@ -42,6 +42,20 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz",
"integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw=="
},
"@types/webidl-conversions": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
"integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
},
"@types/whatwg-url": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
"integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
"requires": {
"@types/node": "*",
"@types/webidl-conversions": "*"
}
},
"@webassemblyjs/ast": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
......@@ -505,8 +519,7 @@
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
"dev": true
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
},
"base64id": {
"version": "2.0.0",
......@@ -776,6 +789,25 @@
"pako": "~1.0.5"
}
},
"bson": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/bson/-/bson-4.6.0.tgz",
"integrity": "sha512-8jw1NU1hglS+Da1jDOUYuNcBJ4cNHCFIqzlwoFNnsTOg2R/ox0aTYcTiBN4dzRa9q7Cvy6XErh3L8ReTEb9AQQ==",
"requires": {
"buffer": "^5.6.0"
},
"dependencies": {
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
}
}
},
"buffer": {
"version": "4.9.2",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
......@@ -1375,6 +1407,11 @@
}
}
},
"denque": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
"integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ=="
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
......@@ -2326,8 +2363,7 @@
"ieee754": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
"dev": true
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
},
"iferr": {
"version": "0.1.5",
......@@ -2796,6 +2832,12 @@
"readable-stream": "^2.0.1"
}
},
"memory-pager": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
"optional": true
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
......@@ -2939,6 +2981,26 @@
"minimist": "^1.2.5"
}
},
"mongodb": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.2.0.tgz",
"integrity": "sha512-lg3MJ9dAKxhogRnIB6/j63gfD7JryZwRC0nNzZ82RhENw4nCmscZVqRfOmNzTvSNndJx9ZhxZpm9JvnKuH/GTA==",
"requires": {
"bson": "^4.5.4",
"denque": "^2.0.1",
"mongodb-connection-string-url": "^2.2.0",
"saslprep": "^1.0.3"
}
},
"mongodb-connection-string-url": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.2.0.tgz",
"integrity": "sha512-U0cDxLUrQrl7DZA828CA+o69EuWPWEJTwdMPozyd7cy/dbtncUZczMw7wRHcwMD7oKOn0NM2tF9jdf5FFVW9CA==",
"requires": {
"@types/whatwg-url": "^8.2.1",
"whatwg-url": "^11.0.0"
}
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
......@@ -3557,8 +3619,7 @@
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"pupa": {
"version": "2.1.1",
......@@ -3816,6 +3877,15 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"saslprep": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
"optional": true,
"requires": {
"sparse-bitfield": "^3.0.3"
}
},
"schema-utils": {
"version": "2.6.5",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz",
......@@ -4205,6 +4275,15 @@
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"dev": true
},
"sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
"optional": true,
"requires": {
"memory-pager": "^1.0.2"
}
},
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
......@@ -4501,6 +4580,14 @@
"nopt": "~1.0.10"
}
},
"tr46": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
"integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
"requires": {
"punycode": "^2.1.1"
}
},
"tslib": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
......@@ -4940,6 +5027,11 @@
}
}
},
"webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
},
"webpack": {
"version": "4.42.1",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.1.tgz",
......@@ -5092,6 +5184,15 @@
"source-map": "~0.6.1"
}
},
"whatwg-url": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
"integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
"requires": {
"tr46": "^3.0.0",
"webidl-conversions": "^7.0.0"
}
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
......
......@@ -23,6 +23,7 @@
"dependencies": {
"express": "^4.17.1",
"jquery": "^3.6.0",
"mongodb": "^4.2.0",
"nodemon": "^2.0.15",
"socket.io": "^4.3.2",
"socket.io-client": "^4.3.2"
......
This diff could not be displayed because it is too large.
......@@ -5,29 +5,29 @@ const MongoClient = mongodb.MongoClient;
var app = express()
const PORT = 1697;
const PORT = 8484;
const url = 'mongodb://mongo:27017';
var db;
app.use(express.urlencoded({ extended: true }));
app.use("/public", express.static('./public'));
app.get("/*", (req, res) => {
res.sendFile(path.join(__dirname, "./public/index.html"))
})
app.get('/festivalList', (req, res) => { // localhost:3000/festivalList 입력하면 list.ejs에 저장한 형식대로 정보 불러와짐
//디비에 저장된 festivals 라는 collection안의 데이터(제목 또는 내용 등)를 꺼내기
db.collection('festivals').find().toArray((err, rslt) => { //DB에서 데이터를 찾음 festivals라는 collection안의 데이터를 꺼내게 됨
if (err) throw err;
console.log(rslt);
res.render('list.ejs', { posts: rslt }); // 찾은 데이터를 ejs 파일에 넣음
res.json(rslt); // 찾은 데이터를 json으로 전송
});
});
app.get("/*", (req, res) => {
res.sendFile(path.join(__dirname, "./public/index.html"))
})
MongoClient.connect(url, (error, client) => { // 서버열때 url 사용 mongoDB와 연결시키기
if (error) return console.log(error);
db = client.db('myFirstDatabase');
db = client.db('test');
app.listen(PORT, () => {
console.log(`Server lauched on port ${PORT}`);
});
......
......@@ -9,8 +9,14 @@
function LoadFestas() {
let url = "/festivalList";
jQuery.getJSON(url, (json) => {
AllFestas.set(json.response.body.items.item);
AllFestas.set(json);
// console.log(json);
});
// let url = "http://api.visitkorea.or.kr/openapi/service/rest/KorService/areaBasedList?ServiceKey=2lFkvQJYgzOOhwUKiUt8aZVNpd1PpBOf%2FfMNW17cl25DE0GUEDddeR9iGnuSUpggjUoIUgamfhcvnKQ3eH1dAw%3D%3D&contentTypeId=15&areaCode=&sigunguCode=&cat1=&cat2=&cat3=&listYN=Y&MobileOS=ETC&MobileApp=TourAPI3.0_Guide&arrange=A&numOfRows=12&pageNo=1&_type=json";
// jQuery.getJSON(url, (json) => {
// AllFestas.set(json.response.body.items.item);
// console.log(json.response.body.items.item);
// });
}
</script>
......
......@@ -80,7 +80,7 @@
return function() {
Festa = festa;
ShowInfo = true;
console.log(Festa);
// console.log(Festa);
}
};
kakao.maps.event.addListener(marker, 'click', showInfo(data[i]));
......
......@@ -23,9 +23,9 @@
let festaChecked = [];
$: festaList = $AllFestas.filter( v => {
if(v.addr1) {
let district = v.addr1.split(" ")[0];
let city = v.addr1.split(" ")[1];
if(v.addr) {
let district = v.addr.split(" ")[0];
let city = v.addr.split(" ")[1];
return ($District === "" || district === $District) &&
($City === "" || city === $City);
} else {
......@@ -33,7 +33,7 @@
}
});
$: festaParsed = festaList.map( (v, i) => {
return { "id" : i, "title" : v.title, "addr1" : v.addr1, "contentid" : v.contentid, "checked" : false }
return { "id" : i, "title" : v.title, "addr" : v.addr, "contentid" : v.contentid, "checked" : false }
});
$: if ($Changed) {
let len = festaList.length >= 9 ? 9 : festaList.length;
......@@ -142,7 +142,7 @@
<div class="{festa.checked ? "selected" : "festa"}"
on:click={() => {check(festa.id)}}>
<div class="title">{festa.title}</div>
<div class="addr"><img alt="pin" src="/public/map-pin.png"><div>{festa.addr1}</div></div>
<div class="addr"><img alt="pin" src="/public/map-pin.png"><div>{festa.addr}</div></div>
</div>
{/each}
{:else}
......
<script>
import SideBar from "./SideBar.svelte"
export let festa;
export let sidebar_show = false;
var side = "right";
var weatherData, weathers;
const WEATHERIMG = {
"맑음" : "./public/sunny.png",
"비" : "./public/rain.png",
"비/눈" : "./public/rainsnow.png",
"눈" : "./public/snow.png"
}
function hide() {
if (window.scrollY > 400) {
sidebar_show = false;
}
}
$: if(festa.weathers) weatherData = JSON.parse(festa.weathers);
$: if(festa.weathers) weathers = Array.from(Object.keys(weatherData)).map((v) => {
return { "date" : v.slice(4), "temp" : weatherData[v].temp, "weather" : weatherData[v].weather };
});
</script>
<style>
.info {
display: flex;
flex-direction: column;
align-items: center;
}
.title {
font-size: 18pt;
font-weight: bold;
}
.content {
padding: 0.5rem 0.5rem 0.5rem;
text-align: left;
}
.festaimg {
max-width: 560px;
}
.locpin, .telpin, .calpin {
width: 20px;
height: 20px;
}
.weather {
/* border: 1px solid #999999; */
border-collapse: collapse;
}
.weather td {
padding: 0.3rem;
border: 1px solid #cccccc;
}
.weatherimg {
width : 100px;
}
</style>
<svelte:window on:scroll={hide}></svelte:window>
<SideBar bind:show={sidebar_show} {side}>
<div class="info">
<div class="title">{festa.title}</div>
<img class="festaimg" alt="festaimg" src={festa.firstimage}><br>
{#if weathers}
<table class="weather"><tr>
{#each weathers as weather}
<td class="weathercell">
<img class="weatherimg" alt="weather" src={WEATHERIMG[weather.weather]}><br>
{weather.date.slice(0, 2) + '/' + weather.date.slice(2, 4)}<br>
{weather.temp}℃<br>
</td>
{/each}
</tr></table>
{/if}
<div class="content">
<img class="locpin" alt="pin" src="/public/map-pin.png"> 개최지 : {festa.addr}<br>
<img class="telpin" alt="pin" src="/public/tel-pin.jpeg"> 전화번호 : {festa.tel}<br>
<img class="calpin" alt="pin" src="/public/cal-pin.png"> 행사일 : {festa.eventstartdate} - {festa.eventenddate}<br>
</div>
</div>
</SideBar>
This diff could not be displayed because it is too large.
<script>
import SideBar from "./SideBar.svelte"
export let festa;
export let sidebar_show = false;
let side = "right";
function hide() {
if (window.scrollY > 400) {
sidebar_show = false;
}
}
</script>
<style>
.title {
font-size: 18pt;
font-weight: bold;
text-align: center;
}
.content {
padding: 0.5rem 0.5rem 0.5rem;
text-align: center;
}
.info img {
max-height: 20rem;
}
</style>
<svelte:window on:scroll={hide}></svelte:window>
<SideBar bind:show={sidebar_show} {side}>
<div class="info">
<div class="title">{festa.title}</div>
<img alt="festaImg" src={festa.firstimage}><br>
<div class="content">
개최지 : {festa.addr1}<br>
전화번호 : {festa.tel}<br>
<!-- 행사 시작일 : {festa.startdate}<br>
행사 시작일 : {festa.enddate}<br>
날씨 : {festa.weather 어쩌구} -->
</div>
</div>
</SideBar>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Festival Information</title>
</head>
<body>
<% for(let i=0; i < posts.length ; i++){ %>
<h4>제목 : <%= posts[i].title %>
</h4>
<h4>주소 : <%= posts[i].addr %>
</h4>
<h4>전화번호 : <%= posts[i].tel %>
</h4>
<h4>mapx : <%= posts[i].mapx %>
</h4>
<h4>mapy : <%= posts[i].mapy %>
</h4>
<h4>갱신일 : <%= posts[i].updatedAt %>
</h4>
<h4> ------------------- </h4>
<% } %>
</body>
</html>
\ No newline at end of file