fpx-engine 0.7.6__tar.gz → 0.7.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/PKG-INFO +15 -12
  2. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/README.md +14 -11
  3. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/_api/_client.py +10 -0
  4. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/account/account.py +36 -0
  5. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/account/subclasses/profile.py +2 -0
  6. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/main.py +23 -1
  7. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/middlewares/_request_engine.py +2 -2
  8. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/utils/errors.py +7 -0
  9. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx_engine.egg-info/PKG-INFO +15 -12
  10. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/pyproject.toml +1 -1
  11. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/LICENSE +0 -0
  12. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/__init__.py +0 -0
  13. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/_parsers/__init__.py +0 -0
  14. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/_parsers/_base.py +0 -0
  15. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/_parsers/_category.py +0 -0
  16. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/_parsers/_chats.py +0 -0
  17. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/_parsers/_lots.py +0 -0
  18. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/_parsers/_orders.py +0 -0
  19. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/_parsers/_profile.py +0 -0
  20. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/account/subclasses/addons.py +0 -0
  21. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/account/subclasses/category.py +0 -0
  22. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/account/subclasses/chat.py +0 -0
  23. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/account/subclasses/editor.py +0 -0
  24. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/account/subclasses/lot.py +0 -0
  25. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/account/subclasses/order.py +0 -0
  26. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/account/subclasses/review.py +0 -0
  27. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/runner/runner.py +0 -0
  28. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/runner/subclasses/_category.py +0 -0
  29. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/runner/subclasses/_chat.py +0 -0
  30. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/runner/subclasses/_order.py +0 -0
  31. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/runner/subclasses/_review.py +0 -0
  32. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/classes/runner/subclasses/router.py +0 -0
  33. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/fsm/__init__.py +0 -0
  34. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/fsm/fsm.py +0 -0
  35. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/models/__init__.py +0 -0
  36. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/models/account.py +0 -0
  37. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/models/chat.py +0 -0
  38. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/models/lots.py +0 -0
  39. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/py.typed +0 -0
  40. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/services/__init__.py +0 -0
  41. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/utils/dependencies.py +0 -0
  42. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/utils/storage/__init__.py +0 -0
  43. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/utils/storage/base.py +0 -0
  44. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/utils/storage/file.py +0 -0
  45. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/utils/storage/memory.py +0 -0
  46. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx/utils/storage/redis.py +0 -0
  47. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx_engine.egg-info/SOURCES.txt +0 -0
  48. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx_engine.egg-info/dependency_links.txt +0 -0
  49. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx_engine.egg-info/requires.txt +0 -0
  50. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/fpx_engine.egg-info/top_level.txt +0 -0
  51. {fpx_engine-0.7.6 → fpx_engine-0.7.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fpx-engine
3
- Version: 0.7.6
3
+ Version: 0.7.7
4
4
  Summary: Автоматизация работы с FunPay
5
5
  Author-email: Be My Code <gettofarmila@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/bymyforge/fpx
@@ -36,17 +36,20 @@ Dynamic: license-file
36
36
 
37
37
  <p align="center">
38
38
  <a href="https://github.com/bymyforge/fpx" target="_blank">
39
- <img src="https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white" alt="GitHub">
40
- </a>
41
- <a href="https://fpx.readthedocs.io/ru/latest/" target="_blank">
42
- <img src="https://img.shields.io/badge/Документация-00b0ff?style=for-the-badge&logo=read-the-docs&logoColor=white" alt="Read the Docs">
43
- </a>
44
- <a href="https://t.me/fpx_engine" target="_blank">
45
- <img src="https://img.shields.io/badge/Телеграм_Чат-26A5E4?style=for-the-badge&logo=telegram&logoColor=white" alt="Telegram">
46
- </a>
47
- <a href="https://pypi.org/project/fpx-engine/" target="_blank">
48
- <img src="https://img.shields.io/badge/PyPI-3775A9?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI">
49
- </a>
39
+ <img src="https://img.shields.io/badge/GitHub-temp_inactive-lightgrey?style=for-the-badge&logo=github&logoColor=white" alt="GitHub (temp inactive)">
40
+ </a>
41
+ <a href="https://gitlab.com/funpayx/fpx" target="_blank">
42
+ <img src="https://img.shields.io/badge/GitLab-FC6D26?style=for-the-badge&logo=gitlab&logoColor=white" alt="GitLab">
43
+ </a>
44
+ <a href="https://fpx.readthedocs.io/ru/latest/" target="_blank">
45
+ <img src="https://img.shields.io/badge/Документация-00b0ff?style=for-the-badge&logo=read-the-docs&logoColor=white" alt="Read the Docs">
46
+ </a>
47
+ <a href="https://t.me/fpx_engine" target="_blank">
48
+ <img src="https://img.shields.io/badge/Телеграм_Чат-26A5E4?style=for-the-badge&logo=telegram&logoColor=white" alt="Телеграм Чат">
49
+ </a>
50
+ <a href="https://pypi.org/project/fpx-engine/" target="_blank">
51
+ <img src="https://img.shields.io/badge/PyPI-3775A9?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI">
52
+ </a>
50
53
  </p>
51
54
 
52
55
  ---
@@ -11,17 +11,20 @@
11
11
 
12
12
  <p align="center">
13
13
  <a href="https://github.com/bymyforge/fpx" target="_blank">
14
- <img src="https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white" alt="GitHub">
15
- </a>
16
- <a href="https://fpx.readthedocs.io/ru/latest/" target="_blank">
17
- <img src="https://img.shields.io/badge/Документация-00b0ff?style=for-the-badge&logo=read-the-docs&logoColor=white" alt="Read the Docs">
18
- </a>
19
- <a href="https://t.me/fpx_engine" target="_blank">
20
- <img src="https://img.shields.io/badge/Телеграм_Чат-26A5E4?style=for-the-badge&logo=telegram&logoColor=white" alt="Telegram">
21
- </a>
22
- <a href="https://pypi.org/project/fpx-engine/" target="_blank">
23
- <img src="https://img.shields.io/badge/PyPI-3775A9?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI">
24
- </a>
14
+ <img src="https://img.shields.io/badge/GitHub-temp_inactive-lightgrey?style=for-the-badge&logo=github&logoColor=white" alt="GitHub (temp inactive)">
15
+ </a>
16
+ <a href="https://gitlab.com/funpayx/fpx" target="_blank">
17
+ <img src="https://img.shields.io/badge/GitLab-FC6D26?style=for-the-badge&logo=gitlab&logoColor=white" alt="GitLab">
18
+ </a>
19
+ <a href="https://fpx.readthedocs.io/ru/latest/" target="_blank">
20
+ <img src="https://img.shields.io/badge/Документация-00b0ff?style=for-the-badge&logo=read-the-docs&logoColor=white" alt="Read the Docs">
21
+ </a>
22
+ <a href="https://t.me/fpx_engine" target="_blank">
23
+ <img src="https://img.shields.io/badge/Телеграм_Чат-26A5E4?style=for-the-badge&logo=telegram&logoColor=white" alt="Телеграм Чат">
24
+ </a>
25
+ <a href="https://pypi.org/project/fpx-engine/" target="_blank">
26
+ <img src="https://img.shields.io/badge/PyPI-3775A9?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI">
27
+ </a>
25
28
  </p>
26
29
 
27
30
  ---
@@ -1,4 +1,5 @@
1
1
  import json
2
+ import secrets
2
3
 
3
4
 
4
5
  class FunPayClient:
@@ -6,6 +7,15 @@ class FunPayClient:
6
7
  self._account = account
7
8
  self.client = http_client
8
9
 
10
+ async def refresh_session_cookies(self) -> dict:
11
+ objects = [{"type": "chat_counter", "id": "0", "tag": secrets.token_hex(4), "data": False}]
12
+ payload = {"objects": json.dumps(objects)}
13
+ headers = {"X-Requested-With": "XMLHttpRequest"}
14
+
15
+ r = await self.client.request("POST", "/runner/", data=payload, headers=headers)
16
+
17
+ return r
18
+
9
19
  async def get_chats_page(self) -> str:
10
20
  r = await self._account._request_engine.execute("GET", "/chat/")
11
21
  return r.text
@@ -1,3 +1,5 @@
1
+ import asyncio
2
+ import re
1
3
  from dataclasses import dataclass, field
2
4
  from typing import Optional
3
5
 
@@ -14,6 +16,7 @@ from fpx.classes.account.subclasses.order import OrderManager
14
16
  from fpx.classes.account.subclasses.profile import ProfileManager
15
17
  from fpx.classes.account.subclasses.review import ReviewManager
16
18
  from fpx.middlewares._request_engine import RequestEngine
19
+ from fpx.utils.errors import FpxRefreshCookieError
17
20
 
18
21
 
19
22
  @dataclass
@@ -62,3 +65,36 @@ class Account:
62
65
 
63
66
  result = await self._client.upload_image(image_data)
64
67
  return result["fileId"]
68
+
69
+ async def _refresh_cookies(self):
70
+ cookies = await self._client.refresh_session_cookies()
71
+ headers = cookies.headers
72
+ MAX_AGE_RE = re.compile(r"max-age=(\d+)", re.IGNORECASE)
73
+ for raw_cookie in headers.get_list("set-cookie"):
74
+ if raw_cookie.startswith("golden_seal="):
75
+ match = MAX_AGE_RE.search(raw_cookie)
76
+ return int(match.group(1)) if match else None
77
+ return None
78
+
79
+ async def refresh_cookies_cycle(self):
80
+ """
81
+ Обновление gseal и PHPSESSID.
82
+ Запускает цикл обновления куков.
83
+ Сам внутри обновляет куки каждую неделю.
84
+
85
+ Raises:
86
+ FpxRefreshCookieError: Ошибка обновления куков
87
+ """
88
+ while True:
89
+ ex_time = None
90
+ atts = 0
91
+ while ex_time is None:
92
+ try:
93
+ ex_time = await self._refresh_cookies()
94
+ except Exception as e:
95
+ atts += 1
96
+ if atts > 3:
97
+ raise FpxRefreshCookieError(f"Ошибка обновления куков: {e}")
98
+ if ex_time is None:
99
+ await asyncio.sleep(15)
100
+ await asyncio.sleep(ex_time)
@@ -157,6 +157,8 @@ class ProfileManager:
157
157
  html = await self._account._client.get_finance_page()
158
158
  step = "парсинг данных"
159
159
  balance = self._account._parser.parse_finanses(html)
160
+ except fpx_err.FpxAuthError:
161
+ raise
160
162
  except Exception as e:
161
163
  raise fpx_err.FpxGetProfileError(f"При сборе баланса, выполняя {step} произошла ошибка: {e}")
162
164
  return balance
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  import re
2
3
 
3
4
  import httpx
@@ -15,6 +16,11 @@ class FunPayTools:
15
16
  def __init__(
16
17
  self, gkey: str, gseal: str | None = None, storage: BaseStorage | None = None, proxy=None, http_client=None
17
18
  ):
19
+ if gseal or gseal is None:
20
+ print(
21
+ "ВАЖНО: С выхода релиза 0.8.0 аргумент gseal будет удалён, теперь он подставляется "
22
+ "автоматически, просьба не передавать аргумент gseal во избежание проблем."
23
+ )
18
24
  if not gkey:
19
25
  raise FpxAuthError("gkey и gseal не могут быть None.")
20
26
  if not GKEY_PATTERN.match(gkey):
@@ -22,7 +28,9 @@ class FunPayTools:
22
28
  if gseal:
23
29
  if not GSEAL_PATTERN.match(gseal):
24
30
  raise FpxAuthError("Неверный формат gseal, перепроверь его.")
25
- self._cookies = {"golden_key": gkey, "golden_seal": gseal, "locale": "ru"}
31
+ self._cookies = {"golden_key": gkey, "locale": "ru"}
32
+ if gseal:
33
+ self._cookies["golden_seal"] = gseal
26
34
  self._headers = {
27
35
  "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0",
28
36
  "Accept-Language": "ru-RU,ru;q=0.9",
@@ -58,14 +66,28 @@ class FunPayTools:
58
66
  self.account._request_engine.runner = self.runner
59
67
  self.storage = storage or MemoryStorage()
60
68
  self.runner.storage = self.storage
69
+ self._refresh_task: asyncio.Task | None = None
70
+
71
+ try:
72
+ loop = asyncio.get_running_loop()
73
+ self._refresh_task = loop.create_task(self.account.refresh_cookies_cycle())
74
+ except RuntimeError:
75
+ pass
61
76
 
62
77
  async def __aenter__(self):
78
+ self._refresh_task = asyncio.create_task(self.account.refresh_cookies_cycle())
63
79
  return self
64
80
 
65
81
  async def __aexit__(self, exc_type, exc_val, exc_tb):
66
82
  await self.shutdown()
67
83
 
68
84
  async def shutdown(self):
85
+ if self._refresh_task and not self._refresh_task.done():
86
+ self._refresh_task.cancel()
87
+ try:
88
+ await self._refresh_task
89
+ except asyncio.CancelledError:
90
+ pass
69
91
  if hasattr(self, "runner") and self.runner.is_running:
70
92
  self.runner.is_running = False
71
93
  if self._client and not self._client.is_closed:
@@ -15,8 +15,6 @@ class RequestEngine:
15
15
  attempts = 3
16
16
  backoff = 1.5 # множитель времени ожидания
17
17
  if method.upper() in ("POST", "PUT", "DELETE"):
18
- if "golden_seal" in self._client.cookies:
19
- raise fpx_err.FpxAbsentGoldenSeal()
20
18
  if "data" not in kwargs:
21
19
  kwargs["data"] = {}
22
20
  if "headers" not in kwargs:
@@ -48,6 +46,8 @@ class RequestEngine:
48
46
  sleep_time = backoff ** float(attempt)
49
47
  await asyncio.sleep(sleep_time)
50
48
  continue
49
+ if response.url == "https://funpay.com/account/login":
50
+ raise fpx_err.FpxAuthError("Неверный gkey, обнови свои куки.")
51
51
  return response
52
52
  except httpx.ReadTimeout as e:
53
53
  if method.upper() == "GET":
@@ -42,6 +42,13 @@ class FpxHandlerError(FpxError):
42
42
  # аккаунт
43
43
 
44
44
 
45
+ class FpxRefreshCookieError(FpxAccountError):
46
+ """Ошибка обновления куков"""
47
+
48
+ def __init__(self, message="Ошибка обновления куков"):
49
+ super().__init__(message)
50
+
51
+
45
52
  class FpxAbsentGoldenSeal(FpxAccountError):
46
53
  """Для POST запроса обязателен gseal."""
47
54
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fpx-engine
3
- Version: 0.7.6
3
+ Version: 0.7.7
4
4
  Summary: Автоматизация работы с FunPay
5
5
  Author-email: Be My Code <gettofarmila@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/bymyforge/fpx
@@ -36,17 +36,20 @@ Dynamic: license-file
36
36
 
37
37
  <p align="center">
38
38
  <a href="https://github.com/bymyforge/fpx" target="_blank">
39
- <img src="https://img.shields.io/badge/GitHub-181717?style=for-the-badge&logo=github&logoColor=white" alt="GitHub">
40
- </a>
41
- <a href="https://fpx.readthedocs.io/ru/latest/" target="_blank">
42
- <img src="https://img.shields.io/badge/Документация-00b0ff?style=for-the-badge&logo=read-the-docs&logoColor=white" alt="Read the Docs">
43
- </a>
44
- <a href="https://t.me/fpx_engine" target="_blank">
45
- <img src="https://img.shields.io/badge/Телеграм_Чат-26A5E4?style=for-the-badge&logo=telegram&logoColor=white" alt="Telegram">
46
- </a>
47
- <a href="https://pypi.org/project/fpx-engine/" target="_blank">
48
- <img src="https://img.shields.io/badge/PyPI-3775A9?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI">
49
- </a>
39
+ <img src="https://img.shields.io/badge/GitHub-temp_inactive-lightgrey?style=for-the-badge&logo=github&logoColor=white" alt="GitHub (temp inactive)">
40
+ </a>
41
+ <a href="https://gitlab.com/funpayx/fpx" target="_blank">
42
+ <img src="https://img.shields.io/badge/GitLab-FC6D26?style=for-the-badge&logo=gitlab&logoColor=white" alt="GitLab">
43
+ </a>
44
+ <a href="https://fpx.readthedocs.io/ru/latest/" target="_blank">
45
+ <img src="https://img.shields.io/badge/Документация-00b0ff?style=for-the-badge&logo=read-the-docs&logoColor=white" alt="Read the Docs">
46
+ </a>
47
+ <a href="https://t.me/fpx_engine" target="_blank">
48
+ <img src="https://img.shields.io/badge/Телеграм_Чат-26A5E4?style=for-the-badge&logo=telegram&logoColor=white" alt="Телеграм Чат">
49
+ </a>
50
+ <a href="https://pypi.org/project/fpx-engine/" target="_blank">
51
+ <img src="https://img.shields.io/badge/PyPI-3775A9?style=for-the-badge&logo=pypi&logoColor=white" alt="PyPI">
52
+ </a>
50
53
  </p>
51
54
 
52
55
  ---
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fpx-engine"
7
- version = "0.7.6"
7
+ version = "0.7.7"
8
8
  authors = [
9
9
  { name="Be My Code", email="gettofarmila@gmail.com" },
10
10
  ]
File without changes
File without changes
File without changes
File without changes
File without changes