From 534d1073f3a6f3ac4e9a0cf2e490af83801ae7d0 Mon Sep 17 00:00:00 2001 From: cemn <127931228+fridge7809@users.noreply.github.com> Date: Thu, 15 Feb 2024 23:46:22 +0100 Subject: [PATCH] refactor timeline Co-authored-by: chatgpt --- routes/timeline.js | 189 +++++++++------------------------------- services/userService.js | 100 +++++++++++++++++++++ 2 files changed, 141 insertions(+), 148 deletions(-) create mode 100644 services/userService.js diff --git a/routes/timeline.js b/routes/timeline.js index 4f2f15c..06f7625 100644 --- a/routes/timeline.js +++ b/routes/timeline.js @@ -1,9 +1,9 @@ var express = require('express'); var router = express.Router(); -var router = express.Router(); -const sqlite3 = require('sqlite3').verbose(); const crypto = require('crypto'); const session = require('express-session'); +const UserService = require('../services/userService'); +const userService = new UserService(); router.use(session({ secret: 'devving-and-opssing', @@ -11,7 +11,6 @@ router.use(session({ saveUninitialized: true })); -// Callback to protect endpoints with authentication const requireAuth = (req, res, next) => { if (req.session.username) { next(); @@ -25,33 +24,28 @@ function gravatar_url(email, size = 80) { return `http://www.gravatar.com/avatar/${hash}?d=identicon&s=${size}`; } -// Database connection -let db = new sqlite3.Database('./db/minitwit.db', sqlite3.OPEN_READWRITE, (err) => { - if (err) { - console.error(err.message); - } else { - console.log('Connected to the minitwit.db'); - } -}); +function formatMessages(messages) { + messages.forEach(message => { + const date = new Date(message.pub_date * 1000); + const year = date.getUTCFullYear(); + const month = ("0" + (date.getUTCMonth() + 1)).slice(-2); + const day = ("0" + date.getUTCDate()).slice(-2); + const hours = ("0" + date.getUTCHours()).slice(-2); + const minutes = ("0" + date.getUTCMinutes()).slice(-2); + message.pub_date = year + "-" + month + "-" + day + " @ " + hours + ":" + minutes; + message.gravatar = gravatar_url(message.email, 48); + delete message.email; + }); + return messages; +} router.post('/add_message', requireAuth, async function (req, res, next) { try { - const userId = req.session.username.id; const messageContent = req.body.text; const currentDate = new Date().getTime(); - const flagged = 0; - - console.log(currentDate); - const sql = `insert into message (author_id, text, pub_date, flagged) values (?, ?, ?, ?)`; - db.run(sql, [userId, messageContent, currentDate, flagged], (err) => { - if (err) { - console.error(err.message); - } - }); - - res.redirect('/'); - + await userService.addMessage(userId, messageContent, currentDate); + res.redirect('/') } catch (error) { console.log(error); res.status(500).send('Server error'); @@ -64,167 +58,66 @@ router.get('/logout', function (req, res) { res.redirect('/public'); }); -/* GET current user timeline page. */ router.get('/', requireAuth, async function (req, res, next) { try { - const { username } = req.session.username; - const id = req.session.username.id; + const userId = req.session.username.id; const g = { user: req.session.username }; const profile_user = 'example_profile_user'; const followed = true; - - const sql = `SELECT message.text, message.pub_date, message.flagged, user.username, user.email - FROM message - JOIN user ON message.author_id = user.user_id - WHERE message.flagged != 1 and message.author_id = ? - order by message.pub_date desc - LIMIT 50;` - - const messages = await new Promise((resolve, reject) => { - db.all(sql, [id], (err, messages) => { - if (err) reject(err); - else resolve(messages); - }); - }); - - messages.forEach(message => { - const date = new Date(message.pub_date * 1000); - const year = date.getUTCFullYear(); - const month = ("0" + (date.getUTCMonth() + 1)).slice(-2); - const day = ("0" + date.getUTCDate()).slice(-2); - const hours = ("0" + date.getUTCHours()).slice(-2); - const minutes = ("0" + date.getUTCMinutes()).slice(-2); - message.pub_date = year + "-" + month + "-" + day + " @ " + hours + ":" + minutes; - message.gravatar = gravatar_url(message.email, 48); - delete message.email; - }); - - console.log(messages); + let messages = await userService.getMessagesByUserId(userId); res.render('timeline', { endpoint: 'timeline', title: `${g.user.username}'s timeline`, - messages: messages, + messages: formatMessages(messages), g: g, profile_user: profile_user, followed: followed, }); - } catch (error) { console.error(error.message); res.status(500).send('Server error'); } }); -/* GET public timeline page. */ router.get('/public', async function (req, res, next) { - const g = { user: req.session.username }; - const endpoint = 'user' - const profile_user = 'example_profile_user'; // Example value, replace with actual profile user data - const followed = true; // Example value, replace with actual logic to determine if user is followed - - const sql = `SELECT message.text, message.pub_date, message.flagged, user.username, user.email - FROM message - JOIN user ON message.author_id = user.user_id - WHERE message.flagged != 1 - order by message.pub_date desc - LIMIT 50;` - - const messages = await new Promise((resolve, reject) => { - db.all(sql, [], (err, messages) => { - if (err) reject(err); - else resolve(messages); + try { + const g = { user: req.session.username }; + const endpoint = 'user' + const profile_user = 'example_profile_user'; + const followed = true; + let messages = await userService.getPublicTimelineMessages(); + res.render('timeline', { + endpoint: endpoint, + title: `Public Timeline`, + messages: formatMessages(messages), + g: g, + profile_user: profile_user, + followed: followed, }); - }); - - messages.forEach(message => { - const date = new Date(message.pub_date * 1000); - const year = date.getUTCFullYear(); - const month = ("0" + (date.getUTCMonth() + 1)).slice(-2); - const day = ("0" + date.getUTCDate()).slice(-2); - const hours = ("0" + date.getUTCHours()).slice(-2); - const minutes = ("0" + date.getUTCMinutes()).slice(-2); - message.pub_date = year + "-" + month + "-" + day + " @ " + hours + ":" + minutes; - message.gravatar = gravatar_url(message.email, 48); - delete message.email; - }); - - - res.render('timeline', { - endpoint: endpoint, - title: `Public Timeline`, - messages: messages, - g: g, - profile_user: profile_user, - followed: followed, - }); - + } catch (error) { + console.error(error.message); + res.status(500).send('Server error'); + } }); -/* GET timeline of another user. */ router.get('/:username', async function (req, res, next) { try { const g = { user: req.session.username }; const profile_user = 'example_profile_user'; const followed = true; - const username = req.params.username; - let userId; - const row = await new Promise((resolve, reject) => { - db.get(`SELECT user_id FROM user - JOIN message m - ON m.author_id = user.user_id - WHERE user.username = ?`, [username], (err, row) => { - if (err) reject(err); - else resolve(row); - }); - }); - - if (row) { - userId = row.user_id; - } - - const findMessages = `SELECT - message.text, - message.pub_date, - message.flagged, - user.username, - user.email - FROM message - JOIN user ON user.user_id = message.author_id - WHERE message.flagged != 1 AND user.user_id = ? - LIMIT 50;` - - const messages = await new Promise((resolve, reject) => { - db.all(findMessages, [userId], (err, messages) => { - if (err) reject(err); - else resolve(messages); - }); - }); - - messages.forEach(message => { - const date = new Date(message.pub_date * 1000); - const year = date.getUTCFullYear(); - const month = ("0" + (date.getUTCMonth() + 1)).slice(-2); - const day = ("0" + date.getUTCDate()).slice(-2); - const hours = ("0" + date.getUTCHours()).slice(-2); - const minutes = ("0" + date.getUTCMinutes()).slice(-2); - message.pub_date = year + "-" + month + "-" + day + " @ " + hours + ":" + minutes; - message.gravatar = gravatar_url(message.email, 48); - delete message.email; - }); - - console.log(messages); + const userId = await userService.getUserIdByUsername(username); + let messages = await userService.getMessagesByUserId(userId); res.render('timeline', { endpoint: 'user', title: `${username}'s Timeline`, - messages: messages, + messages: formatMessages(messages), g: g, profile_user: profile_user, followed: followed, }); - } catch (error) { console.error(error.message); res.status(500).send('Server error'); diff --git a/services/userService.js b/services/userService.js new file mode 100644 index 0000000..823a6aa --- /dev/null +++ b/services/userService.js @@ -0,0 +1,100 @@ +const sqlite3 = require('sqlite3').verbose(); + +class UserService { + constructor() { + this.db = new sqlite3.Database('./db/minitwit.db', sqlite3.OPEN_READWRITE, (err) => { + if (err) { + console.error(err.message); + } else { + console.log('Added db connection from user service'); + } + }); + } + + async addMessage(userId, messageContent, currentDate) { + const flagged = 0; + const sql = `INSERT INTO message (author_id, text, pub_date, flagged) VALUES (?, ?, ?, ?)`; + return new Promise((resolve, reject) => { + this.db.run(sql, [userId, messageContent, currentDate, flagged], (err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + } + + async getMessagesByUserId(id) { + const sql = `SELECT message.text, message.pub_date, message.flagged, user.username, user.email + FROM message + JOIN user ON message.author_id = user.user_id + WHERE message.flagged != 1 AND message.author_id = ? + ORDER BY message.pub_date DESC + LIMIT 50`; + return new Promise((resolve, reject) => { + this.db.all(sql, [id], (err, messages) => { + if (err) { + reject(err); + } else { + resolve(messages); + } + }); + }); + } + + async getMessagesFromUserAndFollowedUsers(userId) { + const sql = `SELECT message.text, message.pub_date, message.flagged, user.username, user.email + FROM message + JOIN user ON message.author_id = user.user_id + JOIN follower ON user.user_id = follower.who_id + WHERE message.flagged != 1 AND (follower.whom_id = message.author_id OR message.author_id = ?) + ORDER BY message.pub_date DESC + LIMIT 50`; + return new Promise((resolve, reject) => { + this.db.all(sql, [userId], (err, messages) => { + if (err) { + reject(err); + } else { + resolve(messages); + } + }); + }); + } + + async getPublicTimelineMessages() { + const sql = `SELECT message.text, message.pub_date, message.flagged, user.username, user.email + FROM message + JOIN user ON message.author_id = user.user_id + WHERE message.flagged != 1 + ORDER BY message.pub_date DESC + LIMIT 50`; + return new Promise((resolve, reject) => { + this.db.all(sql, [], (err, messages) => { + if (err) { + reject(err); + } else { + resolve(messages); + } + }); + }); + } + + async getUserIdByUsername(username) { + const sql = `SELECT user_id FROM user + JOIN message m + ON m.author_id = user.user_id + WHERE user.username = ?`; + return new Promise((resolve, reject) => { + this.db.get(sql, [username], (err, row) => { + if (err) { + reject(err); + } else { + resolve(row ? row.user_id : null); + } + }); + }); + } +} + +module.exports = UserService; \ No newline at end of file