]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/controllers/api/jobs.ts
Add ability to cancel & delete video imports
[github/Chocobozzz/PeerTube.git] / server / controllers / api / jobs.ts
1 import express from 'express'
2 import { HttpStatusCode, Job, JobState, JobType, ResultList, UserRight } from '@shared/models'
3 import { isArray } from '../../helpers/custom-validators/misc'
4 import { JobQueue } from '../../lib/job-queue'
5 import {
6 asyncMiddleware,
7 authenticate,
8 ensureUserHasRight,
9 jobsSortValidator,
10 openapiOperationDoc,
11 paginationValidatorBuilder,
12 setDefaultPagination,
13 setDefaultSort
14 } from '../../middlewares'
15 import { listJobsValidator } from '../../middlewares/validators/jobs'
16
17 const jobsRouter = express.Router()
18
19 jobsRouter.post('/pause',
20 authenticate,
21 ensureUserHasRight(UserRight.MANAGE_JOBS),
22 asyncMiddleware(pauseJobQueue)
23 )
24
25 jobsRouter.post('/resume',
26 authenticate,
27 ensureUserHasRight(UserRight.MANAGE_JOBS),
28 asyncMiddleware(resumeJobQueue)
29 )
30
31 jobsRouter.get('/:state?',
32 openapiOperationDoc({ operationId: 'getJobs' }),
33 authenticate,
34 ensureUserHasRight(UserRight.MANAGE_JOBS),
35 paginationValidatorBuilder([ 'jobs' ]),
36 jobsSortValidator,
37 setDefaultSort,
38 setDefaultPagination,
39 listJobsValidator,
40 asyncMiddleware(listJobs)
41 )
42
43 // ---------------------------------------------------------------------------
44
45 export {
46 jobsRouter
47 }
48
49 // ---------------------------------------------------------------------------
50
51 async function pauseJobQueue (req: express.Request, res: express.Response) {
52 await JobQueue.Instance.pause()
53
54 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
55 }
56
57 async function resumeJobQueue (req: express.Request, res: express.Response) {
58 await JobQueue.Instance.resume()
59
60 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
61 }
62
63 async function listJobs (req: express.Request, res: express.Response) {
64 const state = req.params.state as JobState
65 const asc = req.query.sort === 'createdAt'
66 const jobType = req.query.jobType
67
68 const jobs = await JobQueue.Instance.listForApi({
69 state,
70 start: req.query.start,
71 count: req.query.count,
72 asc,
73 jobType
74 })
75 const total = await JobQueue.Instance.count(state, jobType)
76
77 const result: ResultList<Job> = {
78 total,
79 data: await Promise.all(jobs.map(j => formatJob(j, state)))
80 }
81
82 return res.json(result)
83 }
84
85 async function formatJob (job: any, state?: JobState): Promise<Job> {
86 const error = isArray(job.stacktrace) && job.stacktrace.length !== 0
87 ? job.stacktrace[0]
88 : null
89
90 return {
91 id: job.id,
92 state: state || await job.getState(),
93 type: job.queue.name as JobType,
94 data: job.data,
95 progress: await job.progress(),
96 priority: job.opts.priority,
97 error,
98 createdAt: new Date(job.timestamp),
99 finishedOn: new Date(job.finishedOn),
100 processedOn: new Date(job.processedOn)
101 }
102 }