xync-client 0.0.49.dev13__tar.gz → 0.0.50.dev1__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 (113) hide show
  1. {xync_client-0.0.49.dev13/xync_client.egg-info → xync_client-0.0.50.dev1}/PKG-INFO +1 -1
  2. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Abc/Ex.py +7 -1
  3. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Bybit/agent.py +144 -5
  4. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Bybit/ex.py +9 -3
  5. xync_client-0.0.50.dev1/xync_client/Pms/Ozon/__init__.py +63 -0
  6. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Sber/__init__.py +41 -48
  7. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1/xync_client.egg-info}/PKG-INFO +1 -1
  8. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client.egg-info/SOURCES.txt +0 -1
  9. xync_client-0.0.49.dev13/xync_client/Pms/Ozon/__init__.py +0 -29
  10. xync_client-0.0.49.dev13/xync_client/Pms/Ozon/chrome.py +0 -29
  11. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/.env.sample +0 -0
  12. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/.gitignore +0 -0
  13. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/.pre-commit-config.yaml +0 -0
  14. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/README.md +0 -0
  15. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/makefile +0 -0
  16. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/pyproject.toml +0 -0
  17. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/setup.cfg +0 -0
  18. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/TestAgent.py +0 -0
  19. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/TestAsset.py +0 -0
  20. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/TestEx.py +0 -0
  21. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/TestOrder.py +0 -0
  22. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/_todo_refact/Binance/test_binance.py +0 -0
  23. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/_todo_refact/Bybit/test_bybit.py +0 -0
  24. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/_todo_refact/Bybit/test_bybit_p2p.py +0 -0
  25. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/_todo_refact/Gate/test_gate.py +0 -0
  26. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/_todo_refact/Htx/test_htx_p2p.py +0 -0
  27. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/_todo_refact/Wallet/test_agent.py +0 -0
  28. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/_todo_refact/Wallet/test_ex.py +0 -0
  29. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/_todo_refact/__init__.py +0 -0
  30. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/tests/_todo_refact/_test_ex.py +0 -0
  31. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Abc/Agent.py +0 -0
  32. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Abc/Asset.py +0 -0
  33. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Abc/Auth.py +0 -0
  34. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Abc/BaseTest.py +0 -0
  35. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Abc/InAgent.py +0 -0
  36. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Abc/Order.py +0 -0
  37. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Abc/types.py +0 -0
  38. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Binance/__init__.py +0 -0
  39. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Binance/binance_async.py +0 -0
  40. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Binance/earn_api.py +0 -0
  41. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Binance/etype/ad.py +0 -0
  42. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Binance/etype/pm.py +0 -0
  43. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Binance/ex.py +0 -0
  44. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Binance/exceptions.py +0 -0
  45. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Binance/sapi.py +0 -0
  46. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Binance/web_c2c.py +0 -0
  47. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BingX/__init__.py +0 -0
  48. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BingX/agent.py +0 -0
  49. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BingX/base.py +0 -0
  50. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BingX/etype/ad.py +0 -0
  51. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BingX/etype/pm.py +0 -0
  52. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BingX/ex.py +0 -0
  53. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BingX/req.mjs +0 -0
  54. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BingX/sign.js +0 -0
  55. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BitGet/__init__.py +0 -0
  56. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BitGet/agent.py +0 -0
  57. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BitGet/etype/ad.py +0 -0
  58. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BitGet/ex.py +0 -0
  59. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/BitPapa/ex.py +0 -0
  60. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Bybit/InAgent.py +0 -0
  61. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Bybit/etype/ad.py +0 -0
  62. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Bybit/etype/cred.py +0 -0
  63. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Bybit/etype/order.py +0 -0
  64. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Bybit/web_earn.py +0 -0
  65. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Bybit/web_p2p.py +0 -0
  66. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Bybit/ws.py +0 -0
  67. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Gate/etype/ad.py +0 -0
  68. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Gate/ex.py +0 -0
  69. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Gate/premarket.py +0 -0
  70. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Gmail/__init__.py +0 -0
  71. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Htx/agent.py +0 -0
  72. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Htx/earn.py +0 -0
  73. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Htx/etype/__init__.py +0 -0
  74. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Htx/etype/ad.py +0 -0
  75. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Htx/etype/cred.py +0 -0
  76. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Htx/etype/pm.py +0 -0
  77. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Htx/etype/test.py +0 -0
  78. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Htx/ex.py +0 -0
  79. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/KuCoin/etype/ad.py +0 -0
  80. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/KuCoin/etype/pm.py +0 -0
  81. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/KuCoin/ex.py +0 -0
  82. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/KuCoin/web.py +0 -0
  83. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Mexc/etype/ad.py +0 -0
  84. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Mexc/etype/pm.py +0 -0
  85. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Mexc/ex.py +0 -0
  86. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Okx/etype/ad.py +0 -0
  87. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Okx/etype/pm.py +0 -0
  88. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Okx/ex.py +0 -0
  89. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/.gitignore +0 -0
  90. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Alfa/__init__.py +0 -0
  91. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Alfa/state.json +0 -0
  92. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Tinkoff/__init__.py +0 -0
  93. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Tinkoff/state.json +0 -0
  94. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Volet/__init__.py +0 -0
  95. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Volet/_todo_req/req.mjs +0 -0
  96. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Volet/_todo_req/req.py +0 -0
  97. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Volet/api.py +0 -0
  98. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/Pms/Volet/pl.py +0 -0
  99. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/TgWallet/agent.py +0 -0
  100. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/TgWallet/asset.py +0 -0
  101. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/TgWallet/auth.py +0 -0
  102. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/TgWallet/ex.py +0 -0
  103. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/TgWallet/inAgent.py +0 -0
  104. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/TgWallet/order.py +0 -0
  105. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/TgWallet/pyd.py +0 -0
  106. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/TgWallet/pyro.py +0 -0
  107. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/TgWallet/web.py +0 -0
  108. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/__init__.py +0 -0
  109. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/loader.py +0 -0
  110. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client/pm_unifier.py +0 -0
  111. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client.egg-info/dependency_links.txt +0 -0
  112. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client.egg-info/requires.txt +0 -0
  113. {xync_client-0.0.49.dev13 → xync_client-0.0.50.dev1}/xync_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xync-client
3
- Version: 0.0.49.dev13
3
+ Version: 0.0.50.dev1
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client
@@ -65,7 +65,13 @@ class BaseExClient(HttpClient):
65
65
  # 24: Список объяв по (buy/sell, cur, coin, pm)
66
66
  @abstractmethod
67
67
  async def ads(
68
- self, coin_exid: str, cur_exid: str, is_sell: bool, pm_exids: list[str | int] = None, amount: int = None
68
+ self,
69
+ coin_exid: str,
70
+ cur_exid: str,
71
+ is_sell: bool,
72
+ pm_exids: list[str | int] = None,
73
+ amount: int = None,
74
+ lim: int = None,
69
75
  ) -> list[BaseAd]: # {ad.id: ad}
70
76
  ...
71
77
 
@@ -1,6 +1,7 @@
1
1
  import logging
2
2
  import re
3
3
  from asyncio import run, sleep, gather
4
+ from difflib import SequenceMatcher
4
5
  from enum import IntEnum
5
6
  from http.client import HTTPException
6
7
  from typing import Literal
@@ -9,11 +10,12 @@ import pyotp
9
10
  from asyncpg import ConnectionDoesNotExistError
10
11
  from bybit_p2p import P2P
11
12
  from bybit_p2p._exceptions import FailedRequestError
13
+ from tortoise.expressions import F
12
14
  from urllib3.exceptions import ReadTimeoutError
13
15
  from x_model import init_db
14
16
  from xync_schema import models
15
17
 
16
- from xync_schema.models import Cur, Actor
18
+ from xync_schema.models import Cur, Actor, Cond, Direction, CondCond
17
19
 
18
20
  from xync_client.Abc.Agent import BaseAgentClient
19
21
  from xync_client.Abc.types import BaseOrderReq, FlatDict
@@ -177,8 +179,16 @@ class AgentClient(BaseAgentClient): # Bybit client
177
179
  res = await self._post("/fiat/otc/maker/work-config/switch", data)
178
180
  return res
179
181
 
