diff --git a/app/sheets/sheets_manager.py b/app/sheets/sheets_manager.py index 87e2655..cfa785f 100644 --- a/app/sheets/sheets_manager.py +++ b/app/sheets/sheets_manager.py @@ -45,6 +45,7 @@ def clear_cache(self, guild_id: Optional[int] = None): async def get_sheet_for_guild( self, guild_id: int, sheet_id: str ) -> Optional[gspread.Spreadsheet]: + self.connect() if not self.client: return None @@ -62,6 +63,7 @@ async def get_sheet_for_guild( async def create_sheet_for_guild( self, guild_id: int, guild_name: str ) -> tuple[str, str]: + self.connect() if not self.client: raise Exception("Google Sheets client not connected") @@ -227,11 +229,11 @@ async def _setup_stats_sheet(self, spreadsheet: gspread.Spreadsheet, guild_name: self._apply_default_font(sheet, 2) self._auto_resize_columns(spreadsheet, sheet, 2) - async def sync_items(self, guild_id: int, sheet_id: str, items: List[Item], usernames: dict[int, str]): + async def sync_items(self, guild_id: int, sheet_id: str, items: List[Item], usernames: dict[int, str]) -> bool: spreadsheet = await self.get_sheet_for_guild(guild_id, sheet_id) if not spreadsheet: logger.warning(f"Could not get spreadsheet for guild {guild_id}") - return + return False try: sheet = spreadsheet.worksheet("Items") @@ -264,17 +266,19 @@ async def sync_items(self, guild_id: int, sheet_id: str, items: List[Item], user self._auto_resize_columns(spreadsheet, sheet, num_cols) logger.info(f"Synced {len(items)} items for guild {guild_id}") + return True except Exception as e: logger.error(f"Failed to sync items for guild {guild_id}: {e}") + return False async def sync_checkouts( self, guild_id: int, sheet_id: str, checkouts: List[Checkout], items_map: dict, usernames: dict[int, str] - ): + ) -> bool: spreadsheet = await self.get_sheet_for_guild(guild_id, sheet_id) if not spreadsheet: logger.warning(f"Could not get spreadsheet for guild {guild_id}") - return + return False try: sheet = spreadsheet.worksheet("Active Checkouts") @@ -320,15 +324,17 @@ async def sync_checkouts( self._auto_resize_columns(spreadsheet, sheet, num_cols) logger.info(f"Synced {len(checkouts)} checkouts for guild {guild_id}") + return True except Exception as e: logger.error(f"Failed to sync checkouts for guild {guild_id}: {e}") + return False - async def sync_audit_log(self, guild_id: int, sheet_id: str, logs: List[AuditLog], usernames: dict[int, str]): + async def sync_audit_log(self, guild_id: int, sheet_id: str, logs: List[AuditLog], usernames: dict[int, str]) -> bool: spreadsheet = await self.get_sheet_for_guild(guild_id, sheet_id) if not spreadsheet: logger.warning(f"Could not get spreadsheet for guild {guild_id}") - return + return False try: sheet = spreadsheet.worksheet("Audit Log") @@ -357,9 +363,11 @@ async def sync_audit_log(self, guild_id: int, sheet_id: str, logs: List[AuditLog self._auto_resize_columns(spreadsheet, sheet, num_cols) logger.info(f"Synced {len(rows)} audit log entries for guild {guild_id}") + return True except Exception as e: logger.error(f"Failed to sync audit log for guild {guild_id}: {e}") + return False async def append_audit_log(self, guild_id: int, sheet_id: str, log_entry: AuditLog): spreadsheet = await self.get_sheet_for_guild(guild_id, sheet_id) @@ -382,10 +390,10 @@ async def append_audit_log(self, guild_id: int, sheet_id: str, log_entry: AuditL except Exception as e: logger.error(f"Failed to append audit log for guild {guild_id}: {e}") - async def update_stats(self, guild_id: int, sheet_id: str, stats: dict): + async def update_stats(self, guild_id: int, sheet_id: str, stats: dict) -> bool: spreadsheet = await self.get_sheet_for_guild(guild_id, sheet_id) if not spreadsheet: - return + return False try: sheet = spreadsheet.worksheet("Stats") @@ -401,15 +409,17 @@ async def update_stats(self, guild_id: int, sheet_id: str, stats: dict): ]) # type: ignore self._auto_resize_columns(spreadsheet, sheet, 2) + return True except Exception as e: logger.error(f"Failed to update stats for guild {guild_id}: {e}") + return False - async def full_sync(self, db_manager, guild_id: int): + async def full_sync(self, db_manager, guild_id: int) -> bool: settings = await db_manager.get_guild_settings(guild_id) if not settings or not settings.google_sheet_id: logger.warning(f"No Google Sheet configured for guild {guild_id}") - return + return False logger.info(f"Starting full Google Sheets sync for guild {guild_id}...") @@ -427,9 +437,9 @@ async def full_sync(self, db_manager, guild_id: int): items_map = {item.id: item.item_name for item in items} - await self.sync_items(guild_id, settings.google_sheet_id, items, usernames) - await self.sync_checkouts(guild_id, settings.google_sheet_id, checkouts, items_map, usernames) - await self.sync_audit_log(guild_id, settings.google_sheet_id, audit_logs, usernames) + success = await self.sync_items(guild_id, settings.google_sheet_id, items, usernames) + success |= await self.sync_checkouts(guild_id, settings.google_sheet_id, checkouts, items_map, usernames) + success |= await self.sync_audit_log(guild_id, settings.google_sheet_id, audit_logs, usernames) total_qty = sum(item.quantity_total for item in items) checked_out_qty = sum(item.quantity_checked_out for item in items) @@ -441,9 +451,13 @@ async def full_sync(self, db_manager, guild_id: int): "active_checkouts": len(checkouts), "utilization_rate": (checked_out_qty / total_qty * 100) if total_qty else 0, } - await self.update_stats(guild_id, settings.google_sheet_id, stats) + success |= await self.update_stats(guild_id, settings.google_sheet_id, stats) - logger.info("Google Sheets full sync complete") + if not success: + logger.info("Google Sheets full sync complete") + return False + + return True def _get_column_letter(n: int):