правки имен
This commit is contained in:
@@ -97,17 +97,17 @@ from .error import (
|
|||||||
WorkspaceNotFound,
|
WorkspaceNotFound,
|
||||||
)
|
)
|
||||||
from .login_token import LoginToken
|
from .login_token import LoginToken
|
||||||
from .placement import PostViewsAvailability, Publication, PublicationStatus
|
from .placement import (
|
||||||
from .post import Post
|
|
||||||
from .post_views_history import PostViewsHistory
|
|
||||||
from .project import Project, ProjectStatus
|
|
||||||
from .purchase import (
|
|
||||||
CostType,
|
CostType,
|
||||||
InviteLinkType,
|
InviteLinkType,
|
||||||
Placement,
|
Placement,
|
||||||
PlacementStatus,
|
PlacementStatus,
|
||||||
PlacementType,
|
PlacementType,
|
||||||
)
|
)
|
||||||
|
from .post import Post
|
||||||
|
from .post_views_history import PostViewsHistory
|
||||||
|
from .project import Project, ProjectStatus
|
||||||
|
from .publication import PostViewsAvailability, Publication, PublicationStatus
|
||||||
from .subscription import Subscription, SubscriptionStatus
|
from .subscription import Subscription, SubscriptionStatus
|
||||||
from .telegram_user import TelegramUser
|
from .telegram_user import TelegramUser
|
||||||
from .user import User
|
from .user import User
|
||||||
|
|||||||
@@ -1,60 +1,71 @@
|
|||||||
import enum
|
import enum
|
||||||
|
import uuid
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from uuid import UUID
|
|
||||||
|
|
||||||
from tortoise import fields
|
from tortoise import fields
|
||||||
|
|
||||||
from .base import TimestampedModel
|
from .base import TimestampedModel
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from .channel import Channel
|
||||||
from .creative import Creative
|
from .creative import Creative
|
||||||
from .post import Post
|
|
||||||
from .project import Project
|
from .project import Project
|
||||||
from .purchase import Placement
|
|
||||||
|
|
||||||
__all__ = ['Publication', 'PublicationStatus', 'PostViewsAvailability']
|
__all__ = ['Placement', 'PlacementStatus', 'PlacementType', 'InviteLinkType', 'CostType']
|
||||||
|
|
||||||
|
|
||||||
class PublicationStatus(str, enum.Enum):
|
class CostType(enum.StrEnum):
|
||||||
ACTIVE = 'active' # Пост найден и отслеживается
|
FIXED = 'fixed'
|
||||||
ARCHIVED = 'archived' # Вручную архивировано
|
CPM = 'cpm'
|
||||||
|
|
||||||
|
|
||||||
class PostViewsAvailability(str, enum.Enum):
|
class PlacementStatus(enum.StrEnum):
|
||||||
UNKNOWN = 'unknown' # Ещё не проверялось
|
PLANNED = 'planned'
|
||||||
AVAILABLE = 'available' # Просмотры доступны
|
APPROVED = 'approved'
|
||||||
UNAVAILABLE = 'unavailable' # Нет доступа / битая ссылка / приватный канал
|
REJECTED = 'rejected'
|
||||||
MANUAL = 'manual' # Просмотры вводятся вручную
|
IN_PROGRESS = 'in_progress'
|
||||||
|
COMPLETED = 'completed'
|
||||||
|
|
||||||
|
|
||||||
class Publication(TimestampedModel):
|
class PlacementType(enum.StrEnum):
|
||||||
"""Публикация, мониторимая системой (бывший Placement)"""
|
SELF_PROMO = 'self_promo'
|
||||||
|
STANDARD = 'standard'
|
||||||
|
|
||||||
wanted_placement_date = fields.DatetimeField(db_column='placement_date')
|
|
||||||
cost = fields.FloatField(null=True)
|
class InviteLinkType(enum.StrEnum):
|
||||||
|
PUBLIC = 'public' # открытая ссылка
|
||||||
|
APPROVAL = 'approval' # с одобрением ботом
|
||||||
|
|
||||||
|
|
||||||
|
class Placement(TimestampedModel):
|
||||||
|
status = fields.CharEnumField(PlacementStatus, default=PlacementStatus.PLANNED)
|
||||||
|
placement_at = fields.DatetimeField(null=True)
|
||||||
|
payment_at = fields.DatetimeField(null=True)
|
||||||
|
cost_type = fields.CharEnumField(CostType, null=True, max_length=8)
|
||||||
|
cost_value = fields.FloatField(null=True)
|
||||||
|
cost_before_bargain = fields.FloatField(null=True)
|
||||||
|
placement_type = fields.CharEnumField(PlacementType, null=True, max_length=16)
|
||||||
|
format = fields.TextField(null=True)
|
||||||
comment = fields.TextField(null=True)
|
comment = fields.TextField(null=True)
|
||||||
|
|
||||||
status = fields.CharEnumField(PublicationStatus, default=PublicationStatus.ACTIVE)
|
invite_link = fields.CharField(max_length=512)
|
||||||
|
invite_link_type = fields.CharEnumField(InviteLinkType)
|
||||||
|
|
||||||
project: fields.ForeignKeyRelation['Project'] = fields.ForeignKeyField(
|
project: fields.ForeignKeyRelation['Project'] = fields.ForeignKeyField(
|
||||||
'models.Project', related_name='publications', on_delete=fields.CASCADE, index=True
|
'models.Project', related_name='placements', on_delete=fields.CASCADE, index=True
|
||||||
)
|
)
|
||||||
creative: fields.ForeignKeyRelation['Creative'] = fields.ForeignKeyField(
|
creative: fields.ForeignKeyRelation['Creative'] = fields.ForeignKeyField(
|
||||||
'models.Creative', related_name='publications', on_delete=fields.CASCADE, index=True
|
'models.Creative', related_name='placements', on_delete=fields.CASCADE, index=True
|
||||||
)
|
)
|
||||||
placement: fields.ForeignKeyRelation['Placement'] = fields.ForeignKeyField(
|
channel: fields.ForeignKeyRelation['Channel'] = fields.ForeignKeyField(
|
||||||
'models.Placement', related_name='publications', on_delete=fields.CASCADE, index=True
|
'models.Channel', related_name='placements', on_delete=fields.CASCADE, index=True
|
||||||
)
|
|
||||||
|
|
||||||
post: fields.ForeignKeyRelation['Post'] | None = fields.ForeignKeyField(
|
|
||||||
'models.Post', related_name='publications', on_delete=fields.SET_NULL, null=True, index=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
project_id: UUID
|
project_id: uuid.UUID
|
||||||
creative_id: UUID
|
creative_id: uuid.UUID
|
||||||
post_id: UUID | None
|
channel_id: uuid.UUID
|
||||||
placement_id: UUID
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table = 'publication'
|
table = 'placement'
|
||||||
|
indexes = (('project', 'status'),)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from uuid import UUID
|
|||||||
from tortoise import fields
|
from tortoise import fields
|
||||||
|
|
||||||
from .base import TimestampedModel
|
from .base import TimestampedModel
|
||||||
from .purchase import InviteLinkType
|
from .placement import InviteLinkType
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .channel import Channel
|
from .channel import Channel
|
||||||
|
|||||||
58
src/domain/publication.py
Normal file
58
src/domain/publication.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import enum
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
from tortoise import fields
|
||||||
|
|
||||||
|
from .base import TimestampedModel
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .creative import Creative
|
||||||
|
from .placement import Placement
|
||||||
|
from .post import Post
|
||||||
|
from .project import Project
|
||||||
|
|
||||||
|
__all__ = ['Publication', 'PublicationStatus', 'PostViewsAvailability']
|
||||||
|
|
||||||
|
|
||||||
|
class PublicationStatus(str, enum.Enum):
|
||||||
|
ACTIVE = 'active' # Пост найден и отслеживается
|
||||||
|
ARCHIVED = 'archived' # Вручную архивировано
|
||||||
|
|
||||||
|
|
||||||
|
class PostViewsAvailability(str, enum.Enum):
|
||||||
|
UNKNOWN = 'unknown' # Ещё не проверялось
|
||||||
|
AVAILABLE = 'available' # Просмотры доступны
|
||||||
|
UNAVAILABLE = 'unavailable' # Нет доступа / битая ссылка / приватный канал
|
||||||
|
MANUAL = 'manual' # Просмотры вводятся вручную
|
||||||
|
|
||||||
|
|
||||||
|
class Publication(TimestampedModel):
|
||||||
|
wanted_placement_date = fields.DatetimeField(db_column='placement_date')
|
||||||
|
cost = fields.FloatField(null=True)
|
||||||
|
comment = fields.TextField(null=True)
|
||||||
|
|
||||||
|
status = fields.CharEnumField(PublicationStatus, default=PublicationStatus.ACTIVE)
|
||||||
|
|
||||||
|
project: fields.ForeignKeyRelation['Project'] = fields.ForeignKeyField(
|
||||||
|
'models.Project', related_name='publications', on_delete=fields.CASCADE, index=True
|
||||||
|
)
|
||||||
|
creative: fields.ForeignKeyRelation['Creative'] = fields.ForeignKeyField(
|
||||||
|
'models.Creative', related_name='publications', on_delete=fields.CASCADE, index=True
|
||||||
|
)
|
||||||
|
placement: fields.ForeignKeyRelation['Placement'] = fields.ForeignKeyField(
|
||||||
|
'models.Placement', related_name='publications', on_delete=fields.CASCADE, index=True
|
||||||
|
)
|
||||||
|
|
||||||
|
post: fields.ForeignKeyRelation['Post'] | None = fields.ForeignKeyField(
|
||||||
|
'models.Post', related_name='publications', on_delete=fields.SET_NULL, null=True, index=True
|
||||||
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
project_id: UUID
|
||||||
|
creative_id: UUID
|
||||||
|
post_id: UUID | None
|
||||||
|
placement_id: UUID
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table = 'publication'
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
import enum
|
|
||||||
import uuid
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from tortoise import fields
|
|
||||||
|
|
||||||
from .base import TimestampedModel
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from .channel import Channel
|
|
||||||
from .creative import Creative
|
|
||||||
from .project import Project
|
|
||||||
|
|
||||||
__all__ = ['Placement', 'PlacementStatus', 'PlacementType', 'InviteLinkType', 'CostType']
|
|
||||||
|
|
||||||
|
|
||||||
class CostType(enum.StrEnum):
|
|
||||||
FIXED = 'fixed'
|
|
||||||
CPM = 'cpm'
|
|
||||||
|
|
||||||
|
|
||||||
class PlacementStatus(enum.StrEnum):
|
|
||||||
PLANNED = 'planned'
|
|
||||||
APPROVED = 'approved'
|
|
||||||
REJECTED = 'rejected'
|
|
||||||
IN_PROGRESS = 'in_progress'
|
|
||||||
COMPLETED = 'completed'
|
|
||||||
|
|
||||||
|
|
||||||
class PlacementType(enum.StrEnum):
|
|
||||||
SELF_PROMO = 'self_promo'
|
|
||||||
STANDARD = 'standard'
|
|
||||||
|
|
||||||
|
|
||||||
class InviteLinkType(enum.StrEnum):
|
|
||||||
PUBLIC = 'public' # открытая ссылка
|
|
||||||
APPROVAL = 'approval' # с одобрением ботом
|
|
||||||
|
|
||||||
|
|
||||||
class Placement(TimestampedModel):
|
|
||||||
"""Размещение, управляемое пользователем (бывший PurchaseChannel + Purchase)"""
|
|
||||||
|
|
||||||
status = fields.CharEnumField(PlacementStatus, default=PlacementStatus.PLANNED)
|
|
||||||
placement_at = fields.DatetimeField(null=True)
|
|
||||||
payment_at = fields.DatetimeField(null=True)
|
|
||||||
cost_type = fields.CharEnumField(CostType, null=True, max_length=8)
|
|
||||||
cost_value = fields.FloatField(null=True)
|
|
||||||
cost_before_bargain = fields.FloatField(null=True)
|
|
||||||
placement_type = fields.CharEnumField(PlacementType, null=True, max_length=16)
|
|
||||||
format = fields.TextField(null=True)
|
|
||||||
comment = fields.TextField(null=True)
|
|
||||||
|
|
||||||
invite_link = fields.CharField(max_length=512)
|
|
||||||
invite_link_type = fields.CharEnumField(InviteLinkType)
|
|
||||||
|
|
||||||
project: fields.ForeignKeyRelation['Project'] = fields.ForeignKeyField(
|
|
||||||
'models.Project', related_name='placements', on_delete=fields.CASCADE, index=True
|
|
||||||
)
|
|
||||||
creative: fields.ForeignKeyRelation['Creative'] = fields.ForeignKeyField(
|
|
||||||
'models.Creative', related_name='placements', on_delete=fields.CASCADE, index=True
|
|
||||||
)
|
|
||||||
channel: fields.ForeignKeyRelation['Channel'] = fields.ForeignKeyField(
|
|
||||||
'models.Channel', related_name='placements', on_delete=fields.CASCADE, index=True
|
|
||||||
)
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
project_id: uuid.UUID
|
|
||||||
creative_id: uuid.UUID
|
|
||||||
channel_id: uuid.UUID
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
table = 'placement'
|
|
||||||
indexes = (('project', 'status'),)
|
|
||||||
|
|
||||||
|
|
||||||
# DEPRECATED: старые модели, будут удалены после миграции
|
|
||||||
|
|
||||||
# class PurchaseStatus(enum.StrEnum):
|
|
||||||
# ACTIVE = 'active'
|
|
||||||
# ARCHIVED = 'archived'
|
|
||||||
#
|
|
||||||
# class PurchaseChannelStatus(enum.StrEnum):
|
|
||||||
# PLANNED = 'planned'
|
|
||||||
# APPROVED = 'approved'
|
|
||||||
# REJECTED = 'rejected'
|
|
||||||
# IN_PROGRESS = 'in_progress'
|
|
||||||
# COMPLETED = 'completed'
|
|
||||||
#
|
|
||||||
# class PurchaseType(enum.StrEnum):
|
|
||||||
# SELF_PROMO = 'self_promo'
|
|
||||||
# STANDARD = 'standard'
|
|
||||||
#
|
|
||||||
# class Purchase(TimestampedModel):
|
|
||||||
# ...
|
|
||||||
#
|
|
||||||
# class PurchaseChannel(TimestampedModel):
|
|
||||||
# ...
|
|
||||||
@@ -7,7 +7,7 @@ from tortoise import fields
|
|||||||
from .base import TimestampedModel
|
from .base import TimestampedModel
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .placement import Publication
|
from .publication import Publication
|
||||||
from .telegram_user import TelegramUser
|
from .telegram_user import TelegramUser
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ from .base import TimestampedModel
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .channel import Channel
|
from .channel import Channel
|
||||||
from .creative import Creative
|
from .creative import Creative
|
||||||
|
from .placement import Placement
|
||||||
from .project import Project
|
from .project import Project
|
||||||
from .purchase import Placement
|
|
||||||
from .user import User
|
from .user import User
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import uuid
|
|||||||
|
|
||||||
import pydantic
|
import pydantic
|
||||||
|
|
||||||
from src.domain.purchase import CostType, InviteLinkType, PlacementStatus, PlacementType
|
from src.domain.placement import CostType, InviteLinkType, PlacementStatus, PlacementType
|
||||||
|
|
||||||
from .channel import ChannelOutput
|
from .channel import ChannelOutput
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
from .fetch_publication_post_cycle import fetch_publication_post_cycle
|
|
||||||
from .get_publication import get_publication
|
|
||||||
from .get_publications import get_publications
|
|
||||||
|
|
||||||
__all__ = ['fetch_publication_post_cycle', 'get_publication', 'get_publications']
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
from .create_placements import create_placements
|
|
||||||
from .get_placement import get_placement_user
|
|
||||||
from .get_placements import get_placements
|
|
||||||
|
|
||||||
__all__ = ['create_placements', 'get_placement_user', 'get_placements']
|
|
||||||
Reference in New Issue
Block a user