From cd77d7b21efe4ab3f920aced696eb57959e35acc Mon Sep 17 00:00:00 2001 From: Eng-M-Abdrabbou Date: Sat, 28 Sep 2024 15:50:39 +0400 Subject: [PATCH 01/27] added a watch functionality to userprofile.html and UPmovies.html and saved movie data in a session so it would be taken to the streaming page to play the movie there as requested. --- Client/UPmovies.html | 344 ++++++++++++++++++++++++++++++++++++++++ Client/UserProfile.html | 115 +++++++++++++- Client/movie2.html | 211 +++++++++++++++++++++--- Server/movie.js | 334 +++++++++++++++++++++++++++++++++----- 4 files changed, 933 insertions(+), 71 deletions(-) create mode 100644 Client/UPmovies.html diff --git a/Client/UPmovies.html b/Client/UPmovies.html new file mode 100644 index 0000000..23dc5ad --- /dev/null +++ b/Client/UPmovies.html @@ -0,0 +1,344 @@ + + + + + + + Products - StreamHub + + + + + + + + + + + + + +

Featured Movies:

+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Client/UserProfile.html b/Client/UserProfile.html index 6435c68..6dbf403 100644 --- a/Client/UserProfile.html +++ b/Client/UserProfile.html @@ -215,6 +215,7 @@
${movieInfo.title}
const userData = data.data; console.log(data.data); displayUserProfile(userData); + } else { console.error('Error:', data.message); } @@ -276,18 +277,120 @@

Movies:

