majuna/app/lists/bc2.py

95 lines
2.3 KiB
Python

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}