mirror of
https://github.com/YunoHost/yunorunner.git
synced 2024-09-03 20:05:52 +02:00
[enh] make one new page per app
This commit is contained in:
parent
719cb13c08
commit
84cc6f86a3
2 changed files with 113 additions and 7 deletions
43
run.py
43
run.py
|
@ -322,7 +322,7 @@ async def run_job(worker, job):
|
|||
await broadcast({
|
||||
"action": "update_job",
|
||||
"data": model_to_dict(job),
|
||||
}, ["jobs", f"job-{job.id}"])
|
||||
}, ["jobs", f"job-{job.id}", f"app-jobs-{job.url_or_path}"])
|
||||
|
||||
# fake stupid command, whould run CI instead
|
||||
task_logger.info(f"Starting job '{job.name}' #{job.id}...")
|
||||
|
@ -351,7 +351,7 @@ async def run_job(worker, job):
|
|||
"action": "update_job",
|
||||
"id": job.id,
|
||||
"data": model_to_dict(job),
|
||||
}, ["jobs", f"job-{job.id}"])
|
||||
}, ["jobs", f"job-{job.id}", f"app-jobs-{job.url_or_path}"])
|
||||
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
|
@ -385,7 +385,7 @@ async def run_job(worker, job):
|
|||
"action": "update_job",
|
||||
"id": job.id,
|
||||
"data": model_to_dict(job),
|
||||
}, ["jobs", f"job-{job.id}"])
|
||||
}, ["jobs", f"job-{job.id}", f"app-jobs-{job.url_or_path}"])
|
||||
|
||||
|
||||
async def broadcast(message, channels):
|
||||
|
@ -539,6 +539,24 @@ async def ws_apps(request, websocket):
|
|||
await websocket.recv()
|
||||
|
||||
|
||||
@app.websocket('/app-<app_name>-ws')
|
||||
async def ws_app(request, websocket, app_name):
|
||||
# XXX I don't check if the app exists because this websocket is supposed to
|
||||
# be only loaded from the app page which does this job already
|
||||
app = Repo.select().where(Repo.name == app_name)[0]
|
||||
|
||||
subscribe(websocket, f"app-jobs-{app.url}")
|
||||
|
||||
await websocket.send(ujson.dumps({
|
||||
"action": "init_jobs",
|
||||
"data": Job.select().where(Job.url_or_path == app.url).order_by(-Job.id),
|
||||
}))
|
||||
|
||||
while True:
|
||||
# do nothing with input but wait
|
||||
await websocket.recv()
|
||||
|
||||
|
||||
def require_token():
|
||||
def decorator(f):
|
||||
@wraps(f)
|
||||
|
@ -584,7 +602,7 @@ async def api_new_job(request):
|
|||
await broadcast({
|
||||
"action": "new_job",
|
||||
"data": model_to_dict(job),
|
||||
}, "jobs")
|
||||
}, ["jobs", f"app-jobs-{job.url_or_path}"])
|
||||
|
||||
return response.text("ok")
|
||||
|
||||
|
@ -618,7 +636,7 @@ async def api_delete_job(request, job_id):
|
|||
await broadcast({
|
||||
"action": "delete_job",
|
||||
"data": data,
|
||||
}, ["jobs", f"job-{job_id}"])
|
||||
}, ["jobs", f"job-{job_id}", f"app-jobs-{job.url_or_path}"])
|
||||
|
||||
return response.text("ok")
|
||||
|
||||
|
@ -643,7 +661,7 @@ async def api_stop_job(request, job_id):
|
|||
await broadcast({
|
||||
"action": "update_job",
|
||||
"data": model_to_dict(job),
|
||||
}, ["jobs", f"job-{job.id}"])
|
||||
}, ["jobs", f"job-{job.id}", f"app-jobs-{job.url_or_path}"])
|
||||
|
||||
return response.text("ok")
|
||||
|
||||
|
@ -662,7 +680,7 @@ async def api_stop_job(request, job_id):
|
|||
await broadcast({
|
||||
"action": "update_job",
|
||||
"data": model_to_dict(job),
|
||||
}, ["jobs", f"job-{job.id}"])
|
||||
}, ["jobs", f"job-{job.id}", f"app-jobs-{job.url_or_path}"])
|
||||
|
||||
return response.text("ok")
|
||||
|
||||
|
@ -710,6 +728,17 @@ async def html_apps(request):
|
|||
return {'relative_path_to_root': '../', 'path': request.path}
|
||||
|
||||
|
||||
@app.route('/apps/<app_name>/')
|
||||
@jinja.template('app.html')
|
||||
async def html_app(request, app_name):
|
||||
app = Repo.select().where(Repo.name == app_name)
|
||||
|
||||
if app.count == 0:
|
||||
raise NotFound()
|
||||
|
||||
return {"app": app[0], 'relative_path_to_root': '../../', 'path': request.path}
|
||||
|
||||
|
||||
@app.route('/')
|
||||
@jinja.template('index.html')
|
||||
async def html_index(request):
|
||||
|
|
77
templates/app.html
Normal file
77
templates/app.html
Normal file
|
@ -0,0 +1,77 @@
|
|||
<% extends "base.html" %>
|
||||
|
||||
<% block content %>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">Jobs for app <{ app.name }> <a target="_blank" href="<{ app.url }>">↪</a></h1>
|
||||
<div id="jobs">
|
||||
<table class="table is-bordered is-hoverable is-striped is-fullwidth">
|
||||
<thead>
|
||||
<th>App</th>
|
||||
<th>State</th>
|
||||
<th>Created time</th>
|
||||
<th>Started time</th>
|
||||
<th>End time</th>
|
||||
</thead>
|
||||
<tr v-for="(job, index) in jobs" :id="job.id" v-bind:class="[{deleted: job.deleted}, job.state + 'Job']">
|
||||
<td><a v-if="!job.deleted" v-bind:href="'<{ relative_path_to_root }>job/' + job.id">{{job.name}}</a><span v-if="job.deleted">{{job.name}} (deleted)</span> <small title="job's id">#{{job.id}} </small></td>
|
||||
<td>{{job.state}}</td>
|
||||
<td>{{timestampToDate(job.created_time)}}</td>
|
||||
<td>{{timestampToDate(job.started_time)}}</td>
|
||||
<td>{{timestampToDate(job.end_time)}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<% endblock %>
|
||||
|
||||
<% block javascript %>
|
||||
<script>
|
||||
(function() {
|
||||
var app = new Vue({
|
||||
el: '#jobs',
|
||||
data: {
|
||||
jobs: []
|
||||
},
|
||||
methods: {
|
||||
timestampToDate: function (timestamp) {
|
||||
console.log(timestamp)
|
||||
if (timestamp === null) return "";
|
||||
|
||||
return new Date(timestamp * 1000).toLocaleString()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
ws = new ReconnectingWebSocket(websocketPrefix() + '://' + document.domain + ':' + location.port + websocketRelativePath('<{ path }>') + '/app-<{ app.name }>-ws');
|
||||
|
||||
ws.onmessage = function (event) {
|
||||
var message = JSON.parse(event.data);
|
||||
var data = message.data;
|
||||
var action = message.action;
|
||||
|
||||
if (action == "init_jobs") {
|
||||
app.jobs = data;
|
||||
} else if (action == "update_job") {
|
||||
for (var i = 0; i < app.jobs.length; ++i) {
|
||||
if (app.jobs[i].id == data.id) {
|
||||
Vue.set(app.jobs, i, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (action == "new_job") {
|
||||
app.jobs.splice(0, 0, data);
|
||||
} else if (action == "delete_job") {
|
||||
for (var i = 0; i < app.jobs.length; ++i) {
|
||||
if (app.jobs[i].id == data.id) {
|
||||
Vue.set(app.jobs[i], 'deleted', true);
|
||||
Vue.set(app.jobs[i], 'state', 'deleted');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})()
|
||||
</script>
|
||||
<% endblock %>
|
Loading…
Add table
Reference in a new issue