Fixes
This commit is contained in:
+5
-4
@@ -3,6 +3,7 @@ use strict;
|
||||
use Dancer2;
|
||||
use Dancer2::Plugin::Database;
|
||||
use Data::Dumper;
|
||||
use JSON ();
|
||||
use SQL::SplitStatement;
|
||||
use HTTP::Lite;
|
||||
|
||||
@@ -164,8 +165,8 @@ post '/api/v1/task/:task/complete' => sub {
|
||||
# Accept both JSON body and form-encoded data for assign_key/results.
|
||||
my ($assign_key, $results);
|
||||
my $ct = request_header('Content-Type') || '';
|
||||
if ($ct eq 'application/json') {
|
||||
my $body = decode_json(request->body());
|
||||
if ($ct =~ m{application/json}i) {
|
||||
my $body = JSON::decode_json(request->body());
|
||||
$assign_key = $body->{assign_key};
|
||||
$results = $body->{results};
|
||||
} else {
|
||||
@@ -195,7 +196,7 @@ post '/api/v1/task/:task/complete' => sub {
|
||||
}
|
||||
|
||||
# Update the task as completed (store results as JSON text for MariaDB)
|
||||
my $results_json = defined $results ? encode_json($results) : 'null';
|
||||
my $results_json = defined $results ? JSON::encode_json($results) : 'null';
|
||||
my $update_sth = database->prepare("UPDATE tasks SET status='COMPLETED', results=?, updated_at=NOW() WHERE id=?");
|
||||
$update_sth->execute($results_json, $task_id);
|
||||
if($update_sth->rows == 0) {
|
||||
@@ -245,4 +246,4 @@ sub max {
|
||||
|
||||
sub min {
|
||||
return (sort { $a <=> $b } @_)[0];
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
curl http://10.0.1.7:11434/api/generate -d '{
|
||||
"model": "qwen3.6:35b-a3b",
|
||||
"keep_alive": "60m"
|
||||
}'
|
||||
@@ -310,10 +310,17 @@ def api_submit_review(task_id):
|
||||
return jsonify({"error": "verdict is required"}), 400
|
||||
|
||||
try:
|
||||
result = api_post(f"task/{task_id}/complete", {
|
||||
"results": {"reviewer_verdict": verdict},
|
||||
api_response = api_post(f"task/{task_id}/complete", {
|
||||
"results": {
|
||||
"review_verdict": verdict,
|
||||
},
|
||||
})
|
||||
return jsonify({
|
||||
"status": "completed",
|
||||
"task_id": task_id,
|
||||
"verdict": verdict,
|
||||
"api_response": api_response,
|
||||
})
|
||||
return jsonify({"status": "completed", "task_id": task_id, "verdict": verdict})
|
||||
except requests.RequestException as exc:
|
||||
return jsonify({"error": f"API error: {exc}"}), 503
|
||||
|
||||
@@ -445,6 +452,7 @@ _REVIEW_TEMPLATE = """
|
||||
.actions{display:flex;gap:12px;margin-top:14px}
|
||||
.action-btn{flex:1;padding:14px;border:2px solid #dee2e6;border-radius:8px;background:#fff;cursor:pointer;font-size:15px;font-weight:600;transition:all .15s;text-align:center}
|
||||
.action-btn:hover{border-color:#007bff;transform:translateY(-1px);box-shadow:0 2px 8px rgba(0,0,0,.1)}
|
||||
.action-btn:disabled{opacity:.6;cursor:not-allowed;transform:none}
|
||||
.action-btn.false-positive:hover{border-color:#dc3545;color:#dc3545;background:#fff5f5}
|
||||
.action-btn.correct:hover{border-color:#28a745;color:#28a745;background:#f0fff4}
|
||||
.skip-btn:hover{border-color:#6c757d;color:#6c757d;background:#f8f9fa}
|
||||
@@ -453,6 +461,7 @@ _REVIEW_TEMPLATE = """
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="flash"></div>
|
||||
<div class="header">
|
||||
<h1>VideoDetect</h1>
|
||||
<a href="/">« Back to queue</a>
|
||||
@@ -497,33 +506,58 @@ _REVIEW_TEMPLATE = """
|
||||
|
||||
<script>
|
||||
async function submitVerdict(verdict) {
|
||||
const resp = await fetch(`/api/review/submit/{{ video.id }}`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({verdict})
|
||||
});
|
||||
if (resp.ok) {
|
||||
showFlash('Verdict submitted ✓', '#28a745');
|
||||
setTimeout(() => location.href = '/', 1000);
|
||||
} else {
|
||||
const err = await resp.json();
|
||||
alert(err.error || 'Submission failed');
|
||||
setActionButtonsDisabled(true);
|
||||
showFlash('Submitting verdict...', '#007bff');
|
||||
|
||||
try {
|
||||
const resp = await fetch(`/api/review/submit/{{ video.id }}`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({verdict})
|
||||
});
|
||||
const body = await resp.json().catch(() => ({}));
|
||||
if (resp.ok) {
|
||||
showFlash('Verdict submitted', '#28a745');
|
||||
setTimeout(() => location.href = '/', 1000);
|
||||
} else {
|
||||
alert(body.error || 'Submission failed');
|
||||
setActionButtonsDisabled(false);
|
||||
}
|
||||
} catch (err) {
|
||||
alert(`Submission failed: ${err.message}`);
|
||||
setActionButtonsDisabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
async function skipTask() {
|
||||
if (!confirm('Skip this task? It will be returned to the PENDING queue.')) return;
|
||||
const resp = await fetch(`/api/review/skip/{{ video.id }}`, {method: 'POST'});
|
||||
if (resp.ok) {
|
||||
showFlash('Task skipped, returned to queue', '#6c757d');
|
||||
setTimeout(() => location.href = '/', 1000);
|
||||
} else {
|
||||
alert('Skip failed');
|
||||
setActionButtonsDisabled(true);
|
||||
showFlash('Skipping task...', '#6c757d');
|
||||
|
||||
try {
|
||||
const resp = await fetch(`/api/review/skip/{{ video.id }}`, {method: 'POST'});
|
||||
if (resp.ok) {
|
||||
showFlash('Task skipped, returned to queue', '#6c757d');
|
||||
setTimeout(() => location.href = '/', 1000);
|
||||
} else {
|
||||
alert('Skip failed');
|
||||
setActionButtonsDisabled(false);
|
||||
}
|
||||
} catch (err) {
|
||||
alert(`Skip failed: ${err.message}`);
|
||||
setActionButtonsDisabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
function setActionButtonsDisabled(disabled) {
|
||||
document.querySelectorAll('.action-btn').forEach((button) => {
|
||||
button.disabled = disabled;
|
||||
});
|
||||
}
|
||||
|
||||
function showFlash(msg, color) {
|
||||
const el = document.getElementById('flash');
|
||||
if (!el) return;
|
||||
el.textContent = msg; el.style.background = color; el.style.display = 'block';
|
||||
setTimeout(() => el.style.display = 'none', 2500);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user