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:
SimplifiedPrivacy 2026-08-15 14:09:34 -04:00
parent 31488f790e
commit 829feb5939
6 changed files with 28 additions and 4 deletions

View file

@ -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

View file

@ -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}!"

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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)