11# standard
2+ import json
23import os
4+ import platform
35import re
6+ import shutil
47
58# third-party
69import tomlkit
710from dynaconf import Dynaconf , Validator , ValidationError
11+ from platformdirs import user_config_dir , user_data_dir
812
913# Parent Category to folder
1014CATEGORY_MAP = {
5155 "2675" : "lootnscoot" ,
5256}
5357
58+ BREADCRUMB_FILENAME = "last_command.json"
59+ DEFAULT_CONFIG_DIR = user_config_dir ("redfetch" , "RedGuides" )
60+
61+ script_dir = os .path .dirname (os .path .abspath (__file__ ))
62+ os .environ ['REDFETCH_SCRIPT_DIR' ] = script_dir
63+
64+ # Populated by initialize_config()
65+ config_dir = None
66+ env_file_path = None
67+ settings = None
68+
5469
5570def validate_no_eqgame (path ):
5671 """Validate that the path and its parents don't contain eqgame.exe."""
@@ -94,8 +109,8 @@ def normalize_category_paths(data):
94109 return data
95110
96111
97- # Custom Dynaconf validator specifically for SPECIAL_RESOURCE paths
98112def normalize_paths_in_dict (data , parent_key = None ):
113+ """Dynaconf validator for SPECIAL_RESOURCE paths."""
99114 if isinstance (data , dict ):
100115 for key , value in data .items ():
101116 if isinstance (value , dict ):
@@ -115,16 +130,6 @@ def normalize_paths_in_dict(data, parent_key=None):
115130 return data
116131
117132
118- # Initialize variables
119- script_dir = os .path .dirname (os .path .abspath (__file__ ))
120- os .environ ['REDFETCH_SCRIPT_DIR' ] = script_dir
121-
122- # Declare these variables; they will be initialized in initialize_config()
123- config_dir = None
124- env_file_path = None
125- settings = None
126-
127-
128133def initialize_config ():
129134 """Initialize configuration settings."""
130135 from redfetch .config_firstrun import first_run_setup
@@ -136,9 +141,7 @@ def initialize_config():
136141 os .environ ['REDFETCH_CONFIG_DIR' ] = config_dir
137142
138143 # Data dir: Linux default uses XDG data dir (~/.local/share), else same as config
139- import platform
140- from platformdirs import user_config_dir , user_data_dir
141- is_linux_default = platform .system () == "Linux" and config_dir == user_config_dir ("redfetch" , "RedGuides" )
144+ is_linux_default = platform .system () == "Linux" and config_dir == DEFAULT_CONFIG_DIR
142145 data_dir = user_data_dir ("redfetch" , "RedGuides" ) if is_linux_default else config_dir
143146 os .makedirs (data_dir , exist_ok = True )
144147 os .environ ['REDFETCH_DATA_DIR' ] = data_dir
@@ -177,10 +180,48 @@ def initialize_config():
177180 ]
178181 )
179182
183+ write_breadcrumb ()
184+
180185 # Return the settings object for potential use
181186 return settings
182187
183188
189+ def _resolve_redfetch_executable ():
190+ """PYAPP will give a path when built with PYAPP_PASS_LOCATION=1"""
191+ pyapp = os .environ .get ("PYAPP" )
192+ if pyapp and "redfetch" in os .path .basename (pyapp ).lower () and os .path .exists (pyapp ):
193+ return os .path .abspath (pyapp )
194+
195+ cmd = shutil .which ("redfetch" )
196+ if cmd :
197+ return os .path .abspath (cmd )
198+
199+ return None
200+
201+
202+ def write_breadcrumb () -> None :
203+ """A breadcrumb in the user config dir to track the most recently used redfetch binary's location."""
204+ try :
205+ program = _resolve_redfetch_executable ()
206+ if program is None :
207+ return
208+
209+ os .makedirs (DEFAULT_CONFIG_DIR , exist_ok = True )
210+ breadcrumb_path = os .path .join (DEFAULT_CONFIG_DIR , BREADCRUMB_FILENAME )
211+ with open (breadcrumb_path , "w" , encoding = "utf-8" ) as f :
212+ json .dump ({"program" : program }, f )
213+ except Exception :
214+ pass
215+
216+
217+ def remove_breadcrumb () -> None :
218+ breadcrumb_path = os .path .join (DEFAULT_CONFIG_DIR , BREADCRUMB_FILENAME )
219+ try :
220+ os .remove (breadcrumb_path )
221+ except FileNotFoundError :
222+ pass
223+
224+
184225def switch_environment (new_env ):
185226 """Switch the environment and update the settings."""
186227 if settings is None :
0 commit comments