Introduced new model: Plan. This differs from the legacy subscriptions because its based on time in months and supports multiple protocols at once in a list enum format
This commit is contained in:
parent
f2922b02a0
commit
9627b1861d
7 changed files with 70 additions and 6 deletions
|
|
@ -6,7 +6,7 @@ import os
|
|||
@dataclass(frozen=True)
|
||||
class Constants:
|
||||
|
||||
DB_VERSION_THIS_APP_WANTS = 2
|
||||
DB_VERSION_THIS_APP_WANTS = 3
|
||||
|
||||
# Fallback for development (running outside AppImage)
|
||||
fallback_non_appimage = os.path.dirname(os.path.abspath(__file__))
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from core.errors.logger import logger
|
|||
from core.models.orm_models.Location import Location
|
||||
from core.models.orm_models.Operator import Operator
|
||||
from core.models.orm_models.Dependency import Dependency
|
||||
from core.models.orm_models.Plan import Plan
|
||||
from core.Constants import Constants
|
||||
|
||||
from core.controllers.ApplicationController import ApplicationController
|
||||
|
|
@ -35,7 +36,8 @@ ORM_TABLES = {
|
|||
"locations": Location,
|
||||
"operators": Operator,
|
||||
"application_versions": ApplicationVersion,
|
||||
"dependencies": Dependency
|
||||
"dependencies": Dependency,
|
||||
"plans": Plan,
|
||||
}
|
||||
|
||||
LEGACY_SQL_FUNCT_DICT = {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ def migrate_sql() -> DatabaseOperation:
|
|||
from core.models.orm_models.CachedSync import CachedSync
|
||||
from core.models.orm_models.EncryptedProxy import EncryptedProxy
|
||||
from core.models.orm_models.Dependency import Dependency
|
||||
MODELS = [Location, Operator, CachedSync, EncryptedProxy, Dependency]
|
||||
from core.models.orm_models.Plan import Plan
|
||||
MODELS = [Location, Operator, CachedSync, EncryptedProxy, Dependency, Plan]
|
||||
logger.info(f"[MIGRATION] Tables loaded")
|
||||
except:
|
||||
logger.error(f"[MIGRATION] Could not load models. Critical failure.")
|
||||
|
|
|
|||
|
|
@ -146,9 +146,11 @@ def create_ALL_tables():
|
|||
from core.models.orm_models.Operator import Operator
|
||||
from core.models.orm_models.CachedSync import CachedSync
|
||||
from core.models.orm_models.EncryptedProxy import EncryptedProxy
|
||||
from core.models.SubscriptionPlan import SubscriptionPlan
|
||||
from core.models.orm_models.Plan import Plan
|
||||
from core.models.orm_models.ApplicationVersion import ApplicationVersion
|
||||
from core.models.orm_models.Dependency import Dependency
|
||||
# legacy:
|
||||
from core.models.SubscriptionPlan import SubscriptionPlan
|
||||
|
||||
try:
|
||||
BaseModel.metadata.create_all(engine, checkfirst=True)
|
||||
|
|
|
|||
|
|
@ -21,5 +21,13 @@ class CachedSync(Base):
|
|||
client_version: Mapped[Optional[int]] = mapped_column(Integer, nullable=False, default=0)
|
||||
operators: Mapped[Optional[int]] = mapped_column(Integer, nullable=False, default=0)
|
||||
locations: Mapped[Optional[int]] = mapped_column(Integer, nullable=False, default=0)
|
||||
subscriptions: Mapped[Optional[int]] = mapped_column(Integer, nullable=False, default=0)
|
||||
dependencies: Mapped[Optional[int]] = mapped_column(Integer, nullable=False, default=0)
|
||||
|
||||
# legacy:
|
||||
subscriptions: Mapped[Optional[int]] = mapped_column(Integer, nullable=False, default=0)
|
||||
|
||||
# v2 refactor:
|
||||
plans: Mapped[Optional[int]] = mapped_column(Integer, nullable=False, default=0)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
50
core/models/orm_models/Plan.py
Normal file
50
core/models/orm_models/Plan.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
from core.models.enum_models import ProtocolChoice
|
||||
from core.models.orm_models.Base import BaseModel
|
||||
from core.Constants import Constants
|
||||
from core.errors.logger import logger
|
||||
|
||||
import enum
|
||||
from sqlalchemy.orm import Mapped
|
||||
from sqlalchemy import Column, Integer, String, Boolean, UniqueConstraint, JSON, TypeDecorator, Numeric
|
||||
from sqlalchemy.orm import declarative_base
|
||||
|
||||
|
||||
class EnumList(TypeDecorator):
|
||||
"""Stores a list of ProtocolChoice enums as a JSON list of strings."""
|
||||
impl = JSON
|
||||
|
||||
def process_bind_param(self, value, dialect):
|
||||
if value is not None:
|
||||
# Create a set of all valid values
|
||||
valid_values = {item.value for item in ProtocolChoice}
|
||||
|
||||
filtered = []
|
||||
for item in value:
|
||||
# 1. Get the raw value regardless of if it's an Enum or String
|
||||
val = item.value if isinstance(item, enum.Enum) else item
|
||||
|
||||
# 2. Only keep it if it exists in our valid_values set
|
||||
if val in valid_values:
|
||||
filtered.append(val)
|
||||
else:
|
||||
logger.error(f"Dropped an invalid item: {val}")
|
||||
pass
|
||||
|
||||
return filtered
|
||||
return None
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
# Convert strings from DB back into enum members
|
||||
if value is not None:
|
||||
return [ProtocolChoice(item) for item in value]
|
||||
return None
|
||||
|
||||
|
||||
class Plan(BaseModel):
|
||||
__tablename__ = 'plans'
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
months = Column(Integer, unique=False, nullable=False)
|
||||
supported_protocols = Column(EnumList, nullable=False)
|
||||
cost = Column(Numeric(precision=10, scale=2), nullable=False)
|
||||
|
||||
|
|
@ -10,7 +10,8 @@ def switch_endpoint_domain(domain: str) -> dict:
|
|||
"subscriptions": f"https://{domain}/api/v1/subscription-plans",
|
||||
"applications": f"https://{domain}/api/v1/platforms/linux-x86_64/applications",
|
||||
"application_versions": f"https://{domain}/api/v1/platforms/linux-x86_64/application-versions",
|
||||
"dependencies": f"https://{domain}/api/v1/dependencies"
|
||||
"dependencies": f"https://{domain}/api/v1/dependencies",
|
||||
"plans": f"https://{domain}/api/v2/time_based_plans"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue