xync-db 0.4.0__tar.gz → 0.4.2.dev12__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.4.0 → xync_db-0.4.2.dev12}/PKG-INFO +1 -1
- xync_db-0.4.2.dev12/src/xync_db/migrations/models/0007_agent_auth_notify.py +41 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/models/__init__.py +12 -10
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/.gitignore +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/README.md +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/pyproject.toml +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/__init__.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/config.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/enums.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/exceptions.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/graph.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/i18n.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/logo.png +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/CLAUDE.md +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/__init__.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/0001_initial.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/0002_triggers.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/0003_files_seed.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/0004_all_seed.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/0005_credex_del.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/0006_credex_orphan.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/__init__.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/seed/__init__.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/seed/a_actor_seed.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/seed/a_tg_seed.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/seed/b_htx_seed.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/migrations/models/seed/xync_files.sql +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/models/CLAUDE.md +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/py.typed +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/shared.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/typs/__init__.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/typs/db/__init__.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/typs/db/actor.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/typs/db/ad.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/typs/db/common.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/typs/db/cred.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/typs/db/order.py +0 -0
- {xync_db-0.4.0 → xync_db-0.4.2.dev12}/src/xync_db/typs/db/pm.py +0 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Agent `auth` change → `agents_upd_auth` channel (reactive session reload).
|
|
2
|
+
|
|
3
|
+
The chrome-extension re-posts an agent's web session (cookies/headers) through `POST /public/set-agent`
|
|
4
|
+
whenever the owner clicks it — but it fires even when nothing changed (the partner just re-opens the
|
|
5
|
+
ext). So instead of reacting in the endpoint on every call, we react in the DB on a real change: the
|
|
6
|
+
existing `agent_upd()` AFTER-UPDATE trigger gains a second, independent branch that emits
|
|
7
|
+
`agents_upd_auth` ONLY when `auth` actually changed (`OLD.auth IS DISTINCT FROM NEW.auth`).
|
|
8
|
+
|
|
9
|
+
service-api's pg-listener (`api.handlers.agents.agents_auth_upd`) then patches the cookies/headers into
|
|
10
|
+
the LIVE http-session of the running agent client (`BaseAgentClient.reload_auth`) — so subsequent
|
|
11
|
+
requests use the fresh session without a service restart — and notifies the agent's owner + the admin.
|
|
12
|
+
|
|
13
|
+
Independent of the `agents_upd_status` branch (status and auth can change together or apart). Payload is
|
|
14
|
+
the full `row_to_json(NEW)` (handler hydrates `Agent(**data)` for actor_id + auth), mirroring
|
|
15
|
+
`actor_person_needs_def_user`.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from typing import ClassVar
|
|
19
|
+
|
|
20
|
+
from tortoise.migrations.migration import Migration as BaseMigration
|
|
21
|
+
from tortoise.migrations.operations import RunSQL
|
|
22
|
+
|
|
23
|
+
AGENT_AUTH_SQL = """
|
|
24
|
+
CREATE OR REPLACE FUNCTION agent_upd() returns trigger as $agent_upd_trg$
|
|
25
|
+
BEGIN
|
|
26
|
+
IF OLD.status != NEW.status THEN
|
|
27
|
+
PERFORM pg_notify('agents_upd_status', jsonb_build_array(row_to_json(NEW), OLD.status)::varchar);
|
|
28
|
+
END IF;
|
|
29
|
+
IF OLD.auth IS DISTINCT FROM NEW.auth THEN
|
|
30
|
+
PERFORM pg_notify('agents_upd_auth', row_to_json(NEW)::varchar);
|
|
31
|
+
END IF;
|
|
32
|
+
RETURN NULL;
|
|
33
|
+
END
|
|
34
|
+
$agent_upd_trg$ LANGUAGE plpgsql;
|
|
35
|
+
CREATE OR REPLACE TRIGGER agent_upd AFTER UPDATE ON "agent" FOR EACH ROW EXECUTE FUNCTION agent_upd();
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class Migration(BaseMigration):
|
|
40
|
+
dependencies: ClassVar = [("models", "0006_credex_orphan")]
|
|
41
|
+
operations: ClassVar = [RunSQL(AGENT_AUTH_SQL)]
|
|
@@ -15,6 +15,7 @@ from cryptography.exceptions import InvalidSignature
|
|
|
15
15
|
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey, Ed25519PublicKey
|
|
16
16
|
from tortoise import BackwardFKRelation, BackwardOneToOneRelation, BaseDBAsyncClient, connections
|
|
17
17
|
from tortoise import Model as BaseModel
|
|
18
|
+
from tortoise.expressions import Q
|
|
18
19
|
from tortoise.fields import (
|
|
19
20
|
CASCADE,
|
|
20
21
|
BigIntField,
|
|
@@ -685,9 +686,10 @@ class User(TgUser, TsTrait):
|
|
|
685
686
|
# тейкеру прячем незашаренные объявы share-hex-бирж (hex IS NULL AND ex∈SHARE_HEX_EX_IDS): без
|
|
686
687
|
# share-hex url-кнопку не построить. Сужено до этих бирж, чтобы не зацепить hot-биржи без share-hex.
|
|
687
688
|
# Свои (mine, страница settings) оставляем — их видно для шеринга.
|
|
688
|
-
|
|
689
|
+
# один Q: исключаем строго пересечение (Tortoise's exclude(**kwargs) отрицал бы условия порознь)
|
|
690
|
+
adq = adq.exclude(Q(hex__isnull=True, ad__maker__ex_id__in=SHARE_HEX_EX_IDS))
|
|
689
691
|
bads = await adq.filter(ad__pair_side__is_sell=False)
|
|
690
|
-
# остаток каждой монеты (asset.free) у акторов персон этого юзера, по бирже и монете
|
|
692
|
+
# остаток каждой монеты (asset.free) у акторов персон этого юзера, по бирже и монете # noqa: RUF003
|
|
691
693
|
coin_balances: dict[int, dict[int, int]] = {}
|
|
692
694
|
for ex_id, coin_id, total in (
|
|
693
695
|
await Asset.filter(agent__actor__person__user_id=self.id)
|
|
@@ -1016,7 +1018,7 @@ class Agent(Model, TsTrait):
|
|
|
1016
1018
|
|
|
1017
1019
|
@classmethod
|
|
1018
1020
|
async def upsert(
|
|
1019
|
-
cls, exid: int, host: str, auth: dict, exp: int, rname: str, nick: str, email: str
|
|
1021
|
+
cls, exid: int, host: str, auth: dict, exp: int | None, rname: str, nick: str, email: str = ""
|
|
1020
1022
|
) -> tuple[int, Agent, bool]:
|
|
1021
1023
|
err = 0
|
|
1022
1024
|
if host and (ex := await Ex.get_or_none(host=host)):
|
|
@@ -1317,18 +1319,18 @@ class MyAd(Model): # Road
|
|
|
1317
1319
|
)
|
|
1318
1320
|
|
|
1319
1321
|
@classmethod
|
|
1320
|
-
async def
|
|
1321
|
-
"""ad_id активных hot-объяв share-hex
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1322
|
+
async def unshared_ad_ids(cls, agent_id: int, hex_ex_ids: list[int] = SHARE_HEX_EX_IDS) -> list[int]:
|
|
1323
|
+
"""ad_id активных hot-объяв ДАННОГО агента-мейкера на share-hex-бирже без MyAd.hex (не зашарены →
|
|
1324
|
+
скрыты от тейкеров get_hot_ads'ом). Для адресного уведомления ВЛАДЕЛЬЦА (не админа), когда его
|
|
1325
|
+
торговля на бирже выключена и он отказался её включать (handlers.agents.share_or_ask).
|
|
1326
|
+
Раньше тут был глобальный старт-алибат `unshared_hot_ad_ids` всем — его слал админу бот на старте."""
|
|
1325
1327
|
return (
|
|
1326
1328
|
await cls.filter(
|
|
1327
1329
|
hex__isnull=True,
|
|
1328
1330
|
ad__status=AdStatus.active,
|
|
1329
1331
|
ad__maker__ex_id__in=hex_ex_ids,
|
|
1332
|
+
ad__maker__agent__id=agent_id,
|
|
1330
1333
|
credexs__cred__ovr_pm_id=0,
|
|
1331
|
-
ad__maker__agent__status__in=[AgentStatus.listen, AgentStatus.race_listen], # listen-бит (& 2)
|
|
1332
1334
|
)
|
|
1333
1335
|
.distinct()
|
|
1334
1336
|
.values_list("ad_id", flat=True)
|
|
@@ -1952,7 +1954,7 @@ class Order(Model, TsTrait):
|
|
|
1952
1954
|
|
|
1953
1955
|
# партнерские отчисления:
|
|
1954
1956
|
if self.ad.maker.person.user.status == UserStatus.HOT_PARTNER:
|
|
1955
|
-
hspread = abs(self.ad.price - self.ad.pair_side.pair.
|
|
1957
|
+
hspread = abs(self.ad.price - self.ad.pair_side.pair.rate)
|
|
1956
1958
|
earn = hspread * self.quantity * 0.0001
|
|
1957
1959
|
fee = int(earn * (0.7 - self.ad.maker.person.user.bonus * 0.0001)) # 1% = 100
|
|
1958
1960
|
b = await self.ad.maker.person.user.balance(self.ad.pair_side.pair.cur_id)
|
|
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
|
|
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
|
|
File without changes
|