Location model shifts to boolean types. This will force a migration via Constants DB version.

This commit is contained in:
SimplifiedPrivacy 2026-10-03 16:55:22 -04:00
parent 9627b1861d
commit b132265a04
5 changed files with 124 additions and 25 deletions

View file

@ -0,0 +1,67 @@
from core.models.orm_calls.location_calls import get_profile_location_data
from core.models.enum_models import ProtocolChoice, get_choice_list
from core.models.orm_models.Location import Location
from core.errors.logger import logger
from core.models.Result import Result, ResultError
ALL_PROTOCOLS = [e.value for e in ProtocolChoice]
"""
Outputs:
Returns a list of supported protocols for a given location.
Inputs:
location_codes format: 'location_codes': 'us_wa'
"""
# if "_" not in location_codes:
# error_msg = f"This is a developer error. No location data found for {location_codes}"
# logger.error(error_msg)
# return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
def get_supported_protocols_for_location(location_codes: str, profile_type: str = None) -> Result:
country, city = location_codes.split("_")
print(f"country is {country}")
print(f"city is {city}")
# this IS doing sql:
location = get_profile_location_data(country_code=country, city_code=city)
print(f"location is {location}")
print(f"location type is {type(location)}")
# return location
if not location:
error_msg = f"This is a developer error. No location data found for {location_codes}"
logger.error(error_msg)
return Result(valid=False, error_type=ResultError.INVALID_INPUT, message=error_msg)
# this is NOT doing sql
supported_protocols = _get_supported_protocols_for_location(location=location, as_strings=True)
if profile_type == "system-wide" and ProtocolChoice.SOCK5_PROXY.value in supported_protocols:
supported_protocols.remove(ProtocolChoice.SOCK5_PROXY.value)
return Result(valid=True, data=supported_protocols)
def _get_supported_protocols_for_location(location: Location, as_strings: bool = False) -> list:
"""Doesn't do SQL to get a list of supported locations"""
SUPPORTED_PROTOCOLS = []
for each_protocol in ALL_PROTOCOLS:
supported = location.supports_protocol(enum_value=each_protocol)
print(f"supported for {each_protocol} is {supported}")
print(f"type of supported is {type(supported)}")
if supported:
print(f"THIS IS TRUE for {each_protocol}")
SUPPORTED_PROTOCOLS.append(each_protocol)
return SUPPORTED_PROTOCOLS

View file

