2025-05-23 16:13:25 +02:00

138 lines
4.3 KiB
Python

from datetime import datetime
from flask import Blueprint, jsonify, request
from ..models import ActivityLog, ActivityCategory, PaperMetadata
from .. import db
bp = Blueprint("api", __name__, url_prefix="/api")
@bp.route("/activity_logs")
def get_activity_logs():
"""Get activity logs with filtering options."""
# Get query parameters
category = request.args.get("category")
action = request.args.get("action")
after = request.args.get("after")
limit = request.args.get("limit", 20, type=int)
# Build query
query = ActivityLog.query
if category:
query = query.filter(ActivityLog.category == category)
if action:
query = query.filter(ActivityLog.action == action)
if after:
try:
after_date = datetime.fromisoformat(after.replace("Z", "+00:00"))
query = query.filter(ActivityLog.timestamp > after_date)
except (ValueError, TypeError):
pass
# Order by most recent first and limit results
logs = query.order_by(ActivityLog.timestamp.desc()).limit(limit).all()
# Format the results
result = []
for log in logs:
log_data = {
"id": log.id,
"timestamp": log.timestamp.isoformat(),
"category": log.category,
"action": log.action,
"description": log.description,
"status": log.status,
"paper_id": log.paper_id,
"extra_data": log.extra_data
}
result.append(log_data)
return jsonify(result)
@bp.route("/papers")
def search_papers():
"""
Search for papers by title, DOI, or ID.
Query parameters:
- query: Search term (required)
- limit: Maximum number of results (default: 10)
"""
query = request.args.get('query', '')
limit = int(request.args.get('limit', 10))
if not query:
return jsonify({
"success": False,
"message": "Search query is required",
"papers": []
})
# Try to parse query as an ID first
try:
paper_id = int(query)
paper_by_id = PaperMetadata.query.get(paper_id)
if paper_by_id:
return jsonify({
"success": True,
"papers": [{
"id": paper_by_id.id,
"title": paper_by_id.title,
"doi": paper_by_id.doi,
"journal": paper_by_id.journal,
"status": paper_by_id.status,
"created_at": paper_by_id.created_at.isoformat() if paper_by_id.created_at else None,
"updated_at": paper_by_id.updated_at.isoformat() if paper_by_id.updated_at else None
}]
})
except ValueError:
pass # Not an ID, continue with text search
# Search in title and DOI
search_term = f"%{query}%"
papers = PaperMetadata.query.filter(
db.or_(
PaperMetadata.title.ilike(search_term),
PaperMetadata.doi.ilike(search_term)
)
).limit(limit).all()
return jsonify({
"success": True,
"papers": [{
"id": paper.id,
"title": paper.title,
"doi": paper.doi,
"journal": paper.journal,
"status": paper.status,
"created_at": paper.created_at.isoformat() if paper.created_at else None,
"updated_at": paper.updated_at.isoformat() if paper.updated_at else None
} for paper in papers]
})
@bp.route("/papers/<int:paper_id>")
def get_paper(paper_id):
"""Get details of a single paper by ID."""
paper = PaperMetadata.query.get(paper_id)
if not paper:
return jsonify({
"success": False,
"message": f"Paper with ID {paper_id} not found"
})
return jsonify({
"success": True,
"paper": {
"id": paper.id,
"title": paper.title,
"doi": paper.doi,
"journal": paper.journal,
"status": paper.status,
"error_msg": paper.error_msg,
"file_path": paper.file_path,
"created_at": paper.created_at.isoformat() if paper.created_at else None,
"updated_at": paper.updated_at.isoformat() if paper.updated_at else None
}
})