The profile object now has a ticket field. It's now none by default. Also the profile object is passed in, for the use of tickets, both for GUI and core.
This commit is contained in:
parent
31488f790e
commit
829feb5939
6 changed files with 28 additions and 4 deletions
|
|
@ -1,8 +1,13 @@
|
||||||
# Major Change Log:
|
# Major Change Log:
|
||||||
|
|
||||||
|
# Codes/Tickets
|
||||||
|
### Aug 15, 2026
|
||||||
|
The profile object now has a ticket field. It's now none by default. Also the profile object is passed in, for the use of tickets, both for GUI and core.
|
||||||
|
<br/>
|
||||||
|
|
||||||
# Wipe & Respawn Codes/Tickets
|
# Wipe & Respawn Codes/Tickets
|
||||||
### Aug 14, 2026
|
### Aug 14, 2026
|
||||||
Introduced Ticket/Billing-Code Respawn, with dual paths on the ticket prep orchestration, it's helper functions, and the main prep controller. This introduced the functions, which were tested with a demo CLI client and local server, and appears to be stable. Server-side endpoints will be pushed as well. Note: This update couples profiles more closely with which ticket slot is being used for it, but they are not yet officially tied. In the future, they should be.
|
Introduced Ticket/Billing-Code Respawn, with dual paths on the ticket prep orchestration, it's helper functions, and the main prep controller. This introduced the functions, which were tested with a demo CLI client and local server, and appears to be stable. Server-side endpoints will be pushed as well. Note: This update couples profile slot ids more closely with which ticket slot id is being used for it, but they are not yet officially tied. In the future, they should be.
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
# Reduce Redundancy
|
# Reduce Redundancy
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,9 @@ def respawn_billing_code_into_ticket(
|
||||||
|
|
||||||
# Now that the billing code has been wiped by the server, wipe it locally:
|
# Now that the billing code has been wiped by the server, wipe it locally:
|
||||||
profile.subscription = None
|
profile.subscription = None
|
||||||
|
|
||||||
|
# save the ticket,
|
||||||
|
profile.ticket = which_ticket
|
||||||
profile.save()
|
profile.save()
|
||||||
|
|
||||||
notification = f"Respawn Done for Profile {profile.id}!"
|
notification = f"Respawn Done for Profile {profile.id}!"
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,13 @@ from core.services.helpers.get_value_from_config import get_value_from_config
|
||||||
from core.utils.basic_operations.does_file_exist import does_file_exist
|
from core.utils.basic_operations.does_file_exist import does_file_exist
|
||||||
from core.utils.basic_operations.write_or_read_from_json import update_json
|
from core.utils.basic_operations.write_or_read_from_json import update_json
|
||||||
from core.services.prepare_tickets.ticket_tracker import get_all_unused_tickets
|
from core.services.prepare_tickets.ticket_tracker import get_all_unused_tickets
|
||||||
|
from core.models.session.SessionProfile import SessionProfile
|
||||||
|
from core.models.system.SystemProfile import SystemProfile
|
||||||
from core.errors.logger import logger
|
from core.errors.logger import logger
|
||||||
|
|
||||||
|
# generic
|
||||||
import random
|
import random
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
def modify_random_tickets_setting(
|
def modify_random_tickets_setting(
|
||||||
|
|
@ -138,6 +143,7 @@ def use_ticket(
|
||||||
which_location: str,
|
which_location: str,
|
||||||
ticket_observer: TicketObserver,
|
ticket_observer: TicketObserver,
|
||||||
connection_observer: ConnectionObserver,
|
connection_observer: ConnectionObserver,
|
||||||
|
profile: Optional[Union[SessionProfile, SystemProfile]] = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
|
|
||||||
which_ticket = str(which_ticket) # type: ignore
|
which_ticket = str(which_ticket) # type: ignore
|
||||||
|
|
@ -173,11 +179,21 @@ def use_ticket(
|
||||||
ticket_observer.notify("connecting", "Connecting..")
|
ticket_observer.notify("connecting", "Connecting..")
|
||||||
reply = use_ticket_orchestrator(which_ticket, which_location, connection_observer)
|
reply = use_ticket_orchestrator(which_ticket, which_location, connection_observer)
|
||||||
|
|
||||||
|
# API reply did NOT go through:
|
||||||
if isinstance(reply, ApiResponse):
|
if isinstance(reply, ApiResponse):
|
||||||
error_msg = reply.message
|
error_msg = reply.message
|
||||||
reply_as_dict = {"valid": False, "message": f"API Failed: {error_msg}"}
|
reply_as_dict = {"valid": False, "message": f"API Failed: {error_msg}"}
|
||||||
return reply_as_dict
|
return reply_as_dict
|
||||||
else:
|
else:
|
||||||
|
# this is dict in theory,
|
||||||
|
if isinstance(reply, dict):
|
||||||
|
valid = reply.get("valid", False)
|
||||||
|
# then if it worked, update the profile to save the ticket,
|
||||||
|
if valid and profile:
|
||||||
|
profile.ticket = which_ticket
|
||||||
|
profile.save()
|
||||||
|
logger.info(f"Saved ticket {which_ticket} to profile {profile.id}!")
|
||||||
|
|
||||||
return reply
|
return reply
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ class BaseProfile(ABC):
|
||||||
subscription: Optional[Subscription]
|
subscription: Optional[Subscription]
|
||||||
type: ProfileType
|
type: ProfileType
|
||||||
location: Optional[Location] = field(metadata=config(exclude=Exclude.ALWAYS)) # SQLAlchemy object
|
location: Optional[Location] = field(metadata=config(exclude=Exclude.ALWAYS)) # SQLAlchemy object
|
||||||
|
|
||||||
# legacy version included it to be serialized, but now it's an SQLAlchemy object.
|
# legacy version included it to be serialized, but now it's an SQLAlchemy object.
|
||||||
# location: Optional[Location]
|
# location: Optional[Location]
|
||||||
|
|
||||||
|
|
@ -110,8 +110,6 @@ class BaseProfile(ABC):
|
||||||
|
|
||||||
|
|
||||||
def save(self: Self, app_version_dict: dict = None):
|
def save(self: Self, app_version_dict: dict = None):
|
||||||
print("We are able to trigger save on the parent")
|
|
||||||
|
|
||||||
# === SERIALIZATION ===
|
# === SERIALIZATION ===
|
||||||
config_dict = self.to_dict()
|
config_dict = self.to_dict()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ class SessionProfile(BaseProfile):
|
||||||
resolution: str
|
resolution: str
|
||||||
application_version: Optional[ApplicationVersion]
|
application_version: Optional[ApplicationVersion]
|
||||||
connection: Optional[SessionConnection] = None
|
connection: Optional[SessionConnection] = None
|
||||||
|
ticket: Optional[int] = None
|
||||||
|
|
||||||
def has_connection(self):
|
def has_connection(self):
|
||||||
return self.connection is not None
|
return self.connection is not None
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import subprocess
|
||||||
@dataclass
|
@dataclass
|
||||||
class SystemProfile(BaseProfile):
|
class SystemProfile(BaseProfile):
|
||||||
connection: Optional[SystemConnection]
|
connection: Optional[SystemConnection]
|
||||||
|
ticket: Optional[int] = None
|
||||||
|
|
||||||
def get_system_config_path(self):
|
def get_system_config_path(self):
|
||||||
filepath = self.__get_system_config_path(self.id)
|
filepath = self.__get_system_config_path(self.id)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue