This commit is contained in:
tejusk2 2022-07-28 19:42:22 -05:00
commit f1e9351dad
26 changed files with 127 additions and 122 deletions

View file

@ -1,3 +1,4 @@
import { Helmet } from 'react-helmet';
import { Outlet } from 'react-router-dom';
import { Box, CssBaseline } from '@mui/material';
import { createTheme, ThemeProvider } from '@mui/material/styles';
@ -22,6 +23,9 @@ export default function Layout() {
return (
<ThemeProvider theme={theme}>
<CssBaseline enableColorScheme />
<Helmet>
<title>qOverflow</title>
</Helmet>
<main>
<Navbar />
<Box sx={{ height: '92vh' }}>

View file

@ -1,5 +1,7 @@
import { Helmet } from 'react-helmet';
import { Link, useLocation } from 'react-router-dom';
import { Card, CardContent, Grid, Typography, Alert } from '@mui/material';
import { LoginForm } from '../controllers/FormControllers';
export default function Login() {
@ -10,29 +12,34 @@ export default function Login() {
}
return (
<Grid
container
spacing={2}
alignItems='center'
justifyContent='center'
style={{ height: '92vh' }}
>
<Grid item xs={3.5} />
<Grid item xs={5}>
<Card sx={{ padding: '1vh' }}>
<CardContent>
<LoginForm />
<Typography variant='body1'>
Forgot your password?{' '}
<Link to='/users/recover'>Recover Password</Link>
</Typography>
</CardContent>
</Card>
{returnMsg() ? (
<Alert severity='warning'> {returnMsg()} </Alert>
) : null}
<>
<Helmet>
<title>Log In - qOverflow</title>
</Helmet>
<Grid
container
spacing={2}
alignItems='center'
justifyContent='center'
style={{ height: '92vh' }}
>
<Grid item xs={3.5} />
<Grid item xs={5}>
<Card sx={{ padding: '1vh' }}>
<CardContent>
<LoginForm />
<Typography variant='body1'>
Forgot your password?{' '}
<Link to='/users/recover'>Recover Password</Link>
</Typography>
</CardContent>
</Card>
{returnMsg() ? (
<Alert severity='warning'> {returnMsg()} </Alert>
) : null}
</Grid>
<Grid item xs={3.5} />
</Grid>
<Grid item xs={3.5} />
</Grid>
</>
);
}

View file

@ -1,3 +1,4 @@
import { Helmet } from 'react-helmet';
import { Card, CardContent, Grid } from '@mui/material';
import CAPTCHA from 'assets/captcha.jpg';
@ -5,6 +6,10 @@ import { RegisterForm } from 'controllers/FormControllers';
export default function Register() {
return (
<>
<Helmet>
<title>Register - qOverflow</title>
</Helmet>
<Grid
container
spacing={2}
@ -25,5 +30,6 @@ export default function Register() {
</Grid>
<Grid item xs={3.5} />
</Grid>
</>
);
}

View file

@ -10,7 +10,7 @@ const http = require('http');
const mongoose = require('mongoose');
const cron = require('node-cron');
const {getAllQuestions, getAllUsers } = require('server/services/getData');
const { refreshQuestions, refreshUsers } = require('server/utils/cronRefresh');
require('dotenv').config();
@ -39,8 +39,8 @@ mongoose.connect(process.env.DB_CONN_STRING, {
mongoose.connection.once('open', () => console.log('MongoDB connected'));
mongoose.connection.on('error', console.error.bind(console, 'MongoDB connection error:'));
cron.schedule('*/2 * * * *', getAllUsers);
cron.schedule('*/30 * * * * *', getAllQuestions);
cron.schedule('*/30 * * * * *', refreshQuestions);
cron.schedule('*/2 * * * *', refreshUsers);
server.listen(port, console.log(`Listening on port: ${port}`));
server.on('error', onError);

View file

@ -1,7 +1,7 @@
const config = require('server/config.json');
const Answer = require('server/db/models/Answer');
const User = require('server/db/models/User');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const getUserLevel = require('server/utils/getUserLevel');
const createRequest = require('server/utils/api');

View file

@ -1,7 +1,7 @@
const config = require('server/config.json');
const Answer = require('server/db/models/Answer');
const Comment = require('server/db/models/Comment');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const createRequest = require('server/utils/api');
const getUserLevel = require('server/utils/getUserLevel');

View file

@ -1,6 +1,6 @@
const config = require('server/config.json');
const Comment = require('server/db/models/Comment');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const createRequest = require('server/utils/api');
const getUserLevel = require('server/utils/getUserLevel');

View file

@ -1,6 +1,6 @@
const config = require('server/config.json');
const Answer = require('server/db/models/Answer');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const createRequest = require('server/utils/api');
async function EditAnswerAccepted(req, res) {

View file

@ -1,5 +1,5 @@
const config = require('server/config.json');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const createRequest = require('server/utils/api');

View file

@ -1,6 +1,6 @@
const config = require('server/config.json');
const Question = require('server/db/models/Question');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const createRequest = require('server/utils/api');
const getUserLevel = require('server/utils/getUserLevel');

View file

@ -1,6 +1,6 @@
const config = require('server/config.json');
const Question = require('server/db/models/Question');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const getUserLevel = require('server/utils/getUserLevel');
const createRequest = require('server/utils/api');

View file

@ -1,6 +1,6 @@
const config = require('server/config.json');
const Question = require('server/db/models/Question');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const getUserLevel = require('server/utils/getUserLevel');
const createRequest = require('server/utils/api');

View file

@ -1,7 +1,7 @@
const config = require('server/config.json');
const User = require('server/db/models/User');
const Vote = require('server/db/models/Vote');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const createRequest = require('server/utils/api');
const getUserLevel = require('server/utils/getUserLevel');

View file

@ -1,48 +1,21 @@
const config = require('server/config.json');
const Answer = require('server/db/models/Answer');
const Question = require('server/db/models/Question');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const fetchAnswers = require('server/utils/fetchAnswers');
const { getAllAnswers } = require('server/utils/getData');
async function GetAnswers(req, res) {
const { question_id } = req.params;
const question = await getQuestion(question_id);
if (!question) return res.status(404).send(config.errorNotFound);
// Fetch answers if expired
if (Number(question.lastAnswerFetch) + config.answerExpires < Date.now()) {
const { success, requests } = await fetchAnswers(
`/questions/${question_id}/answers`
);
if (!success) return res.status(500).send(config.errorGeneric);
// Reformat questions and patch to cache
await requests
.map(({ answer_id, ...answer }) => {
return {
...answer,
id: answer_id,
question_id
}
})
.map(async (answer) => {
if (answer.accepted) {
await Question.findByIdAndUpdate(question_id, {
hasAccepted: true,
});
}
return Answer.findByIdAndUpdate(answer.id, answer, {
upsert: true,
});
});
const answers = await getAllAnswers({ question_id });
return res.send({ answers });
} else{
const answers = await Answer.find({ question_id });
return res.send({ answers });
}
const answers = await Answer.find({ question_id });
return res.send({ answers });
}
module.exports = GetAnswers;

View file

@ -1,6 +1,6 @@
const config = require('server/config.json');
const Comment = require('server/db/models/Comment');
const { getQuestion, refreshQuestion } = require('server/services/questionServices');
const { getQuestion, refreshQuestion } = require('server/utils/question');
const fetchComments = require('server/utils/fetchComments');
async function GetComments(req, res) {

View file

@ -1,5 +1,5 @@
const config = require('server/config.json');
const { getQuestion } = require('server/services/questionServices');
const { getQuestion } = require('server/utils/question');
async function GetQuestion(req, res) {
const { question_id } = req.params;

View file

@ -1,30 +0,0 @@
const Question = require('server/db/models/Question');
const User = require('server/db/models/User');
const fetchData = require('server/utils/fetchData');
async function getAllData(_job, done, Model, url, id, dataName) {
console.log('[INFO]: Refreshing question database.');
const data = await fetchData(url, id, dataName);
if (!success) console.log(`[ERROR]: ${dataName} fetch failed`);
for (const item of data)
await Model.findByIdAndUpdate(item[id], {
...item,
id: item[id],
}, { upsert: true })
done();
}
async function getAllQuestions(_job, done) {
return getAllData(_job, done, Question, '/questions/search', 'question_id', 'questions')
}
async function getAllUsers(_job, done) {
return getAllData(_job, done, User, '/users', 'user_id', 'users')
}
module.exports = {
getAllQuestions,
getAllUsers
};

View file

@ -0,0 +1,15 @@
const { getAllQuestions, getAllUsers } = require('./getData');
async function refreshQuestions(_job, done) {
await getAllQuestions();
done();
}
async function refreshUsers(_job, done) {
await getAllUsers();
done();
}
module.exports = {
refreshQuestions,
refreshUsers
}

View file

@ -1,12 +1,10 @@
const createRequest = require('./api');
const defaultAcc = [];
async function fetchData(
url,
id,
dataName,
acc = defaultAcc,
acc = [],
after = ''
) {
const { success, [dataName]: data } = await createRequest('get', url, { after });

View file

@ -1,19 +0,0 @@
const createRequest = require('./api');
const defaultAcc = [];
async function fetchQuestions(
acc = defaultAcc,
after = ''
) {
const { success, questions } = await createRequest('get', '/questions/search', { after });
if (!success || !questions.length) return acc;
const newAcc = [...acc, ...questions];
const oldest = users[questions.length - 1];
return fetchQuestions(newAcc, oldest.question_id);
}
module.exports = fetchQuestions;

51
server/utils/getData.js Normal file
View file

@ -0,0 +1,51 @@
const Answer = require('server/db/models/Answer');
const Comment = require('server/db/models/Comment');
const Mail = require('server/db/models/Mail');
const Question = require('server/db/models/Question');
const User = require('server/db/models/User');
const fetchData = require('server/utils/fetchData');
async function getAllData(Model, url, id, dataName) {
console.log(`[INFO]: Refreshing ${dataName} database.`);
let data = await fetchData(url, id, dataName);
data = data.map((item) => ({
...item,
id: item[id],
}));
for (const item of data)
await Model.findByIdAndUpdate(item[id], item, { upsert: true });
return data;
}
async function getAllAnswers({ question_id, username }) {
if (question_id)
return getAllData(Answer, `/questions/${question_id}/answers`, 'answer_id', 'answers')
else if (username)
return getAllData(Answer, `/users/${username}/answers`, 'answer_id', 'answers')
}
async function getAllComments({ question_id }) {
return getAllData(Comment, `/questions/${question_id}/comments`, 'comment_id', 'comments')
}
async function getAllMail({ question_id }) {
return getAllData(Mail, `/questions/${question_id}/comments`, 'mail_id', 'mail')
}
async function getAllQuestions({ username }) {
if (username)
return getAllData(Question, `/users/${username}/questions`, 'question_id', 'questions')
else
return getAllData(Question, `/questions/search`, 'question_id', 'questions')
}
async function getAllUsers() {
return getAllData(User, `/users`, 'user_id', 'users')
}
module.exports = {
getAllAnswers,
getAllComments,
getAllQuestions,
getAllUsers
};