xync-db 0.5.5.dev23__tar.gz → 0.5.5.dev26__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.
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/PKG-INFO +1 -1
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/login_store.py +1 -1
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/models/__init__.py +39 -10
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/.gitignore +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/README.md +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/pyproject.toml +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/__init__.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/config.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/enums.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/exceptions.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/graph.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/i18n.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/logo.png +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/CLAUDE.md +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/__init__.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/0001_initial.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/0002_triggers.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/0003_seed.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/__init__.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/__init__.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/a_actor_seed.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/a_bin_seed.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/a_country_seed.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/a_tg_seed.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/b_htx_seed.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/c_net_seed.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/countries.json +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/ranges.csv +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/xync_files.sql +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/models/CLAUDE.md +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/py.typed +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/shared.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/typs/__init__.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/typs/db/__init__.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/typs/db/actor.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/typs/db/ad.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/typs/db/common.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/typs/db/cred.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/typs/db/order.py +0 -0
- {xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/typs/db/pm.py +0 -0
|
@@ -88,7 +88,7 @@ async def login_fulfil(token: str, payload: dict[str, Any]) -> bool:
|
|
|
88
88
|
return True
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
async def login_take(token: str) -> dict[str, Any] |
|
|
91
|
+
async def login_take(token: str) -> dict[str, Any] | object | None:
|
|
92
92
|
"""Poll a token. Returns `MISSING` if it never existed / expired, `None` if it exists but
|
|
93
93
|
Start wasn't tapped yet, or the payload dict once ready (consumed: the token is deleted)."""
|
|
94
94
|
if _redis is not None:
|
|
@@ -490,6 +490,16 @@ class User(TgUser, TsTrait):
|
|
|
490
490
|
# self.pm_clients = {pma.pm_id: pma.client() for pma in self.pm_agents}
|
|
491
491
|
# self.agent_clients = {a.id: a.client() for a in self.person.actor.agents}
|
|
492
492
|
|
|
493
|
+
@property
|
|
494
|
+
def handle(self) -> str | None:
|
|
495
|
+
"""«@username» из Telegram либо None (ждёт prefetched `username`)."""
|
|
496
|
+
return self.username.username and "@" + self.username.username
|
|
497
|
+
|
|
498
|
+
@property
|
|
499
|
+
def title(self) -> str:
|
|
500
|
+
"""Отображаемое имя: first_name → @handle → id:N (ждёт prefetched `username`)."""
|
|
501
|
+
return self.first_name or self.handle or f"id:{self.id}"
|
|
502
|
+
|
|
493
503
|
@classmethod
|
|
494
504
|
async def mark_membership(
|
|
495
505
|
cls, username_id: int, *, in_channel: bool | None = None, in_chat: bool | None = None
|
|
@@ -687,13 +697,7 @@ class User(TgUser, TsTrait):
|
|
|
687
697
|
)
|
|
688
698
|
c["amount"] += a["free"] / 10**scale
|
|
689
699
|
users = await cls.filter(id__in=[uid for uid in ss if uid]).prefetch_related("username")
|
|
690
|
-
names = {
|
|
691
|
-
u.id: (
|
|
692
|
-
u.first_name or (u.username and u.username.username and "@" + u.username.username) or f"id:{u.id}",
|
|
693
|
-
u.username and u.username.username and "@" + u.username.username,
|
|
694
|
-
)
|
|
695
|
-
for u in users
|
|
696
|
-
}
|
|
700
|
+
names = {u.id: (u.title, u.handle) for u in users}
|
|
697
701
|
return cls._assemble_rich(ss, cur_meta, usdt_rate, coins_by_user, names)
|
|
698
702
|
|
|
699
703
|
async def balance(self, cur_id: int, ts: int | None = None) -> int:
|
|
@@ -1245,9 +1249,25 @@ class Agent(Model, TsTrait):
|
|
|
1245
1249
|
|
|
1246
1250
|
@classmethod
|
|
1247
1251
|
async def upsert(
|
|
1248
|
-
cls,
|
|
1252
|
+
cls,
|
|
1253
|
+
exid: int,
|
|
1254
|
+
host: str,
|
|
1255
|
+
auth: dict,
|
|
1256
|
+
exp: int | None,
|
|
1257
|
+
rname: str | None,
|
|
1258
|
+
nick: str,
|
|
1259
|
+
email: str | None = None,
|
|
1260
|
+
user: User | None = None,
|
|
1249
1261
|
) -> tuple[int, Agent, bool]:
|
|
1250
|
-
"""Единый писатель агента (за `/public/set-agent`).
|
|
1262
|
+
"""Единый писатель агента (за `/public/set-agent` и OAuth «Connect Bybit»). `exp=None` — срок
|
|
1263
|
+
web-сессии неизвестен (Htx/Mexc, голые API-ключи из OAuth) → `expire_at` не трогаем. У OAuth-ключей
|
|
1264
|
+
и имени нет (`rname=None`, `nick=""`) — их дозаполнит `Ex.person_save`/`actor_save` по данным биржи.
|
|
1265
|
+
|
|
1266
|
+
`user` — владелец УЖЕ известен (OAuth из приложения залогиненного юзера): актор сразу
|
|
1267
|
+
привязывается к нему `Actor.set_user` (тот же мердж персон, что по ответу админа), без
|
|
1268
|
+
USER_DEF-вопроса «чей это агент?». Актор чужого юзера → PermissionError, агента не трогаем.
|
|
1269
|
+
|
|
1270
|
+
Bootstrap-персону нового актора резолвим
|
|
1251
1271
|
ПО `note` (`"{ex_id}:{exid}"`, уникальному по актору) — тем же ключом, что клиентский
|
|
1252
1272
|
`Ex.person_save`, чтобы у Person был ОДИН путь создания (D-035). По НЕуникальному `name` НЕ
|
|
1253
1273
|
ищем: именно `get_or_none(name=rname)` ронял прод `MultipleObjectsReturned` на тёзках без юзера.
|
|
@@ -1265,6 +1285,8 @@ class Agent(Model, TsTrait):
|
|
|
1265
1285
|
note = f"{ex.id}:{exid}" # ключ bootstrap-персоны актора (как в Ex.person_save)
|
|
1266
1286
|
if person := await Person.get_or_none(note=note):
|
|
1267
1287
|
pass # актор уже знаком — берём его bootstrap-персону
|
|
1288
|
+
elif user: # владелец известен — персона без USER_DEF (админа не зовём), к юзеру ниже set_user'ом
|
|
1289
|
+
person = await Person.create(name=rname, note=note)
|
|
1268
1290
|
else:
|
|
1269
1291
|
# gmail-автолинк: замаскированная биржей почта, однозначно (ровно 1 gmail по LIKE,
|
|
1270
1292
|
# где `*`→`_`) указывающая на юзера, сразу привязывает актора к его персоне — без
|
|
@@ -1286,9 +1308,16 @@ class Agent(Model, TsTrait):
|
|
|
1286
1308
|
person = await Person.create(name=rname, note=note, status=PersonStatus.USER_DEF)
|
|
1287
1309
|
err = 1 # ждём привязки к юзеру через def_user
|
|
1288
1310
|
actor = await Actor.create(ex=ex, exid=exid, name=nick, person=person)
|
|
1311
|
+
if user:
|
|
1312
|
+
await actor.fetch_related("person")
|
|
1313
|
+
if actor.person.user_id not in (None, user.id):
|
|
1314
|
+
raise PermissionError(f"Actor#{actor.id} ({ex.name}:{exid}) belongs to user#{actor.person.user_id}")
|
|
1315
|
+
if not actor.person.user_id:
|
|
1316
|
+
await actor.set_user(user.username_id)
|
|
1289
1317
|
if ag := await Agent.get_or_none(actor=actor):
|
|
1290
1318
|
ag.auth |= auth
|
|
1291
|
-
|
|
1319
|
+
if exp is not None:
|
|
1320
|
+
ag.expire_at = exp
|
|
1292
1321
|
await ag.save(update_fields=["auth", "expire_at"])
|
|
1293
1322
|
created = False
|
|
1294
1323
|
else:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/a_actor_seed.py
RENAMED
|
File without changes
|
{xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/a_bin_seed.py
RENAMED
|
File without changes
|
{xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/a_country_seed.py
RENAMED
|
File without changes
|
|
File without changes
|
{xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/b_htx_seed.py
RENAMED
|
File without changes
|
{xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/c_net_seed.py
RENAMED
|
File without changes
|
{xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/countries.json
RENAMED
|
File without changes
|
|
File without changes
|
{xync_db-0.5.5.dev23 → xync_db-0.5.5.dev26}/src/xync_db/migrations/models/seed/xync_files.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|