import builtins from datetime import datetime from typing import List, Dict, Union, Any, Optional from pydantic import BaseModel, Field from app.models.mirrors import Origin, Proxy class BC2Alternative(BaseModel): proto: str type: str created_at: datetime updated_at: datetime url: str class BC2Site(BaseModel): main_domain: str = Field(description="The main domain name of the website, excluding \"www.\" if present.", examples=["bbc.co.uk", "bbc.com", "guardianproject.info"]) available_alternatives: List[BC2Alternative] class BypassCensorship2(BaseModel): version: str = Field(description="Version number of the Bypass Censorship Extension schema in use", ) sites: List[BC2Site] class Config: title = "Bypass Censorship Version 2" def onion_alternative(origin: Origin) -> List[Dict[str, Any]]: url: Optional[str] = origin.onion() if url is None: return [] else: return [{ "proto": "tor", "type": "eotk", "created_at": str(origin.added), "updated_at": str(origin.updated), "url": url} ] def proxy_alternative(proxy: Proxy) -> Dict[str, Any]: return { "proto": "https", "type": "mirror", "created_at": str(proxy.added), "updated_at": str(proxy.updated), "url": proxy.url } def main_domain(origin: Origin) -> str: # Both description and domain_name are required to be not null in the database schema description: str = origin.description if description.startswith("proxy:"): return description[len("proxy:"):].replace("www.", "") domain_name: str = origin.domain_name return domain_name.replace("www.", "") def active_proxies(origin: Origin, provider: str) -> List[Proxy]: def _filter_fn(proxy: Proxy) -> bool: return proxy.url is not None and not proxy.deprecated and not proxy.destroyed and proxy.provider == provider return list(filter(_filter_fn, origin.proxies)) def mirror_sites(provider: str = "cloudfront") -> Dict[ str, Union[str, List[Dict[str, Union[str, List[Dict[str, str]]]]]]]: return {"version": "2.0", "sites": [{"main_domain": main_domain(origin), "available_alternatives": onion_alternative(origin) + [ proxy_alternative(proxy) for proxy in active_proxies(origin, provider)]} for origin in Origin.query.order_by(Origin.domain_name).all() if origin.destroyed is None]} if getattr(builtins, "__sphinx_build__", False): schema = BypassCensorship2.schema_json()