from typing import List, Optional, TypedDict from app.models.base import Pool from app.models.mirrors import Origin, Proxy class BC2Alternative(TypedDict): proto: str type: str created_at: str updated_at: str url: str class BC2Site(TypedDict): main_domain: str available_alternatives: List[BC2Alternative] class BypassCensorship2(TypedDict): version: str sites: List[BC2Site] def onion_alternative(origin: Origin) -> List[BC2Alternative]: url: Optional[str] = origin.onion() if url is None: return [] return [ { "proto": "tor", "type": "eotk", "created_at": str(origin.added), "updated_at": str(origin.updated), "url": url, } ] def proxy_alternative(proxy: Proxy) -> Optional[BC2Alternative]: if proxy.url is None: return None return { "proto": "https", "type": "mirror", "created_at": proxy.added.isoformat(), "updated_at": proxy.updated.isoformat(), "url": proxy.url, } def main_domain(origin: Origin) -> str: 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, pool: Pool) -> List[Proxy]: return [ proxy for proxy in origin.proxies if proxy.url is not None and not proxy.deprecated and not proxy.destroyed and proxy.pool_id == pool.id ] def mirror_sites(pool: Pool) -> BypassCensorship2: origins = ( Origin.query.filter(Origin.destroyed.is_(None)) .order_by(Origin.domain_name) .all() ) sites: List[BC2Site] = [] for origin in origins: # Gather alternatives, filtering out None values from proxy_alternative alternatives = onion_alternative(origin) + [ alt for proxy in active_proxies(origin, pool) if (alt := proxy_alternative(proxy)) is not None ] # Add the site dictionary to the list sites.append( { "main_domain": main_domain(origin), "available_alternatives": list(alternatives), } ) return {"version": "2.0", "sites": sites}