AutoPercenty3/titleManager/db_test1.py

264 lines
10 KiB
Python

from pymongo import MongoClient, ASCENDING
from pymongo.errors import ConnectionFailure
from typing import Optional, List, Dict
import logging
from datetime import datetime, timezone
# --- MongoDBManager 클래스 ---
class MongoDBManager:
def __init__(self, db_url: str, db_name: str = 'AutoPercenty'):
"""MongoDB와의 연결을 설정하고 데이터베이스를 설정합니다."""
try:
self.client = MongoClient(db_url)
self.db = self.client[db_name]
self.collection = None
print("MongoDB 연결 성공!")
except ConnectionFailure as e:
print(f"MongoDB 연결 실패: {e}")
raise
def set_collection(self, collection_name: str):
"""컬렉션을 설정합니다."""
self.collection = self.db[collection_name]
def insert_one(self, document: Dict) -> bool:
"""단일 문서를 컬렉션에 추가합니다."""
try:
self.collection.insert_one(document)
return True
except Exception as e:
print(f"문서 삽입 실패: {e}")
return False
def find_one(self, query: Dict) -> Optional[Dict]:
"""단일 문서를 조회합니다."""
return self.collection.find_one(query)
def find(self, query: Dict, projection: Dict = None) -> List[Dict]:
"""여러 문서를 조회합니다."""
return list(self.collection.find(query, projection))
def update_one(self, query: Dict, update_data: Dict) -> bool:
"""단일 문서를 업데이트합니다."""
result = self.collection.update_one(query, {"$set": update_data})
return result.modified_count > 0
def delete_one(self, query: Dict) -> bool:
"""단일 문서를 삭제합니다."""
result = self.collection.delete_one(query)
return result.deleted_count > 0
def insert_multiple(self, documents: List[Dict]) -> bool:
"""여러 문서를 컬렉션에 추가합니다."""
try:
if len(documents) > 10:
documents = documents[:10] # 최대 10개까지만 추가
self.collection.insert_many(documents)
return True
except Exception as e:
print(f"여러 문서 삽입 실패: {e}")
return False
def find_all(self, query: Dict = {}) -> List[Dict]:
"""모든 문서를 조회합니다."""
return list(self.collection.find(query))
def close_connection(self):
"""MongoDB 연결을 닫습니다."""
self.client.close()
print("MongoDB 연결이 종료되었습니다.")
# --- ForbiddenWordManager 클래스 ---
logger = logging.getLogger('ForbiddenWordManager')
class ForbiddenWordManager:
def __init__(self, db_manager, collection_name='ForbbidenDB'):
self.db_manager = db_manager
self.db_manager.set_collection(collection_name)
def register_word(self, word: str, kipris_results: List[Dict], added_by: str):
"""
Kipris API 결과를 바탕으로 최대 10개의 금지어를 등록.
"""
count = 0
for result in kipris_results:
if count >= 10:
break
category_code = result.get("category_code")
existing_entry = self.db_manager.find_one({"word": word, "category_code": category_code})
if existing_entry:
logger.debug(f"'{word}' (카테고리 코드: {category_code})는 이미 등록되어 있음.")
continue
document = {
"word": word,
"has_trademark": True,
"title": result.get("title"),
"registration_date": result.get("registration_date", "N/A"),
"applicant_name": result.get("applicant_name", "N/A"),
"category_code": category_code,
"category_description": result.get("category_description", "N/A"),
"created_at": datetime.utcnow(),
"added_by": added_by,
"status": "미인증"
}
self.db_manager.insert_one(document)
logger.debug(f"'{word}' (카테고리 코드: {category_code})가 금지어로 등록됨.")
count += 1
if count == 0:
logger.debug(f"'{word}'와 관련된 새로운 카테고리 코드가 발견되지 않음.")
else:
logger.debug(f"'{word}'와 관련된 금지어가 {count}개 등록됨.")
def authenticate_word(self, word: str, admin_user: str):
"""관리자가 단어를 인증"""
result = self.db_manager.update_one(
{"word": word},
{"$set": {"status": "인증", "authenticated_by": admin_user, "authenticated_at": datetime.utcnow()}}
)
# 참고: update_one에서 bool을 반환하므로 matched_count 접근은 불가합니다.
if result:
logger.debug(f"'{word}'가 인증됨.")
return True
else:
logger.debug(f"'{word}'를 찾을 수 없음.")
return False
def update_word(self, word: str, update_fields: dict):
"""금지어 정보 업데이트 (관리자만 가능)"""
update_fields["updated_at"] = datetime.utcnow()
result = self.db_manager.update_one({"word": word}, {"$set": update_fields})
if result:
logger.debug(f"'{word}'의 정보가 업데이트됨.")
return True
else:
logger.debug(f"'{word}'를 찾을 수 없음.")
return False
def delete_word(self, word: str):
"""금지어 삭제"""
result = self.db_manager.delete_one({"word": word})
if result:
logger.debug(f"'{word}'가 삭제됨.")
return True
else:
logger.debug(f"'{word}'를 찾을 수 없음.")
return False
def list_all_words(self, filter_status=None):
"""모든 금지어 목록 조회 (필터링 가능)"""
query = {}
if filter_status:
query["status"] = filter_status
return list(self.db_manager.find(query, {"_id": 0}))
def is_word_forbidden(self, word: str) -> List[Dict]:
"""단어가 금지어 목록에 있는지 확인하고 모든 일치하는 레코드를 반환"""
results = list(self.db_manager.find({"word": word}, {"_id": 0}))
if results:
logger.debug(f"'{word}'에 대한 금지어가 {len(results)}개 발견됨.")
return results
else:
logger.debug(f"'{word}'에 대한 금지어가 발견되지 않음.")
return []
# --- 테스트 코드 ---
if __name__ == "__main__":
# 로깅 설정 (DEBUG 레벨로 설정하여 logger.debug 출력 확인)
logging.basicConfig(level=logging.DEBUG)
# MongoDB 연결 설정 (실제 환경에 맞게 수정)
db_url = 'mongodb://root:1234@cckb9998.synology.me:27017/'
db_name = 'AutoPercenty'
# MongoDBManager 인스턴스 생성
db_manager = MongoDBManager(db_url=db_url, db_name=db_name)
# ForbiddenWordManager 인스턴스 생성 (자동으로 'ForbbidenDB' 컬렉션 사용)
forbidden_manager = ForbiddenWordManager(db_manager)
# # 테스트를 위해 기존 금지어 컬렉션을 초기화 (컬렉션 삭제)
# db_manager.collection.drop()
# print("기존 금지어 컬렉션 초기화 완료.\n")
# # 샘플 금지어 데이터 등록 (예제에서는 'Apple', 'iPhone', 'Max'를 금지어로 등록)
# sample_forbidden_words = [
# {
# "word": "Apple",
# "has_trademark": True,
# "title": "Dummy Title Apple",
# "registration_date": "2020-01-01",
# "applicant_name": "Dummy Applicant",
# "category_code": "001",
# "category_description": "Dummy description",
# "created_at": datetime.now(timezone.utc),
# "added_by": "test",
# "status": "인증"
# },
# {
# "word": "iPhone",
# "has_trademark": True,
# "title": "Dummy Title iPhone",
# "registration_date": "2020-02-01",
# "applicant_name": "Dummy Applicant",
# "category_code": "002",
# "category_description": "Dummy description",
# "created_at": datetime.now(timezone.utc),
# "added_by": "test",
# "status": "인증"
# },
# {
# "word": "Max",
# "has_trademark": True,
# "title": "Dummy Title Max",
# "registration_date": "2020-03-01",
# "applicant_name": "Dummy Applicant",
# "category_code": "003",
# "category_description": "Dummy description",
# "created_at": datetime.now(timezone.utc),
# "added_by": "test",
# "status": "인증"
# }
# ]
# for doc in sample_forbidden_words:
# if db_manager.insert_one(doc):
# print(f"'{doc['word']}' 금지어 등록 완료.")
# else:
# print(f"'{doc['word']}' 금지어 등록 실패.")
# 테스트용 샘플 상품명 설정
sample_product_name = "Apple iPhone 14 Pro Max"
print(f"\n샘플 상품명: {sample_product_name}")
# 상품명을 단어 단위(공백 기준)로 분리
product_words = sample_product_name.split()
print("상품명 단어 목록:", product_words)
# 각 단어에 대해 금지어 여부 확인
forbidden_words_found = {}
for word in product_words:
entries = forbidden_manager.is_word_forbidden(word)
if entries:
forbidden_words_found[word] = entries
print(f"단어 '{word}'는 금지어 목록에 존재합니다.")
else:
print(f"단어 '{word}'는 금지어 목록에 존재하지 않습니다.")
# 최종 필터링 결과 출력
print("\n금지어 필터링 결과:")
if forbidden_words_found:
for word, entries in forbidden_words_found.items():
print(f"'{word}': {entries}")
else:
print("금지어가 발견되지 않았습니다.")
# MongoDB 연결 종료
db_manager.close_connection()