SeungJun Baek

프로젝트 완성

{
"exec":"npx babel-node src/backend/server.js"
"exec":"npx babel-node src/backend/init.js"
}
......
This diff is collapsed. Click to expand it.
......@@ -16,8 +16,12 @@
},
"dependencies": {
"babel-loader": "^8.2.5",
"bcrypt": "^5.0.1",
"connect-mongo": "^4.6.0",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"express-session": "^1.17.3",
"mongoose": "^6.3.5",
"node-fetch": "^2.6.1",
"pug": "^3.0.2"
}
......
export const home = (req,res)=>{
return res.render("home",{siteTitle: "movie!",pageTitle:"home Page!"});
import fetch from"node-fetch";
import User from "../../models/User"
import bcrypt from "bcrypt"
export const home = async(req,res)=>{
const KEY= process.env.API_KEY
const data = await fetch(`https://api.themoviedb.org/3/trending/movie/week?api_key=${KEY}`,{
method:"GET",
})
const movies = await data.json();
return res.render("home",{siteTitle: "movie!",pageTitle:"home Page!",movies: movies.results});
}
export const getJoin = (req,res) =>{
res.render('join.pug',{pageTitle:"Join!",siteTitle:"movie!"})
}
export const postJoin = async (req,res) =>{
const { email,
username,
password,
passwordcheck, } = req.body;
const pageTitle = "Join";
if (password !== passwordcheck) {
return res.status(400).render("join.pug", {
pageTitle,
errorMessage: "Password confirmation does not match.",
});
}
const exists = await User.exists({ $or: [{ username }, { email }] });
if (exists) {
return res.status(400).render("join", {
pageTitle,
errorMessage: "This username/email is already taken.",
});
}
try {
await User.create({
username,
email,
password,
});
return res.redirect("/login");
} catch(error){
return res.status(400).res.render("join", {
pageTitle: "Upload Video" ,
errorMessage: error._message,
});
}
}
export const join= (req,res) =>{
return res.send("hello this is joinpage!");
export const getLogin = (req,res)=>{
return res.render("login",{siteTitle:"movie!",pageTitle:"Login!"})
}
export const login = (req,res)=>{
return res.send("hello this is login!");
export const postLogin = async (req,res) =>
{
const PAGETITLE = "Login"
const {username,password} = req.body;
console.log(username,password)
const user = await User.findOne({username});
console.log(user)
if(!user){
return res.status(400).render("login",{pageTitle:PAGETITLE,error:"An account with that username is not found"})
}
if (user.isO_Auth)
return res.status(400).render("login",{pageTitle:PAGETITLE,error:"Please login with Github"})
const ok = await bcrypt.compare(password,user.password);
if(!ok){
return res.status(400).render("login",{pageTitle:PAGETITLE,error:"something wrong..."})
}
req.session.loggedIn = true;
req.session.user = user;
return res.redirect('/');
}
export const startGithubLogin = (req,res) =>
{
const baseURL = `https://github.com/login/oauth/authorize`
const config = {
client_id: process.env.O_Auth_client_id,
allow_signup:false,
scope:"read:user user:email"
}
const params = new URLSearchParams(config).toString();
const finalURL = `${baseURL}?${params}`
console.log(finalURL);
return res.redirect(finalURL);
}
export const finishGithubLogin = async (req,res) =>
{
const config = {
client_id: process.env.O_AUTH_CLIENT_ID,
client_secret : process.env.O_Auth_scret,
code: req.query.code
}
const params = new URLSearchParams(config).toString();
const baseURL = `https://github.com/login/oauth/access_token`;
const finalURL = `${baseURL}?${params}`;
console.log(req.query);
const data = await fetch(finalURL,{
method:"POST",
headers:{
Accept: "application/json",
}
});
const token = await data.json();
if("access_token" in token)
{
const {access_token} = token;
const apiUrl = "https://api.github.com"
const getUserData = await fetch(`${apiUrl}/user`,{
method:"GET",
headers:{
Authorization: `token ${access_token}`
}
});
const emailData = await (
await fetch(`${apiUrl}/user/emails`,{
method:"GET",
headers:{
Authorization: `token ${access_token}`
}
})
).json();
const emailObj = emailData.find((email) => email.primary === true && email.verified === true);
if(!emailObj){
return res.status(400).redirect('/login');
}
let user = await User.findOne({email: emailObj.email});
if(!user){
user = await User.create({
email:emailObj.email,
username:userData.login,
password:"",
isO_Auth: true,
});
}
req.session.loggedIn = true,
req.session.user = user;
return res.redirect("/");
}else{
res.status(400).redirect("/login")
}
}
\ No newline at end of file
......
......@@ -13,6 +13,34 @@ export const showMovies = (req,res) =>{
res.send("movie home");
}
export const movieInformation = (req,res)=>{
res.send("movie detail");
}
\ No newline at end of file
export const movieInformation = async (req,res)=>{
const {id}= req.params;
const KEY= process.env.API_KEY
const data = await fetch(`https://api.themoviedb.org/3/movie/${id}?api_key=${KEY}&language=ko-KR`)
const info = await data.json();
res.render('detail.pug',{siteTitle:"movie!",pageTitle:`${info.original_title}`,info})
}
export const getDiscover = (req, res)=>{
res.render('discover',{siteTitle:"movie!"})
}
export const postDiscover = async (req, res)=>{
const {year, genre,rating} = req.body
console.log(year,genre,rating)
const KEY= process.env.API_KEY
const genreData = await fetch(`https://api.themoviedb.org/3/genre/movie/list?api_key=${KEY}&language=en-US`)
const genres = await genreData.json()
const target = genres.genres.filter(index => index.name === genre)
const genreId = target[0].id
const moviesData = await fetch(`
https://api.themoviedb.org/3/discover/movie?api_key=${KEY}&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&year=${year}&vote_average.gte=${rating}&with_genres=28%2C12&with_watch_monetization_types=flatrate`,
{
method:"GET"
})
const Result = await moviesData.json()
const movies = Result.results
console.log(movies)
return res.render(`discoverResult.pug`,{siteTitle:"movie!",movies})
}
......
export const userId = (req,res) =>{
//getMovies();
res.send("user page");
export const logout =(req,res)=>{
req.session.destroy();
return res.redirect("/")
}
export const userLikemovie = (req,res) =>{
//getMovies();
res.send("user's favorite");
}
......
import mongoose from "mongoose";
mongoose.connect(process.env.DB_URL)
const db = mongoose.connection;
db.on("error",(error)=>console.log("DB Error",error))
db.once("open",()=>console.log("DB is Ready!"))
\ No newline at end of file
import "dotenv/config"
import "./db"
import "../models/User"
import app from "./server";
console.log("hihihihihih")
const PORT = 3000
app.listen(PORT,() => console.log(`The Server is running on http://localhost:${PORT}`));
export const editLocals = (req,res,next) =>{
res.locals.loggedIn = Boolean(req.session.loggedIn)
res.locals.loggedInUser = req.session.user;
next();
}
\ No newline at end of file
import express from "express";
import {home,join,login} from "../controllers/globalController"
import {getJoin, getLogin, home, postJoin, postLogin} from "../controllers/globalController"
import { logout } from "../controllers/usersController";
const globalRouter = express.Router();
globalRouter.get('/',home);
globalRouter.get('/join',join);
globalRouter.get('/login',login);
globalRouter.get("/logout",logout)
globalRouter.route('/join').get(getJoin).post(postJoin)
globalRouter.route('/login').get(getLogin).post(postLogin)
export default globalRouter
\ No newline at end of file
......
import express from "express";
import { showMovies, movieInformation } from "../controllers/movieController";
import { showMovies, movieInformation, getDiscover, postDiscover } from "../controllers/movieController";
const movieRouter = express.Router();
movieRouter.get('/',showMovies);
movieRouter.get('/:id', movieInformation);
movieRouter.get('/:id(\\d+)', movieInformation);
movieRouter.route('/discover/').get(getDiscover).post(postDiscover)
export default movieRouter;
\ No newline at end of file
......
import express from "express";
import { userId, userLikemovie } from "../controllers/usersController";
import { finishGithubLogin, startGithubLogin } from "../controllers/globalController";
const userRouter = express.Router();
userRouter.get('/:id(\\d+)', userId);
userRouter.get('/likemovie', userLikemovie);
userRouter.get("/github/start",startGithubLogin)
userRouter.get("/github/finish",finishGithubLogin)
export default userRouter
\ No newline at end of file
......
......@@ -2,14 +2,29 @@ import express from "express"
import global from "./routers/globalRouter";
import movies from "./routers/movieRouter";
import users from "./routers/userRouter";
import session from "express-session";
import MongoStore from "connect-mongo";
import { editLocals } from "./middlewares";
const PORT = 3000
const app = express();
app.use(express.json())
app.use(express.urlencoded({extend: true}))
app.use(session({
secret:process.env.COOKIE_SCRET,
resave:false,
saveUninitialized:false,
store: MongoStore.create({mongoUrl: process.env.DB_URL})
}))
app.set('view engine',"pug");
app.set("views",process.cwd() +"/src/views");
app.use(editLocals);
app.use('/',global);
app.use('/movies',movies);
app.use('/users',users)
app.listen(PORT,() => console.log(`The Server is running on http://localhost:${PORT}`));
export default app
......
import bcrypt from "bcrypt";
import mongoose from "mongoose";
const userSchema = new mongoose.Schema({
email: { type: String, required: true, unique: true },
username: { type: String, unique: true },
password: { type: String, },
likeMovies: [{type: String}],
isO_Auth: {type:Boolean,default:false}
});
userSchema.pre('save', async function(){
console.log("Users password:", this.password);
this.password = await bcrypt.hash(this.password, 5);``
console.log("Users password:", this.password);
})
const User = mongoose.model("User", userSchema);
export default User;
\ No newline at end of file
extends layout.pug
include mixins/trending.pug
block content
div
h1=pageTitle
img(src=`https://www.themoviedb.org/t/p/w600_and_h900_bestv2${info.poster_path}`)
div
span=info.overview
br
span
a(href=`https://www.themoviedb.org/movie/${info.id}`) The movie DB에서 영화정보 보기 →
\ No newline at end of file
extends layout.pug
block content
form(method="POST")
select(name="year")
option(value="" selected) 년도선택
option(value="2017") 2017
option(value="2018") 2018
option(value="2019") 2019
option(value="2020") 2020
option(value="2021") 2021
option(value="2022") 2022
select(name="genre")
option(value="") 장르 선택
option(value="Action") 액션
option(value="Adventure") 어드벤쳐
option(value="Animation") 애니메이션
option(value="Comedy") 코미디
option(value="Crime") 범죄
option(value="Documentary") 다큐
option(value="Drama") 드라마
option(value="Family") 가족영화
option(value="Fantasy") 판타지
option(value="History") 역사
option(value="Horror") 호러
option(value="Music") 음악
option(value="Mystery") 미스터리
option(value="Romance") 로멘스
option(value="Science Fiction") 공상과학
option(value="TV Movie") Tv영화
option(value="Thriller") 스릴러
option(value="War") 전쟁
option(value="Western") 서부영화
select(name="rating")
option(value="") 평점 선택
option(value="5.0") 5.0
option(value="6.0") 6.0
option(value="7.0") 7.0
option(value="8.0") 8.0
option(value="9.0") 9.0
input(value="영화 검색!" type="submit")
extends layout.pug
include mixins/movies.pug
block content
div
h1 영화 검색 결과
+movies(movies)
\ No newline at end of file
extends layout.pug
include mixins/trending.pug
block content
div
h1=pageTitle
\ No newline at end of file
h1=pageTitle
small 이번주에 인기있는 영화들
+trending(movies)
\ No newline at end of file
......
extends layout.pug
block content
if errorMessage
h3=errorMessage
h1=pageTitle
form(method="POST")
input(name="email" placeholder="your email plz" required type="email")
input(name="username" placeholder="your nickname!" required)
input(name="password" placeholder="your password" required type="password")
input(name="passwordcheck" placeholder="passwowrd validation" required type="password")
input(value="join now!" type="submit")
hr
span
a(href="/login") you already have account? login now! →
\ No newline at end of file
extends layout.pug
block content
if errorMessage
h3=errorMessage
h1=pageTitle
form(method="POST")
input(name="username" placeholder="your username plz" required type="text")
input(name="password" placeholder="your password" required type="password")
input(value="login now!" type="submit")
hr
span
a(href="/join") you don't have account? Join now! →
a(href="/users/github/start") Continue with Github →
\ No newline at end of file
mixin movies(movies)
div
ul
each movie in movies
li
a(href=`/movies/${movie.id}`)=movie.title
\ No newline at end of file
mixin trending(movies)
div
ul
each movie in movies
li
a(href=`/movies/${movie.id}`)=movie.title
\ No newline at end of file
......@@ -4,4 +4,12 @@ header
li
a(href="/") Home
li
a(href="/movies") Movies
\ No newline at end of file
a(href="/movies/discover/") Movies
if loggedIn
li
a(href="/logout") logout
else
li
a(href="/login") login
li
a(href="/join") join
\ No newline at end of file
......