update formatting
restructure project add cancellation token to cancel mcp server collection from serving
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
use tracing::Level;
|
||||
use chrono::{Duration, Local};
|
||||
use crate::caldav::client::{
|
||||
AuthorizedCaldavClient, find_calendars, get_caldav_client, get_components, upload_components,
|
||||
};
|
||||
use crate::caldav::event::McpEvent;
|
||||
use crate::caldav::todo::McpTodo;
|
||||
use crate::server_handler::{
|
||||
McpServerHandler, McpServerHandlerError, get_additional_property, get_property_as_string,
|
||||
};
|
||||
use chrono::{Duration, Local};
|
||||
use http::Uri;
|
||||
use icalendar::{Event, EventLike, Todo};
|
||||
use libdav::dav::FoundCollection;
|
||||
@@ -19,7 +19,7 @@ use serde::Deserialize;
|
||||
use std::str::FromStr;
|
||||
use toml::Value;
|
||||
use toml::map::Map;
|
||||
use crate::caldav::event::McpEvent;
|
||||
use tracing::Level;
|
||||
|
||||
mod client;
|
||||
mod datetime_conversion;
|
||||
@@ -193,8 +193,11 @@ impl CalDavHandler {
|
||||
}
|
||||
|
||||
#[tool(description = "gets events of next 7 days")]
|
||||
async fn get_upcoming_events(&self, parameters: Parameters<GetCalendarComponentParameters>) -> Result<CallToolResult, ErrorData> {
|
||||
const DAYS_DELTA: Duration = Duration::days(7);
|
||||
async fn get_upcoming_events(
|
||||
&self,
|
||||
parameters: Parameters<GetCalendarComponentParameters>,
|
||||
) -> Result<CallToolResult, ErrorData> {
|
||||
const DAYS_DELTA: Duration = Duration::days(7);
|
||||
const RECURRENCE_LIMIT: u16 = 10;
|
||||
|
||||
let calendar = self.get_calendar_by_name(parameters.0.calendar_name)?;
|
||||
@@ -203,7 +206,7 @@ impl CalDavHandler {
|
||||
let mut events: Vec<McpEvent> = Vec::new();
|
||||
|
||||
for component in components {
|
||||
if let Some(event_component) = component.as_event() {
|
||||
if let Some(event_component) = component.as_event() {
|
||||
let event: McpEvent = event_component.clone().try_into()?;
|
||||
|
||||
let lower_bound = Local::now().with_timezone(&icalendar::Tz::Local(Local));
|
||||
@@ -212,28 +215,37 @@ impl CalDavHandler {
|
||||
|
||||
match recurrence {
|
||||
Ok(recurrence) => {
|
||||
let recurrence_result = recurrence.after(lower_bound).before(upper_bound).all(RECURRENCE_LIMIT);
|
||||
let recurrence_result = recurrence
|
||||
.after(lower_bound)
|
||||
.before(upper_bound)
|
||||
.all(RECURRENCE_LIMIT);
|
||||
|
||||
for date in recurrence_result.dates {
|
||||
let mut event_instance = event.clone();
|
||||
event_instance.start = Some(date.with_timezone(&Local{}));
|
||||
event_instance.start = Some(date.with_timezone(&Local {}));
|
||||
|
||||
if let Some(start) = event.start && let Some(end) = event.end {
|
||||
let event_duration = end-start;
|
||||
event_instance.end = Some(event_instance.start.unwrap() + event_duration);
|
||||
if let Some(start) = event.start
|
||||
&& let Some(end) = event.end
|
||||
{
|
||||
let event_duration = end - start;
|
||||
event_instance.end =
|
||||
Some(event_instance.start.unwrap() + event_duration);
|
||||
}
|
||||
|
||||
events.push(event_instance);
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::event!(Level::INFO, "recurrence error occured. Event '{event:?}' is ignored: {error}");
|
||||
tracing::event!(
|
||||
Level::INFO,
|
||||
"recurrence error occured. Event '{event:?}' is ignored: {error}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events.sort_by_key(|event|event.start);
|
||||
events.sort_by_key(|event| event.start);
|
||||
|
||||
Ok(CallToolResult::structured(serde_json::json!(events)))
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ use axum::Router;
|
||||
use axum::response::Json;
|
||||
use own_assist_common::exit_msg;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::select;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{Level, event};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
@@ -58,7 +60,7 @@ fn bind_address_format(url: url::Url) -> String {
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn serve(config: Config) {
|
||||
pub async fn serve(config: Config) -> CancellationToken {
|
||||
let routes = Json(
|
||||
config
|
||||
.servers
|
||||
@@ -84,12 +86,17 @@ pub async fn serve(config: Config) {
|
||||
.inspect_err(exit_msg!("Error bind tcp listener: {e:#?}"))
|
||||
.unwrap();
|
||||
|
||||
let ct = tokio_util::sync::CancellationToken::new();
|
||||
let cancellation_token = CancellationToken::new();
|
||||
let cloned_cancellation_token = cancellation_token.clone();
|
||||
|
||||
let _ = axum::serve(tcp_listener, router)
|
||||
.with_graceful_shutdown(async move {
|
||||
tokio::signal::ctrl_c().await.unwrap();
|
||||
ct.cancel();
|
||||
select! {
|
||||
_ = cloned_cancellation_token.cancelled() => (),
|
||||
_ = tokio::signal::ctrl_c() => (),
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
||||
cancellation_token
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use mcp_server_collection::config::Config;
|
||||
use mcp_server_collection::serve;
|
||||
use own_assist_common::{exit_msg, init_tracing_subscriber};
|
||||
use tokio::main;
|
||||
use tokio::{main};
|
||||
|
||||
#[main]
|
||||
async fn main() {
|
||||
|
||||
Reference in New Issue
Block a user