Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PORT=2000
Binary file added dump.rdb
Binary file not shown.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"jsondiffpatch": "^0.4.1",
"moment": "^2.29.1",
"mongoose": "^5.9.26",
"nodemon": "^1.19.4"
"nodemon": "^1.19.4",
"redis": "3.1.0"
},
"devDependencies": {
"eslint": "^6.5.1",
Expand Down
296 changes: 267 additions & 29 deletions src/controllers/article_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ const mockController = require('../mock')
const mongoose = require('mongoose')
const categories = ['政經', '社會', '環境', '運動', '國際', '科技', '生活']

const Redis = require('redis')

const redisClient = Redis.createClient()
const DEFAULT_EXPIRATION = 3600

const isExistedAuthor = (originalAuthors, targetAuthor) => {
return originalAuthors.some(author => JSON.stringify(author) === JSON.stringify(targetAuthor))
}
Expand Down Expand Up @@ -186,22 +191,22 @@ module.exports = {
message: '查無搜尋結果'
})
} else {
const latestNewsCount = await LatestNews.find({}).sort({ _id: -1 })
console.log(latestNewsCount)
// const latestNewsCount = await LatestNews.find({}).sort({ _id: -1 })
// console.log(latestNewsCount)
const doc2 = []
var i = 0
for (const latestNews of latestNewsCount) {
if (i <= 6) {
try {
const { category, title, viewsCount, _id, tags, lastUpdatedAt, editedCount, blocks } = await Article.findById(latestNews.articleId)
// console.log(await Article.findById(latestNews.articleId))
doc2.push({ category, title, viewsCount, _id, tags, lastUpdatedAt, editedCount, blocks })
} catch (error) {
console.log(error)
}
}
i += 1
}
// var i = 0
// for (const latestNews of latestNewsCount) {
// if (i <= 6) {
// try {
// const { category, title, viewsCount, _id, tags, lastUpdatedAt, editedCount, blocks } = await Article.findById(latestNews.articleId)
// // console.log(await Article.findById(latestNews.articleId))
// doc2.push({ category, title, viewsCount, _id, tags, lastUpdatedAt, editedCount, blocks })
// } catch (error) {
// console.log(error)
// }
// }
// i += 1
// }
res.json({
code: 200,
type: 'success',
Expand All @@ -210,6 +215,97 @@ module.exports = {
}
})
},
async getPopularArticle (req, res, next) {
console.log('getting Popular articles')
if (req.query.mode === MODE.DEBUG) {
console.log('[Mock][Articles] use mock data')
mockController.mockArticles(req, res)
return
}
if (req.query.limit === undefined) {
req.query.limit = 6 /// default value
console.log(`default limit value : ${req.query.limit}`)
}
console.log(req.query.limit, ' limit')
const keyword = req.query.q || ''

const limit = Number(req.query.limit)
console.log('getArticles: ' + keyword + ',' + limit, ' .......')
Article.find(
{
$or: [
{
title: {
$regex: keyword,
$options: 'i'
}
},
{
outline: {
$regex: keyword,
$options: 'i'
}
}
]
},
null,
{ limit: limit, sort: { viewsCount: -1 } }
).exec(async (err, doc) => {
if (err || doc.length === 0) {
res.status(200).send({
code: 404,
type: 'success',
message: '查無搜尋結果'
})
} else {
for (let i = 0; i < doc.length; i++) {
console.log(i, doc[i].title, doc[i]._id, doc[i].viewsCount)
}
res.json({
code: 200,
type: 'success',
data: [doc]
})
}
})
},
async getArticlesOthers (req, res, next) {
console.log('getting Popular articles')
if (req.query.mode === MODE.DEBUG) {
console.log('[Mock][Articles] use mock data')
mockController.mockArticles(req, res)
return
}
if (req.query.limit === undefined) {
req.query.limit = 6 /// default value
console.log(`default limit value : ${req.query.limit}`)
}
console.log(req.query.limit, ' limit')
const keyword = req.query.q || ''

const limit = Number(req.query.limit)
console.log('getArticles: ' + keyword + ',' + limit, ' .......')
Article.aggregate(
[{ $sample: { size: 6 } }]
).exec(async (err, doc) => {
if (err || doc.length === 0) {
res.status(200).send({
code: 404,
type: 'success',
message: '查無搜尋結果'
})
} else {
for (let i = 0; i < doc.length; i++) {
console.log(i, doc[i].title, doc[i]._id, doc[i].viewsCount, 'random')
}
res.json({
code: 200,
type: 'success',
data: [doc]
})
}
})
},
searchArticles (req, res, next) {
const keyword = req.query.q || ''
const checkQueryLimit = Number(req.query.limit)
Expand Down Expand Up @@ -736,21 +832,163 @@ module.exports = {
console.log(error)
}
},
async getPopularArticle (req, res, next) {
const latestNewsCount = await LatestNews.find({}).sort({ _id: -1 })
const doc = []
var i = 0
for (const latestNews of latestNewsCount) {
if (i <= 6) {
const { category, title, viewsCount } = Article.findById(latestNews.articleId)
doc.push({ category, title, viewsCount })
// async getPopularArticle (req, res, next) {
// const latestNewsCount = await LatestNews.find({}).sort({ _id: -1 })
// const doc = []
// var i = 0
// for (const latestNews of latestNewsCount) {
// if (i <= 6) {
// const { category, title, viewsCount } = Article.findById(latestNews.articleId)
// doc.push({ category, title, viewsCount })
// }
// i += 1
// }
// res.status(200).send({
// code: 200,
// type: 'success',
// data: doc
// })
// },
async getArticleAuthorsImg (req, res, next) {
console.log('article/getArticleAuthors.....')
try {
const articleId = req.params.id
const authorsData = await getOrSetCache(`ArticleId:${articleId}_AuthorsImg`, async () => {
const doc = await Article.findById(articleId).exec()
const authors = []
for (const author of doc.authors) {
const { displayName, photoURL, email } = await Utils.firebase.getUserInfoById(
author.uid
)
authors.push({ uid: author.uid, displayName: displayName, photoURL: photoURL, email: email, isAnomynous: author.isAnonymous })
}
return authors
})

res.status(200).send({
code: 200,
type: 'success',
data: authorsData,
message: '已成功抓取作者'
})
} catch (error) {
console.log(error)
}
},
async putDeleteArticleById (req, res, next) {
try {
const { id } = req.body
const deletedArticle = await Article.findById(id)
if (deletedArticle === undefined) {
return res.status(200).send({
code: 500,
type: 'error',
message: '文章的ID輸入有誤,請重新查詢'
})
}
i += 1

// 刪除 ../models/article.js 的 articleSchema // 還有 blockSchema (增加刪除標記)
deletedArticle.blocks.forEach((block, index) => {
if (block.blockDateTime == null) {
console.log(
'blockDateTime bug 就算沒有打blockDatetime 也可以發布新block'
)
block.blockDateTime = Date.now() // default 把 block date time設定為現在
}
block.isdeleted = true
})
deletedArticle.isdeleted = true

await deletedArticle.save()

const allArticleblocks = await Block.find({ articleId: id })

// 刪除 ../models/block.js 的blockSchema // 還有 block 裡面的 revision schema
allArticleblocks.forEach(async (block, blockIndex) => {
block.isdeleted = true
block.revisions.forEach(async (rev, revIndex) => {
rev.isdeleted = true
})
await block.save()
})
// 刪除../models/content.js 的 content schema
const allContents = await Content.find({ articleId: id })
allContents.forEach(async (content, contentIndex) => {
content.isdeleted = true
await content.save()
})
// latestNews
const allLatest = await LatestNews.find({ articleId: id })
allLatest.forEach(async (latest, Index) => {
latest.isdeleted = true
await latest.save()
})

// version
const allVersion = await Version.find({ articleId: id })
console.log(allVersion, ' allv')
allVersion.forEach(async (ver, verIndex) => {
ver.versions.forEach((v2, v2Index) => {
v2.blocks.forEach((v3, v3Index) => {
console.log(v3, ` v33 ${v3Index}`)
v3.isdeleted = true
})
v2.isdeleted = true
})
ver.isdeleted = true
await ver.save()
})
return res.status(200).send({
test: '軟刪除成功'
})
} catch (error) {
console.log(error)
res.status(200).send({
code: 500,
type: 'error',
message: error.message
})
}
},
async deleteArticleById (req, res, next) {
try {
const { id } = req.body
const article = await Article.findOne({ _id: id })
await Article.deleteOne({ _id: id })

await Block.deleteMany({ articleId: id })
await Content.deleteMany({ articleId: id })
await LatestNews.deleteMany({ articleId: id })
await Version.deleteMany({ articleId: id })

return res.status(200).send({
test: `硬刪除成功 articleid: ${id} ${article.title}`
})
} catch (error) {
console.log(error)
res.status(200).send({
code: 500,
type: 'error',
message: error.message
})
}
res.status(200).send({
code: 200,
type: 'success',
data: doc
})
}
}

function getOrSetCache (key, cb) {
return new Promise((resolve, reject) => {
redisClient.get(key, async (error, data) => {
if (error) {
return reject(error)
}
if (data != null) {
console.log('Cache Hit')
return resolve(JSON.parse(data))
}
console.log('Cache Miss')
const freshData = await cb()
redisClient.setex(key, DEFAULT_EXPIRATION, JSON.stringify(freshData))
resolve(freshData)
})
})
}
52 changes: 51 additions & 1 deletion src/controllers/auth_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,57 @@ const auth = {
})
}
},
getArticlesInfo
getArticlesInfo,
async getManyUsersInfo (req, res) {
try {
const { uids } = req.body
const userinfo = []
for (let i = 0; i < uids.length; i++) {
const uid = uids[i]
const { displayName } = await Utils.firebase.getUserInfoById(
uid
)
const userRef = firebase.db.collection('articles').doc(uid)
const points = await Utils.firebase.handleGetUserPoints(uid)
const doc = await userRef.get()
const editedList = doc.get('edited') || []
const viewedList = doc.data().viewed || []
const subscribedList = doc.get('subscribed') || []

const editedArticleIds = editedList.map(edited => edited.articleId)
const viewedArticleIds = viewedList
const subscribedArticleIds = subscribedList.map(subscribed => subscribed.articleId)
// for(let j=0;jh)
const q = handleGetArticlesByArray
const result = await Promise.all([q(editedArticleIds), q(viewedArticleIds), q(subscribedArticleIds)])
console.log(result[0].length, result[1].length, result[2].length, '000000000')
console.log(editedArticleIds.length, viewedArticleIds.length, subscribedArticleIds.length)
result[0].forEach((e, i) => {
console.log(e.title, ':....')
})
userinfo.push({
displayName: displayName,
edited: result[0],
viewed: result[1],
subscribed: result[2],
points
})
}
res.json({
code: 200,
type: 'success',
message: `已成功傳送${userinfo.length}個使用者資料`,
data: userinfo
})
} catch (error) {
console.log(error)
res.status(500).send({
code: 500,
type: 'error',
message: error.message
})
}
}
}

async function getArticlesInfo (req, res) {
Expand Down
Loading