majuna/app/portal/report.py

140 lines
4.4 KiB
Python
Raw Normal View History

# mypy: ignore-errors
from datetime import datetime, timedelta, timezone
2023-10-29 21:18:40 +00:00
2023-10-23 17:33:17 +01:00
from flask import Blueprint, render_template
from flask.typing import ResponseReturnValue
from sqlalchemy import and_, desc, func
2023-10-29 21:18:40 +00:00
from sqlalchemy.orm import aliased
2023-10-23 17:33:17 +01:00
from app.extensions import db
2023-10-29 21:18:40 +00:00
from app.models import Deprecation
from app.models.mirrors import Country, Origin, Proxy
2023-10-23 17:33:17 +01:00
report = Blueprint("report", __name__)
2023-10-31 17:37:05 +00:00
def generate_subqueries():
DeprecationAlias = aliased(Deprecation)
now = datetime.now(tz=timezone.utc)
2023-10-29 21:18:40 +00:00
deprecations_24hr_subquery = (
db.session.query(
2023-10-31 17:37:05 +00:00
DeprecationAlias.resource_id,
2024-12-06 18:15:47 +00:00
func.count(DeprecationAlias.resource_id).label("deprecations_24hr"),
2023-10-29 21:18:40 +00:00
)
.filter(
2024-12-06 18:15:47 +00:00
DeprecationAlias.reason.like("block_%"),
2023-10-31 17:37:05 +00:00
DeprecationAlias.deprecated_at >= now - timedelta(hours=24),
2024-12-06 18:15:47 +00:00
DeprecationAlias.resource_type == "Proxy",
2023-10-29 21:18:40 +00:00
)
2023-10-31 17:37:05 +00:00
.group_by(DeprecationAlias.resource_id)
2023-10-29 21:18:40 +00:00
.subquery()
)
deprecations_72hr_subquery = (
db.session.query(
2023-10-31 17:37:05 +00:00
DeprecationAlias.resource_id,
2024-12-06 18:15:47 +00:00
func.count(DeprecationAlias.resource_id).label("deprecations_72hr"),
2023-10-29 21:18:40 +00:00
)
.filter(
2024-12-06 18:15:47 +00:00
DeprecationAlias.reason.like("block_%"),
2023-10-31 17:37:05 +00:00
DeprecationAlias.deprecated_at >= now - timedelta(hours=72),
2024-12-06 18:15:47 +00:00
DeprecationAlias.resource_type == "Proxy",
2023-10-29 21:18:40 +00:00
)
2023-10-31 17:37:05 +00:00
.group_by(DeprecationAlias.resource_id)
2023-10-29 21:18:40 +00:00
.subquery()
)
2023-10-31 17:37:05 +00:00
return deprecations_24hr_subquery, deprecations_72hr_subquery
def countries_report():
deprecations_24hr_subquery, deprecations_72hr_subquery = generate_subqueries()
2023-10-29 21:18:40 +00:00
return (
db.session.query(
Country,
2024-12-06 18:15:47 +00:00
func.coalesce(
func.sum(deprecations_24hr_subquery.c.deprecations_24hr), 0
).label("total_deprecations_24hr"),
func.coalesce(
func.sum(deprecations_72hr_subquery.c.deprecations_72hr), 0
).label("total_deprecations_72hr"),
2023-10-29 21:18:40 +00:00
)
.join(Origin, Country.origins)
.join(Proxy, Origin.proxies)
2024-12-06 18:15:47 +00:00
.outerjoin(
deprecations_24hr_subquery,
Proxy.id == deprecations_24hr_subquery.c.resource_id,
)
.outerjoin(
deprecations_72hr_subquery,
Proxy.id == deprecations_72hr_subquery.c.resource_id,
)
2023-10-29 21:18:40 +00:00
.group_by(Country.id)
.all()
)
2023-10-31 17:37:05 +00:00
def origins_report():
deprecations_24hr_subquery, deprecations_72hr_subquery = generate_subqueries()
return (
db.session.query(
Origin,
2024-12-06 18:15:47 +00:00
func.coalesce(
func.sum(deprecations_24hr_subquery.c.deprecations_24hr), 0
).label("total_deprecations_24hr"),
func.coalesce(
func.sum(deprecations_72hr_subquery.c.deprecations_72hr), 0
).label("total_deprecations_72hr"),
2023-10-31 17:37:05 +00:00
)
.outerjoin(Proxy, Origin.proxies)
2024-12-06 18:15:47 +00:00
.outerjoin(
deprecations_24hr_subquery,
Proxy.id == deprecations_24hr_subquery.c.resource_id,
)
.outerjoin(
deprecations_72hr_subquery,
Proxy.id == deprecations_72hr_subquery.c.resource_id,
)
2023-10-31 17:37:05 +00:00
.filter(Origin.destroyed.is_(None))
.group_by(Origin.id)
.order_by(desc("total_deprecations_24hr"))
.all()
)
2024-12-06 18:15:47 +00:00
@report.app_template_filter("country_name")
2023-10-29 21:18:40 +00:00
def country_description_filter(country_code):
country = Country.query.filter_by(country_code=country_code).first()
return country.description if country else None
2024-12-06 18:15:47 +00:00
@report.route("/blocks", methods=["GET"])
2023-10-23 17:33:17 +01:00
def report_blocks() -> ResponseReturnValue:
2024-12-06 18:15:47 +00:00
blocked_today = (
db.session.query( # type: ignore[no-untyped-call]
Origin.domain_name,
Origin.description,
Proxy.added,
Proxy.deprecated,
Proxy.deprecation_reason,
)
.join(Origin, Origin.id == Proxy.origin_id)
.filter(
and_(
Proxy.deprecated > datetime.now(tz=timezone.utc) - timedelta(days=1),
Proxy.deprecation_reason.like("block_%"),
)
)
.all()
)
return render_template(
"report_blocks.html.j2",
blocked_today=blocked_today,
origins=sorted(origins_report(), key=lambda o: o[1], reverse=True),
countries=sorted(
countries_report(), key=lambda c: c[0].risk_level, reverse=True
),
)