const card = document.createElement('div'); card.className = 'movie-card'; card.innerHTML = ` - ${movieInfo.title} -
${movieInfo.title}
-

${movieInfo.description}

- + ${movieInfo.data.title} +
${movieInfo.data.title}
+

${movieInfo.data.description}

+ `; return card; } -function watchMovie(movieId) { - window.location.href = `/movie?id=${movieId}`; +function getUserIdFromSession() { + return new Promise((resolve, reject) => { + fetch('/profile', { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + }) + .then((response) => response.json()) + .then((data) => { + if (data.success) { + const userData = data.data; + console.log("User data received:", userData); + if (userData && userData.id) { + console.log("User ID found:", userData.id); + resolve(userData.id); + } else { + console.error('User ID not found in response'); + resolve(null); + } + } else { + console.error('Error:', data.message); + resolve(null); + } + }) + .catch((error) => { + console.error('Error fetching user profile:', error); + reject(error); + }); + }); } + + + + + + +// function watchMovie(movieId) { +// const userId = getUserIdFromSession(); +// console.log("User ID: and HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", userId); +// console.log("Sending request to prepare movie:", { movieId, userId }); +// +// fetch('/prepare-movie', { +// method: 'POST', +// headers: { +// 'Content-Type': 'application/json', +// }, +// body: JSON.stringify({ movieId, userId }), +// }) +// .then(response => response.json()) +// .then(data => { +// console.log("Received response:", data); +// if (data.success) { +// setTimeout(() => { +// window.location.href = '/movie'; +// }, 1000); +// } else { +// console.error('Error preparing movie:', data.message); +// alert('Error preparing movie: ' + data.message); +// } +// }) +// .catch(error => { +// console.error('Error:', error); +// alert('An error occurred: ' + error.message); +// }); +// } + + + +async function watchMovie(movieId) { + try { + const userId = await getUserIdFromSession(); + if (!userId) { + console.error('No user ID found. User might not be logged in.'); + alert('Please log in to watch the movie.'); + return; + } + + console.log("Sending request to prepare movie:", { movieId, userId }); + + const response = await fetch('/prepare-movie', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ movieId, userId }), + }); + + const data = await response.json(); + console.log("Received response:", data); + + if (data.success) { + setTimeout(() => { + window.location.href = '/movie'; + }, 1000); + } else { + console.error('Error preparing movie:', data.message); + alert('Error preparing movie: ' + data.message); + } + } catch (error) { + console.error('Error:', error); + alert('An error occurred: ' + error.message); + } +} + + + // Initialize the page fetchUserProfileAndRecommendations(); diff --git a/Client/movie2.html b/Client/movie2.html index 8706b46..93b2c93 100644 --- a/Client/movie2.html +++ b/Client/movie2.html @@ -5,7 +5,7 @@ - Products - StreamHub + watching - StreamHub @@ -45,29 +45,10 @@

Movies



- - - - - +
- - - -
@@ -145,11 +126,18 @@

Movies

-
-
-

+
+
+
+ + +
+ +
+ +
@@ -186,6 +174,181 @@

About

+ diff --git a/Server/movie.js b/Server/movie.js index ca95724..0c798a4 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -316,58 +316,58 @@ app.get('/searchMovies', async (req, res) => { // plan to start a session here, where when a user presses a mvies to watch it will be stored in the session and direct them to this page // where they can watch the video, the video path will be a variable in the session and the video info from the db too. -app.get("/video", function (req, res) { - // Ensure there is a range given for the video - const range = req.headers.range; - if (!range) { - return res.status(400).send("Requires Range header"); - } +// app.get("/video", function (req, res) { +// // Ensure there is a range given for the video +// const range = req.headers.range; +// if (!range) { +// return res.status(400).send("Requires Range header"); +// } - console.log('Range:', range); +// console.log('Range:', range); - // get video stats (about 61MB) - const videoPath = "uploads/movies/1726081504391.mp4"; +// // get video stats (about 61MB) +// const videoPath = "uploads/movies/1726081504391.mp4"; - if (!fs.existsSync(videoPath)) { - console.error(`Video file not found: ${videoPath}`); - return res.status(404).send("Video not found"); - } +// if (!fs.existsSync(videoPath)) { +// console.error(`Video file not found: ${videoPath}`); +// return res.status(404).send("Video not found"); +// } - const videoSize = fs.statSync(`${__dirname}/${videoPath}`).size; - // Parse Range - // Example: "bytes=32324-" - const CHUNK_SIZE = 10 ** 6; // 1MB - const start = Number(range.replace(/\D/g, "")); - const end = Math.min(start + CHUNK_SIZE, videoSize - 1); +// const videoSize = fs.statSync(`${__dirname}/${videoPath}`).size; +// // Parse Range +// // Example: "bytes=32324-" +// const CHUNK_SIZE = 10 ** 6; // 1MB +// const start = Number(range.replace(/\D/g, "")); +// const end = Math.min(start + CHUNK_SIZE, videoSize - 1); - console.log(`Streaming bytes ${start}-${end} of ${videoSize}`); +// console.log(`Streaming bytes ${start}-${end} of ${videoSize}`); - // Create headers - const contentLength = end - start + 1; - const headers = { - "Content-Range": `bytes ${start}-${end}/${videoSize}`, - "Accept-Ranges": "bytes", - "Content-Length": contentLength, - "Content-Type": "video/mp4", - }; +// // Create headers +// const contentLength = end - start + 1; +// const headers = { +// "Content-Range": `bytes ${start}-${end}/${videoSize}`, +// "Accept-Ranges": "bytes", +// "Content-Length": contentLength, +// "Content-Type": "video/mp4", +// }; - // HTTP Status 206 for Partial Content - res.writeHead(206, headers); +// // HTTP Status 206 for Partial Content +// res.writeHead(206, headers); - // create video read stream for this particular chunk - const videoStream = fs.createReadStream(videoPath, { start, end }); +// // create video read stream for this particular chunk +// const videoStream = fs.createReadStream(videoPath, { start, end }); - // Stream the video chunk to the client - videoStream.on('open', () => { - videoStream.pipe(res); - }); +// // Stream the video chunk to the client +// videoStream.on('open', () => { +// videoStream.pipe(res); +// }); - videoStream.on('error', (streamErr) => { - console.error('Stream Error:', streamErr); - res.end(streamErr); - }); -}); +// videoStream.on('error', (streamErr) => { +// console.error('Stream Error:', streamErr); +// res.end(streamErr); +// }); +// }); @@ -628,6 +628,258 @@ app.get('/search/:fName/:lName', async (request, response) => { }); +// app.post("/watch-movie", async (req, res) => { +// const { movieId, userId } = req.body; + +// try { +// // Fetch movie info from the database +// const movieInfo = await db.fetchMovieInfoById(movieId); + +// // Store movie info and user info in the session +// req.session.movieInfo = movieInfo; +// req.session.userId = userId; + +// // Redirect to the movie page +// res.redirect("/movie"); +// } catch (err) { +// console.log(err); +// res.status(500).json({ success: false, message: err.message }); +// } +// }); + +// // Serve the movie page +// app.get("/movie", function (req, res) { +// if (!req.session.movieInfo) { +// return res.status(400).send("No movie info in session"); +// } + +// res.sendFile(path.join(__dirname, '..', 'Client', 'movie.html')); +// }); + +// // Serve the video +// app.get("/video", function (req, res) { +// const range = req.headers.range; +// if (!range) { +// return res.status(400).send("Requires Range header"); +// } + +// const videoPath = req.session.movieInfo.videoPath; +// if (!fs.existsSync(videoPath)) { +// console.error(`Video file not found: ${videoPath}`); +// return res.status(404).send("Video not found"); +// } + +// const videoSize = fs.statSync(videoPath).size; +// const CHUNK_SIZE = 10 ** 6; // 1MB +// const start = Number(range.replace(/\D/g, "")); +// const end = Math.min(start + CHUNK_SIZE, videoSize - 1); + +// const contentLength = end - start + 1; +// const headers = { +// "Content-Range": `bytes ${start}-${end}/${videoSize}`, +// "Accept-Ranges": "bytes", +// "Content-Length": contentLength, +// "Content-Type": "video/mp4", +// }; + +// res.writeHead(206, headers); + +// const videoStream = fs.createReadStream(videoPath, { start, end }); +// videoStream.pipe(res); + +// videoStream.on('error', (streamErr) => { +// console.error('Stream Error:', streamErr); +// res.end(streamErr); +// }); +// }); + + + + + + +app.post("/prepare-movie", async (req, res) => { + const { movieId, userId } = req.body; + + console.log("Received request to prepare movie:", { movieId, userId }); + + try { + // Fetch movie info from the database + const movieInfo = await db.fetchMovieInfoById(movieId); + + console.log("Fetched movie info:", movieInfo); + + if (!movieInfo) { + console.log("No movie info found for id:", movieId); + return res.status(404).json({ success: false, message: "Movie not found" }); + } + + // Store movie info and user info in the session + req.session.movieInfo = movieInfo; + req.session.userId = userId; + + console.log('Movie info set in session:', req.session.movieInfo); + + // Save the session explicitly + req.session.save((err) => { + if (err) { + console.error("Session save error:", err); + return res.status(500).json({ success: false, message: "Error saving session" }); + } + console.log('Session saved successfully. Session data:', req.session); + res.json({ success: true, message: "Movie prepared successfully" }); + }); + } catch (err) { + console.error("Error in /prepare-movie:", err); + res.status(500).json({ success: false, message: err.message }); + } +}); + + + + + +app.get("/movie", function (req, res) { + console.log("Session in /movie:", req.session); + if (!req.session.movieInfo) { + console.log("No movie info found in session"); + return res.status(400).send("No movie info in session. Please select a movie first."); + } + + console.log("Movie info found:", req.session.movieInfo); + res.sendFile(path.join(__dirname, '..', 'Client', 'UPmovie.html')); +}); + + +app.get("/movie-info", (req, res) => { + console.log("Session in /movie-info:", req.session); + if (!req.session.movieInfo) { + console.log("No movie info found in /movie-info"); + return res.status(400).json({ success: false, message: "No movie info in session" }); + } + + console.log("Sending movie info:", req.session.movieInfo); + res.json({ + success: true, + movieInfo: req.session.movieInfo, + userId: req.session.userId + }); +}); + + + + + +app.use((req, res, next) => { + console.log('Session ID:', req.sessionID); + console.log('Session Data:', req.session); + next(); +}); + + + + + + + + + +app.post("/watch-movie", async (req, res) => { + const { movieId, userId } = req.body; + + try { + // Fetch movie info from the database + const movieInfo = await db.fetchMovieInfoById(movieId); + + // Store movie info and user info in the session + req.session.movieInfo = movieInfo; + req.session.userId = userId; + + // Redirect to the movie page + res.redirect("/movie"); + } catch (err) { + console.log(err); + res.status(500).json({ success: false, message: err.message }); + } +}); + +// app.get("/movie", function (req, res) { +// if (!req.session.movieInfo) { +// return res.status(400).send("No movie info in session"); +// } + +// res.sendFile(path.join(__dirname, '..', 'Client', 'UPmovie.html')); +// }); + +app.get("/video", function (req, res) { + const range = req.headers.range; + if (!range) { + return res.status(400).send("Requires Range header"); + } + + const videoPath = req.session.movieInfo.filepath; + if (!fs.existsSync(videoPath)) { + console.error(`Video file not found: ${videoPath}`); + return res.status(404).send("Video not found"); + } + + const videoSize = fs.statSync(videoPath).size; + const CHUNK_SIZE = 10 ** 6; // 1MB + const start = Number(range.replace(/\D/g, "")); + const end = Math.min(start + CHUNK_SIZE, videoSize - 1); + + const contentLength = end - start + 1; + const headers = { + "Content-Range": `bytes ${start}-${end}/${videoSize}`, + "Accept-Ranges": "bytes", + "Content-Length": contentLength, + "Content-Type": "video/mp4", + }; + + res.writeHead(206, headers); + + const videoStream = fs.createReadStream(videoPath, { start, end }); + videoStream.pipe(res); + + videoStream.on('error', (streamErr) => { + console.error('Stream Error:', streamErr); + res.end(streamErr); + }); +}); + + +// app.get("/movie-info", (req, res) => { +// if (!req.session.movieInfo) { +// return res.status(400).json({ success: false, message: "No movie info in session" }); +// } + +// res.json({ +// success: true, +// movieInfo: req.session.movieInfo, +// userId: req.session.userId +// }); +// }); + + + + + + + + + + + +app.get('/movie-info/:title', async (request, response) => { + try { + const { title } = request.params; + const result = await db.fetchMovieInfo(title); + response.json({ data: result }); + } catch (err) { + console.log(err); + response.status(500).json({ success: false, message: err.message }); + } +}); app.get("/signup.html", (req, res) => { res.sendFile(path.join(__dirname, '..', 'Client', 'signup.html')); From b487da5f83d382c4f968b1c554d7b329d91e94ce Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Fri, 11 Oct 2024 16:48:00 +0400 Subject: [PATCH 02/27] basic forum created and displayed with userId ( still in progress ) --- Client/forums.html | 86 ++++++++++++++++++++++++++++++++++++++++++++++ Server/movie.js | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 Client/forums.html diff --git a/Client/forums.html b/Client/forums.html new file mode 100644 index 0000000..0606338 --- /dev/null +++ b/Client/forums.html @@ -0,0 +1,86 @@ + + + + + + Forum + + + +

Discussion Forum

+
+ + + diff --git a/Server/movie.js b/Server/movie.js index 0c798a4..d4d4963 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -881,6 +881,66 @@ app.get('/movie-info/:title', async (request, response) => { } }); + +// forums api + +app.post('/users', (req, res) => { + const { fName, lName, Email, Password } = req.body; + const sql = 'INSERT INTO user (fName, lName, Email, Password) VALUES (?, ?, ?, ?)'; + db.query(sql, [fName, lName, Email, Password], (err, result) => { + if (err) throw err; + res.sendStatus(201); + }); +}); + +app.get('/forums', (req, res) => { + const sql = 'SELECT forums.*, user.fName as username FROM forums JOIN user ON forums.user_id = user.id'; + db.query(sql, (err, result) => { + if (err) throw err; + res.json(result); + }); +}); + +app.get('/comments', (req, res) => { + const forumId = req.query.forum_id; + const sql = 'SELECT comments.*, user.fName as username FROM comments JOIN user ON comments.user_id = user.id WHERE forum_id = ?'; + db.query(sql, [forumId], (err, result) => { + if (err) throw err; + res.json(result); + }); +}); + +app.post('/forums', (req, res) => { + const { title, content, user_id } = req.body; + const sql = 'INSERT INTO forums (title, content, user_id) VALUES (?, ?, ?)'; + db.query(sql, [title, content, user_id], (err, result) => { + if (err) throw err; + res.sendStatus(201); + }); +}); + +app.post('/comments', (req, res) => { + const { forum_id, user_id, content, image_url } = req.body; + const sql = 'INSERT INTO comments (forum_id, user_id, content, image_url) VALUES (?, ?, ?, ?)'; + db.query(sql, [forum_id, user_id, content, image_url], (err, result) => { + if (err) throw err; + res.sendStatus(201); + }); +}); + + + + + + + + + + + + + + app.get("/signup.html", (req, res) => { res.sendFile(path.join(__dirname, '..', 'Client', 'signup.html')); }); @@ -933,6 +993,11 @@ app.get("/UserProfile.html", (req, res) => { res.sendFile(path.join(__dirname, '..', 'Client', 'UserProfile.html')); }); +// forums link +app.get("/forums.html", (req, res) => { + res.sendFile(path.join(__dirname, '..', 'Client', 'forums.html')); +}); + app.get("*", (req, res) => { res.status(404).send("Page not found"); }); From f6d8a0969977e9d159deee03e551eb9894066e47 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sat, 12 Oct 2024 13:26:43 +0400 Subject: [PATCH 03/27] the forums content being displayed including the comments made by specific user ( changes made to movies.js and forums.html) --- Client/forums.html | 128 ++++++++++++++++++--------------------------- Server/movie.js | 63 +++++++++++----------- 2 files changed, 84 insertions(+), 107 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index 0606338..5b13d2d 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -1,86 +1,60 @@ - + - - - Forum - + Forums -

Discussion Forum

-
- + fetch(`/comments/${forum.id}`) + .then(response => response.json()) + .then(comments => { + let commentContainer = document.getElementById(`comments-${forum.id}`); + comments.forEach(comment => { + let commentElement = document.createElement('p'); + commentElement.innerHTML = `${comment.user_id}: ${comment.content}`; + commentContainer.appendChild(commentElement); + }); + }); + }); + }); + + diff --git a/Server/movie.js b/Server/movie.js index d4d4963..a6b5b0d 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -884,49 +884,52 @@ app.get('/movie-info/:title', async (request, response) => { // forums api -app.post('/users', (req, res) => { - const { fName, lName, Email, Password } = req.body; - const sql = 'INSERT INTO user (fName, lName, Email, Password) VALUES (?, ?, ?, ?)'; - db.query(sql, [fName, lName, Email, Password], (err, result) => { - if (err) throw err; - res.sendStatus(201); +// Server/movie.js +app.post('/addcomment', (req, res) => { + let comment = { forum_id: req.body.forum_id, body: req.body.body, user_id: req.body.user_id }; + let sql = 'INSERT INTO comments SET ?'; + db.query(sql, comment, (err) => { + if (err) { + throw err; + } + res.send('Comment added...'); }); }); +// Get all Forums app.get('/forums', (req, res) => { - const sql = 'SELECT forums.*, user.fName as username FROM forums JOIN user ON forums.user_id = user.id'; - db.query(sql, (err, result) => { - if (err) throw err; - res.json(result); + let sql = 'SELECT * FROM forums'; + db.query(sql, (err, results) => { + if (err) { + throw err; + } + res.json(results); }); }); -app.get('/comments', (req, res) => { - const forumId = req.query.forum_id; - const sql = 'SELECT comments.*, user.fName as username FROM comments JOIN user ON comments.user_id = user.id WHERE forum_id = ?'; - db.query(sql, [forumId], (err, result) => { - if (err) throw err; - res.json(result); +// Get Comments for a Forum +app.get('/comments/:forum_id', (req, res) => { + let sql = `SELECT * FROM comments WHERE forum_id = ${req.params.forum_id}`; + db.query(sql, (err, results) => { + if (err) { + throw err; + } + res.json(results); }); }); -app.post('/forums', (req, res) => { - const { title, content, user_id } = req.body; - const sql = 'INSERT INTO forums (title, content, user_id) VALUES (?, ?, ?)'; - db.query(sql, [title, content, user_id], (err, result) => { - if (err) throw err; - res.sendStatus(201); +// Create a new forum +app.post('/addforum', (req, res) => { + let forum = { title: req.body.title, body: req.body.body, user_id: req.body.user_id }; + let sql = 'INSERT INTO forums SET ?'; + db.query(sql, forum, (err) => { + if (err) { + throw err; + } + res.send('Forum added...'); }); }); -app.post('/comments', (req, res) => { - const { forum_id, user_id, content, image_url } = req.body; - const sql = 'INSERT INTO comments (forum_id, user_id, content, image_url) VALUES (?, ?, ?, ?)'; - db.query(sql, [forum_id, user_id, content, image_url], (err, result) => { - if (err) throw err; - res.sendStatus(201); - }); -}); From ac5fe893dfbaf942806c7d8a313bf3ee2fd1377b Mon Sep 17 00:00:00 2001 From: Talal-q19 <106393662+Talal-q19@users.noreply.github.com> Date: Sat, 12 Oct 2024 13:28:40 +0400 Subject: [PATCH 04/27] Create ReadMe Talal --- ReadMe Talal | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ReadMe Talal diff --git a/ReadMe Talal b/ReadMe Talal new file mode 100644 index 0000000..ccfc77c --- /dev/null +++ b/ReadMe Talal @@ -0,0 +1,4 @@ +Talals git commits +* forums comments and post +* movie recommender with js +* will make additional chatting functionality next week From aa7bc14d6dec7e0d3736c79fda9a43ee8b28b5e6 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sat, 12 Oct 2024 14:16:57 +0400 Subject: [PATCH 05/27] debugged code updated --- Client/forums.html | 16 ++++++++++++++-- Server/movie.js | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index 5b13d2d..aadfb19 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -6,12 +6,19 @@

Create a Forum

+

+ +

-
-
+ + +
+
+ +
@@ -33,10 +40,15 @@

Comments:

+

+ +

+ +
`; diff --git a/Server/movie.js b/Server/movie.js index a6b5b0d..a358d88 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -886,7 +886,7 @@ app.get('/movie-info/:title', async (request, response) => { // Server/movie.js app.post('/addcomment', (req, res) => { - let comment = { forum_id: req.body.forum_id, body: req.body.body, user_id: req.body.user_id }; + let comment = { forum_id: req.body.forum_id, content: req.body.content, user_id: req.body.user_id }; let sql = 'INSERT INTO comments SET ?'; db.query(sql, comment, (err) => { if (err) { @@ -920,7 +920,7 @@ app.get('/comments/:forum_id', (req, res) => { // Create a new forum app.post('/addforum', (req, res) => { - let forum = { title: req.body.title, body: req.body.body, user_id: req.body.user_id }; + let forum = { title: req.body.title, content: req.body.content, user_id: req.body.user_id }; let sql = 'INSERT INTO forums SET ?'; db.query(sql, forum, (err) => { if (err) { From 0d7813d679dc813cc123f4ea275a8021ba0c161e Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sat, 12 Oct 2024 15:18:27 +0400 Subject: [PATCH 06/27] comments were bugging fixed that only UI is left --- Client/forums.html | 4 ++-- Server/movie.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index aadfb19..57ef088 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -45,8 +45,8 @@

Comments:


-
-
+
+
diff --git a/Server/movie.js b/Server/movie.js index a358d88..d32f572 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -944,6 +944,7 @@ app.post('/addforum', (req, res) => { + app.get("/signup.html", (req, res) => { res.sendFile(path.join(__dirname, '..', 'Client', 'signup.html')); }); From 1591f2e0bba70383069aec39d92912b3ef1c1566 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sat, 12 Oct 2024 15:22:01 +0400 Subject: [PATCH 07/27] added a new db with forums and comments --- streamhubdb_2.sql | 246 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 streamhubdb_2.sql diff --git a/streamhubdb_2.sql b/streamhubdb_2.sql new file mode 100644 index 0000000..0cf13ff --- /dev/null +++ b/streamhubdb_2.sql @@ -0,0 +1,246 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- Host: 127.0.0.1 +-- Generation Time: Oct 12, 2024 at 01:20 PM +-- Server version: 10.4.32-MariaDB +-- PHP Version: 8.0.30 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `streamhubdb` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `comments` +-- + +CREATE TABLE `comments` ( + `id` int(11) NOT NULL, + `forum_id` int(11) DEFAULT NULL, + `user_id` int(11) DEFAULT NULL, + `content` text DEFAULT NULL, + `image_url` varchar(255) DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT current_timestamp() +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `comments` +-- + +INSERT INTO `comments` (`id`, `forum_id`, `user_id`, `content`, `image_url`, `created_at`) VALUES +(1, 1, 1, 'hello', NULL, '2024-10-11 13:25:03'), +(2, 1, 3, 'wow this is epic', NULL, '2024-10-12 09:25:22'), +(11, 7, 8, 'nah it was greate', NULL, '2024-10-12 10:53:35'), +(12, 1, 8, 'i agree with 3 it was epic', NULL, '2024-10-12 10:54:39'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `forums` +-- + +CREATE TABLE `forums` ( + `id` int(11) NOT NULL, + `title` varchar(255) NOT NULL, + `content` text DEFAULT NULL, + `user_id` int(11) DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT current_timestamp() +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `forums` +-- + +INSERT INTO `forums` (`id`, `title`, `content`, `user_id`, `created_at`) VALUES +(1, 'scifi', 'helllo i love movie', 1, '2024-10-11 12:38:41'), +(2, 'action movie', 'this was ggreate', 1, '2024-10-12 09:56:44'), +(6, 'interstller', 'i love this movie', 8, '2024-10-12 10:22:05'), +(7, 'fnaf', 'mid horror mobie', 3, '2024-10-12 10:50:34'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `movies` +-- + +CREATE TABLE `movies` ( + `mid` int(10) NOT NULL, + `title` varchar(30) NOT NULL, + `genre` varchar(20) NOT NULL, + `rdate` varchar(5) NOT NULL, + `runtime` varchar(4) NOT NULL, + `description` varchar(100) NOT NULL, + `viewers` int(10) DEFAULT 1, + `imgpath` text NOT NULL, + `filepath` text NOT NULL, + `trailer_url` varchar(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `movies` +-- + +INSERT INTO `movies` (`mid`, `title`, `genre`, `rdate`, `runtime`, `description`, `viewers`, `imgpath`, `filepath`, `trailer_url`) VALUES +(1, 'Oz the Great and Powerful', 'Adventure', '2013-', '130', 'A small-time magician is swept away to an enchanted land and is forced into a power struggle between', 1, 'uploads\\posters\\1726081513616.jpg', 'uploads\\movies\\1726081504391.mp4', 'https://www.youtube.com/results?search_query=oz+the+great+and+powerful+trailer'), +(3, 'My Man Godfrey', 'Comedy', '1936-', '94', 'A scatterbrained socialite hires a vagrant as a family butler - but there\'s more to Godfrey than mee', 1, 'uploads\\posters\\1726082269866.jpg', 'uploads\\movies\\1726082265639.mp4', 'https://www.imdb.com/video/vi3249931545/?ref_=ext_shr_lnk'), +(5, 'His Girl Friday', 'Romance', '1940-', '93', 'A newspaper editor uses every trick in the book to keep his ace reporter ex-wife from quitting and r', 1, 'uploads\\posters\\1726137862535.jpg', 'uploads\\movies\\1726137861727.mp4', 'https://www.imdb.com/video/vi4108846105/?playlistId=tt0032599&ref_=ext_shr_lnk'), +(7, 'Disorder in the Court', 'Comedy', '1936-', '16', 'The stooges are witnesses at a trial where their friend, a dancer at a nightclub where they are musi', 1, 'uploads\\posters\\1726139019012.jpg', 'uploads\\movies\\1726139004943.mp4', 'https://www.youtube.com/watch?v=E33qzW4Qvr8'), +(53, 'Big Duck update test', 'Adventure', '2020-', '15', 'Lmaoooo!', 1, 'uploads\\posters\\1726396270555.jpeg', 'uploads\\movies\\1726396268948.mp4', 'https://www.imdb.com/video/vi3249931545/?ref_=ext_shr_lnk'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `user` +-- + +CREATE TABLE `user` ( + `id` int(255) NOT NULL, + `fName` varchar(255) NOT NULL, + `lName` varchar(255) NOT NULL, + `Email` varchar(255) NOT NULL, + `Password` varchar(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `user` +-- + +INSERT INTO `user` (`id`, `fName`, `lName`, `Email`, `Password`) VALUES +(1, 'The', 'Admin', 'admin@boss.com', '123'), +(3, 'TheTop', 'G', 'TheTopG@nice.com', '555'), +(6, 'Supa', 'HotFire', 'BoomPow@gmail.com', '987'), +(8, 'jack', 'sam', 'hossam@powpow.com', '573985738'), +(11, 'TheMan', 'TheMyth', 'TheLegend@me.com', '9001'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `user_movie_interaction` +-- + +CREATE TABLE `user_movie_interaction` ( + `interaction_id` int(11) NOT NULL, + `user_id` int(11) DEFAULT NULL, + `movie_id` int(11) DEFAULT NULL, + `viewed` tinyint(1) DEFAULT 0, + `liked` tinyint(1) DEFAULT 0, + `rated` tinyint(1) DEFAULT 0, + `rating` decimal(2,1) DEFAULT NULL CHECK (`rating` between 0 and 5), + `added_to_watchlist` tinyint(1) DEFAULT 0, + `picked_during_signup` tinyint(1) DEFAULT 0 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `comments` +-- +ALTER TABLE `comments` + ADD PRIMARY KEY (`id`), + ADD KEY `forum` (`forum_id`), + ADD KEY `user` (`user_id`); + +-- +-- Indexes for table `forums` +-- +ALTER TABLE `forums` + ADD PRIMARY KEY (`id`), + ADD KEY `users` (`user_id`); + +-- +-- Indexes for table `movies` +-- +ALTER TABLE `movies` + ADD PRIMARY KEY (`mid`); + +-- +-- Indexes for table `user` +-- +ALTER TABLE `user` + ADD PRIMARY KEY (`id`); + +-- +-- Indexes for table `user_movie_interaction` +-- +ALTER TABLE `user_movie_interaction` + ADD PRIMARY KEY (`interaction_id`), + ADD KEY `midf` (`movie_id`), + ADD KEY `uidf` (`user_id`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `comments` +-- +ALTER TABLE `comments` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=13; + +-- +-- AUTO_INCREMENT for table `forums` +-- +ALTER TABLE `forums` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8; + +-- +-- AUTO_INCREMENT for table `movies` +-- +ALTER TABLE `movies` + MODIFY `mid` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=54; + +-- +-- AUTO_INCREMENT for table `user` +-- +ALTER TABLE `user` + MODIFY `id` int(255) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=13; + +-- +-- AUTO_INCREMENT for table `user_movie_interaction` +-- +ALTER TABLE `user_movie_interaction` + MODIFY `interaction_id` int(11) NOT NULL AUTO_INCREMENT; + +-- +-- Constraints for dumped tables +-- + +-- +-- Constraints for table `comments` +-- +ALTER TABLE `comments` + ADD CONSTRAINT `forum` FOREIGN KEY (`forum_id`) REFERENCES `forums` (`id`), + ADD CONSTRAINT `user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + +-- +-- Constraints for table `forums` +-- +ALTER TABLE `forums` + ADD CONSTRAINT `users` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + +-- +-- Constraints for table `user_movie_interaction` +-- +ALTER TABLE `user_movie_interaction` + ADD CONSTRAINT `midf` FOREIGN KEY (`movie_id`) REFERENCES `movies` (`mid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `uidf` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; From 7cce45a5695a2a02a11e39d9b204e55e0a7e0b70 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Thu, 17 Oct 2024 20:38:26 +0400 Subject: [PATCH 08/27] made a ui for the forum still work in progress need to add delete and user id --- Client/forums.html | 30 +++++++++++++++++------------- Client/styles.css | 16 ++++++++++++++++ Client/stylesheet.css | 17 ++++++++++++++++- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index 57ef088..f8991d8 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -2,6 +2,7 @@ Forums +

Create a Forum

@@ -10,20 +11,18 @@

Create a Forum



-

-

-

Forums

-
+
+
- - + \ No newline at end of file diff --git a/Client/styles.css b/Client/styles.css index 32646e8..15e885a 100644 --- a/Client/styles.css +++ b/Client/styles.css @@ -251,4 +251,20 @@ video { .video-container.scrubbing .timeline, .timeline-container:hover .timeline { height: 100%; +} + + +.forums-container { + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +.card { + margin: 20px; + padding: 20px; + border: 1px solid #ddd; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + width: 300px; } \ No newline at end of file diff --git a/Client/stylesheet.css b/Client/stylesheet.css index a5e9c51..5391505 100644 --- a/Client/stylesheet.css +++ b/Client/stylesheet.css @@ -15,4 +15,19 @@ table, th, td { th, td { padding: 5px; -} \ No newline at end of file +} + +.forums-container { + display: flex; + flex-wrap: wrap; + justify-content: center; + } + + .card { + margin: 20px; + padding: 20px; + border: 1px solid #ddd; + border-radius: 10px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + width: 300px; + } \ No newline at end of file From 326280f3a6ec6c3554557b09f5dbba19746bc0f2 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Thu, 17 Oct 2024 20:44:59 +0400 Subject: [PATCH 09/27] minor changes --- Client/forums.html | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index f8991d8..b5cfbfa 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -34,11 +34,18 @@

Forums

forumElement.innerHTML = `
- Forum Title : ${forum.title} +

Forum Title: ${forum.title}

+

Posted by: ${forum.user_id}

-
posted by ${forum.user_id}
-

${forum.content}

+

Forum Content

${forum.content}

+ + +
+ + +
+

Comments

From 3c7fa66cfd4bc3e4a60d476ab9cbb49b925ee878 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sat, 19 Oct 2024 20:42:54 +0400 Subject: [PATCH 10/27] forums comments bugs fixed --- Client/forums.html | 216 +++++++++++++++++++++++++++++++-------------- Server/movie.js | 96 +++++++++++++------- 2 files changed, 215 insertions(+), 97 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index b5cfbfa..a951f80 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -1,83 +1,171 @@ - + - Forums - + + + Forum App + -

Create a Forum

- +

Forum App

+
+

Create Forum

+ + + + + + - \ No newline at end of file + diff --git a/Server/movie.js b/Server/movie.js index d32f572..7a65180 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -884,54 +884,84 @@ app.get('/movie-info/:title', async (request, response) => { // forums api -// Server/movie.js -app.post('/addcomment', (req, res) => { - let comment = { forum_id: req.body.forum_id, content: req.body.content, user_id: req.body.user_id }; - let sql = 'INSERT INTO comments SET ?'; - db.query(sql, comment, (err) => { - if (err) { - throw err; - } - res.send('Comment added...'); +// Middleware to check if user is logged in +function isLoggedIn(req, res, next) { + if (req.headers['user-id']) { + req.user = { id: req.headers['user-id'] }; + next(); + } else { + next(); + } +} + +app.post('/forums', isLoggedIn, (req, res) => { + if (!req.user) return res.status(403).send('Login required'); + + const { title, content } = req.body; + const user_id = req.user.id; + db.query('INSERT INTO forums (title, content, user_id) VALUES (?, ?, ?)', [title, content, user_id], (err, result) => { + if (err) throw err; + res.send('Forum created'); }); }); -// Get all Forums app.get('/forums', (req, res) => { - let sql = 'SELECT * FROM forums'; - db.query(sql, (err, results) => { - if (err) { - throw err; - } - res.json(results); + db.query('SELECT * FROM forums', (err, result) => { + if (err) throw err; + res.send(result); }); }); -// Get Comments for a Forum -app.get('/comments/:forum_id', (req, res) => { - let sql = `SELECT * FROM comments WHERE forum_id = ${req.params.forum_id}`; - db.query(sql, (err, results) => { - if (err) { - throw err; - } - res.json(results); +app.delete('/forums/:id', isLoggedIn, (req, res) => { + if (!req.user) return res.status(403).send('Login required'); + + const forum_id = req.params.id; + db.query('DELETE FROM forums WHERE id = ? AND user_id = ?', [forum_id, req.user.id], (err, result) => { + if (err) throw err; + res.send('Forum deleted'); }); }); -// Create a new forum -app.post('/addforum', (req, res) => { - let forum = { title: req.body.title, content: req.body.content, user_id: req.body.user_id }; - let sql = 'INSERT INTO forums SET ?'; - db.query(sql, forum, (err) => { - if (err) { - throw err; - } - res.send('Forum added...'); +app.post('/forums/:id/postcomments', isLoggedIn, (req, res) => { + if (!req.user) return res.status(403).send('Login required'); + + const { content } = req.body; + const forum_id = req.params.id; + const user_id = req.user.id; + db.query('INSERT INTO comments (forum_id, user_id, content) VALUES (?, ?, ?)', [forum_id, user_id, content], (err, result) => { + if (err) throw err; + res.send('Comment created'); }); }); +app.get('/forums/:id/comments', async (req, res) => { + try { + const forumId = req.params.id; + if (!forumId) { + return res.status(400).send({ error: 'Forum ID is required' }); + } + const comments = await db.query('SELECT * FROM comments WHERE forum_id = ?', [forumId]); + if (comments.length === 0) { + return res.status(404).send({ message: 'No comments found for this forum' }); + } + res.send(comments); + } catch (err) { + console.error(err); + res.status(500).send({ error: 'Database query failed' }); + } +}); + +app.delete('/comments/:id', isLoggedIn, (req, res) => { + if (!req.user) return res.status(403).send('Login required'); + + const comment_id = req.params.id; + db.query('DELETE FROM comments WHERE id = ? AND user_id = ?', [comment_id, req.user.id], (err, result) => { + if (err) throw err; + res.send('Comment deleted'); + }); +}); From f40914a4269e74fe9bce90ba71e36f324b68671e Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sat, 19 Oct 2024 22:01:46 +0400 Subject: [PATCH 11/27] all the functionalties done only UI left --- Client/forums.html | 105 +++++++++++++++++++++++++-------------------- Server/movie.js | 8 ++-- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index a951f80..e9ea689 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -21,7 +21,7 @@

Create Forum

diff --git a/Server/movie.js b/Server/movie.js index 7a65180..54e0011 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -922,15 +922,15 @@ app.delete('/forums/:id', isLoggedIn, (req, res) => { }); }); -app.post('/forums/:id/postcomments', isLoggedIn, (req, res) => { +app.post('/forums/:forumId/comments', isLoggedIn, (req, res) => { if (!req.user) return res.status(403).send('Login required'); const { content } = req.body; - const forum_id = req.params.id; + const forum_id = req.params.forumId; const user_id = req.user.id; db.query('INSERT INTO comments (forum_id, user_id, content) VALUES (?, ?, ?)', [forum_id, user_id, content], (err, result) => { - if (err) throw err; - res.send('Comment created'); + if (err) throw err; + res.send('Comment created'); }); }); From 1cf192548bec0e95303af823697394252a5f21c7 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sun, 20 Oct 2024 16:46:46 +0400 Subject: [PATCH 12/27] ui changes made to forums --- Client/forums.html | 187 ++++++++++++++++++++++++++------------------- 1 file changed, 110 insertions(+), 77 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index e9ea689..57e2b84 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -7,22 +7,59 @@ + + + + + +

Forum App

+ +
+
+ +
+
+
+

Create Forum

+
+
+ + +
+
+ + +
+ +
+
+
+
+
-

Create Forum

-
- - - -
+ + + From a967db179bf49a5916047525726fe1b1d080af7a Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sun, 20 Oct 2024 17:17:04 +0400 Subject: [PATCH 13/27] forums are complete --- Client/forums.html | 93 ++++++++++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 33 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index 57e2b84..642e800 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -25,7 +25,8 @@ - + +

Forum App

@@ -93,29 +94,50 @@

Create Forum

const forumElement = document.createElement('div'); forumElement.className = 'forum'; forumElement.innerHTML = ` -
-
- The forum is made by : ${forum.user_id} +
+
+ The forum is made by : ${forum.user_id} +
+
+
${forum.title}
+

${forum.content}.

+ ${forum.user_id == userId ? `` : ''} + + + + +
+
+
Comments:
+
-
-
${forum.title}
-

${forum.content}.

- ${forum.user_id == userId ? `` : ''} -
+
+
+ + + `; forumCardsContainer.appendChild(forumElement); forumsDiv.appendChild(forumCardsContainer); @@ -126,19 +148,24 @@
Comments:
.then(comments => { const commentsDiv = document.getElementById(`comments-${forum.id}`); comments.forEach(comment => { - const commentElement = document.createElement('div'); - commentElement.className = 'comment'; - const commentText = document.createElement('p'); - commentText.textContent = `Commented by User ID: ${comment.user_id} - ${comment.content}`; - - if (comment.user_id == userId) { - const deleteButton = document.createElement('button'); - deleteButton.textContent = 'Delete'; - deleteButton.onclick = () => deleteComment(comment.id); - commentElement.appendChild(deleteButton); - } - commentElement.appendChild(commentText); - commentsDiv.appendChild(commentElement); + const commentElement = document.createElement('div'); +commentElement.className = 'comment'; +const commentText = document.createElement('p'); +commentText.textContent = `Commented by User ID: ${comment.user_id} - ${comment.content}`; + +const commentContainer = document.createElement('div'); +commentContainer.appendChild(commentText); + +if (comment.user_id == userId) { + const deleteButton = document.createElement('button'); + deleteButton.className = 'btn btn-danger btn-sm'; + deleteButton.innerHTML = ' Delete'; + deleteButton.onclick = () => deleteComment(comment.id); + commentContainer.appendChild(deleteButton); +} + +commentElement.appendChild(commentContainer); +commentsDiv.appendChild(commentElement); }); }) .catch(error => console.error('Error fetching comments:', error)); From ec9913c64ae0b4229dd8c993ecfd2384f80374d1 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sun, 20 Oct 2024 17:22:53 +0400 Subject: [PATCH 14/27] added updated db --- streamhubdb_3.sql | 257 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 streamhubdb_3.sql diff --git a/streamhubdb_3.sql b/streamhubdb_3.sql new file mode 100644 index 0000000..20978ea --- /dev/null +++ b/streamhubdb_3.sql @@ -0,0 +1,257 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- Host: 127.0.0.1 +-- Generation Time: Oct 20, 2024 at 03:21 PM +-- Server version: 10.4.28-MariaDB +-- PHP Version: 8.0.28 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `streamhubdb` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `comments` +-- + +CREATE TABLE `comments` ( + `id` int(11) NOT NULL, + `forum_id` int(11) DEFAULT NULL, + `user_id` int(11) DEFAULT NULL, + `content` text DEFAULT NULL, + `image_url` varchar(255) DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT current_timestamp() +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `comments` +-- + +INSERT INTO `comments` (`id`, `forum_id`, `user_id`, `content`, `image_url`, `created_at`) VALUES +(2, 1, 3, 'wow this is epic', NULL, '2024-10-12 09:25:22'), +(12, 1, 8, 'i agree with 3 it was epic', NULL, '2024-10-12 10:54:39'), +(13, 1, 1, 'no stfu', NULL, '2024-10-12 12:34:06'), +(14, 9, 1, 'agree', NULL, '2024-10-12 20:10:08'), +(18, 1, 8, 'u speak no', NULL, '2024-10-15 18:03:14'), +(19, 1, 1, 'i speakl yes', NULL, '2024-10-15 18:08:23'), +(21, 1, 3, 'yoyo', NULL, '2024-10-15 18:38:33'), +(23, 1, 8, 'sup', NULL, '2024-10-15 19:01:30'), +(54, 11, 1, 'gg', NULL, '2024-10-18 14:54:14'), +(57, 6, 6, 'woowoowow', NULL, '2024-10-19 17:21:36'), +(60, 1, 6, 'idk', NULL, '2024-10-19 17:31:11'), +(62, 30, 6, 'do the comments work', NULL, '2024-10-19 18:00:18'), +(72, 36, 8, 'does it work', NULL, '2024-10-20 12:54:36'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `forums` +-- + +CREATE TABLE `forums` ( + `id` int(11) NOT NULL, + `title` varchar(255) NOT NULL, + `content` text DEFAULT NULL, + `user_id` int(11) DEFAULT NULL, + `created_at` timestamp NOT NULL DEFAULT current_timestamp() +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `forums` +-- + +INSERT INTO `forums` (`id`, `title`, `content`, `user_id`, `created_at`) VALUES +(1, 'scifi', 'helllo i love movie', 1, '2024-10-11 12:38:41'), +(6, 'interstller', 'i love this movie', 8, '2024-10-12 10:22:05'), +(9, 'martian', 'goated movie', 6, '2024-10-12 20:09:53'), +(11, 'ASDS', 'SDSA', 3, '2024-10-16 10:11:50'), +(30, 'test forum', 'hello this work', 6, '2024-10-19 18:00:05'), +(36, 'fast and furious', 'i dont like them ', 8, '2024-10-20 12:37:43'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `movies` +-- + +CREATE TABLE `movies` ( + `mid` int(10) NOT NULL, + `title` varchar(30) NOT NULL, + `genre` varchar(20) NOT NULL, + `rdate` varchar(5) NOT NULL, + `runtime` varchar(4) NOT NULL, + `description` varchar(100) NOT NULL, + `viewers` int(10) DEFAULT 1, + `imgpath` text NOT NULL, + `filepath` text NOT NULL, + `trailer_url` varchar(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `movies` +-- + +INSERT INTO `movies` (`mid`, `title`, `genre`, `rdate`, `runtime`, `description`, `viewers`, `imgpath`, `filepath`, `trailer_url`) VALUES +(1, 'Oz the Great and Powerful', 'Adventure', '2013-', '130', 'A small-time magician is swept away to an enchanted land and is forced into a power struggle between', 1, 'uploads\\posters\\1726081513616.jpg', 'uploads\\movies\\1726081504391.mp4', 'https://www.youtube.com/results?search_query=oz+the+great+and+powerful+trailer'), +(3, 'My Man Godfrey', 'Comedy', '1936-', '94', 'A scatterbrained socialite hires a vagrant as a family butler - but there\'s more to Godfrey than mee', 1, 'uploads\\posters\\1726082269866.jpg', 'uploads\\movies\\1726082265639.mp4', 'https://www.imdb.com/video/vi3249931545/?ref_=ext_shr_lnk'), +(5, 'His Girl Friday', 'Romance', '1940-', '93', 'A newspaper editor uses every trick in the book to keep his ace reporter ex-wife from quitting and r', 1, 'uploads\\posters\\1726137862535.jpg', 'uploads\\movies\\1726137861727.mp4', 'https://www.imdb.com/video/vi4108846105/?playlistId=tt0032599&ref_=ext_shr_lnk'), +(7, 'Disorder in the Court', 'Comedy', '1936-', '16', 'The stooges are witnesses at a trial where their friend, a dancer at a nightclub where they are musi', 1, 'uploads\\posters\\1726139019012.jpg', 'uploads\\movies\\1726139004943.mp4', 'https://www.youtube.com/watch?v=E33qzW4Qvr8'), +(53, 'Big Duck update test', 'Adventure', '2020-', '15', 'Lmaoooo!', 1, 'uploads\\posters\\1726396270555.jpeg', 'uploads\\movies\\1726396268948.mp4', 'https://www.imdb.com/video/vi3249931545/?ref_=ext_shr_lnk'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `user` +-- + +CREATE TABLE `user` ( + `id` int(255) NOT NULL, + `fName` varchar(255) NOT NULL, + `lName` varchar(255) NOT NULL, + `Email` varchar(255) NOT NULL, + `Password` varchar(255) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `user` +-- + +INSERT INTO `user` (`id`, `fName`, `lName`, `Email`, `Password`) VALUES +(1, 'The', 'Admin', 'admin@boss.com', '123'), +(3, 'TheTop', 'G', 'TheTopG@nice.com', '555'), +(6, 'Supa', 'HotFire', 'BoomPow@gmail.com', '987'), +(8, 'jack', 'sam', 'hossam@powpow.com', '573985738'), +(11, 'TheMan', 'TheMyth', 'TheLegend@me.com', '9001'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `user_movie_interaction` +-- + +CREATE TABLE `user_movie_interaction` ( + `interaction_id` int(11) NOT NULL, + `user_id` int(11) DEFAULT NULL, + `movie_id` int(11) DEFAULT NULL, + `viewed` tinyint(1) DEFAULT 0, + `liked` tinyint(1) DEFAULT 0, + `rated` tinyint(1) DEFAULT 0, + `rating` decimal(2,1) DEFAULT NULL CHECK (`rating` between 0 and 5), + `added_to_watchlist` tinyint(1) DEFAULT 0, + `picked_during_signup` tinyint(1) DEFAULT 0 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `comments` +-- +ALTER TABLE `comments` + ADD PRIMARY KEY (`id`), + ADD KEY `forum` (`forum_id`), + ADD KEY `user` (`user_id`); + +-- +-- Indexes for table `forums` +-- +ALTER TABLE `forums` + ADD PRIMARY KEY (`id`), + ADD KEY `users` (`user_id`); + +-- +-- Indexes for table `movies` +-- +ALTER TABLE `movies` + ADD PRIMARY KEY (`mid`); + +-- +-- Indexes for table `user` +-- +ALTER TABLE `user` + ADD PRIMARY KEY (`id`); + +-- +-- Indexes for table `user_movie_interaction` +-- +ALTER TABLE `user_movie_interaction` + ADD PRIMARY KEY (`interaction_id`), + ADD KEY `midf` (`movie_id`), + ADD KEY `uidf` (`user_id`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `comments` +-- +ALTER TABLE `comments` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=77; + +-- +-- AUTO_INCREMENT for table `forums` +-- +ALTER TABLE `forums` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=38; + +-- +-- AUTO_INCREMENT for table `movies` +-- +ALTER TABLE `movies` + MODIFY `mid` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=54; + +-- +-- AUTO_INCREMENT for table `user` +-- +ALTER TABLE `user` + MODIFY `id` int(255) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=13; + +-- +-- AUTO_INCREMENT for table `user_movie_interaction` +-- +ALTER TABLE `user_movie_interaction` + MODIFY `interaction_id` int(11) NOT NULL AUTO_INCREMENT; + +-- +-- Constraints for dumped tables +-- + +-- +-- Constraints for table `comments` +-- +ALTER TABLE `comments` + ADD CONSTRAINT `forum` FOREIGN KEY (`forum_id`) REFERENCES `forums` (`id`) ON DELETE CASCADE, + ADD CONSTRAINT `user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + +-- +-- Constraints for table `forums` +-- +ALTER TABLE `forums` + ADD CONSTRAINT `users` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`); + +-- +-- Constraints for table `user_movie_interaction` +-- +ALTER TABLE `user_movie_interaction` + ADD CONSTRAINT `midf` FOREIGN KEY (`movie_id`) REFERENCES `movies` (`mid`) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT `uidf` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; From cacecc5d14fe12edf76aabcc5355c33b2a763d89 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sun, 20 Oct 2024 23:34:02 +0400 Subject: [PATCH 15/27] last update on forums fixed create forums --- Client/forums.html | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/Client/forums.html b/Client/forums.html index 642e800..5a04122 100644 --- a/Client/forums.html +++ b/Client/forums.html @@ -18,6 +18,19 @@ margin: 2rem; width: 40rem; } +#collapse-create-forum .form-group { + display: flex; + align-items: center; + margin-bottom: 20px; +} + +#collapse-create-forum .form-group label { + margin-right: 5px; +} + +#collapse-create-forum .form-group input, #collapse-create-forum .form-group textarea { + flex: 1; +} @@ -41,20 +54,20 @@

Forum App

Create Forum

-
- - +
+ +
+ +
-
- - +
+ +
+ +
- - -
-
- +
+ + \ No newline at end of file diff --git a/Server/movie.js b/Server/movie.js index 54e0011..e312daf 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -893,7 +893,7 @@ function isLoggedIn(req, res, next) { next(); } } - +// Create a new forum app.post('/forums', isLoggedIn, (req, res) => { if (!req.user) return res.status(403).send('Login required'); @@ -905,6 +905,8 @@ app.post('/forums', isLoggedIn, (req, res) => { }); }); + +// Get all forums app.get('/forums', (req, res) => { db.query('SELECT * FROM forums', (err, result) => { if (err) throw err; @@ -912,6 +914,8 @@ app.get('/forums', (req, res) => { }); }); + +// Delete a forum app.delete('/forums/:id', isLoggedIn, (req, res) => { if (!req.user) return res.status(403).send('Login required'); @@ -922,6 +926,7 @@ app.delete('/forums/:id', isLoggedIn, (req, res) => { }); }); +// Create a new comment app.post('/forums/:forumId/comments', isLoggedIn, (req, res) => { if (!req.user) return res.status(403).send('Login required'); @@ -934,6 +939,7 @@ app.post('/forums/:forumId/comments', isLoggedIn, (req, res) => { }); }); +// Get all comments app.get('/forums/:id/comments', async (req, res) => { try { const forumId = req.params.id; @@ -953,6 +959,8 @@ app.get('/forums/:id/comments', async (req, res) => { } }); +// Delete a comment + app.delete('/comments/:id', isLoggedIn, (req, res) => { if (!req.user) return res.status(403).send('Login required'); @@ -965,6 +973,75 @@ app.delete('/comments/:id', isLoggedIn, (req, res) => { +//code for chatting + +// Send message +app.post('/send', (req, res) => { + const { from_user_id, to_user_id, message } = req.body; + if (!from_user_id) { + res.status(401).json({ success: false, error: "You must be logged in to send a message" }); + return; + } + + db.query("INSERT INTO messages (from_user_id, to_user_id, message) VALUES (?, ?, ?)", [from_user_id, to_user_id, message], (err, result) => { + if (err) { + res.status(500).json({ success: false, error: err.message }); + } else { + res.status(200).json({ success: true }); + } + }); +}); + +// Get messages for user +app.get('/messages/:user_id', (req, res) => { + const user_id = req.params.user_id; + console.log(`Received request for messages for user ${user_id}`); + console.log('Request headers:', req.headers); + console.log('Request query:', req.query); + console.log('About to execute database query...'); + + db.query("SELECT * FROM messages WHERE to_user_id = ?", [user_id]) + .then(rows => { + if (rows.length === 0) { + console.log(`No messages found for user ${user_id}`); + res.status(404).json({ error: 'No messages found for this user' }); + } else { + console.log(`Fetched ${rows.length} messages for user ${user_id}`); + console.log(`Preparing response...`); + console.log('Response data:', rows); + res.json({ messages: rows }); + console.log(`Response sent.`); + } + }) + .catch(err => { + console.error(`Error fetching messages: ${err.message}`); + res.status(500).json({ error: err.message }); + }); +}); +// Send message +/* +const defaultUserId = 1; + app.post('/send', (req, res) => { + const { to_user_id, message } = req.body; + const stmt = db.prepare("INSERT INTO messages (from_user_id, to_user_id, message) VALUES (?, ?, ?)"); + stmt.run(defaultUserId, to_user_id, message); + stmt.finalize(); + res.status(200).json({ success: true }); +});*/ + +// Get messages for user +/*app.get('/messages/:user_id', (req, res) => { + const user_id = req.params.user_id; + db.all("SELECT * FROM messages WHERE to_user_id = ?", [user_id], (err, rows) => { + if (err) { + res.status(500).json({ success: false, error: err.message }); + return; + } + res.status(200).json({ success: true, messages: rows }); + }); +});*/ + + @@ -1032,6 +1109,11 @@ app.get("/forums.html", (req, res) => { res.sendFile(path.join(__dirname, '..', 'Client', 'forums.html')); }); + +// chat link +app.get("/chat.html", (req, res) => { + res.sendFile(path.join(__dirname, '..', 'Client', 'chat.html')); +}); app.get("*", (req, res) => { res.status(404).send("Page not found"); }); From 1a348f80eab8f8a54d4ac507b24e5ed040e52c29 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sat, 26 Oct 2024 15:03:55 +0400 Subject: [PATCH 18/27] added chat functionality works completely --- Client/chat.html | 174 ++++++++++++++++++++++------------------------- Server/movie.js | 26 +++---- 2 files changed, 96 insertions(+), 104 deletions(-) diff --git a/Client/chat.html b/Client/chat.html index 61c4798..e8d480e 100644 --- a/Client/chat.html +++ b/Client/chat.html @@ -34,112 +34,102 @@ background-color: #0056b3; } .messages { - margin-top: 20px; - max-height: 300px; - overflow-y: auto; - background: #f9f9f9; - padding: 10px; - border-radius: 5px; + display: block; } .message { - padding: 5px 10px; - margin: 5px 0; + display: block; + margin-bottom: 10px; } - .from-me { - background-color: #d1ffd1; - align-self: flex-start; + .message-bubble { + padding: 10px; + border-radius: 10px; + margin-bottom: 10px; } - .from-them { - background-color: #f1f1f1; - align-self: flex-end; + .message-bubble.signed-in { + background-color: #C6F4D6; + align-self: flex-end; + } + + .message-bubble.recipient { + background-color: #ADD8E6; + align-self: flex-start; + } + .message-container { + display: flex; + flex-direction: column; }
-

Chat with User 3

+

Chat with 1

+
-
-
- - + + async function loadMessages() { + try { + const response = await fetch(`/messages/${signedInUserId}`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + }); + if (response.ok) { + const data = await response.json(); + const messagesContainer = document.getElementById('messages'); + messagesContainer.innerHTML = ''; + + if (data.messages && data.messages.length > 0) { + // Sort messages by ID to ensure chronological order + data.messages.sort((a, b) => a.id - b.id); + + // Combine messages and format them for display + data.messages.forEach(msg => { + const messageBubble = document.createElement('div'); + messageBubble.className = 'message-bubble'; + + if (msg.from_user_id === signedInUserId) { + messageBubble.classList.add('signed-in'); + } else { + messageBubble.classList.add('recipient'); + } + + messageBubble.innerHTML = msg.message; + + const messageContainer = document.createElement('div'); + messageContainer.className = 'message-container'; + messageContainer.appendChild(messageBubble); + + messagesContainer.appendChild(messageContainer); + }); + } + } + } catch (error) { + console.log('Error:', error); + } + } + + loadMessages(); + \ No newline at end of file diff --git a/Server/movie.js b/Server/movie.js index e312daf..33b70c4 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -992,6 +992,7 @@ app.post('/send', (req, res) => { }); }); +// Get messages for user // Get messages for user app.get('/messages/:user_id', (req, res) => { const user_id = req.params.user_id; @@ -1000,18 +1001,19 @@ app.get('/messages/:user_id', (req, res) => { console.log('Request query:', req.query); console.log('About to execute database query...'); - db.query("SELECT * FROM messages WHERE to_user_id = ?", [user_id]) - .then(rows => { - if (rows.length === 0) { - console.log(`No messages found for user ${user_id}`); - res.status(404).json({ error: 'No messages found for this user' }); - } else { - console.log(`Fetched ${rows.length} messages for user ${user_id}`); - console.log(`Preparing response...`); - console.log('Response data:', rows); - res.json({ messages: rows }); - console.log(`Response sent.`); - } + const queries = [ + db.query("SELECT * FROM messages WHERE to_user_id = ?", [user_id]), + db.query("SELECT * FROM messages WHERE from_user_id = ?", [user_id]) + ]; + + Promise.all(queries) + .then(([receivedMessages, sentMessages]) => { + const allMessages = receivedMessages.concat(sentMessages); + console.log(`Fetched ${allMessages.length} messages for user ${user_id}`); + console.log(`Preparing response...`); + console.log('Response data:', allMessages); + res.json({ messages: allMessages }); + console.log(`Response sent.`); }) .catch(err => { console.error(`Error fetching messages: ${err.message}`); From 198f7ca5e098a7c50510e1935c0b58ede7b07ec3 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sat, 26 Oct 2024 17:19:02 +0400 Subject: [PATCH 19/27] added functionality to select users --- Client/chat.html | 149 +++++++++++++++++++++++++++++------------------ Server/movie.js | 29 +++++++++ 2 files changed, 122 insertions(+), 56 deletions(-) diff --git a/Client/chat.html b/Client/chat.html index e8d480e..04ae2e4 100644 --- a/Client/chat.html +++ b/Client/chat.html @@ -17,6 +17,12 @@ border-radius: 10px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } + .hidden { + display: none; + } + .visible { + display: block; + } .message-input { width: calc(100% - 22px); padding: 10px; @@ -45,15 +51,14 @@ border-radius: 10px; margin-bottom: 10px; } - .message-bubble.signed-in { - background-color: #C6F4D6; - align-self: flex-end; - } - - .message-bubble.recipient { - background-color: #ADD8E6; - align-self: flex-start; - } + .message-bubble.signed-in { + background-color: #C6F4D6; + align-self: flex-end; + } + .message-bubble.recipient { + background-color: #ADD8E6; + align-self: flex-start; + } .message-container { display: flex; flex-direction: column; @@ -62,17 +67,50 @@
-

Chat with 1

-
- - +

Chat

+ + +
- \ No newline at end of file + diff --git a/Server/movie.js b/Server/movie.js index 33b70c4..60a6e40 100644 --- a/Server/movie.js +++ b/Server/movie.js @@ -1020,6 +1020,35 @@ app.get('/messages/:user_id', (req, res) => { res.status(500).json({ error: err.message }); }); }); + + + + app.get('/searchUser/:id', async (req, res) => { + const id = req.params.id; + console.log('Received request to search user with id:', id); + + if (!id) { + console.error('No ID provided'); + return res.status(400).json({ success: false, error: 'No ID provided' }); + } + + try { + const result = await db.query("SELECT * FROM user WHERE id = ?", [id]); + if (result.length > 0) { + const user = result[0]; + return res.status(200).json({ user }); + } else { + return res.status(404).json({ success: false, error: 'User not found' }); + } + } catch (err) { + console.error('Database error:', err); + return res.status(500).json({ success: false, error: err.message }); + } + }); + + + + // Send message /* const defaultUserId = 1; From a36717739089fc590cadd9085d87817b47056d20 Mon Sep 17 00:00:00 2001 From: Talal-q19 Date: Sat, 26 Oct 2024 18:58:22 +0400 Subject: [PATCH 20/27] added a proper ui --- Client/chat.html | 97 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 32 deletions(-) diff --git a/Client/chat.html b/Client/chat.html index 04ae2e4..af234a8 100644 --- a/Client/chat.html +++ b/Client/chat.html @@ -65,45 +65,78 @@ } + + + + + -
-

Chat

- - - +
+

Chat

+
+
+
+ + + +
+
+
+
+
+
+
+
+
+ + +
+ +
+ + + + + + + +
+ +
-

Forum App

- -
-
- -
-
-
-

Create Forum

-
-
- -
- +
+
+ +
+
+
+

Create Forum

+ +
+ +
+ +
+
+
+ +
+ +
+
+ + +
+
+ + +
+ +
+
+
+
+
+
+

About

+
-
-
- -
- +
+
+ + + StreamHub
+

The best Streaming platform for You and your Family!

-
-
-
-
+
+
+
+

Copyright © 2024 StreamHub

+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+ +