Skip to content

Commit 93f8bb1

Browse files
committed
Implement logic
1 parent e2b1156 commit 93f8bb1

File tree

4 files changed

+39
-4
lines changed

4 files changed

+39
-4
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""API endpoint for OWASP project health metrics."""
2+
3+
from pathlib import Path
4+
5+
from django.conf import settings
6+
from django.core.management import call_command
7+
from django.http import FileResponse
8+
from ninja import Router
9+
from ninja.errors import HttpError
10+
11+
from apps.owasp.models.project_health_metrics import ProjectHealthMetrics
12+
13+
router = Router()
14+
15+
16+
@router.get("/{project_key}/pdf")
17+
def get_project_health_metrics_pdf(request, project_key: str):
18+
"""Generate and return a PDF report of project health metrics."""
19+
if not ProjectHealthMetrics.objects.filter(project__key=f"www-project-{project_key}").exists():
20+
raise HttpError(404, f"No health metrics found for project '{project_key}'")
21+
22+
file_name = f"{project_key}_health_metrics_report.pdf"
23+
pdf_path = Path(settings.BASE_DIR) / "reports" / file_name
24+
call_command(
25+
"owasp_generate_project_health_metrics_pdf",
26+
project_key=project_key,
27+
)
28+
if not pdf_path.exists():
29+
raise HttpError(404, f"PDF report for project '{project_key}' not found")
30+
return FileResponse(Path.open(pdf_path, "rb"), as_attachment=True, filename=file_name)

backend/apps/owasp/api/v1/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
from apps.owasp.api.v1.committee import router as committee_router
77
from apps.owasp.api.v1.event import router as event_router
88
from apps.owasp.api.v1.project import router as project_router
9+
from apps.owasp.api.v1.project_health_metrics import router as project_health_metrics_router
910

1011
router = Router()
1112

1213
router.add_router(r"/chapters", chapter_router)
1314
router.add_router(r"/committees", committee_router)
1415
router.add_router(r"/events", event_router)
1516
router.add_router(r"/projects", project_router)
17+
router.add_router(r"/project-health-metrics", project_health_metrics_router)

frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ const ProjectHealthMetricsDetails: FC = () => {
6363
color="primary"
6464
onPress={async () => {
6565
await fetchMetricsPDF(
66-
`owasp/projects-health-metrics/${projectKey}/pdf`,
67-
`${metrics.projectName}-health-metrics.pdf`
66+
`owasp/project-health-metrics/${projectKey}/pdf`,
67+
`${projectKey}-health-metrics.pdf`
6868
)
6969
}}
7070
>

frontend/src/server/fetchMetricsPDF.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ export const fetchMetricsPDF = async (path: string, fileName: string): Promise<v
99
},
1010
})
1111
if (!response.ok) {
12-
throw new Error(`Failed to fetch PDF: ${response.statusText}`)
12+
handleAppError(new Error(`Failed to fetch PDF: ${response.status} ${response.statusText}`))
13+
return
1314
}
1415
try {
1516
const blob = await response.blob()
1617
if (!blob) {
17-
throw new Error('No PDF data received')
18+
handleAppError(new Error('No data received from the server'))
19+
return
1820
}
1921
const url = window.URL.createObjectURL(blob)
2022
const link = document.createElement('a')
@@ -23,6 +25,7 @@ export const fetchMetricsPDF = async (path: string, fileName: string): Promise<v
2325
document.body.appendChild(link)
2426
link.click()
2527
document.body.removeChild(link)
28+
window.URL.revokeObjectURL(url)
2629
} catch (error) {
2730
handleAppError(error)
2831
}

0 commit comments

Comments
 (0)