grass.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. """
  2. @ Author: Mr.Hat
  3. @ Date: 2024/3/30 14:05
  4. @ Description:
  5. @ History:
  6. """
  7. import asyncio
  8. import uuid
  9. import aiohttp
  10. from fake_useragent import UserAgent
  11. from tenacity import stop_after_attempt, retry, retry_if_not_exception_type, wait_random, retry_if_exception_type
  12. from data.config import MIN_PROXY_SCORE
  13. from .grass_sdk.extension import GrassWs
  14. from .grass_sdk.website import GrassRest
  15. from .utils import logger
  16. from .utils.exception import WebsocketClosedException, LowProxyScoreException, ProxyScoreNotFoundException, \
  17. ProxyForbiddenException
  18. from better_proxy import Proxy
  19. class Grass(GrassWs, GrassRest):
  20. def __init__(self, _id: int, email: str, password: str, proxy: str = None):
  21. self.proxy = Proxy.from_str(proxy).as_url if proxy else None
  22. super(GrassWs, self).__init__(email=email, password=password, user_agent=UserAgent().random, proxy=self.proxy)
  23. self.proxy_score = None
  24. self.id = _id
  25. self.session = aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(ssl=False))
  26. async def start(self):
  27. # logger.info(f"{self.id} | {self.email} | Starting...")
  28. user_id = await self.enter_account()
  29. browser_id = str(uuid.uuid3(uuid.NAMESPACE_DNS, self.proxy or ""))
  30. await self.run(browser_id, user_id)
  31. async def run(self, browser_id: str, user_id: str):
  32. while True:
  33. try:
  34. await self.connection_handler()
  35. await self.auth_to_extension(browser_id, user_id)
  36. if self.proxy_score is None:
  37. await asyncio.sleep(1)
  38. await self.handle_proxy_score(MIN_PROXY_SCORE)
  39. while True:
  40. await self.send_ping()
  41. await self.send_pong()
  42. logger.info(f"{self.id} | Mined grass.")
  43. await asyncio.sleep(19.9)
  44. except WebsocketClosedException as e:
  45. logger.info(f"Websocket closed: {e}. Retrying...")
  46. except ConnectionResetError as e:
  47. logger.info(f"Connection reset: {e}. Retrying...")
  48. except TypeError as e:
  49. logger.info(f"Type error: {e}. Retrying...")
  50. await asyncio.sleep(1)
  51. @retry(stop=stop_after_attempt(30),
  52. retry=(retry_if_exception_type(ConnectionError) | retry_if_not_exception_type(ProxyForbiddenException)),
  53. wait=wait_random(0.5, 1),
  54. reraise=True)
  55. async def connection_handler(self):
  56. logger.info(f"{self.id} | Connecting...")
  57. await self.connect()
  58. logger.info(f"{self.id} | Connected")
  59. @retry(stop=stop_after_attempt(10),
  60. retry=retry_if_not_exception_type(LowProxyScoreException),
  61. before_sleep=lambda retry_state, **kwargs: logger.info(f"{retry_state.outcome.exception()}"),
  62. wait=wait_random(5, 7),
  63. reraise=True)
  64. async def handle_proxy_score(self, min_score: int):
  65. if (proxy_score := await self.get_proxy_score_by_device_id()) is None:
  66. # logger.info(f"{self.id} | Proxy score not found for {self.proxy}. Guess Bad proxies! Continue...")
  67. # return None
  68. raise ProxyScoreNotFoundException(f"{self.id} | Proxy score not found for {self.proxy}. Guess Bad proxies!")
  69. elif proxy_score >= min_score:
  70. self.proxy_score = proxy_score
  71. logger.success(f"{self.id} | Proxy score: {self.proxy_score}")
  72. return True
  73. else:
  74. raise LowProxyScoreException(f"{self.id} | Too low proxy score: {proxy_score} for {self.proxy}. Exit...")