Spaces:
Building
Building
from google.cloud import firestore | |
from google.oauth2 import service_account | |
from config.settings import Settings | |
from src.logger import logger | |
from datetime import datetime | |
class FirestoreDB: | |
def __init__(self): | |
# Kiểm tra FIRESTORE_CREDENTIALS từ Settings | |
if not Settings.FIRESTORE_CREDENTIALS: | |
logger.error("Thiếu FIRESTORE_CREDENTIALS trong cấu hình.") | |
raise ValueError("Thiếu FIRESTORE_CREDENTIALS. Vui lòng đặt biến môi trường FIRESTORE_CREDENTIALS với nội dung JSON credentials.") | |
try: | |
# Khởi tạo credentials từ FIRESTORE_CREDENTIALS | |
credentials_dict = Settings.FIRESTORE_CREDENTIALS | |
if not isinstance(credentials_dict, dict) or "type" not in credentials_dict: | |
raise ValueError("FIRESTORE_CREDENTIALS không phải là JSON hợp lệ.") | |
# Sử dụng credentials cho google-cloud-firestore | |
credentials_obj = service_account.Credentials.from_service_account_info(credentials_dict) | |
self.db = firestore.Client(credentials=credentials_obj, project=credentials_dict.get("project_id")) | |
logger.info("Khởi tạo FirestoreDB thành công với FIRESTORE_CREDENTIALS.") | |
except Exception as e: | |
logger.error(f"Lỗi khi khởi tạo FirestoreDB: {str(e)}") | |
raise | |
self.documents = self.db.collection("documents") | |
self.lottery = self.db.collection("lottery") | |
def save_document(self, text, vector): | |
if not self.document_exists(text): | |
self.documents.add({"text": text, "vector": vector.tolist()}) | |
logger.info(f"Đã lưu document: {text[:50]}...") | |
def document_exists(self, text): | |
query = self.documents.where(filter=firestore.FieldFilter("text", "==", text)) | |
return bool(query.get()) | |
def get_all_documents(self): | |
return [(doc.to_dict()["text"], doc.to_dict()["vector"]) for doc in self.documents.stream()] | |
def save_lottery(self, data): | |
ngay = data.get("ngay") | |
dai = data.get("dai") | |
if not all([ngay, dai]): | |
logger.error("Dữ liệu thiếu ngay hoặc dai") | |
return False | |
try: | |
# Chuyển đổi ngày từ YYYY-MM-DD sang DD-MM-YYYY | |
ngay = datetime.strptime(ngay, "%Y-%m-%d").strftime("%d-%m-%Y") | |
data["ngay"] = ngay | |
except ValueError as e: | |
logger.error(f"Định dạng ngày không hợp lệ: {ngay}, lỗi: {str(e)}") | |
return False | |
key = f"lottery-{ngay}_{dai}" # Thêm tiền tố "lottery-" để đồng bộ | |
logger.debug(f"Dữ liệu lottery trước khi lưu: {data}") | |
self.lottery.document(key).set(data) | |
logger.info(f"Đã lưu (hoặc ghi đè) lottery: {key}") | |
return True | |
def lottery_exists(self, key): | |
return bool(self.lottery.document(key).get().exists) | |
def get_lottery(self, dai, start_date, end_date): | |
try: | |
docs = self.lottery.where(filter=firestore.FieldFilter("dai", "==", dai)).stream() | |
data = [] | |
for doc in docs: | |
doc_data = doc.to_dict() | |
ngay = doc_data.get("ngay") | |
if not ngay or not isinstance(ngay, str): | |
logger.warning(f"Bỏ qua bản ghi có 'ngay' không hợp lệ: {doc.id}, ngay: {ngay}") | |
continue | |
try: | |
doc_date = datetime.strptime(ngay, "%d-%m-%Y") | |
# Nếu start_date và end_date đều được cung cấp | |
if start_date and end_date: | |
start = datetime.strptime(start_date, "%d-%m-%Y") | |
end = datetime.strptime(end_date, "%d-%m-%Y") | |
if start <= doc_date <= end: | |
data.append(doc_data) | |
# Nếu chỉ có end_date (như trong analyze_position) | |
elif end_date: | |
end = datetime.strptime(end_date, "%d-%m-%Y") | |
if doc_date <= end: | |
data.append(doc_data) | |
# Nếu không có ngày cụ thể, lấy tất cả | |
else: | |
data.append(doc_data) | |
except ValueError: | |
logger.warning(f"Ngày không hợp lệ trong bản ghi: {doc.id}, ngay: {ngay}") | |
continue | |
logger.debug(f"Dữ liệu lấy từ Firestore cho {dai} từ {start_date} đến {end_date}: {data}") | |
return data | |
except Exception as e: | |
logger.error(f"Lỗi khi lấy dữ liệu xổ số: {str(e)}") | |
return [] | |
def get_lottery_by_date(self, dai, date): | |
try: | |
if not date or not isinstance(date, str): | |
logger.warning(f"Ngày không hợp lệ: {date}") | |
return None | |
datetime.strptime(date, "%d-%m-%Y") # Kiểm tra định dạng | |
docs = self.lottery.where(filter=firestore.FieldFilter("dai", "==", dai)).where(filter=firestore.FieldFilter("ngay", "==", date)).stream() | |
result = [doc.to_dict() for doc in docs if doc.to_dict().get("ngay") and isinstance(doc.to_dict().get("ngay"), str)] | |
if len(result) > 1: | |
logger.warning(f"Tìm thấy nhiều document khớp với {dai} ngày {date}: {len(result)} document") | |
logger.debug(f"Dữ liệu từ get_lottery_by_date cho {dai} ngày {date}: {result}") | |
return result[0] if result else None | |
except ValueError as e: | |
logger.error(f"Lỗi định dạng ngày trong get_lottery_by_date: {str(e)}") | |
return None | |
except Exception as e: | |
logger.error(f"Lỗi khi lấy dữ liệu xổ số theo ngày: {str(e)}") | |
return None |