@ -3,21 +3,20 @@ from core.errors.logger import logger
from core.models.Result import Result, ResultError from core.models.Result import Result, ResultError
from core.services.networking.systemwide.general_tools.manage_sudo_configs import remove_sudo_config from core.services.networking.systemwide.general_tools.manage_sudo_configs import remove_sudo_config
# JSON Models
from core.models.BaseProfile import BaseProfile as Profile from core.models.BaseProfile import BaseProfile as Profile
from core.models.BaseProfile import ProfileType from core.models.BaseProfile import ProfileType
from core.models.Subscription import Subscription
from core.models.session.SessionProfile import SessionProfile
from core.models.system.SystemProfile import SystemProfile
# ORM Models
from core.models.orm_models.Location import Location
from core.models.orm_models.Operator import Operator
# ORM Calls # ORM Calls
from core.models.orm_calls.location_calls import get_profile_location_data from core.models.orm_calls.location_calls import get_profile_location_data
from core.models.BaseProfile import get_application_version from core.models.BaseProfile import get_application_version
# previously used:
# from core.models.Subscription import Subscription
# from core.models.session.SessionProfile import SessionProfile
# from core.models.system.SystemProfile import SystemProfile
# from core.models.orm_models.Location import Location
# from core.models.orm_models.Operator import Operator
SYSTEMWIDE_CHOICES = ['wireguard', 'hysteria2', 'vless'] SYSTEMWIDE_CHOICES = ['wireguard', 'hysteria2', 'vless']
SESSION_CHOICES = ['wireguard', 'tor', 'proxy'] SESSION_CHOICES = ['wireguard', 'tor', 'proxy']
@ -42,9 +41,7 @@ def update_profile(
key: str, key: str,
new_value: str) -> Result: new_value: str) -> Result:
return Result(valid=False, error_type=ResultError.UNKNOWN, message="This is a test fail") # final_data = None
final_data = None
logger.info(f"[UPDATE PROFILE] Recieved profile_id {profile_id}, key {key}, and new_value {new_value}.") logger.info(f"[UPDATE PROFILE] Recieved profile_id {profile_id}, key {key}, and new_value {new_value}.")
if not key or not new_value: if not key or not new_value:
@ -109,14 +106,10 @@ def update_profile(
return Result(valid=False, message="Invalid Value to Edit", error_type=ResultError.INVALID_INPUT) return Result(valid=False, message="Invalid Value to Edit", error_type=ResultError.INVALID_INPUT)
logger.info("[UPDATE PROFILE] Passing to Profile model to save..") logger.info("[UPDATE PROFILE] Passing to Profile model to save..")
return _literally_save(profile)
def _literally_save(profile: Profile) -> Result:
try: try:
profile.save() profile.save()
logger.info("[UPDATE PROFILE] Save worked, passing to the GUI the Result..") logger.info("[UPDATE PROFILE] Save worked, passing to the GUI the Result..")
return Result(valid=True, data=final_data) return Result(valid=True)
except Exception as e: except Exception as e:
error_msg = f"Profile save failed because {str(e)}" error_msg = f"Profile save failed because {str(e)}"
return Result(valid=False, message=error_msg, error_type=ResultError.UNKNOWN) return Result(valid=False, message=error_msg, error_type=ResultError.UNKNOWN)
@ -170,5 +163,5 @@ def change_systemwide_connection(profile: Profile, new_value: str) -> Result:
# UPDATE PROFILE # UPDATE PROFILE
logger.info("Literally updating the value..") logger.info("Literally updating the value..")
profile.connection.code = new_value profile.connection.code = new_value
final_data = "edit_session" # final_data = "edit_session"
return Result(valid=True, data=profile) return Result(valid=True, data=profile)

View file

@ -6,7 +6,7 @@ class ProtocolChoice(Enum):
HYSTERIA2 = "hysteria2" HYSTERIA2 = "hysteria2"
VLESS = "vless" VLESS = "vless"
SOCK5_PROXY = "proxy" SOCK5_PROXY = "proxy"
MASKED_WIREGUARD = "masked_wireguard" # MASKED_WIREGUARD = "masked_wireguard"
class Currency(Enum): class Currency(Enum):
MONERO = "monero" MONERO = "monero"

View file

@ -1,5 +1,6 @@
from core.models.orm_models.Location import Location from core.models.orm_models.Location import Location
from core.models.orm_models.Operator import Operator from core.models.orm_models.Operator import Operator
from core.models.enum_models import ProtocolChoice, get_choice_list
from core.models.manage.wrapper import safe_db_operation, WrapperRollback from core.models.manage.wrapper import safe_db_operation, WrapperRollback
from core.models.DatabaseOperation import DatabaseOperation, DBErrorType from core.models.DatabaseOperation import DatabaseOperation, DBErrorType
from core.errors.logger import logger from core.errors.logger import logger
@ -11,6 +12,8 @@ from sqlalchemy.orm import Session
from typing import Optional from typing import Optional
import random import random
ALL_PROTOCOLS = get_choice_list(ProtocolChoice)
@safe_db_operation @safe_db_operation
def execute_location_sql(country_code: str, city_code: str, session: Session) -> DatabaseOperation: def execute_location_sql(country_code: str, city_code: str, session: Session) -> DatabaseOperation:
location_object = session.execute( location_object = session.execute(
@ -58,3 +61,18 @@ def get_random_location(filter_out_list: Optional[list] = None) -> Location:
if random_pick not in filter_out_list: if random_pick not in filter_out_list:
return random_pick return random_pick
def get_supported_protocols_for_location(location: Location, as_strings: bool = False) -> list:
"""Doesn't do SQL to get a list of supported locations"""
SUPPORTED_PROTOCOLS = []
for each_protocol in ALL_PROTOCOLS:
if location.supports_protocol(protocol):
if as_strings:
SUPPORTED_PROTOCOLS.append(each_protocol.value)
else:
SUPPORTED_PROTOCOLS.append(each_protocol)
return SUPPORTED_PROTOCOLS

View file

@ -1,11 +1,11 @@
from sqlalchemy import Integer, String, ForeignKey from sqlalchemy import Integer, String, ForeignKey, Boolean
from sqlalchemy.orm import declarative_base, mapped_column, Mapped, relationship from sqlalchemy.orm import declarative_base, mapped_column, Mapped, relationship
from typing import Optional from typing import Optional
from sqlalchemy.orm import Mapped from sqlalchemy.orm import Mapped
from core.models.orm_models.Base import BaseModel from core.models.orm_models.Base import BaseModel
from core.models.orm_models.Operator import Operator from core.models.orm_models.Operator import Operator
from core.models.enum_models import ProtocolChoice
class Location(BaseModel): class Location(BaseModel):
__tablename__ = 'locations' __tablename__ = 'locations'
@ -40,11 +40,11 @@ class Location(BaseModel):
) )
provider_name: Mapped[Optional[str]] = mapped_column(String, nullable=True, default=None) provider_name: Mapped[Optional[str]] = mapped_column(String, nullable=True, default=None)
available: Mapped[Optional[bool]] = mapped_column(String, nullable=True, default=None) available: Mapped[Optional[bool]] = mapped_column(Boolean, nullable=True, default=None)
is_proxy_capable: Mapped[Optional[bool]] = mapped_column(String, nullable=True, default=None) is_proxy_capable: Mapped[Optional[bool]] = mapped_column(Boolean, nullable=True, default=None)
is_wireguard_capable: Mapped[Optional[bool]] = mapped_column(String, nullable=True, default=None) is_wireguard_capable: Mapped[Optional[bool]] = mapped_column(Boolean, nullable=True, default=None)
is_hysteria2_capable: Mapped[Optional[bool]] = mapped_column(String, nullable=True, default=None) is_hysteria2_capable: Mapped[Optional[bool]] = mapped_column(Boolean, nullable=True, default=None)
is_vless_capable: Mapped[Optional[bool]] = mapped_column(String, nullable=True, default=None) is_vless_capable: Mapped[Optional[bool]] = mapped_column(Boolean, nullable=True, default=None)
def convert_to_dict(self): def convert_to_dict(self):
return { return {
@ -55,6 +55,27 @@ class Location(BaseModel):
} }
def supports_protocol(self, enum_value: ProtocolChoice) -> bool:
# print(f"inside {self.country_name} {self.name} location model's supports_protocol, the submitted protocol is {enum_value}")
print(f"enum_value type is {type(enum_value)}")
if enum_value is None:
return False
# socks5 proxy name doesn't match 'proxy'
if enum_value == ProtocolChoice.SOCK5_PROXY:
return self.is_proxy_capable
if isinstance(enum_value, ProtocolChoice):
string_version = enum_value.value
else:
string_version = enum_value
field_name = f'is_{string_version}_capable'
print(f"field_name is {field_name}")
return bool(getattr(self, field_name))
# to use: # to use:
# Lookup by location/city codes # Lookup by location/city codes
# record = session.get(Location, (country_code, code)) # record = session.get(Location, (country_code, code))