添加cronjob,每分钟检查并删除超过24h的分享

This commit is contained in:
赵鑫 2022-08-27 01:47:08 +08:00
parent 659aa9d111
commit e88d21e354
3 changed files with 65 additions and 12 deletions

30
package-lock.json generated
View File

@ -10,6 +10,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"bcrypt": "^5.0.1", "bcrypt": "^5.0.1",
"cron": "^2.1.0",
"dotenv": "^16.0.1", "dotenv": "^16.0.1",
"express": "^4.18.1", "express": "^4.18.1",
"md5-file": "^5.0.0", "md5-file": "^5.0.0",
@ -551,6 +552,14 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
}, },
"node_modules/cron": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cron/-/cron-2.1.0.tgz",
"integrity": "sha512-Hq7u3P8y7UWYvsZbSKHHJDVG0VO9O7tp2qljxzTScelcTODBfCme8AIhnZsFwmQ9NchZ3hr2uNr+s3DSms7q6w==",
"dependencies": {
"luxon": "^1.23.x"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -1111,6 +1120,14 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==",
"engines": {
"node": "*"
}
},
"node_modules/make-dir": { "node_modules/make-dir": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@ -2664,6 +2681,14 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
}, },
"cron": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cron/-/cron-2.1.0.tgz",
"integrity": "sha512-Hq7u3P8y7UWYvsZbSKHHJDVG0VO9O7tp2qljxzTScelcTODBfCme8AIhnZsFwmQ9NchZ3hr2uNr+s3DSms7q6w==",
"requires": {
"luxon": "^1.23.x"
}
},
"debug": { "debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -3085,6 +3110,11 @@
"yallist": "^4.0.0" "yallist": "^4.0.0"
} }
}, },
"luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ=="
},
"make-dir": { "make-dir": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",

View File

@ -16,6 +16,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"bcrypt": "^5.0.1", "bcrypt": "^5.0.1",
"cron": "^2.1.0",
"dotenv": "^16.0.1", "dotenv": "^16.0.1",
"express": "^4.18.1", "express": "^4.18.1",
"md5-file": "^5.0.0", "md5-file": "^5.0.0",

View File

@ -6,6 +6,7 @@ const bcrypt = require('bcrypt')
const md5file = require('md5-file') const md5file = require('md5-file')
const express = require('express') const express = require('express')
const mongoose = require('mongoose') const mongoose = require('mongoose')
const CronJob = require('cron').CronJob
const Filesharing = require('./models/Filesharing') const Filesharing = require('./models/Filesharing')
mongoose.connect(MONGODB_URL, (error) => { mongoose.connect(MONGODB_URL, (error) => {
if (error) { if (error) {
@ -14,6 +15,25 @@ mongoose.connect(MONGODB_URL, (error) => {
console.info('mongodb connected successfully') console.info('mongodb connected successfully')
} }
}) })
const job = new CronJob(
'0 * * * * *',
async () => {
const files = await Filesharing.find({ createdAt: { $lt: new Date(Date.now() - 24 * 3600 * 1000) } })
for (let file of files) {
const id = file.id
await Filesharing.findByIdAndDelete(id)
console.log(`删除共享 ${id}`)
const ref_number = await Filesharing.countDocuments({ md5: file.md5 })
if (ref_number == 0) {
const file_path = path.join(__dirname, UPLOAD_SAVE_PATH, file.md5)
fs.unlinkSync(file_path)
console.log(`删除文件 ${file_path}`)
}
}
},
null,
true
)
const app = express() const app = express()
app.set('view engine', 'pug') app.set('view engine', 'pug')
app.use(express.static('public')) app.use(express.static('public'))
@ -47,19 +67,9 @@ app.post('/upload', upload.single('file'), async (req, res) => {
filename: Buffer.from(req.file.originalname, 'latin1').toString('utf8'), filename: Buffer.from(req.file.originalname, 'latin1').toString('utf8'),
password: req.body.password ? await bcrypt.hash(req.body.password, 16) : '', password: req.body.password ? await bcrypt.hash(req.body.password, 16) : '',
}) })
console.log(`上传文件 ${file.filename}`)
res.status(201).render('upload', { file }) res.status(201).render('upload', { file })
}) })
app.get('/file/:md5', async (req, res) => {
try {
const file = await Filesharing.findOne({ md5: req.params.md5 })
if (!file) throw '试图下载不存在的文件'
if (file.password != '') throw '访问的文件需要密码'
res.sendFile(path.join(__dirname, UPLOAD_SAVE_PATH, req.params.md5))
} catch (error) {
console.error(error)
res.sendStatus(404)
}
})
app.get('/download/:id', async (req, res) => { app.get('/download/:id', async (req, res) => {
try { try {
if (!req.params.id.match(/^[0-9a-fA-F]{24}$/)) throw '格式错误的ObjectId' if (!req.params.id.match(/^[0-9a-fA-F]{24}$/)) throw '格式错误的ObjectId'
@ -77,7 +87,8 @@ app.post('/download/:id', async (req, res) => {
const file = await Filesharing.findById(req.params.id) const file = await Filesharing.findById(req.params.id)
if (!file) throw '试图下载不存在的文件' if (!file) throw '试图下载不存在的文件'
if (file.password == '' || (await bcrypt.compare(req.body.password, file.password)) == true) { if (file.password == '' || (await bcrypt.compare(req.body.password, file.password)) == true) {
await file.update({ $inc: { downloads: 1 } }) await Filesharing.findByIdAndUpdate(req.params.id, { $inc: { downloads: 1 } })
console.log(`下载文件 ${file.filename}`)
res.status(200).download(path.join(UPLOAD_SAVE_PATH, file.md5), file.filename) res.status(200).download(path.join(UPLOAD_SAVE_PATH, file.md5), file.filename)
} else { } else {
res.sendStatus(401) res.sendStatus(401)
@ -87,6 +98,17 @@ app.post('/download/:id', async (req, res) => {
res.sendStatus(404) res.sendStatus(404)
} }
}) })
app.get('/file/:md5', async (req, res) => {
try {
const file = await Filesharing.findOne({ md5: req.params.md5 })
if (!file) throw '试图下载不存在的文件'
if (file.password != '') throw '访问的文件需要密码'
res.sendFile(path.join(__dirname, UPLOAD_SAVE_PATH, req.params.md5))
} catch (error) {
console.error(error)
res.sendStatus(404)
}
})
const server = app.listen(SERVER_PORT, SERVER_HOST, () => { const server = app.listen(SERVER_PORT, SERVER_HOST, () => {
console.info(`server is running at http://${SERVER_HOST}:${SERVER_PORT}`) console.info(`server is running at http://${SERVER_HOST}:${SERVER_PORT}`)
}) })