Files
proxy-scraper-checker/proxy_scraper_checker/__main__.py
T

158 lines
4.6 KiB
Python
Raw Normal View History

2023-01-02 00:09:55 +03:00
from __future__ import annotations
import asyncio
import logging
import sys
2024-01-21 17:45:01 +00:00
from typing import TYPE_CHECKING, Dict, Mapping
2023-01-02 00:09:55 +03:00
2024-01-21 17:45:01 +00:00
import aiofiles
import aiofiles.os
2023-01-02 00:09:55 +03:00
import rich.traceback
2024-01-21 17:45:01 +00:00
from aiohttp import ClientSession, TCPConnector
from aiohttp_socks import ProxyType
2023-01-02 00:09:55 +03:00
from rich.console import Console
from rich.logging import RichHandler
2024-01-21 17:45:01 +00:00
from rich.progress import BarColumn, MofNCompleteColumn, Progress, TextColumn
from rich.table import Table
2023-01-02 00:09:55 +03:00
2024-01-21 17:45:01 +00:00
from . import cache, checker, geodb, http, output, scraper, sort, utils
from .settings import Settings
from .storage import ProxyStorage
from .typing_compat import Any
if sys.version_info >= (3, 11):
try:
import tomllib
except ImportError:
# Help users on older alphas
if not TYPE_CHECKING:
import tomli as tomllib
else:
import tomli as tomllib
logger = logging.getLogger(__name__)
2023-01-02 09:44:39 +03:00
2023-01-02 00:09:55 +03:00
def set_event_loop_policy() -> None:
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
elif sys.implementation.name == "cpython" and sys.platform in {
2023-06-27 12:04:44 +03:00
"darwin",
"linux",
}:
2023-01-02 00:09:55 +03:00
try:
2023-11-04 09:29:21 +00:00
import uvloop # noqa: PLC0415
2023-01-02 00:09:55 +03:00
except ImportError:
pass
else:
2023-10-23 01:12:54 +03:00
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
2023-01-02 00:09:55 +03:00
2024-01-21 17:45:01 +00:00
async def read_config(file: str, /) -> Dict[str, Any]:
async with aiofiles.open(file, "rb") as f:
content = await f.read()
return tomllib.loads(utils.bytes_decode(content))
def configure_logging(*, console: Console, debug: bool) -> None:
2023-12-25 15:11:23 +03:00
rich.traceback.install(
console=console, width=None, extra_lines=0, word_wrap=True
)
2023-01-02 00:09:55 +03:00
logging.basicConfig(
2023-02-06 20:59:03 +03:00
level=logging.DEBUG if debug else logging.INFO,
2023-01-02 00:09:55 +03:00
format="%(message)s",
2023-10-31 19:00:46 +03:00
datefmt=logging.Formatter.default_time_format,
2023-01-02 09:44:39 +03:00
handlers=(
RichHandler(
2023-01-02 13:16:05 +03:00
console=console,
omit_repeated_times=False,
show_path=False,
rich_tracebacks=True,
2023-12-25 15:11:23 +03:00
tracebacks_extra_lines=0,
2023-01-02 09:44:39 +03:00
),
),
2023-01-02 00:09:55 +03:00
)
2024-01-21 17:45:01 +00:00
def get_summary_table(
*, before: Mapping[ProxyType, int], after: Mapping[ProxyType, int]
) -> Table:
table = Table()
table.add_column("Protocol", style="cyan")
table.add_column("Working", style="magenta")
table.add_column("Total", style="green")
for proto in sort.PROTOCOL_ORDER:
if total := before.get(proto):
working = after.get(proto, 0)
percentage = working / total
table.add_row(
proto.name, f"{working} ({percentage:.1%})", str(total)
)
return table
2023-02-06 20:59:03 +03:00
2023-02-21 21:22:47 +03:00
async def main() -> None:
2024-01-21 17:45:01 +00:00
cfg = await read_config("config.toml")
2023-01-02 00:09:55 +03:00
console = Console()
2024-01-21 17:45:01 +00:00
configure_logging(console=console, debug=cfg["debug"])
async with ClientSession(
connector=TCPConnector(ssl=http.SSL_CONTEXT),
headers=http.HEADERS,
cookie_jar=http.get_cookie_jar(),
raise_for_status=True,
2024-01-23 09:37:29 +03:00
fallback_charset_resolver=http.fallback_charset_resolver,
2024-01-21 17:45:01 +00:00
) as session:
settings = await Settings.from_mapping(cfg, session=session)
2024-01-21 23:37:46 +03:00
storage = ProxyStorage(protocols=settings.sources)
2024-01-21 17:45:01 +00:00
with Progress(
2024-01-25 11:49:22 +03:00
TextColumn("[yellow]{task.fields[col1]}"),
TextColumn("[red]::"),
TextColumn("[green]{task.fields[col2]}"),
2024-01-21 17:45:01 +00:00
BarColumn(),
MofNCompleteColumn(),
console=console,
transient=True,
) as progress:
scrape = scraper.scrape_all(
progress=progress,
session=session,
settings=settings,
storage=storage,
)
await (
asyncio.gather(
cache.create(),
geodb.download_geodb(progress=progress, session=session),
scrape,
)
if settings.enable_geolocation
else scrape
)
await session.close()
count_before_checking = storage.get_count()
await checker.check_all(
settings=settings,
storage=storage,
progress=progress,
proxies_count=count_before_checking,
)
count_after_checking = storage.get_count()
console.print(
get_summary_table(
before=count_before_checking, after=count_after_checking
)
)
await output.save_proxies(storage=storage, settings=settings)
logger.info(
"Thank you for using https://github.com/monosans/proxy-scraper-checker"
)
2023-01-02 09:44:39 +03:00
if __name__ == "__main__":
2023-02-21 21:22:47 +03:00
set_event_loop_policy()
asyncio.run(main())