@@ -74,3 +74,125 @@ def verify_safe_password(password):
7474
7575 input_hash = hashlib .sha256 (password .encode ('utf-8' )).hexdigest ()
7676 return input_hash == stored_hash
77+ import json
78+ import os
79+ import shutil
80+
81+ # Nombre del archivo de configuración
82+ CONFIG_FILENAME = "visagevault_config.json"
83+
84+ def get_config_path ():
85+ """
86+ Calcula la ruta del archivo de configuración siguiendo estándares.
87+ Prioridad:
88+ 1. Carpeta local (si es portable/desarrollo).
89+ 2. ~/.config/visagevault/ (si está instalado en Linux).
90+ """
91+ base_dir = os .path .dirname (os .path .abspath (__file__ ))
92+
93+ # 1. MODO PORTABLE / DESARROLLO (Windows o ejecución local)
94+ # Si tenemos permiso de escritura en la carpeta del script, usamos esa.
95+ if os .access (base_dir , os .W_OK ):
96+ return os .path .join (base_dir , CONFIG_FILENAME )
97+
98+ # 2. MODO INSTALADO (Linux / AUR / /usr/share)
99+ # Usamos el estándar XDG: ~/.config/visagevault/
100+ user_home = os .path .expanduser ("~" )
101+ config_dir = os .path .join (user_home , ".config" , "visagevault" )
102+
103+ # Crear la carpeta si no existe
104+ if not os .path .exists (config_dir ):
105+ try :
106+ os .makedirs (config_dir , exist_ok = True )
107+ except OSError :
108+ # Fallback extremo: volver a home si falla crear .config
109+ return os .path .join (user_home , CONFIG_FILENAME )
110+
111+ target_config = os .path .join (config_dir , CONFIG_FILENAME )
112+
113+ # --- MIGRACIÓN AUTOMÁTICA ---
114+ # Si existe el archivo viejo en la raíz (~/visagevault_config.json)
115+ # y no existe el nuevo, lo movemos para no perder datos.
116+ old_config_path = os .path .join (user_home , CONFIG_FILENAME )
117+ if os .path .exists (old_config_path ) and not os .path .exists (target_config ):
118+ try :
119+ shutil .move (old_config_path , target_config )
120+ print (f"Configuración migrada de { old_config_path } a { target_config } " )
121+ except Exception as e :
122+ print (f"Error migrando configuración: { e } " )
123+
124+ return target_config
125+
126+ def load_config ():
127+ config_path = get_config_path ()
128+ if not os .path .exists (config_path ):
129+ return {}
130+ try :
131+ with open (config_path , 'r' ) as f :
132+ return json .load (f )
133+ except (json .JSONDecodeError , IOError ):
134+ return {}
135+
136+ def save_config (config_data ):
137+ config_path = get_config_path ()
138+ try :
139+ with open (config_path , 'w' ) as f :
140+ json .dump (config_data , f , indent = 4 )
141+ except IOError as e :
142+ print (f"Error guardando configuración en { config_path } : { e } " )
143+
144+ # --- GETTERS Y SETTERS ESPECÍFICOS ---
145+
146+ def get_photo_directory ():
147+ config = load_config ()
148+ return config .get ('photo_directory' , "" )
149+
150+ def set_photo_directory (path ):
151+ config = load_config ()
152+ config ['photo_directory' ] = path
153+ save_config (config )
154+
155+ def get_thumbnail_size ():
156+ config = load_config ()
157+ # Tamaño por defecto 128 si no existe
158+ return config .get ('thumbnail_size' , 128 )
159+
160+ def set_thumbnail_size (size ):
161+ config = load_config ()
162+ config ['thumbnail_size' ] = size
163+ save_config (config )
164+
165+ def get_drive_folder_id ():
166+ config = load_config ()
167+ return config .get ('drive_folder_id' , None )
168+
169+ def set_drive_folder_id (folder_id ):
170+ config = load_config ()
171+ config ['drive_folder_id' ] = folder_id
172+ save_config (config )
173+
174+ # --- SEGURIDAD CAJA FUERTE ---
175+
176+ def get_safe_password_hash ():
177+ config = load_config ()
178+ return config .get ('safe_password_hash' , None )
179+
180+ def set_safe_password_hash (password_plain ):
181+ import hashlib
182+ # Guardamos solo el hash SHA256, nunca la contraseña plana
183+ hash_object = hashlib .sha256 (password_plain .encode ())
184+ hex_dig = hash_object .hexdigest ()
185+
186+ config = load_config ()
187+ config ['safe_password_hash' ] = hex_dig
188+ save_config (config )
189+
190+ def verify_safe_password (password_plain ):
191+ import hashlib
192+ stored_hash = get_safe_password_hash ()
193+ if not stored_hash : return False
194+
195+ hash_object = hashlib .sha256 (password_plain .encode ())
196+ hex_dig = hash_object .hexdigest ()
197+
198+ return hex_dig == stored_hash
0 commit comments