서주원

Final commit

......@@ -5,20 +5,19 @@ let cardEnUS=[]
let cardKoKR=[]
//카드 덱 ID와 카드 정보를 받아와, 카드별로 dbfId랑 매칭 시킨 후, card 테이블에 추가
//return: 없음
exports.AddCards=(deckId,cards)=>{
fs.readFile('cardskoKR.json',(err,data)=>{
if (err) throw err
cardKoKR=JSON.parse(data)
})
return new Promise((resolve,reject)=>{
//전체 카드 읽어 오기
fs.readFile('cardsenUS.json',(err,data)=>{
if (err) throw err
cardEnUS=JSON.parse(data)
//mysql 연결
mysql.getConnection((err,connection)=>{
if(err) throw err
//카드별로 dbfId 찾기
for (let i=0;i<cards.length;i++) {
let cardCost = cards[i].cardCost
let cardName = cards[i].cardName
......@@ -27,12 +26,13 @@ exports.AddCards=(deckId,cards)=>{
for (let i = 0; i < cardEnUS.length; i++) {
if (cardEnUS[i].name === cardName) {
cardId = cardEnUS[i].dbfId
//single quote 처리
cardName=cardName.replace('\'','\'\'')
break
}
}
//카드 추가
connection.query(`insert into card (deckId,cardId,cardCost,cardName,cardNum) values (\'${deckId}\',\'${cardId}\',\'${cardCost}\',\'${cardName}\',\'${cardNum}\')`, (err, results, fields) => {
//
if (err) throw err
})
}
......
const mysql=require('../../database/mysql')
//덱 ID를 바탕으로 해당 덱에 속해있는 모든 카드 반환
//return: json array
exports.GetCardId=(deckId)=>{
return new Promise((resolve,reject)=>{
mysql.getConnection((err,connection)=>{
......
......@@ -5,9 +5,13 @@ const fs=require('fs')
const ejs=require('ejs')
let globalMulligan
let globalDecks
//result.ejs 렌더링 전 수행됨. 현재 덱 ID와 상대 직업을 가지고 상대의 점유율 상위 3개 덱과, 내 덱의 추천 멀리건 출력
//return : 렌더링 된 result.ejs
exports.GetResult=(req,res)=>{
const deckId=req.session.deckId
const opponentClass=req.session.opponentClass
//덱 ID와 상대 직업 정보 체크
const DataCheck=()=>{
return new Promise((resolve,reject)=>{
if (!deckId || !opponentClass){
......@@ -19,13 +23,15 @@ exports.GetResult=(req,res)=>{
resolve()
})
}
//현재 덱ID를 바탕으로 카드정보 가져오기
const GetCardId=()=>{
return getCardId.GetCardId(deckId)
}
//가져온 카드 정보를 바탕으로, hsreplay.net에서, 덱 검색하기, 검색한 결과의 html을 반환
const GetMulContent=(cardIds)=>{
cardIds=JSON.stringify(cardIds)
cardIds=JSON.parse(cardIds)
//검색을 위한 쿼리스트링
let idInQuery=cardIds[0].cardId
for(let i=1;i<cardIds.length ;i++){
idInQuery+= '%2C'+cardIds[i].cardId
......@@ -50,7 +56,7 @@ exports.GetResult=(req,res)=>{
resolve(asyncFunc())
})
}
//검색한 html을 가지고, 검색결과로 부터 덱의 url 파싱
const GetDeckHref=(content)=>{
return new Promise((resolve,reject)=>{
const $=cheerio.load(content)
......@@ -60,6 +66,7 @@ exports.GetResult=(req,res)=>{
resolve(deckHref)
})
}
//덱의 url을 이용, 해당 덱의 정보를 나타내는 페이지 불러온 후 html로 반환
const GetDeckContent=(href)=>{
return new Promise((resolve,reject)=>{
const asyncFunc=async ()=>{
......@@ -81,6 +88,7 @@ exports.GetResult=(req,res)=>{
resolve(asyncFunc())
})
}
//받아온 html에서 카드 이름과 멀리건 부분 추출
const GetMulligan=(content)=>{
return new Promise((resolve,reject)=>{
const $=cheerio.load(content)
......@@ -90,17 +98,20 @@ exports.GetResult=(req,res)=>{
for(let i=0;i<cardNames.length;i++){
let cardName=$(cardNames[i]).text()
let cardWinRate=$(cardWinRates[6*i]).text()
//문자 삭제하고, 멀리건의 승률이 숫자로만 나타나도록
cardWinRate=cardWinRate.replace('▼','')
cardWinRate=cardWinRate.replace('▲','')
cardWinRate=cardWinRate.replace('%','')
cards.push({cardName:cardName,cardWinRate:cardWinRate})
}
//카드를 멀리건 승률 순서대로 정렬
cards.sort((a,b)=>{
return a.cardWinRate<b.cardWinRate ? 1:-1
})
resolve(cards)
})
}
//상대 직업을 가지고 hsreplay.net에서 검색, html로 반환
const GetOppContent=()=>{
return new Promise((resolve,reject)=>{
const asyncFunc=async ()=>{
......@@ -122,7 +133,7 @@ exports.GetResult=(req,res)=>{
resolve(asyncFunc())
})
}
//받아온 html로부터 덱의 이름, 게임 횟수 추출
const GetDeckInfo=(content)=>{
return new Promise((resolve,reject)=>{
const $=cheerio.load(content)
......
//result 출력 전, 선택한 상대 직업을 세션에 저장
//return: response status code
exports.SetOpponentClass=(req,res)=>{
const opponentClass=req.body.opponentClass
const DataCheck=()=>{
......
const mysql=require('../../database/mysql')
//덱 추가
//return: 없음
exports.AddDeck=(deckOwner,deckTitle,deckCode)=>{
return new Promise((resolve,reject)=> {
mysql.getConnection((err, connection) => {
......@@ -7,7 +8,7 @@ exports.AddDeck=(deckOwner,deckTitle,deckCode)=>{
connection.query(`insert into deck (deckOwner,deckTitle,deckCode) values (\'${deckOwner}\',\'${deckTitle}\',\'${deckCode}\');`, (err, results, fields) => {
if (err) throw err
connection.release()
resolve(results)
resolve()
})
})
})
......
......@@ -2,6 +2,8 @@ const request=require('request')
const iconv=require('iconv-lite')
const charset=require('charset')
//덱 추가시 deck.codes로부터 덱 코드가 의미하는 덱 정보 페이지 크롤링
//return: html
exports.Crawl=(deckCode)=>{
return new Promise((resolve,reject)=>{
request({
......
const mysql=require('../../database/mysql')
//덱의 주인과 덱 이름을 가지고 DeckId값 반환
//return: deckId
exports.GetDeckId=(deckOwner,deckTitle)=>{
return new Promise((resolve,reject)=>{
mysql.getConnection((err,connection)=>{
if (err) throw err
connection.query(`select * from deck where deckOwner=\'${deckOwner}\' and deckTitle=\'${deckTitle}\'`,(err,results,field)=>{
if (err) throw err
//console.log('result in getDeckId'+results[0])
connection.release()
resolve(results[0].id)
})
......
......@@ -4,13 +4,16 @@ const addCards=require('../card/addCards')
const addDeck=require('./addDeck')
const getDeckId=require('./getDeckId')
//새로운 덱 추가
//return : response status code
exports.NewDeck=(req,res)=>{
const deckOwner=req.session.sid
//덱 이름이 주어지지 않았다면 시간으로 저장
const deckTitle=req.body.deckTitle || new Date()
let deckCode=req.body.deckCode
let cards=[]
//덱 코드가 입력 되었는지 체크
const DataCheck=()=>{
return new Promise((resolve,reject)=>{
if(!deckCode){
......@@ -22,32 +25,39 @@ exports.NewDeck=(req,res)=>{
else resolve()
})
}
//덱 코드를 가지고 deck.codes 크롤링, 성공시 html을 reolve해줌
const CrawlPage=()=>{
return crawler.Crawl(deckCode)
}
//받아온 html로부터 덱을 구성하는 카드정보 추출
const DeckCrawl=(result)=>{
const $=cheerio.load(result)
//카드의 코스트 배열
let cardCosts=$('div.hs-tile-info').children('.hs-tile-info-left.mdc-list-item__start-detail')
//카드의 이름 배열
let cardNames=$('div.hs-tile-info').find('span').find('span')
//카드가 들어간 개수 배열
let cardNums=$('div.hs-tile-info').children('.hs-tile-info-right.mdc-list-item__end-detail')
for(let i=0;i<cardNames.length;i++) {
let cardCost=$(cardCosts[i]).text()
let cardName=$(cardNames[i]).text()
let cardNum=$(cardNums[i]).text()
//카드의 개수가 1개라면, 웹에서는 카드의 개수를 공백으로 표현함.
//카드의 개수가 1개가 아니라 2개여도 양 옆 공백이 상당하기 때문에,
//trim()을 우선 사용하고, 결과에 대해서 문자열을 다듬음
if(cardNum.trim()==='')
cardNum='1'
else
cardNum=cardNum.trim()
cards.push({cardCost: cardCost, cardName: cardName, cardNum: cardNum})
}
//console.log(cards)
}
//deck 테이블에 새로운 row 추가
const AddDeck=()=>{
const asyncAddDeck=async ()=>{
try{
const results=await addDeck.AddDeck(deckOwner,deckTitle,deckCode)
await addDeck.AddDeck(deckOwner,deckTitle,deckCode)
}
catch (err) {
throw err
......@@ -55,7 +65,7 @@ exports.NewDeck=(req,res)=>{
}
return asyncAddDeck()
}
//카드를 추가하기 위해 방금 추가한 덱 id를 가져옴
const GetId=()=>{
const asyncGetDeckId=async ()=>{
try{
......@@ -68,6 +78,7 @@ exports.NewDeck=(req,res)=>{
}
return asyncGetDeckId()
}
//card 테이블에 새로운 여러개의 row 추가
const AddCards=(deckId)=>{
return addCards.AddCards(deckId,cards)
}
......
const mysql=require('../../database/mysql')
//사용자의 아이디를 가지고 유저 검색,
//return: 사용자가 있으면, 사용자 정보
// 사용자가 없으면, 없음
exports.findById=(userId)=>{
return new Promise((resolve,reject)=>{
mysql.getConnection((err,connection)=>{
......
const findById=require('./findById')
const bcrypt=require('bcrypt-nodejs')
//입력한 아이디와 비밀번호를 가지고 로그인
exports.Login=(req,res)=>{
const userId=req.body.userId
const password=req.body.password
//아이디와 비밀번호가 존재 하는지 체크
const DataCheck=()=>{
return new Promise((resolve,reject)=>{
if(!userId || !password){
......@@ -16,7 +17,7 @@ exports.Login=(req,res)=>{
else resolve()
})
}
//이 아이디로 등록된 사용자가 있는 지 체크
const IdCheck=()=>{
let user={}
const findUser= async ()=>{
......@@ -30,7 +31,7 @@ exports.Login=(req,res)=>{
}
return findUser()
}
//해당 유저의 비밀번호와 입력된 비밀번호가 같은 지 체크
const PwCheck=(user)=>{
if (user[0]==null){
return Promise.reject({
......@@ -38,6 +39,7 @@ exports.Login=(req,res)=>{
message:'id wrong'
})
}
//암호화 모듈을 사용했기 때문에, 서로 비교하는 함수를 써야함
if(bcrypt.compareSync(password,user[0].password)){
req.session.sid=userId
req.session.save(()=>{
......
const findById=require('./findById')
const mysql=require('../../database/mysql')
const bcrypt=require('bcrypt-nodejs')
//입력된 아이디와 비밀번호를 가지고 회원가입.
//비밀번호 확인은 프론트 단에서 이루어 졌음.
//return: response status code
exports.SignUp=(req,res)=>{
const userId=req.body.userId
const password=req.body.password
//아이디와 비밀번호가 존재하는 지 체크
const DataCheck=()=>{
return new Promise((resolve,reject)=>{
if(!userId || !password){
......@@ -16,6 +19,7 @@ exports.SignUp=(req,res)=>{
else resolve()
})
}
//해당 아이디로 등록한 회원이 있는 지 체크
const UserCheck=()=>{
let user={}
const findUser=async ()=>{
......@@ -29,7 +33,7 @@ exports.SignUp=(req,res)=>{
}
return findUser()
}
//아이디가 중복되지 않았다면 회원가입 진행
const SignUp=(user)=>{
if(user[0]!=null){
return Promise.reject({
......@@ -37,6 +41,7 @@ exports.SignUp=(req,res)=>{
message:'User Already Exists'
})
}
//비밀번호는 암호화 하여 데이터베이스에 저장
const hash=bcrypt.hashSync(password,bcrypt.genSaltSync(10),null)
mysql.getConnection((err,connection)=>{
if(err) throw err
......
......@@ -45,7 +45,7 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Who Are You?</a>
<a class="navbar-brand" href="/main">Who Are You?</a>
</div>
<div class="navbar-collapse collapse" id="navbar" aria-expanded="false" style="height: 1px;">
<ul class="nav navbar-nav">
......
......@@ -18,32 +18,6 @@
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
let mulligan,opponentDecks
$.ajax({
type:'GET',
url:'/api/card/getmulligan',
success:function(result){
mulligan=result
$('#yourMulligan').add('<ul>')
for(let i=0;i<mulligan.length;i++){
$('#yourMulligan').add(`<li><h4>카드 이름:${mulligan[i]['cardName']}</h4><br><h5>멀리건 승률:${mulligan[i]['cardWinRate']}</h5></li>`)
}
$('#yourMulligan').add('</ul>')
}
})
$.ajax({
type:'GET',
url:'/api/card/getopponent',
success:function(result){
opponentDecks=result
$('#opponentDecks').add('<ul>')
for(let i=0;i<opponentDecks.length;i++){
$('#opponentDecks').add(`<li><h4>덱 이름:${opponentDecks[i]['deckTitle']}</h4><br><h5>30일간 플레이 수:${opponentDecks[i]['deckGame']}</h5></li>`)
}
$('#opponentDecks').add('</ul>')
}
})
$('#logoutButton').click(function(){
$.ajax({
type:'POST',
......@@ -91,11 +65,37 @@
<br>
<br>
<h3 class="form-signin-heading">상대편의 주요 덱</h3>
<div id="opponentDecks"></div>
<div id="opponentDecks">
<table class="table" style="text-align: center;">
<thead>
<td>덱 이름</td>
<td>플레이 수</td>
</thead>
<tbody>
<tr>
<td><a class="list-group-item">덱이름1</a></td>
<td><a class="list-group-item">10000</a></td>
</tr>
</tbody>
</table>
</div>
<br>
<br>
<h3 class="form-signin-heading">내 덱의 추천 멀리건</h3>
<div id="yourMulligan"></div>
<div id="yourMulligan">
<table class="table" style="text-align: center;">
<thead>
<td>카드 이름</td>
<td>멀리건 승률</td>
</thead>
<tbody>
<tr>
<td><a class="list-group-item">카드이름1</a></td>
<td><a class="list-group-item">59.8</a></td>
</tr>
</tbody>
</table>
</div>
<br>
<br>
<div class="row">
......