Showing
2 changed files
with
235 additions
and
92 deletions
... | @@ -56,13 +56,27 @@ | ... | @@ -56,13 +56,27 @@ |
56 | <fieldset> | 56 | <fieldset> |
57 | <legend>추천 음악 정보</legend> | 57 | <legend>추천 음악 정보</legend> |
58 | <div><input type="button" value="음악 추천 받기"></div><br> | 58 | <div><input type="button" value="음악 추천 받기"></div><br> |
59 | + <iframe id="video1" width="450" height="280" src="" frameborder="0" allowtransparency="true" allowfullscreen></iframe> | ||
60 | + <a href="#" id="playvideo">Play button</a> | ||
61 | + <script> | ||
62 | + var userLat = 37; | ||
63 | + var userLng = 127; | ||
64 | + fetch("http://localhost:3000/music") | ||
65 | + .then(res => res.json()) | ||
66 | + .then(function(data) { | ||
67 | + $("#playvideo").click(function(){ | ||
68 | + $("#video1")[0].src += data.link; | ||
69 | + }); | ||
70 | + }) | ||
71 | + | ||
72 | + </script> | ||
59 | 73 | ||
60 | - <h4>추천 음악 1</h4> | 74 | + <!-- <h4>추천 음악 1</h4> |
61 | <iframe width="942" height="530" src="https://www.youtube.com/embed/vnS_jn2uibs" title="YouTube video player" frameborder="0" | 75 | <iframe width="942" height="530" src="https://www.youtube.com/embed/vnS_jn2uibs" title="YouTube video player" frameborder="0" |
62 | allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><br> | 76 | allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><br> |
63 | <h4>추천 음악 2</h4> | 77 | <h4>추천 음악 2</h4> |
64 | <iframe width="942" height="530" src="https://www.youtube.com/embed/P6gV_t70KAk" title="YouTube video player" frameborder="0" | 78 | <iframe width="942" height="530" src="https://www.youtube.com/embed/P6gV_t70KAk" title="YouTube video player" frameborder="0" |
65 | - allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><br> | 79 | + allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><br> --> |
66 | </fieldset> | 80 | </fieldset> |
67 | 81 | ||
68 | 82 | ... | ... |
... | @@ -7,123 +7,252 @@ var app = express(); | ... | @@ -7,123 +7,252 @@ var app = express(); |
7 | var fs = require('fs'); | 7 | var fs = require('fs'); |
8 | const session = require('express-session'); | 8 | const session = require('express-session'); |
9 | const exp = require('constants'); | 9 | const exp = require('constants'); |
10 | -const passport = require('passport'), LocalStrategy = require('passport-local').Strategy; | ||
11 | const fileStore = require('session-file-store')(session); | 10 | const fileStore = require('session-file-store')(session); |
12 | var bodyParser = require('body-parser'); | 11 | var bodyParser = require('body-parser'); |
12 | +var cors = require('cors'); | ||
13 | +var request = require('request'); | ||
14 | +const axios = require("axios"); | ||
15 | +const cheerio = require("cheerio"); | ||
16 | +// const fetch = require('node-fetch'); | ||
13 | 17 | ||
18 | +const url_ballad = "https://www.melon.com/genre/song_list.htm?gnrCode=GN0100#params%5BgnrCode%5D=GN0100¶ms%5BdtlGnrCode%5D=¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
19 | +const url_hiphop_kr = "https://www.melon.com/genre/song_list.htm?gnrCode=GN0300#params%5BgnrCode%5D=GN0300¶ms%5BdtlGnrCode%5D=¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
20 | +const url_hiphop_us = "https://www.melon.com/genre/song_list.htm?gnrCode=GN1200#params%5BgnrCode%5D=GN1200¶ms%5BdtlGnrCode%5D=GN1201¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
21 | +const url_dance = "https://www.melon.com/genre/song_list.htm?gnrCode=GN0200#params%5BgnrCode%5D=GN0200¶ms%5BdtlGnrCode%5D=¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
22 | +const url_rock_kr = "https://www.melon.com/genre/song_list.htm?gnrCode=GN0600#params%5BgnrCode%5D=GN0600¶ms%5BdtlGnrCode%5D=¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
23 | +const url_rock_us = "https://www.melon.com/genre/song_list.htm?gnrCode=GN1000#params%5BgnrCode%5D=GN1000¶ms%5BdtlGnrCode%5D=GN1001¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
24 | +const url_pop = "https://www.melon.com/genre/song_list.htm?gnrCode=GN0900#params%5BgnrCode%5D=GN0900¶ms%5BdtlGnrCode%5D=GN0901¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
25 | +const url_RNB_kr = "https://www.melon.com/genre/song_list.htm?gnrCode=GN0400#params%5BgnrCode%5D=GN0400¶ms%5BdtlGnrCode%5D=¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
26 | +const url_RNB_us = "https://www.melon.com/genre/song_list.htm?gnrCode=GN1300#params%5BgnrCode%5D=GN1300¶ms%5BdtlGnrCode%5D=GN1301¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
27 | +const url_indie = "https://www.melon.com/genre/song_list.htm?gnrCode=GN0500#params%5BgnrCode%5D=GN0500¶ms%5BdtlGnrCode%5D=GN0501¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
28 | +const url_newage = "https://www.melon.com/genre/song_list.htm?gnrCode=GN1800#params%5BgnrCode%5D=GN1800¶ms%5BdtlGnrCode%5D=GN1801¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=N&po=pageObj&startIndex=1" | ||
29 | +const url_jazz = "https://www.melon.com/genre/jazz_list.htm?gnrCode=GN1700#params%5BgnrCode%5D=GN1700¶ms%5BdtlGnrCode%5D=GN1701¶ms%5BorderBy%5D=POP¶ms%5BsteadyYn%5D=&po=pageObj&startIndex=1" | ||
14 | 30 | ||
15 | -//미들웨어 리스트 | 31 | +var Youtube = require('youtube-node'); |
16 | -app.use(express.urlencoded({extended:false})); | 32 | +var youtube = new Youtube(); |
17 | -app.use(session({ | 33 | +var limit = 1; |
18 | - secret: 'secret key', | 34 | +youtube.setKey('AIzaSyCXcFg7Aa9WkKfZc5wFcWdsMUJmYw1Yvmo'); |
19 | - resave: false, | ||
20 | - saveUninitialized: false, | ||
21 | - store : new fileStore() | ||
22 | - })); | ||
23 | -app.use(passport.initialize()); | ||
24 | -app.use(passport.session()); | ||
25 | -app.use(express.static('public')); | ||
26 | -app.use(bodyParser.urlencoded({extended:false})); | ||
27 | 35 | ||
28 | -//사용자 정보 session 읽기, 쓰기 | ||
29 | -passport.serializeUser(function(user, done) { //쓰기 | ||
30 | - done(null, user.email); | ||
31 | -}); | ||
32 | 36 | ||
33 | -passport.deserializeUser(function(id, done) { //읽기 | 37 | +app.get('/music', cors(), function (req, res, next) { |
34 | - done(null, id); | 38 | + // var lat=req.query.userLat; |
39 | + // var long=req.query.userLng; | ||
40 | + | ||
41 | + var lat = 37; | ||
42 | + var long = 127; | ||
43 | + | ||
44 | + const APIKEY = "ea903679a6e5a44da75a971c0231f4f4"; | ||
45 | + request("https://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + long + "&appid=" + APIKEY + "&units=metric",function(error, response, body){ | ||
46 | + // fetch("https://api.openweathermap.org/data/2.5/weather?lat=" + userLat + "&lon=" + userLng + "&appid=" + APIKEY + "&units=metric") | ||
47 | + // .then((response) => response.json()) | ||
48 | + // .then(jsonObject => { | ||
49 | + if(!error&&response.statusCode==200) | ||
50 | + //request는 string으로 받아오기 때문에 JSON형태로 바꿔준다. | ||
51 | + var jsonObject = JSON.parse(body); | ||
52 | + | ||
53 | + var WeatherCondition = jsonObject.weather[0].main; //현재 날씨 | ||
54 | + | ||
55 | + | ||
56 | + var rec_song = []; | ||
57 | + | ||
58 | + if(WeatherCondition==="Thunderstorm"){ | ||
59 | + rec_song.concat(parsing(url_ballad), parsing(url_RNB_kr), parsing(url_RNB_us)); | ||
60 | + rec_song = random_5_Select(rec_song); | ||
61 | + } | ||
62 | + if(WeatherCondition==="Drizzle"){ | ||
63 | + rec_song.concat(parsing(url_ballad), parsing(url_RNB_kr), parsing(url_RNB_us)); | ||
64 | + rec_song = random_5_Select(rec_song); | ||
65 | + } | ||
66 | + if(WeatherCondition==="Rain"){ | ||
67 | + rec_song.concat(parsing(url_ballad), parsing(url_RNB_kr), parsing(url_RNB_us)); | ||
68 | + rec_song = random_5_Select(rec_song); | ||
69 | + } | ||
70 | + if(WeatherCondition==="Clear"){ | ||
71 | + rec_song.concat(parsing(url_hiphop_kr), parsing(url_hiphop_us), parsing(url_dance), parsing(url_rock_kr), parsing(url_rock_us)); | ||
72 | + rec_song = random_5_Select(rec_song); | ||
73 | + } | ||
74 | + if(WeatherCondition==="Clouds"){ | ||
75 | + rec_song.concat(parsing(url_pop), parsing(url_RNB_kr), parsing(url_RNB_us), parsing(url_indie)); | ||
76 | + rec_song = random_5_Select(rec_song); | ||
77 | + } | ||
78 | + if(WeatherCondition==="Snow"){rec_song.concat(parsing_exception('snow'));} | ||
79 | + if(WeatherCondition==="Mist"){rec_song.concat(parsing(url_newage));} | ||
80 | + if(WeatherCondition==="Fog"){rec_song.concat(parsing(url_newage));} | ||
81 | + | ||
82 | + //밑 4개 종류의 날씨는 거의 나올 확률이 없으므로 그냥 별 의미는 없이 newage장르로 매치함. | ||
83 | + if(WeatherCondition==="Smoke"){rec_song.concat(parsing(url_newage));} | ||
84 | + if(WeatherCondition==="Haze"){rec_song.concat(parsing(url_newage));} | ||
85 | + if(WeatherCondition==="Dust"){rec_song.concat(parsing(url_newage));} | ||
86 | + if(WeatherCondition==="Sand"){rec_song.concat(parsing(url_newage));} | ||
87 | + | ||
88 | + // for (var a = 0; a < 5; a++) { | ||
89 | + // var url1 = search(rec_song[a]); | ||
90 | + // res.json({link: url1}) | ||
91 | + // } | ||
92 | + var url1 = search(rec_song[0]) | ||
93 | + res.json({link: url1}) | ||
94 | + //document.write(rec_song) | ||
95 | + | ||
35 | }); | 96 | }); |
36 | 97 | ||
37 | -//메인 페이지 | 98 | +const getHTML = async(genre) => { |
38 | -app.get('/', function (req, res) { | 99 | + try{ |
39 | - fs.readFile('first.html', function(error, data) { | 100 | + return await get(genre) |
40 | - res.writeHead(200, { 'Content-Type': 'text/html' }); | 101 | + }catch(err) { |
41 | - res.end(data); | 102 | + console.log(err); |
103 | + } | ||
104 | +} | ||
105 | +const parsing = async(genre) => { | ||
106 | + const html = await getHTML(genre); | ||
107 | + const $ = cheerio.load(html.data); | ||
108 | + const $TitleList = $("div.ellipsis.rank01"); | ||
109 | + | ||
110 | + | ||
111 | + let Titles = []; | ||
112 | + $TitleList.each((index, node) => { | ||
113 | + const title = $(node).find("a").text(); | ||
114 | + Titles[Titles.length] = title; | ||
42 | }); | 115 | }); |
43 | -}); | ||
44 | 116 | ||
45 | -//로그인 페이지 | 117 | + let Titles5 = []; |
46 | -app.get('/login',function(req, res) { | 118 | + for(i = 0; i <= 4; i++){ |
47 | - fs.readFile('login.html', function(error, data) { | 119 | + Titles5.push(Titles[i]) |
48 | - res.writeHead(200, { 'Content-Type': 'text/html'}); | 120 | + }; |
49 | - res.end(data); | 121 | + |
50 | - }) | 122 | + console.log(Titles5); |
51 | -}); | 123 | + return(Titles5); |
124 | +} | ||
52 | 125 | ||
126 | +const parsing_exception = (genre) => { // 'snow' 또는 'classic' 에만 작동합니다. | ||
127 | + snow = ['눈사람', '십이월 이십오일의 고백', '첫 눈', '첫눈처럼 너에게 가겠다', '겨울사랑', '눈꽃', '사월의 눈', '코끝에 겨울', '눈이 내린다', '새겨울', '공드리', | ||
128 | +'눈이 오네', '이번 겨울', 'I Miss You', '나의 옛날 이야기', '너의 모든 순간', '내 생에 아름다운', '너를', '눈의꽃', '야생화']; | ||
53 | 129 | ||
130 | + classic = ['G선상의 아리아', '트로이메라이', '무언가', '백조', '세레나데', '울게하소서', '카발레리아 루스티카나', '사랑의 인사', '보칼리제', '뱃노래', | ||
131 | +'안단테 칸타빌레', '월광의 소나타', '미뉴엣 G장조', '엘리제를 위하여', '로망스']; | ||
54 | 132 | ||
55 | -//로그인 인증 (Passport) | 133 | + function shuffleArray(array) { // array의 요소들을 임의로 섞어주는 함수 |
56 | -passport.use(new LocalStrategy({ | 134 | + array.sort(() => Math.random() - 0.5); |
57 | - //로그인 페이지 input 태그 내 name | ||
58 | - usernameField: 'email', | ||
59 | - passwordField: 'password' | ||
60 | - }, | ||
61 | - (id, password, done)=>{ | ||
62 | - console.log(id,password); | ||
63 | - //회원 정보가 한개이상 있을때 | ||
64 | - if(user){ | ||
65 | - console.log(user); | ||
66 | - | ||
67 | - //아이디가 다를때 | ||
68 | - if (id !== user.email) | ||
69 | - return done(null, false, { message: '아이디가 다릅니다' }); | ||
70 | - //비밀번호가 다를때 | ||
71 | - else if (password !== user.password) | ||
72 | - return done(null, false, { message: '비번이 다릅니다' }); | ||
73 | - //아이디, 비밀번호 모두 맞을 경우 | ||
74 | - return done(null, user); | ||
75 | } | 135 | } |
76 | -})); | 136 | + shuffleArray(snow); //실행할 때마다 snow와 classic에 들어있는 요소들을 랜덤으로 배치 |
137 | + shuffleArray(classic); | ||
77 | 138 | ||
78 | -//로그인 처리 (Passport) | 139 | + let snow5 = [];// 그 중 앞에서 5개를 뽑아 제공 |
79 | -app.post('/login', | 140 | + let classic5 = []; |
80 | -passport.authenticate('local', { | 141 | + for(i = 0; i <= 4; i++){ |
142 | + snow5.push(snow[i]) | ||
143 | + }; | ||
81 | 144 | ||
82 | - successRedirect: '/main', | 145 | + for(i = 0; i <= 4; i++){ |
83 | - failureRedirect: '/login' | 146 | + classic5.push(classic[i]) |
84 | -})); | 147 | + }; |
85 | 148 | ||
149 | + if(genre == 'snow'){ | ||
150 | + console.log(snow5); // console.log() 는 값 시험용으로 우선 넣어두었습니다. | ||
151 | + return(snow5); | ||
152 | + }else if(genre == 'classic'){ | ||
153 | + console.log(snow5); // | ||
154 | + return(classic5); | ||
155 | + }else{ | ||
156 | + console.log("input value error(The input value is snow or classic)"); | ||
157 | + } | ||
158 | +} | ||
86 | 159 | ||
87 | -//회원가입 페이지 Get | 160 | +function random_5_Select(array){ //사용시 array1 = random_5_Select(array1); 이렇게 해주면 됨 |
88 | -app.get('/join',function(req, res) { | 161 | + array.sort(() => Math.random() - 0.5); |
89 | - fs.readFile('register.html', function(error, data) { | 162 | + array.splice(5); |
90 | - res.writeHead(200, { 'Contect-Type': 'text/html'}); | 163 | + return array; |
91 | - res.end(data); | 164 | +} |
92 | - }) | ||
93 | -}); | ||
94 | 165 | ||
95 | -app.get('/main',function(req, res) { | 166 | +function search(word) { |
96 | - fs.readFile('main.html', function(error, data) { | 167 | + youtube.search(word, limit, function (err, result) { // 검색 실행 |
97 | - res.writeHead(200, { 'Contect-Type': 'text/html'}); | 168 | + if (err) { console.log(err); return; } // 에러일 경우 에러공지하고 빠져나감 |
98 | - res.end(data); | ||
99 | - }) | ||
100 | -}); | ||
101 | 169 | ||
102 | -//회원가입 | 170 | + //console.log(JSON.stringify(result, null, 2)); // 받아온 전체 리스트 출력 |
103 | -var user = {}; | 171 | + |
104 | -app.post('/join',(req,res) =>{ | 172 | + var items = result["items"]; // 결과 중 items 항목만 가져옴 |
173 | + var it = items[0]; | ||
174 | + var video_id = it["id"]["videoId"]; | ||
175 | + var url = "https://www.youtube.com/watch?v=" + video_id; | ||
176 | + console.log(url); | ||
177 | + return url; | ||
178 | + | ||
179 | + }); | ||
180 | +} | ||
181 | + | ||
182 | +// if('구현: 음악 추천하기 버튼 누름'){ | ||
183 | +// if(WeatherCondition===Thunderstorm){ | ||
184 | +// rec_Song.concat(parsing(url_ballad), parsing(url_RNB_kr, parsing(url_RNB_us))); | ||
185 | +// rec_song = random_5_Select(rec_song); | ||
186 | +// } | ||
187 | +// if(WeatherCondition===Drizzle){ | ||
188 | +// rec_Song.concat(parsing(url_ballad), parsing(url_RNB_kr, parsing(url_RNB_us))); | ||
189 | +// rec_song = random_5_Select(rec_song); | ||
190 | +// } | ||
191 | +// if(WeatherCondition===Rain){ | ||
192 | +// rec_Song.concat(parsing(url_ballad), parsing(url_RNB_kr, parsing(url_RNB_us))); | ||
193 | +// rec_song = random_5_Select(rec_song); | ||
194 | +// } | ||
195 | +// if(WeatherCondition===Clear){ | ||
196 | +// rec_Song.concat(parsing(url_hiphop_kr), parsing(url_hiphop_us), parsing(url_dance), parsing(url_rock_kr), parsing(url_rock_us)); | ||
197 | +// rec_song = random_5_Select(rec_song); | ||
198 | +// } | ||
199 | +// if(WeatherCondition===Clouds){ | ||
200 | +// rec_Song.concat(parsing(url_pop), parsing(url_RNB_kr), parsing(url_RNB_us), parsing(url_indie)); | ||
201 | +// rec_song = random_5_Select(rec_song); | ||
202 | +// } | ||
203 | +// if(WeatherCondition===Snow){rec_Song.concat(parsing_exception('snow'));} | ||
204 | +// if(WeatherCondition===Mist){rec_Song.concat(parsing(url_newage));} | ||
205 | +// if(WeatherCondition===Fog){rec_Song.concat(parsing(url_newage));} | ||
206 | + | ||
207 | +// //밑 4개 종류의 날씨는 거의 나올 확률이 없으므로 그냥 별 의미는 없이 newage장르로 매치함. | ||
208 | +// if(WeatherCondition===Smoke){rec_Song.concat(parsing(url_newage));} | ||
209 | +// if(WeatherCondition===Haze){rec_Song.concat(parsing(url_newage));} | ||
210 | +// if(WeatherCondition===Dust){rec_Song.concat(parsing(url_newage));} | ||
211 | +// if(WeatherCondition===Sand){rec_Song.concat(parsing(url_newage));} | ||
212 | + | ||
213 | +// document.write(rec_song) | ||
214 | +// } | ||
105 | 215 | ||
106 | - user.email = req.body.email; | ||
107 | - user.password = req.body.password; | ||
108 | - user.name = req.body.name; | ||
109 | 216 | ||
110 | - //로그인 페이지로 이동 | ||
111 | - res.redirect('/login'); | ||
112 | -}); | ||
113 | 217 | ||
114 | -//로그 아웃 처리 | 218 | + |
115 | -app.get('/logout',(req,res)=>{ | 219 | + //res.json({link: "결과 문자열"}) |
116 | - //passport 정보 삭제 | 220 | +}) |
117 | - req.logout(); | 221 | + |
118 | - //서버측 세션 삭제 | 222 | + |
119 | - req.session.destroy(()=>{ | 223 | + |
120 | - //클라이언트 측 세션 암호화 쿠키 삭제 | 224 | +//미들웨어 리스트 |
121 | - res.cookie('connect.sid','',{maxAge:0}); | 225 | +// app.use(urlencoded({extended:false})); |
122 | - res.redirect('/'); | 226 | +// app.use(session({ |
227 | +// secret: 'secret key', | ||
228 | +// resave: false, | ||
229 | +// saveUninitialized: false, | ||
230 | +// store : new fileStore() | ||
231 | +// })); | ||
232 | +// app.use(initialize()); | ||
233 | +// app.use(_session()); | ||
234 | +// app.use(static('public')); | ||
235 | +// app.use(_urlencoded({extended:false})); | ||
236 | + | ||
237 | +//사용자 정보 session 읽기, 쓰기 | ||
238 | +// serializeUser(function(user, done) { //쓰기 | ||
239 | +// done(null, user.email); | ||
240 | +// }); | ||
241 | + | ||
242 | +// deserializeUser(function(id, done) { //읽기 | ||
243 | +// done(null, id); | ||
244 | +// }); | ||
245 | + | ||
246 | +//메인 페이지 | ||
247 | +app.get('/', function (req, res) { | ||
248 | + readFile('first.html', function(error, data) { | ||
249 | + res.writeHead(200, { 'Content-Type': 'text/html' }); | ||
250 | + res.end(data); | ||
123 | }); | 251 | }); |
124 | }); | 252 | }); |
125 | 253 | ||
126 | 254 | ||
255 | + | ||
127 | //포트 연결 | 256 | //포트 연결 |
128 | app.listen(3000, function() { | 257 | app.listen(3000, function() { |
129 | console.log('http://localhost:3000'); | 258 | console.log('http://localhost:3000'); | ... | ... |
-
Please register or login to post a comment