180
- async def ads(self, cnx: models.Coinex, crx: models.Curex, is_sell: bool, pmxs: list[models.Pmex]) -> list[Ad]:
181
- return await self.ex_client.ads(cnx.exid, crx.exid, is_sell, [pmex.exid for pmex in pmxs])
182
+ async def ads(
183
+ self,
184
+ cnx: models.Coinex,
185
+ crx: models.Curex,
186
+ is_sell: bool,
187
+ pmxs: list[models.Pmex],
188
+ amount: int = None,
189
+ lim: int = None,
190
+ ) -> list[Ad]:
191
+ return await self.ex_client.ads(cnx.exid, crx.exid, is_sell, [pmex.exid for pmex in pmxs or []], amount, lim)
182
192
 
183
193
  def online_ads(self) -> str:
184
194
  online = self._get("/fiat/otc/maker/work-config/get")
@@ -432,7 +442,9 @@ class AgentClient(BaseAgentClient): # Bybit client
432
442
  await sleep(15)
433
443
  continue
434
444
  if not (cur_plc := [i for i, ad in enumerate(ads) if int(ad.userId) == self.actor.exid]):
435
- ...
445
+ logging.warning(f"No racing in {'-' if is_sell else '+'}{coinex.exid}/{curex.exid}")
446
+ await sleep(15)
447
+ continue
436
448
  (cur_plc,) = cur_plc
437
449
  mad: Ad = ads.pop(cur_plc)
438
450
  if not ads:
@@ -483,6 +495,131 @@ class AgentClient(BaseAgentClient): # Bybit client
483
495
  logging.warning("Connection failed. Restarting..")
484
496
  await sleep(42)
485
497
 
