1diff --git a/controller/controller.go b/controller/controller.go
2index 3e029f05d736f699c76a95672b6575d4f64fda12..7cbee6a499fa7308f5251df609fdcce179979afd 100644
3--- a/controller/controller.go
4+++ b/controller/controller.go
5@@ -49,3 +49,8 @@ id := c.Param("id")
6 e.Entries.Delete(id)
7 c.HTML(http.StatusOK, "entry", entry)
8 }
9+
10+func (e *Env) GetJobs(c *gin.Context) {
11+ jobs := e.Worker.GetJobs()
12+ c.JSON(http.StatusOK, jobs)
13+}
14diff --git a/routes/routes.go b/routes/routes.go
15index a609019a55130dcc4698cc758c37e2e1df9766a2..79264c5feebe65217e721bde51938d3c3f9942a1 100644
16--- a/routes/routes.go
17+++ b/routes/routes.go
18@@ -29,5 +29,6 @@ r.POST("entries/", env.CreateEntry)
19 r.GET("entries/:id", env.GetEntry)
20 r.POST("entries/:id", env.UpdateEntry)
21 r.DELETE("entries/:id", env.DeleteEntry)
22+ r.GET("jobs/", env.GetJobs)
23 r.Run(":8000")
24 }
25diff --git a/templates/_footer.tmpl b/templates/_footer.tmpl
26index 07bc857b8d34b7ddeec05bcccfad2d690eacf5e9..97a5bf86321cb9dfb79e36f15c192f3bb67392ba 100644
27--- a/templates/_footer.tmpl
28+++ b/templates/_footer.tmpl
29@@ -8,6 +8,20 @@ .then((res)=>{
30 window.location.href = '/'
31 });
32 }
33+
34+ function getStatus() {
35+ fetch("/jobs/", { method: 'GET'})
36+ .then((res) => { return objs = res.json(); })
37+ .then((objs) => {
38+ for (i in objs) {
39+ span = document.getElementById("status_"+objs[i].Id);
40+ span.textContent = objs[i].Status;
41+ }
42+ });
43+ }
44+
45+setInterval(getStatus, 1000);
46+
47 </script>
48 </body>
49 </html>
50diff --git a/templates/_head.tmpl b/templates/_head.tmpl
51index 2bb58c474a8361c1c872edd941179d79702174f0..b99510f9b7ebbd4035848c4735481ebd55ee3a5c 100644
52--- a/templates/_head.tmpl
53+++ b/templates/_head.tmpl
54@@ -2,6 +2,7 @@ {{ define "_head" }}
55 <!DOCTYPE html>
56 <html>
57 <head>
58+ <meta name="viewport" content="width=device-width, initial-scale=1">
59 <link rel="stylesheet" href="/assets/bulma.min.css">
60 </head>
61 <body>
62diff --git a/templates/index.tmpl b/templates/index.tmpl
63index 9bb7512f268db6190caae39503ad6aeac64e2caa..ae7f6747e8f506135ea1732727f54b8ab1886e4c 100644
64--- a/templates/index.tmpl
65+++ b/templates/index.tmpl
66@@ -8,6 +8,7 @@ <th scope="col">ID</th>
67 <th scope="col">Title</th>
68 <th scope="col">Link</th>
69 <th scope="col">Output</th>
70+ <th scope="col">Status</th>
71 <th scope="col"></th>
72 </tr>
73 </thead>
74@@ -18,6 +19,9 @@ <td>{{ .ID }}</td>
75 <td>{{ .Title }}</td>
76 <td>{{ .Link }}</td>
77 <td>{{ .OutputFolder }}</td>
78+ <td>
79+ <span id="status_{{ .ID }}" class="tag is-primary is-light"></span>
80+ </td>
81 <td>
82 <a href="entries/{{ .ID }}" >Edit</a>
83 </span>
84diff --git a/worker/worker.go b/worker/worker.go
85index 5e0c844f45cdbc8f98a369b418264d4ce9254d98..f56716f0b7426fcba4407da26eb8150f8dbd1986 100644
86--- a/worker/worker.go
87+++ b/worker/worker.go
88@@ -10,11 +10,13 @@ work "git.sr.ht/~sircmpwn/dowork"
89 )
90
91 const (
92- statusStoped = "STOPPED"
93- statusStarted = "STARTED"
94+ statusNotQueued = "NOTQUEUED"
95+ statusQueued = "QUEUED"
96+ statusStarted = "RUNNING"
97
98- commandStart = "START"
99- commandStop = "STOP"
100+ commandStart = "START"
101+ commandEnqueue = "ENQUEUE"
102+ commandDequeue = "DEQUEUE"
103 )
104
105 type command struct {
106@@ -27,18 +29,29 @@ jobs map[uint]string
107 c chan command
108 }
109
110+type Job struct {
111+ Id uint
112+ Status string
113+}
114+
115+func (w *Worker) CanEnqueue(index uint) bool {
116+ v, found := w.jobs[index]
117+ return !found || v == statusNotQueued
118+}
119+
120 func (w *Worker) SpawnWorker(index uint, link string, output string) {
121
122- if v, found := w.jobs[index]; found && v == statusStarted {
123+ if !w.CanEnqueue(index) {
124 return
125 }
126
127- w.c <- command{action: commandStart, index: index}
128+ w.c <- command{action: commandEnqueue, index: index}
129 task := work.NewTask(func(ctx context.Context) error {
130+ w.c <- command{action: commandStart, index: index}
131 yt.RunYtDlpProcess(link, output)
132 return nil
133 }).After(func(ctx context.Context, task *work.Task) {
134- w.c <- command{action: commandStop, index: index}
135+ w.c <- command{action: commandDequeue, index: index}
136 })
137
138 work.Enqueue(task)
139@@ -48,10 +61,12 @@ func (w *Worker) startReader() {
140 for true {
141 command := <-w.c
142
143- if command.action == commandStop {
144- w.jobs[command.index] = statusStoped
145+ if command.action == commandEnqueue {
146+ w.jobs[command.index] = statusQueued
147 } else if command.action == commandStart {
148 w.jobs[command.index] = statusStarted
149+ } else if command.action == commandDequeue {
150+ w.jobs[command.index] = statusNotQueued
151 } else {
152 panic(1)
153 }
154@@ -74,3 +89,13 @@ w.jobs = make(map[uint]string)
155 go w.startReader()
156 go w.startScheduler(model)
157 }
158+
159+func (w *Worker) GetJobs() []Job {
160+ jobs := []Job{}
161+
162+ for k, v := range w.jobs {
163+ jobs = append(jobs, Job{Id: k, Status: v})
164+ }
165+
166+ return jobs
167+}