Files
ServerKit/backend/app/api/cron.py
T
Juan Denis 7aa7642586 Add cron job editing and tabbed route support
Backend: add PUT /cron/jobs/<id> endpoint and CronService.update_job to update job metadata and (on Linux) modify the system crontab; includes schedule validation and error handling.

Frontend: add useTabParam hook and update routes/PageTitle logic to support optional :tab URL segments for many pages, enabling deep-linked tabs. Update CronJobs UI to unify create/edit modal, add edit-on-click, run-output modal, improved SVG icon attributes, and wire updateCronJob in the API client. Styles: global SVG button rules, hover for cron items, and run-output styles.
2026-03-03 22:11:30 -05:00

121 lines
2.8 KiB
Python

"""
Cron Job Management API
Endpoints for managing scheduled tasks and cron jobs.
"""
from flask import Blueprint, request, jsonify
from app.middleware.rbac import admin_required, viewer_required
from app.services.cron_service import CronService
cron_bp = Blueprint('cron', __name__)
@cron_bp.route('/status', methods=['GET'])
@viewer_required
def get_status():
"""Get cron service status."""
status = CronService.get_status()
return jsonify(status)
@cron_bp.route('/jobs', methods=['GET'])
@viewer_required
def list_jobs():
"""List all cron jobs."""
result = CronService.list_jobs()
return jsonify(result)
@cron_bp.route('/jobs', methods=['POST'])
@admin_required
def create_job():
"""Create a new cron job."""
data = request.get_json()
schedule = data.get('schedule')
command = data.get('command')
name = data.get('name')
description = data.get('description')
if not schedule:
return jsonify({'success': False, 'error': 'Schedule is required'}), 400
if not command:
return jsonify({'success': False, 'error': 'Command is required'}), 400
result = CronService.add_job(
schedule=schedule,
command=command,
name=name,
description=description
)
if result.get('success'):
return jsonify(result), 201
return jsonify(result), 400
@cron_bp.route('/jobs/<job_id>', methods=['PUT'])
@admin_required
def update_job(job_id):
"""Update a cron job."""
data = request.get_json()
result = CronService.update_job(
job_id=job_id,
name=data.get('name'),
command=data.get('command'),
schedule=data.get('schedule'),
description=data.get('description')
)
if result.get('success'):
return jsonify(result)
return jsonify(result), 400
@cron_bp.route('/jobs/<job_id>', methods=['DELETE'])
@admin_required
def delete_job(job_id):
"""Delete a cron job."""
result = CronService.remove_job(job_id)
if result.get('success'):
return jsonify(result)
return jsonify(result), 400
@cron_bp.route('/jobs/<job_id>/toggle', methods=['POST'])
@admin_required
def toggle_job(job_id):
"""Enable or disable a cron job."""
data = request.get_json()
enabled = data.get('enabled', True)
result = CronService.toggle_job(job_id, enabled)
if result.get('success'):
return jsonify(result)
return jsonify(result), 400
@cron_bp.route('/jobs/<job_id>/run', methods=['POST'])
@admin_required
def run_job(job_id):
"""Run a job immediately."""
result = CronService.run_job_now(job_id)
if result.get('success'):
return jsonify(result)
return jsonify(result), 400
@cron_bp.route('/presets', methods=['GET'])
@viewer_required
def get_presets():
"""Get available schedule presets."""
result = CronService.get_presets()
return jsonify(result)