498
+ async def take(
499
+ self,
500
+ coinex: models.Coinex,
501
+ curex: models.Curex,
502
+ is_sell: bool,
503
+ pms: list[str] = None,
504
+ ceil: float = None,
505
+ volume: float = 9000,
506
+ min_fiat: int = None,
507
+ max_fiat: int = None,
508
+ ):
509
+ k = (-1) ** int(is_sell) # on_buy=1, on_sell=-1
510
+
511
+ if pms:
512
+ creds: dict[models.Pmex, models.CredEx] = await get_creds(pms, self.actor.ex)
513
+ [str(p.exid) for p in creds.values()]
514
+
515
+ if is_sell: # гонка в стакане продажи - мы покупаем монету за ФИАТ
516
+ fiats = await models.Fiat.filter(
517
+ cred_id__in=[cx.cred_id for cx in creds.values()], amount__not=F("target")
518
+ )
519
+ volume = min(volume, max(fiats, key=lambda f: f.target - f.amount).amount / ceil)
520
+ else: # гонка в стакане покупки - мы продаем МОНЕТУ за фиат
521
+ asset = await models.Asset.get(addr__actor=self.actor, addr__coin_id=coinex.coin_id)
522
+ volume = min(volume, asset.free - (asset.freeze or 0) - (asset.lock or 0))
523
+ volume = str(round(volume, coinex.coin.scale))
524
+ dr = await Direction.get(
525
+ pairex__ex=self.ex_client.ex,
526
+ pairex__pair__coin_id=coinex.coin_id,
527
+ pairex__pair__cur_id=curex.cur_id,
528
+ sell=is_sell,
529
+ )
530
+
531
+ all_conds = {k: v for k, v in await Cond.all().values_list("id", "raw_txt")}
532
+ sims: dict[Cond, int] = {}
533
+ while self.actor.person.user.status > 0: # todo: depends on rest asset/fiat
534
+ ads: list[Ad] = await self.ads(coinex, curex, is_sell, pms and list(creds.keys()))
535
+
536
+ if not ads:
537
+ print(coinex.exid, curex.exid, is_sell, "no ads!")
538
+ await sleep(300)
539
+ continue
540
+
541
+ for i, ad in enumerate(ads):
542
+ if (ceil - float(ad.price)) * k < 0:
543
+ break
544
+ if int(ad.userId) == self.actor.exid:
545
+ logging.info(f"My ad {'-' if is_sell else '+'}{coinex.exid}/{curex.exid} on place#{i}")
546
+ continue
547
+ actor, _ = await Actor.update_or_create({"name": ad.nickName}, exid=ad.userId, ex=self.ex_client.ex)
548
+
549
+ if (cleaned := clean(ad.remark)) not in all_conds.values():
550
+ for cid, txt in all_conds.items():
551
+ sim = SequenceMatcher(None, cleaned, txt).ratio()
552
+ if sim > 0.8:
553
+ if (
554
+ old_ad := await models.Ad.filter(cond_id=cid, maker__exid=int(ad.userId))
555
+ .prefetch_related("cond")
556
+ .first()
557
+ ):
558
+ # у этого чела есть объява с почти таким же текстом
559
+ if old_ad.exid == int(ad.id): # и он изменил текст как раз в ней
560
+ # заменяем текст без создания нового cond
561
+ await old_ad.cond.update_or_create(raw_txt=cleaned)
562
+ continue
563
+ else: # но это не оно
564
+ logging.warning(f"ad#{ad.id}-cond#{cid} txt updated:\n{txt}\n|\n|\nV\n{cleaned}")
565
+ # todo: и что тогда делать? ничего, так оставить?
566
+ # похожий текст у другого юзера
567
+ sims[await Cond[cid]] = int(sim * 1000)
568
+ cond, isnew = await Cond.get_or_create(raw_txt=cleaned)
569
+ if isnew:
570
+ all_conds[cond.id] = cond.raw_txt
571
+ [await CondCond.update_or_create({"similarity": s}, cond_rel=c, cond=cond) for c, s in sims.items()]
572
+ sims.clear()
573
+ ad_db, _ = await models.Ad.update_or_create(
574
+ {
575
+ "price": ad.price,
576
+ "amount": ad.quantity,
577
+ "min_fiat": ad.minAmount,
578
+ "max_fiat": ad.maxAmount,
579
+ "cond": cond,
580
+ },
581
+ exid=int(ad.id),
582
+ direction=dr,
583
+ maker=actor,
584
+ )
585
+ #
586
+ # if not isnew and cond.raw_txt != ad.remark:
587
+ # cond.parsed = False
588
+ # await cond.save()
589
+ # logging.warning(f"{actor.name} updated conds!")
590
+ if isnew:
591
+ s = f"{'-' if is_sell else '+'}{ad.price}[{ad.minAmount}-{ad.maxAmount}]{coinex.exid}/{curex.exid}"
592
+ print(s, end=" | ", flush=True)
593
+ try:
594
+ # take
595
+ ...
596
+ except FailedRequestError as e:
597
+ if ExcCode(e.status_code) == ExcCode.RareLimit:
598
+ await sleep(195)
599
+ elif ExcCode(e.status_code) == ExcCode.Timestamp:
600
+ await sleep(2)
601
+ else:
602
+ raise e
603
+ except (ReadTimeoutError, ConnectionDoesNotExistError):
604
+ logging.warning("Connection failed. Restarting..")
605
+ await sleep(6)
606
+
607
+
608
+ def clean(s) -> str:
609
+ clear = r"[^\w\s.,!?;:()\-]"
610
+ repeat = r"(.)\1{2,}"
611
+ s = re.sub(clear, "", s).lower()
612
+ s = re.sub(repeat, r"\1", s)
613
+ return s.replace("\n\n", "\n").replace(" ", " ").strip(" \n/.,!?-")
614
+
615
+
616
+ async def actual_cond():
617
+ conds = await Cond.all()
618
+ for cond in conds:
619
+ if cond.raw_txt != (s := clean(cond.raw_txt)):
620
+ cond.raw_txt = s
621
+ await cond.save()
622
+
486
623
 
487
624
  def step(mad, cad) -> float:
