feat: deploy infrastructure + disk/drive, calendar, presentation, workspaces, onboarding, demo user
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
"""Calendar service — unified interface for Google, Yandex, Apple CalDAV.
|
||||
|
||||
Manages calendar provider connections and event creation.
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Any, Optional
|
||||
from uuid import UUID
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models.user import User
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CALENDAR_PROVIDERS = ("google", "yandex", "apple")
|
||||
|
||||
|
||||
class CalendarService:
|
||||
def __init__(self, db: AsyncSession):
|
||||
self.db = db
|
||||
|
||||
async def get_calendar_credentials(self, user: User) -> Optional[dict[str, Any]]:
|
||||
"""Get stored calendar credentials for user."""
|
||||
if not hasattr(user, "calendar_provider") or not user.calendar_provider:
|
||||
return None
|
||||
if not hasattr(user, "calendar_credentials") or not user.calendar_credentials:
|
||||
return None
|
||||
try:
|
||||
return json.loads(user.calendar_credentials)
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
return None
|
||||
|
||||
async def set_calendar_credentials(
|
||||
self, user: User, provider: str, credentials: dict[str, Any]
|
||||
) -> None:
|
||||
user.calendar_provider = provider
|
||||
user.calendar_credentials = json.dumps(credentials)
|
||||
await self.db.commit()
|
||||
|
||||
async def disconnect_calendar(self, user: User) -> None:
|
||||
user.calendar_provider = None
|
||||
user.calendar_credentials = None
|
||||
await self.db.commit()
|
||||
|
||||
def _get_client(self, provider: str, credentials: dict[str, Any]):
|
||||
"""Get appropriate calendar client for provider."""
|
||||
if provider == "google":
|
||||
from app.integrations.calendar.google_calendar import GoogleCalendarClient
|
||||
return GoogleCalendarClient(access_token=credentials.get("access_token", ""))
|
||||
elif provider == "yandex":
|
||||
from app.integrations.calendar.yandex_calendar import YandexCalendarClient
|
||||
return YandexCalendarClient(access_token=credentials.get("access_token", ""))
|
||||
elif provider == "apple":
|
||||
from app.integrations.calendar.apple_caldav import AppleCalDavStub
|
||||
return AppleCalDavStub()
|
||||
raise ValueError(f"Unknown calendar provider: {provider}")
|
||||
|
||||
async def create_idea_event(self, user: User, idea_title: str, idea_content: str) -> bool:
|
||||
"""Create a calendar event from an idea."""
|
||||
creds = await self.get_calendar_credentials(user)
|
||||
if not creds:
|
||||
logger.warning("No calendar credentials for user %s", user.id)
|
||||
return False
|
||||
|
||||
provider = user.calendar_provider
|
||||
if not provider:
|
||||
return False
|
||||
|
||||
client = self._get_client(provider, creds)
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
start_iso = now.isoformat()
|
||||
end_iso = (now + timedelta(hours=1)).isoformat()
|
||||
|
||||
return await client.create_event(
|
||||
summary=f"Idea: {idea_title[:100]}",
|
||||
description=idea_content[:1000],
|
||||
start_iso=start_iso,
|
||||
end_iso=end_iso,
|
||||
)
|
||||
|
||||
async def list_events(self, user: User, max_results: int = 10) -> list[dict]:
|
||||
creds = await self.get_calendar_credentials(user)
|
||||
if not creds or not user.calendar_provider:
|
||||
return []
|
||||
|
||||
client = self._get_client(user.calendar_provider, creds)
|
||||
return await client.list_events(max_results=max_results)
|
||||
|
||||
async def health_check(self, user: User) -> bool:
|
||||
creds = await self.get_calendar_credentials(user)
|
||||
if not creds or not user.calendar_provider:
|
||||
return False
|
||||
try:
|
||||
client = self._get_client(user.calendar_provider, creds)
|
||||
return await client.health_check()
|
||||
except Exception:
|
||||
return False
|
||||
Reference in New Issue
Block a user