Show completed jobs on jobs page with results links

- Modified jobs route to include completed jobs from last 24 hours
- Updated api/job_status_updates to include completed jobs so frontend gets notified when jobs complete
- Updated jobs page title and description to reflect it shows completed jobs
- Completed jobs already show 'View Result' link via existing JavaScript logic

This ensures users can see their recently completed jobs on the jobs page and easily access results.
parent d73e3e9d
#!/usr/bin/env python3
"""
Script to replace all print() statements with log_message() calls
and add proper imports.
"""
import os
import re
import glob
def get_process_name(filepath):
"""Determine process name from file path."""
filename = os.path.basename(filepath)
if 'backend' in filename:
return 'backend'
elif 'worker_analysis' in filename:
return 'worker_analysis'
elif 'worker_training' in filename:
return 'worker_training'
elif 'web' in filename:
return 'web'
elif 'cluster_master' in filename:
return 'cluster_master'
elif 'cluster_client' in filename:
return 'cluster_client'
elif 'api' in filename:
return 'api'
elif 'admin' in filename:
return 'admin'
elif 'queue' in filename:
return 'queue'
elif 'database' in filename:
return 'database'
elif 'auth' in filename:
return 'auth'
elif 'config' in filename:
return 'config'
elif 'runpod' in filename:
return 'runpod'
elif 'email' in filename:
return 'email'
elif 'payments' in filename:
return 'payments'
elif 'comm' in filename:
return 'comm'
else:
return 'main'
def process_file(filepath):
"""Process a single Python file."""
print(f"Processing {filepath}...")
with open(filepath, 'r') as f:
content = f.read()
# Skip if already processed
if 'from .logging_utils import log_message' in content or 'log_message' in content:
print(f" Already processed, skipping")
return
# Add import after existing imports
import_pattern = r'(from \..* import.*\n)+'
import_match = re.search(import_pattern, content)
if import_match:
# Insert after the last import
insert_pos = import_match.end()
content = content[:insert_pos] + 'from .logging_utils import log_message\n' + content[insert_pos:]
else:
# Add at the beginning after docstring
lines = content.split('\n')
insert_pos = 0
for i, line in enumerate(lines):
if line.strip().startswith('"""') or line.strip().startswith("'''"):
# Find end of docstring
quote = line.strip()[0]
for j in range(i + 1, len(lines)):
if lines[j].strip().endswith(quote * 3):
insert_pos = j + 1
break
break
elif line.strip() and not line.startswith('#'):
insert_pos = i
break
lines.insert(insert_pos, 'from .logging_utils import log_message')
content = '\n'.join(lines)
# Replace print( with log_message(
# This is a simple replacement - may need manual review for complex cases
content = re.sub(r'\bprint\(', 'log_message(', content)
with open(filepath, 'w') as f:
f.write(content)
print(f" Updated {filepath}")
def main():
"""Main function."""
# Find all Python files in vidai directory
py_files = glob.glob('vidai/*.py')
for filepath in py_files:
if os.path.basename(filepath) in ['__init__.py', 'utils.py', 'logging_utils.py']:
continue # Skip these files
process_file(filepath)
print("Done!")
if __name__ == '__main__':
main()
\ No newline at end of file
......@@ -492,8 +492,8 @@
<div class="table-header">
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
<div>
<h2><i class="fas fa-tasks"></i> Active Jobs</h2>
<p style="margin: 0.5rem 0 0 0; color: #64748b; font-size: 0.9rem;">View and manage your queued, processing, and recently cancelled jobs</p>
<h2><i class="fas fa-tasks"></i> Jobs</h2>
<p style="margin: 0.5rem 0 0 0; color: #64748b; font-size: 0.9rem;">View and manage your queued, processing, cancelled, and recently completed jobs</p>
</div>
{% if current_user.get('role') == 'admin' and all_users %}
<div style="display: flex; align-items: center; gap: 0.5rem;">
......
......@@ -368,7 +368,7 @@ def jobs():
all_queue_items = get_user_queue_items(target_user_id)
# Filter for active jobs: queued, processing, and cancelled jobs from last 24 hours
# Filter for active jobs: queued, processing, cancelled, and recently completed jobs from last 24 hours
import time
current_time = time.time()
twenty_four_hours_ago = current_time - (24 * 60 * 60)
......@@ -378,8 +378,8 @@ def jobs():
# Include queued and processing jobs
if job['status'] in ['queued', 'processing']:
active_jobs.append(job)
# Include cancelled jobs from last 24 hours
elif job['status'] == 'cancelled':
# Include cancelled and completed jobs from last 24 hours
elif job['status'] in ['cancelled', 'completed']:
job_time = job.get('created_at')
if isinstance(job_time, str):
from datetime import datetime
......@@ -586,13 +586,38 @@ def api_job_status_updates():
target_user_id = u['id']
break
# Get all active jobs for the target user (not completed/failed)
# Get all jobs for the target user
queue_items = get_user_queue_items(target_user_id)
updates = []
# Filter for jobs that should be shown on the jobs page (same logic as jobs route)
import time
current_time = time.time()
twenty_four_hours_ago = current_time - (24 * 60 * 60)
for job in queue_items:
# Include all active jobs (queued, processing, cancelled)
if job['status'] not in ['completed', 'failed']:
include_job = False
# Include queued and processing jobs
if job['status'] in ['queued', 'processing']:
include_job = True
# Include cancelled and completed jobs from last 24 hours
elif job['status'] in ['cancelled', 'completed']:
job_time = job.get('created_at')
if isinstance(job_time, str):
from datetime import datetime
try:
job_timestamp = datetime.fromisoformat(job_time.replace('Z', '+00:00')).timestamp()
if job_timestamp > twenty_four_hours_ago:
include_job = True
except:
# If we can't parse the timestamp, include it anyway
include_job = True
else:
# If no timestamp, include it
include_job = True
if include_job:
updates.append({
'id': job['id'],
'status': job['status'],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment