import pandas as pd import random import os import asyncio from googleapiclient.discovery import build from config import LOCAL_EXCEL_PATH, DRIVE_EXCEL_FILE_ID, TEMP_VIDEO_DIR import google_utils import facebook_utils # Lock để tránh 2 page cùng ghi file Excel 1 lúc excel_lock = asyncio.Lock() async def process_single_page(page_config, drive_credentials): sheet_name = page_config['sheet_name'] print(f"🚀 [Processor] Bắt đầu xử lý cho Sheet: {sheet_name}") drive_service = build('drive', 'v3', credentials=drive_credentials) async with excel_lock: # 1. Tải file Excel mới nhất về await google_utils.download_file_from_drive(drive_service, DRIVE_EXCEL_FILE_ID, LOCAL_EXCEL_PATH) # 2. Đọc dữ liệu try: df = pd.read_excel(LOCAL_EXCEL_PATH, sheet_name=sheet_name) except ValueError: print(f"❌ Không tìm thấy sheet {sheet_name}") return # 3. Lọc các dòng NYS (Giả sử cột Status là cột E - index 4) # Cấu trúc: A:STT, B:Desc, C:Shopee, D:DriveID, E:Status # Pandas index cột: 0, 1, 2, 3, 4 # Chuẩn hóa tên cột để dễ gọi df.columns = ['STT', 'Desc', 'ShopeeLink', 'DriveVideoID', 'Status', 'NewContent'] # Thêm cột NewContent nếu cần nys_rows = df[df['Status'] == 'NYS'] if nys_rows.empty: print(f"⚠️ Sheet {sheet_name} đã hết bài (không còn NYS).") return # 4. Chọn ngẫu nhiên selected_row_index = random.choice(nys_rows.index) row_data = df.loc[selected_row_index] print(f"--- Đã chọn dòng {selected_row_index + 2} ---") # (Nhả lock Excel ra để xử lý nặng) try: # 5. Gemini viết lại nội dung original_desc = str(row_data['Desc']) new_content = await google_utils.generate_content_with_gemini(original_desc) # 6. Tải video video_drive_id = str(row_data['DriveVideoID']) if not os.path.exists(TEMP_VIDEO_DIR): os.makedirs(TEMP_VIDEO_DIR) local_video_path = os.path.join(TEMP_VIDEO_DIR, f"{sheet_name}_{video_drive_id}.mp4") await google_utils.download_video_by_id(drive_service, video_drive_id, local_video_path) # 7. Upload Facebook video_id = await facebook_utils.upload_reel( page_config['page_id'], page_config['access_token'], local_video_path, new_content ) print(f"✅ Upload thành công. ID: {video_id}") # 8. Comment cta = "🔥 Săn ngay tại đây cả nhà ơi: " comment_msg = f"{cta} {row_data['ShopeeLink']}" await facebook_utils.comment_on_video(video_id, page_config['access_token'], comment_msg) # 9. Cập nhật Excel (Cần Lock lại) async with excel_lock: # Đọc lại file để đảm bảo không đè dữ liệu của luồng khác # (Trong thực tế nên dùng Google Sheets API update cell trực tiếp sẽ tốt hơn download/upload) # Nhưng ở đây ta làm theo logic file Excel local df_update = pd.read_excel(LOCAL_EXCEL_PATH, sheet_name=None) # Đọc tất cả sheet # Cập nhật sheet hiện tại sheet_df = df_update[sheet_name] sheet_df.at[selected_row_index, 'Status'] = 'Uploaded' # Giả sử cột F là nội dung mới if len(sheet_df.columns) > 5: sheet_df.iloc[selected_row_index, 5] = new_content # Lưu và Upload with pd.ExcelWriter(LOCAL_EXCEL_PATH, engine='openpyxl') as writer: for s_name, s_df in df_update.items(): s_df.to_excel(writer, sheet_name=s_name, index=False) await google_utils.upload_file_to_drive(drive_service, LOCAL_EXCEL_PATH, DRIVE_EXCEL_FILE_ID) print(f"✅ Đã cập nhật Excel lên Drive.") # Dọn dẹp if os.path.exists(local_video_path): os.remove(local_video_path) except Exception as e: print(f"❌ Lỗi xử lý Page {sheet_name}: {e}")