Parametr select u vypisu, telo udalosti v calendarView

- calendar/view: include_body a body_type (html, text), telo udalosti
  rovnou ve vypisu bez dalsiho volani
- select u vypisu mailu, udalosti, calendarView, jedne udalosti a skupin;
  nahrazuje vychozi sadu poli
- app/graph_fields.py: vychozi sady a seznamy dostupnych poli, Swagger
  je zobrazuje v popisu parametru
- README: endpointy, popis select, zaznam zmen
This commit is contained in:
JiriUhlir
2026-09-23 06:51:05 +02:00
parent d80193da8b
commit fb97a8bf63
4 changed files with 121 additions and 24 deletions
+28 -13
View File
@@ -6,6 +6,7 @@ from urllib.parse import quote
from fastapi import HTTPException, status
from .graph_client import MicrosoftGraphClient
from .graph_fields import EVENT_DEFAULT_SELECT, GROUP_DEFAULT_SELECT, MESSAGE_DEFAULT_SELECT
from .schemas import (
CalendarEventRequest,
CalendarEventUpdateRequest,
@@ -45,11 +46,13 @@ class MailService:
def __init__(self, graph: MicrosoftGraphClient) -> None:
self._graph = graph
async def list_messages(self, user_id: str, folder: str = "Inbox", top: int = 25) -> Any:
async def list_messages(
self, user_id: str, folder: str = "Inbox", top: int = 25, select: str | None = None
) -> Any:
params = {
"$top": top,
"$orderby": "receivedDateTime desc",
"$select": "id,subject,from,toRecipients,receivedDateTime,hasAttachments,isRead,webLink",
"$select": select or MESSAGE_DEFAULT_SELECT,
}
return await self._graph.request(
"GET",
@@ -82,9 +85,12 @@ class MailService:
)
CALENDAR_EVENT_SELECT = (
"id,subject,start,end,location,attendees,webLink,isOnlineMeeting,onlineMeeting,showAs,isCancelled,organizer"
)
def _with_body(select: str) -> str:
fields = [f.strip() for f in select.split(",") if f.strip()]
for extra in ("body", "bodyPreview"):
if extra not in fields:
fields.append(extra)
return ",".join(fields)
class CalendarService:
@@ -95,11 +101,11 @@ class CalendarService:
"""Default calendar of the mailbox (id, name, owner). Cheapest read-only access check."""
return await self._graph.request("GET", f"/users/{graph_segment(user_id)}/calendar")
async def list_events(self, user_id: str, top: int = 25) -> Any:
async def list_events(self, user_id: str, top: int = 25, select: str | None = None) -> Any:
params = {
"$top": top,
"$orderby": "start/dateTime",
"$select": CALENDAR_EVENT_SELECT,
"$select": select or EVENT_DEFAULT_SELECT,
}
return await self._graph.request("GET", f"/users/{graph_segment(user_id)}/events", params=params)
@@ -110,15 +116,24 @@ class CalendarService:
end: str,
top: int = 25,
time_zone: str | None = None,
include_body: bool = False,
body_type: str = "html",
select: str | None = None,
) -> Any:
fields = select or EVENT_DEFAULT_SELECT
params = {
"startDateTime": start,
"endDateTime": end,
"$top": top,
"$orderby": "start/dateTime",
"$select": CALENDAR_EVENT_SELECT,
"$select": _with_body(fields) if include_body else fields,
}
headers = {"Prefer": f'outlook.timezone="{time_zone}"'} if time_zone else None
prefer: list[str] = []
if time_zone:
prefer.append(f'outlook.timezone="{time_zone}"')
if include_body:
prefer.append(f'outlook.body-content-type="{body_type}"')
headers = {"Prefer": ", ".join(prefer)} if prefer else None
return await self._graph.request(
"GET",
f"/users/{graph_segment(user_id)}/calendarView",
@@ -133,11 +148,11 @@ class CalendarService:
json=request.as_graph_payload(),
)
async def get_event(self, user_id: str, event_id: str) -> Any:
async def get_event(self, user_id: str, event_id: str, select: str | None = None) -> Any:
return await self._graph.request(
"GET",
f"/users/{graph_segment(user_id)}/events/{graph_segment(event_id)}",
params={"$select": CALENDAR_EVENT_SELECT + ",body"},
params={"$select": select or _with_body(EVENT_DEFAULT_SELECT)},
)
async def update_event(self, user_id: str, event_id: str, request: CalendarEventUpdateRequest) -> Any:
@@ -264,8 +279,8 @@ class GroupsService:
def __init__(self, graph: MicrosoftGraphClient) -> None:
self._graph = graph
async def list_groups(self, top: int = 25) -> Any:
params = {"$top": top, "$select": "id,displayName,mail,groupTypes,securityEnabled,mailEnabled"}
async def list_groups(self, top: int = 25, select: str | None = None) -> Any:
params = {"$top": top, "$select": select or GROUP_DEFAULT_SELECT}
return await self._graph.request("GET", "/groups", params=params)
async def list_team_channels(self, team_id: str) -> Any: