fix: фиксы после рефакторинга
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
RUN_IN_TRANSACTION = True
|
||||
|
||||
|
||||
async def upgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
DROP INDEX IF EXISTS "uid_external_ch_telegra_13cca5";
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "uid_external_ch_user_id_289e6a" ON "external_channel" ("user_id", "telegram_id");
|
||||
CREATE INDEX IF NOT EXISTS "idx_external_ch_telegra_13cca5" ON "external_channel" ("telegram_id");"""
|
||||
|
||||
|
||||
async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||
return """
|
||||
DROP INDEX IF EXISTS "idx_external_ch_telegra_13cca5";
|
||||
DROP INDEX IF EXISTS "uid_external_ch_user_id_289e6a";
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "uid_external_ch_telegra_13cca5" ON "external_channel" ("telegram_id");"""
|
||||
|
||||
|
||||
MODELS_STATE = (
|
||||
'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'
|
||||
'8q//AeAg1wo='
|
||||
)
|
||||
@@ -1,3 +1,4 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
import pydantic
|
||||
@@ -30,6 +31,10 @@ class DatabaseBase:
|
||||
self.config = config
|
||||
|
||||
async def connect(self) -> None:
|
||||
if self.config.ECHO:
|
||||
logging.getLogger('tortoise.db_client').setLevel(logging.DEBUG)
|
||||
logging.getLogger('tortoise').setLevel(logging.DEBUG)
|
||||
|
||||
await Tortoise.init(
|
||||
db_url=str(self.config.URL),
|
||||
modules={'models': ['src.domain', 'aerich.models']},
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import datetime
|
||||
import logging
|
||||
import typing
|
||||
import uuid
|
||||
|
||||
@@ -8,6 +9,8 @@ from tortoise.transactions import in_transaction
|
||||
from shared.datebase_base import DatabaseBase
|
||||
from src import domain
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Postgres(DatabaseBase):
|
||||
def transaction(self) -> typing.AsyncContextManager[None]:
|
||||
@@ -89,26 +92,16 @@ class Postgres(DatabaseBase):
|
||||
return await query.first()
|
||||
|
||||
async def get_external_channels_for_target(self, target_channel_id: uuid.UUID) -> list[domain.ExternalChannel]:
|
||||
target = await domain.TargetChannel.filter(id=target_channel_id).prefetch_related('external_channels').first()
|
||||
if not target:
|
||||
return []
|
||||
return await target.external_channels.all()
|
||||
return await domain.ExternalChannel.filter(target_channels__id=target_channel_id).all()
|
||||
|
||||
async def get_user_external_channels(self, user_id: uuid.UUID) -> list[domain.ExternalChannel]:
|
||||
return await domain.ExternalChannel.filter(user_id=user_id).all()
|
||||
|
||||
async def add_external_channel_to_targets(
|
||||
self, external_channel_id: uuid.UUID, target_channel_ids: list[uuid.UUID]
|
||||
self, external_channel: domain.ExternalChannel, target_channel_ids: list[uuid.UUID]
|
||||
) -> None:
|
||||
external_channel = await domain.ExternalChannel.get_or_none(id=external_channel_id)
|
||||
|
||||
if not external_channel:
|
||||
raise ValueError(f'ExternalChannel {external_channel_id} not found')
|
||||
|
||||
for target_id in target_channel_ids:
|
||||
target_channel = await domain.TargetChannel.get_or_none(id=target_id)
|
||||
if target_channel:
|
||||
await external_channel.target_channels.add(target_channel)
|
||||
target_channels = await domain.TargetChannel.filter(id__in=target_channel_ids).all()
|
||||
await external_channel.target_channels.add(*target_channels)
|
||||
|
||||
async def remove_external_channel_from_target(
|
||||
self, external_channel_id: uuid.UUID, target_channel_id: uuid.UUID
|
||||
|
||||
@@ -12,7 +12,7 @@ if TYPE_CHECKING:
|
||||
|
||||
class ExternalChannel(TimestampedModel):
|
||||
id = fields.UUIDField(pk=True)
|
||||
telegram_id = fields.BigIntField(unique=True, index=True)
|
||||
telegram_id = fields.BigIntField(index=True)
|
||||
title = fields.CharField(max_length=255)
|
||||
username = fields.CharField(max_length=255, null=True, index=True)
|
||||
description = fields.TextField(null=True)
|
||||
@@ -28,3 +28,4 @@ class ExternalChannel(TimestampedModel):
|
||||
|
||||
class Meta:
|
||||
table = 'external_channel'
|
||||
unique_together = (('user_id', 'telegram_id'),)
|
||||
|
||||
@@ -2,7 +2,6 @@ __all__ = (
|
||||
'UpdateTargetChanPermissionsInput',
|
||||
'GetUserTargetChansInput',
|
||||
'GetUserTargetChansOutput',
|
||||
'DisconnectTargetChanInput',
|
||||
'DisconnectTargetChanByTgIdInput',
|
||||
'ConnectTargetChanInput',
|
||||
'ConnectTargetChanOutput',
|
||||
@@ -110,7 +109,6 @@ from .target_channel import (
|
||||
ConnectTargetChanInput,
|
||||
ConnectTargetChanOutput,
|
||||
DisconnectTargetChanByTgIdInput,
|
||||
DisconnectTargetChanInput,
|
||||
GetUserTargetChansInput,
|
||||
GetUserTargetChansOutput,
|
||||
UpdateTargetChanPermissionsInput,
|
||||
|
||||
@@ -80,7 +80,7 @@ class Database(typing.Protocol):
|
||||
async def get_user_external_channels(self, user_id: UUID) -> list[domain.ExternalChannel]: ...
|
||||
|
||||
async def add_external_channel_to_targets(
|
||||
self, external_channel_id: UUID, target_channel_ids: list[UUID]
|
||||
self, external_channel: domain.ExternalChannel, target_channel_ids: list[UUID]
|
||||
) -> None: ...
|
||||
|
||||
async def remove_external_channel_from_target(self, external_channel_id: UUID, target_channel_id: UUID) -> None: ...
|
||||
|
||||
@@ -13,6 +13,10 @@ log = logging.getLogger(__name__)
|
||||
async def create_external_channel(
|
||||
self: 'Usecase', input: dto.CreateExternalChannelInput, user_id: uuid.UUID
|
||||
) -> dto.ExternalChannelOutput:
|
||||
existing_channel = await self.database.get_external_channel(user_id, telegram_id=input.telegram_id)
|
||||
if existing_channel:
|
||||
raise domain.ExternalChannelAlreadyExists(input.telegram_id)
|
||||
|
||||
for target_id in input.target_channel_ids:
|
||||
target_channel = await self.database.get_target_channel(user_id, channel_id=target_id)
|
||||
|
||||
@@ -32,7 +36,7 @@ async def create_external_channel(
|
||||
await self.database.create_external_channel(channel)
|
||||
|
||||
if input.target_channel_ids:
|
||||
await self.database.add_external_channel_to_targets(channel.id, input.target_channel_ids)
|
||||
await self.database.add_external_channel_to_targets(channel, input.target_channel_ids)
|
||||
|
||||
log.info(
|
||||
'External channel %s created and linked to %s target channels', input.telegram_id, len(input.target_channel_ids)
|
||||
|
||||
@@ -13,19 +13,14 @@ log = logging.getLogger(__name__)
|
||||
async def create_placement(self: 'Usecase', input: dto.CreatePlacementInput, user_id: uuid.UUID) -> dto.PlacementOutput:
|
||||
target_channel = await self.database.get_target_channel(user_id, channel_id=input.target_channel_id)
|
||||
if not target_channel:
|
||||
log.warning('User %s attempted to create placement for unavailable target %s', user_id, input.target_channel_id)
|
||||
raise domain.TargetChannelNotFound(input.target_channel_id)
|
||||
|
||||
external_channel = await self.database.get_external_channel(user_id, channel_id=input.external_channel_id)
|
||||
if not external_channel:
|
||||
log.warning(
|
||||
'User %s attempted to create placement for unavailable external %s', user_id, input.external_channel_id
|
||||
)
|
||||
raise domain.ExternalChannelNotFound(input.external_channel_id)
|
||||
|
||||
creative = await self.database.get_creative(user_id, input.creative_id)
|
||||
if not creative:
|
||||
log.warning('User %s attempted to create placement for unavailable creative %s', user_id, input.creative_id)
|
||||
raise domain.CreativeNotFound(input.creative_id)
|
||||
|
||||
requires_approval = input.invite_link_type == domain.InviteLinkType.APPROVAL
|
||||
|
||||
Reference in New Issue
Block a user