488
625
  return (
@@ -529,15 +666,17 @@ async def main():
529
666
  # pairex__ex=cl.actor.ex, pairex__pair__coin__ticker="USDT", pairex__pair__cur__ticker="RUB", sell=True
530
667
  # )
531
668
  # await cl.set_creds()
669
+ # await actual_cond()
532
670
  await gather(
533
671
  cl.battle(usdt, rub, False, ["volet"], 79.97), # гонка в стакане покупки - мы продаем
534
- cl.battle(usdt, rub, True, ["volet"], 78.06), # гонка в стакане продажи - мы покупаем
672
+ cl.battle(usdt, rub, True, ["volet"], 79.11), # гонка в стакане продажи - мы покупаем
535
673
  cl.battle(eth, rub, False, ["volet"], 206_000),
536
674
  cl.battle(eth, rub, True, ["volet"], 200_000),
537
675
  cl.battle(btc, rub, False, ["volet"], 8_500_000),
538
676
  cl.battle(btc, rub, True, ["volet"], 8_400_000),
539
677
  cl.battle(usdc, rub, False, ["volet"], 80.5),
540
678
  cl.battle(usdc, rub, True, ["volet"], 79),
679
+ cl.take(usdt, rub, True, ceil=81, volume=360),
541
680
  )
542
681
 
543
682
  bor = BaseOrderReq(
@@ -82,7 +82,13 @@ class ExClient(BaseExClient): # Bybit client
82
82
 
83
83
  # 24: Список объяв по (buy/sell, cur, coin, pm)
84
84
  async def ads(
85
- self, coin_exid: str, cur_exid: str, is_sell: bool, pm_exids: list[str | int] = None, amount: int = None
85
+ self,
86
+ coin_exid: str,
87
+ cur_exid: str,
88
+ is_sell: bool,
89
+ pm_exids: list[str | int] = None,
90
+ amount: int = None,
91
+ lim: int = None,
86
92
  ) -> list[ad.Ad]:
87
93
  data = {
88
94
  "userId": "",
@@ -90,7 +96,7 @@ class ExClient(BaseExClient): # Bybit client
90
96
  "currencyId": cur_exid,
91
97
  "payment": pm_exids or [],
92
98
  "side": "0" if is_sell else "1",
93
- "size": "50",
99
+ "size": lim and str(lim) or "50",
94
100
  "page": "1",
95
101
  "amount": str(amount) if amount else "",
96
102
  "authMaker": False,
@@ -103,7 +109,7 @@ class ExClient(BaseExClient): # Bybit client
103
109
  async def main():
104
110
  _ = await init_db(PG_DSN, models, True)
105
111
  ex = await Ex.get(name="Bybit")
106
- bot: FileClient = await FileClient(TOKEN)
112
+ bot: FileClient = FileClient(TOKEN)
107
113
  await bot.start()
108
114
  cl = ExClient(ex, bot)
109
115
  _ads = await cl.ads("USDT", "GEL", False)
@@ -0,0 +1,63 @@
1
+ from asyncio import run
2
+ from x_model import init_db
3
+ from xync_schema import models
4
+ from xync_client.loader import PG_DSN
5
+ import undetected_chromedriver as uc
6
+ from selenium.webdriver.common.by import By
7
+ from selenium.webdriver.common.action_chains import ActionChains
8
+ import os
9
+ import json
10
+ import time
11
+
12
+ async def save_cookies(driver):
13
+ cookies = driver.get_cookies() # Получаем все куки
14
+ with open("state.json", "w") as file:
15
+ json.dump(cookies, file) # Сохраняем в JSON
16
+
17
+ async def loggin(driver, agent) -> None:
18
+ driver.get("https://finance.ozon.ru")
19
+ with open("state.json", "r") as file:
20
+ cookies = json.load(file)
21
+ for cookie in cookies:
22
+ driver.add_cookie(cookie)
23
+ driver.get("https://finance.ozon.ru/lk")
24
+ pin = agent.auth.get("code")
25
+ actions = ActionChains(driver)
26
+ for char in pin:
27
+ actions.send_keys(char)
28
+ actions.perform()
29
+
30
+
31
+ async def send_cred(driver, amount, payment, cred):
32
+ pass
33
+
34
+
35
+
36
+ async def main():
37
+ _ = await init_db(PG_DSN, models, True)
38
+ agent = await models.PmAgent.filter(pm__norm="ozon", auth__isnull=False).first()
39
+ chrome_options = uc.ChromeOptions()
40
+ chrome_options.add_argument('--disable-gpu')
41
+ chrome_options.add_argument('--no-sandbox')
42
+ driver = uc.Chrome(options=chrome_options)
43
+
44
+ try:
45
+ if not os.path.exists("state.json"):
46
+ driver.get('https://ozon.ru/ozonid-lite')
47
+ time.sleep(3)
48
+ driver.find_element(By.NAME, "autocomplete").send_keys(agent.auth.get("phone"))
49
+ driver.find_element(By.CLASS_NAME, "b201-a").click()
50
+ sms_code = input("Введите 6-ти значный код: ")
51
+ driver.find_element(By.CLASS_NAME, "d01-a.d01-a5").send_keys(sms_code)
52
+ time.sleep(3)
53
+ await save_cookies(driver)
54
+ else:
55
+ await loggin(driver, agent)
56
+ time.sleep(1000)
57
+
58
+ finally:
59
+ driver.quit()
60
+
61
+
62
+ if __name__ == "__main__":
63
+ run(main())
@@ -8,90 +8,84 @@ from xync_schema import models
8
8
  from xync_client.loader import PG_DSN
9
9
 
10
10
 
11
- async def input_(page, selectot: str, code: str)->None:
11
+ async def input_(page, selectot: str, code: str) -> None:
12
12
  await page.wait_for_selector(selectot, timeout=10000)
13
- page.locator('[class="BjsSl7Uv2es5tUtwB03r"]')
14
13
  for i in range(5):
15
14
  await page.keyboard.press(code[i])
16
15
  await page.wait_for_timeout(1000)
17
16
 
17
+
18
18
  async def fiveDigitCode(page, agent):
19
19
  sms_code = input("Введите код из SMS: ")
20
20
  for i in range(5):
21
21
  await page.locator(f'input[name="confirmPassword-{i}"]').fill(sms_code[i])
22
-
23
22
  passcode = input("Введите 5-значный код: ")
24
- await input_(page, '.FWAhBZHPePsATLTVFeTT', passcode)
25
- await input_(page, '.Re_Wg4Drqw9QjVM43vJ_', passcode)
23
+ await input_(page, "[data-testid=login-stage-pin-create] div >> nth=3", passcode)
24
+ await input_(page, "[data-testid=login-stage-pin-create-repeat] div >> nth=3", passcode)
26
25
  agent.auth["pass"] = passcode
27
26
  await agent.save()
28
27
 
29
- async def login_cart(page, number_cart:str, agent)->None:
30
- await page.locator('button[aria-controls="tabpanel-card"]').click()
31
- await page.wait_for_selector('input[placeholder="Введите номер карты"]', timeout=10000)
32
- await page.locator('input[placeholder="Введите номер карты"]').fill(number_cart)
33
- await page.locator('button[type="submit"]').click()
34
- await fiveDigitCode(page, agent)
35
28
 
36
- async def login_and_password(page, login:str, password:str, agent)->None:
29
+ async def login_cart(page, number_cart: str, agent) -> None:
30
+ await page.locator('button[aria-controls="tabpanel-card"]').click()
31
+ await page.wait_for_selector('input[placeholder="Введите номер карты"]', timeout=10000)
32
+ await page.locator('input[placeholder="Введите номер карты"]').fill(number_cart)
33
+ await page.locator('button[type="submit"]').click()
34
+ await fiveDigitCode(page, agent)
35
+
36
+
37
+ async def login_and_password(page, login: str, password: str, agent) -> None:
37
38
  await page.locator('input[autocomplete="login"]').fill(login)
38
39
  await page.locator('input[autocomplete="password"]').fill(password)
39
40
  await page.locator('button[data-testid="button-continue"]').click()
40
41
  await fiveDigitCode(page, agent)
41
42
 
42
- async def logged(page, passcode: str)->None:
43
- await page.wait_for_selector('.UFWVuux_h6LdkrisQYCk', timeout=10000)
44
- page.locator('.WpYaKiJknodWYw32MZd9')
43
+
44
+ async def logged(page, passcode: str) -> None:
45
+ await page.wait_for_selector(".UFWVuux_h6LdkrisQYCk", timeout=10000)
45
46
  for i in range(5):
46
47
  await page.keyboard.press(passcode[i])
47
48
  await page.wait_for_timeout(10000)
48
49
 
49
- async def sendCredCard(
50
- page,
51
- amount: int,
52
- payment: str,
53
- cred: str
54
- )->None:
55
-
56
- await page.locator('a#nav-link-payments').click()
57
- await page.locator('.sxZoARZF').click()
58
- await page.locator('input#text-field-1').fill(cred)
59
- await page.locator('.tMUGN6jK').click()
50
+
51
+ async def sendCredCard(page, amount: int, payment: str, cred: str) -> None:
52
+ await page.locator("a#nav-link-payments").click()
53
+ await page.locator(".sxZoARZF").click()
54
+ await page.locator("input#text-field-1").fill(cred)
55
+ await page.locator(".tMUGN6jK").click()
60
56
  if len(cred) < 15:
61
57
  await page.click('button[title="В другой банк по СБП"]')
62
- await page.fill('input[name="sbptransfer\\:init\\:targetBank"]', payment)
63
- # await page.wait_for_selector('#sbptransfer\\:init\\:targetBank-option-100000000004', state="visible")
64
- await page.locator('#sbptransfer\\:init\\:targetBank-option-100000000004').click()
65
- # await page.wait_for_selector('.Fv3KdbZw', state="visible")
66
- # await page.locator('.Fv3KdbZw').click()
58
+ await page.fill("input#text-field-1", payment)
59
+ await page.locator(".Fv3KdbZw").click()
67
60
  await page.wait_for_selector("#sbptransfer\\:init\\:summ", state="visible")
68
61
  await page.fill("#sbptransfer\\:init\\:summ", str(amount))
69
- await page.click('.transfers-fps-17yzyu7 e5hllya1')
62
+ await page.click(".zcSt16vp")
70
63
  sms_code = input("Введите код из SMS: ")
71
64
  await page.fill('input[autocomplete="one-time-code"]', sms_code)
72
- await page.click('.transfers-fps-17yzyu7 e5hllya1')
65
+ await page.click(".zcSt16vp")
73
66
 
74
67
  else:
75
- await page.wait_for_selector('#p2ptransfer\\:xbcard\\:amount', state="visible")
76
- await page.fill('#p2ptransfer\\:xbcard\\:amount', str(amount))
77
- await page.wait_for_selector('button.bjm6hnlx', state="visible")
68
+ await page.wait_for_selector("#p2ptransfer\\:xbcard\\:amount", state="visible")
69
+ await page.fill("#p2ptransfer\\:xbcard\\:amount", str(amount))
70
+ await page.wait_for_selector("button.bjm6hnlx", state="visible")
78
71
  await page.wait_for_timeout(1000)
79
72
  await page.click('button:has-text("Продолжить")')
80
- await page.click('button.bjm6hnlx')
81
- await page.click('button.bjm6hnlx')
73
+ await page.click("button.bjm6hnlx")
74
+ await page.click("button.bjm6hnlx")
82
75
  sms_code = input("Введите код из SMS: ")
83
- await page.fill('input.MH9z5OYE', sms_code)
84
- await page.click('button.bjm6hnlx')
76
+ await page.fill("input.MH9z5OYE", sms_code)
77
+ await page.click("button.bjm6hnlx")
85
78
 
86
79
 
87
- async def last_transaction(page, amounts: int, transactions: str)->bool:
88
- transaction = await page.locator('.JsCdEfJ6').all_text_contents()
89
- amount = await page.locator('.ibtVVZxM.APTNeSaT').all_text_contents()
80
+ async def last_transaction(page, amounts: int, transactions: str) -> bool:
81
+ transaction = await page.locator(".JsCdEfJ6").all_text_contents()
82
+ amount = await page.locator(".ibtVVZxM.APTNeSaT").all_text_contents()
90
83
  cleaned_amount = int(re.sub(r"[^\d]", "", amount[0]))
91
84
  amount_ = cleaned_amount == amounts
92
85
  transaction_ = transaction[0].strip().upper() == transactions.strip().upper()
93
86
  return amount_ and transaction_
94
87
 
88
+
95
89
  async def check_last_transaction(result: bool):
96
90
  if result:
97
91
  print("Платеж получен")
@@ -100,10 +94,8 @@ async def check_last_transaction(result: bool):
100
94
 
101
95
 
102
96
  async def main():
103
-
104
97
  _ = await init_db(PG_DSN, models, True)
105
98
  agent = await models.PmAgent.filter(pm__norm="sber", auth__isnull=False).first()
106
-
107
99
  storage_state = "state.json" if os.path.exists("state.json") else None
108
100
  url = "https://online.sberbank.ru/CSAFront/index.do"
109
101
  async with async_playwright() as p:
@@ -121,24 +113,25 @@ async def main():
121
113
  await logged(page, agent.auth.get("pass"))
122
114
  result = await last_transaction(page, 20, "твой нейм")
123
115
  await check_last_transaction(result)
124
- await sendCredCard(page, 10, "Т-Банк", "2202 2062 7529 5967")
116
+ await sendCredCard(page, 10, "Т-Банк", "2200 7008 2987 6027")
125
117
  await page.wait_for_timeout(10000)
126
118
 
127
119
  elif login := agent.auth.get("login"):
120
+ await page.wait_for_timeout(1500)
128
121
  if await page.locator('button[aria-controls="tabpanel-login"]').is_visible():
129
122
  await login_and_password(page, login, agent.auth.get("password"), agent)
130
123
  else:
131
124
  await logged(page, agent.auth.get("pass"))
132
125
  result = await last_transaction(page, 20, "твой нейм")
133
126
  await check_last_transaction(result)
134
- await sendCredCard(page, 10, "Т-Банк", "9308185958")
127
+ await sendCredCard(page, 10, "Т-Банк", "2200 7008 2987 6027")
135
128
  await page.wait_for_timeout(10000)
136
129
 
137
-
138
130
  await context.storage_state(path="state.json")
139
131
 
140
132
  await context.close()
141
133
  await browser.close()
142
134
 
135
+
143
136
  if __name__ == "__main__":
144
137
  asyncio.run(main())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xync-client
3
- Version: 0.0.49.dev13
3
+ Version: 0.0.50.dev1
4
4
  Author-email: Mike Artemiev <mixartemev@gmail.com>
5
5
  Project-URL: Homepage, https://gitlab.com/XyncNet/client
6
6
  Project-URL: Repository, https://gitlab.com/XyncNet/client
@@ -90,7 +90,6 @@ xync_client/Pms/.gitignore
90
90
  xync_client/Pms/Alfa/__init__.py
91
91
  xync_client/Pms/Alfa/state.json
92
92
  xync_client/Pms/Ozon/__init__.py
93
- xync_client/Pms/Ozon/chrome.py
94
93
  xync_client/Pms/Sber/__init__.py
95
94
  xync_client/Pms/Tinkoff/__init__.py
96
95
  xync_client/Pms/Tinkoff/state.json
@@ -1,29 +0,0 @@
1
- import undetected_chromedriver as uc
2
- import time
3
-
4
-
5
- def main():
6
- # Initialize Chrome options
7
- chrome_options = uc.ChromeOptions()
8
- # chrome_options.add_argument('--headless') # Uncomment this to run in headless mode
9
- chrome_options.add_argument('--disable-gpu') # Disable GPU usage for compatibility
10
- chrome_options.add_argument('--no-sandbox') # Disable sandboxing for compatibility
11
-
12
- # Initialize the undetected ChromeDriver
13
- driver = uc.Chrome(options=chrome_options)
14
-
15
- try:
16
- # Navigate to a webpage
17
- driver.get('https://ozon.ru')
18
-
19
- # Wait for a few seconds to allow the page to load
20
- time.sleep(5)
21
-
22
- # Print the contents of the page
23
- print(driver.page_source)
24
- finally:
25
- driver.quit()
26
-
27
-
28
- if __name__ == "__main__":
29
- main()
@@ -1,29 +0,0 @@
1
- import undetected_chromedriver as uc
2
- import time
3
-
4
-
5
- def main():
6
- # Initialize Chrome options
7
- chrome_options = uc.ChromeOptions()
8
- # chrome_options.add_argument('--headless') # Uncomment this to run in headless mode
9
- chrome_options.add_argument("--disable-gpu") # Disable GPU usage for compatibility
10
- chrome_options.add_argument("--no-sandbox") # Disable sandboxing for compatibility
11
-
12
- # Initialize the undetected ChromeDriver
13
- driver = uc.Chrome(options=chrome_options)
14
-
15
- try:
16
- # Navigate to a webpage
17
- driver.get("https://finance.ozon.ru/lk")
18
-
19
- # Wait for a few seconds to allow the page to load
20
- time.sleep(5)
21
-
22
- # Print the contents of the page
23
- print(driver.page_source)
24
- finally:
25
- driver.quit()
26
-
27
-
28
- if __name__ == "__main__":
29
- main()