import configparser from cryptography.fernet import Fernet, InvalidToken import os class ConfigManager: def __init__(self, config_file='config.ini', max_businesses=5): self.config_file = config_file self.config = configparser.ConfigParser() self.max_businesses = max_businesses self.valid_markets = ['쿠팡', '스마트스토어', 'esm', '11번가-국내', '11번가-글로벌', '롯데온', '인터파크', '위메프', '옥션1.0'] if not os.path.exists(config_file): self._create_default_config() self.config.read(config_file, encoding='utf-8') if 'DEFAULT' not in self.config or 'encryption_key' not in self.config['DEFAULT']: self.key = Fernet.generate_key() self.config['DEFAULT']['encryption_key'] = self.key.decode() with open(self.config_file, 'w', encoding='utf-8') as configfile: self.config.write(configfile) else: self.key = self.config['DEFAULT']['encryption_key'].encode() self.cipher_suite = Fernet(self.key) def _create_default_config(self): self.config['DEFAULT'] = { 'max_businesses': str(self.max_businesses), 'log_level': 'DEBUG', 'business_count': '0', 'encryption_key': Fernet.generate_key().decode() } for i in range(1, self.max_businesses + 1): section = f'BUSINESS_{i}' self.config[section] = { '사업자별칭': '', '사업자등록번호': '', '상호명': '', '등록날짜': '', '응대전화번호': '', '기타정보Title1': '기타정보1', '기타정보Context1': '', '기타정보Title2': '기타정보2', '기타정보Context2': '', '기타정보Title3': '기타정보3', '기타정보Context3': '', '기타정보Title4': '기타정보4', '기타정보Context4': '', '기타정보Title5': '기타정보5', '기타정보Context5': '', '활성마켓': ', '.join([f"{market}:False" for market in self.valid_markets]) } for market in self.valid_markets: if market == '쿠팡': self.config[section].update({ '쿠팡_쿠팡id': '', '쿠팡_업체코드': '', '쿠팡_accesskey': '', '쿠팡_secretkey': '' }) elif market == '스마트스토어': self.config[section].update({ '스마트스토어_업로드할스마트스토어계정명': '', '스마트스토어_업로드할스마트스토어계정id': '', '스마트스토어_업로드할스마트스토어계정pw': '', '스마트스토어_애플리케이션id': '', '스마트스토어_애플리케이션시크릿': '' }) elif market == 'esm': self.config[section].update({ 'esm_옥션id': '', 'esm_지마켓id': '' }) elif market == '11번가-국내': self.config[section].update({ '11번가-국내_apikey': '' }) elif market == '11번가-글로벌': self.config[section].update({ '11번가-글로벌_apikey': '' }) elif market == '롯데온': self.config[section].update({ '롯데온_apikey': '' }) elif market == '인터파크': self.config[section].update({ '인터파크_상품상태재고수정인증키': '', '인터파크_상품상태재고수정비밀키': '', '인터파크_상품재고조회인증키': '', '인터파크_상품재고조회비밀키': '', '인터파크_상품정보조회인증': '', '인터파크_상품정보조회비밀키': '', '인터파크_상품수정인증키': '', '인터파크_상품수정비밀키': '', '인터파크_상품등록인증키': '', '인터파크_상품등록비밀키': '', '인터파크_반품배송지조회인증키': '', '인터파크_반품배송지조회비밀키': '', '인터파크_반품배송지등록인증키': '', '인터파크_반품배송지등록비밀키': '', '인터파크_상품qna등록인증키': '', '인터파크_상품qna등록비밀키': '', '인터파크_상품qna조회인증키': '', '인터파크_상품qna조회비밀키': '', '인터파크_인터파크업체번호': '', '인터파크_공급계약일련번호': '' }) elif market == '위메프': self.config[section].update({ '위메프_apikey': '' }) elif market == '옥션1.0': self.config[section].update({ '옥션1.0_apikey': '', '옥션1.0_멤버id': '' }) with open(self.config_file, 'w', encoding='utf-8') as configfile: self.config.write(configfile) def save(self): with open(self.config_file, 'w', encoding='utf-8') as configfile: self.config.write(configfile) def get(self, section, option, fallback=None): return self.config.get(section, option, fallback=fallback) def set(self, section, option, value): if not self.config.has_section(section): self.config.add_section(section) self.config.set(section, option, value) with open(self.config_file, 'w', encoding='utf-8') as configfile: self.config.write(configfile) def encrypt(self, data): return self.cipher_suite.encrypt(data.encode()).decode() def decrypt(self, encrypted_data): try: return self.cipher_suite.decrypt(encrypted_data.encode()).decode() except InvalidToken: raise ValueError("Invalid encryption key or corrupted data.") def get_business_info(self, business_section): if not self.config.has_section(business_section): return None business_info = { '사업자별칭': self.config.get(business_section, '사업자별칭', fallback='설정사업자없음'), '사업자등록번호': self.config.get(business_section, '사업자등록번호', fallback='000-00-00000'), '상호명': self.config.get(business_section, '상호명', fallback='설정사업자없음'), '등록날짜': self.config.get(business_section, '등록날짜', fallback='0000-00-00'), '응대전화번호': self.config.get(business_section, '응대전화번호', fallback='000-000-0000'), '기타정보Title1': self.config.get(business_section, '기타정보Title1', fallback=''), '기타정보Context1': self.config.get(business_section, '기타정보Context1', fallback=''), '기타정보Title2': self.config.get(business_section, '기타정보Title2', fallback=''), '기타정보Context2': self.config.get(business_section, '기타정보Context2', fallback=''), '기타정보Title3': self.config.get(business_section, '기타정보Title3', fallback=''), '기타정보Context3': self.config.get(business_section, '기타정보Context3', fallback=''), '기타정보Title4': self.config.get(business_section, '기타정보Title4', fallback=''), '기타정보Context4': self.config.get(business_section, '기타정보Context4', fallback=''), '기타정보Title5': self.config.get(business_section, '기타정보Title5', fallback=''), '기타정보Context5': self.config.get(business_section, '기타정보Context5', fallback='') } return business_info def reset_business_info_and_keys(self, business_id): business_section = f'BUSINESS_{business_id}' if not self.config.has_section(business_section): self.config.add_section(business_section) # 초기화할 기본 사업자 정보 설정 self.config.set(business_section, '사업자별칭', '') self.config.set(business_section, '사업자등록번호', '') self.config.set(business_section, '상호명', '') self.config.set(business_section, '등록날짜', '') self.config.set(business_section, '응대전화번호', '') for j in range(1, 6): self.config.set(business_section, f'기타정보Title{j}', '') self.config.set(business_section, f'기타정보Context{j}', '') # 마켓 이름으로 시작하는 모든 키 초기화 for key in list(self.config[business_section].keys()): if any(key.startswith(market) for market in self.valid_markets): self.config.set(business_section, key, '') with open(self.config_file, 'w', encoding='utf-8') as configfile: self.config.write(configfile) def set_business_info(self, business_id, business_info): # print(f"set_business_info || business_info : {business_info}") business_section = f'BUSINESS_{business_id}' # print(f"set_business_info || business_section : {business_section}") self.set(business_section, '사업자별칭', business_info['사업자별칭']) self.set(business_section, '사업자등록번호', business_info['사업자등록번호']) self.set(business_section, '상호명', business_info['상호명']) self.set(business_section, '등록날짜', business_info['등록날짜']) self.set(business_section, '응대전화번호', business_info['응대전화번호']) for j in range(1, 6): # print(f"j : {j}") self.set(business_section, f'기타정보Title{j}', business_info[f'기타정보Title{j}']) self.set(business_section, f'기타정보Context{j}', business_info[f'기타정보Context{j}']) def get_all_businesses(self): businesses = [] for section in self.config.sections(): if section.startswith('BUSINESS_'): businesses.append(section) return businesses def has_business_info(self, business_id): business_section = f'BUSINESS_{business_id}' if not self.config.has_section(business_section): return False # Check if any essential business info fields are not empty essential_fields = ['사업자별칭', '사업자등록번호', '상호명', '등록날짜', '응대전화번호'] for field in essential_fields: if self.config.get(business_section, field, fallback=''): return True # Check if any market-related fields are not empty for key in self.config.options(business_section): market_name = key.split('_', 1)[0] if market_name in self.valid_markets: if self.config.get(business_section, key, fallback=''): return True return False def get_api_keys(self, business_section): print(f"get_api_keys | business_section : {business_section}") if not self.config.has_section(business_section): return {} api_keys = {} all_sections = self.config.options(business_section) # print(f"get_api_keys | all_sections : {len(all_sections)}개의 섹션 존재 \n {all_sections}") for key in all_sections: market_name = key.split('_', 1)[0] # print(f"get_api_keys | market_name : {market_name}") if market_name in self.valid_markets and '_' in key: market, key_name = key.split('_', 1) # print(f"get_api_keys | market : {market}") # print(f"get_api_keys | key_name : {key_name}") if market not in api_keys: api_keys[market] = {} # print(f"{market} 이름이 api_keys에 없기 때문에 추가") encrypted_value = self.config.get(business_section, key) if encrypted_value: try: decrypted_value = self.decrypt(encrypted_value) api_keys[market][key_name] = decrypted_value except Exception as e: api_keys[market][key_name] = '' else: api_keys[market][key_name] = '' return api_keys def set_api_keys(self, business_id, api_keys): business_section = f'BUSINESS_{business_id}' if not self.config.has_section(business_section): self.config.add_section(business_section) for market, keys in api_keys.items(): for key_name, key_value in keys.items(): encrypted_value = self.encrypt(key_value) self.config.set(business_section, f'{market}_{key_name}', encrypted_value) with open(self.config_file, 'w', encoding='utf-8') as configfile: self.config.write(configfile) def reset_settings(self): if os.path.exists(self.config_file): os.remove(self.config_file) self._create_default_config() self.config.read(self.config_file, encoding='utf-8') def get_user_info(self): user_id = self.get('Percenty_Setting', 'user_id', fallback='') encrypted_password = self.get('Percenty_Setting', 'password', fallback='') headless = self.get('Percenty_Setting', 'headless', fallback=True) password = self.decrypt(encrypted_password) if encrypted_password else '' return user_id, password, headless def get_active_markets(self, business_index): section = f"BUSINESS_{business_index}" active_markets = self.config.get(section, "활성마켓", fallback="") market_dict = {market: False for market in self.valid_markets} # 기본값 False로 초기화 if active_markets: active_market_list = [market.strip() for market in active_markets.split(',')] for market_entry in active_market_list: if ':' in market_entry: # Ensure it has the right format market_name, status = market_entry.split(':') market_dict[market_name.strip()] = status.strip().lower() == 'true' return market_dict def set_active_markets(self, business_index, active_markets): business_section = f'BUSINESS_{business_index}' if not self.config.has_section(business_section): self.config.add_section(business_section) active_markets_str = ', '.join([f"{market}:{str(state)}" for market, state in active_markets.items()]) self.config.set(business_section, '활성마켓', active_markets_str)