Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 29 additions & 15 deletions app/sheets/sheets_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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")

Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand All @@ -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")
Expand All @@ -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}...")

Expand All @@ -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)
Expand All @@ -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):
Expand Down
Loading