138 lines
4.3 KiB
Python
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
|
|
}
|
|
}) |