Skip to content

Commit

Permalink
Refactored the calendar to refresh continuously
Browse files Browse the repository at this point in the history
  • Loading branch information
CommanderStorm committed May 9, 2024
1 parent a9227ce commit ec353a9
Show file tree
Hide file tree
Showing 15 changed files with 124 additions and 185 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions server/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions server/main-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ actix-governor = { version = "0.5.0", features = ["logger"] }
# proposing feedback
tempfile = "3.10.1"
base64 = "0.22.1"
time = "0.3.36"

[dev-dependencies]
pretty_assertions = "1.4.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,31 @@ use std::{env, io};

use cached::instant::Instant;
use chrono::{DateTime, Utc};
use log::{debug, error, info, warn};
use log::{debug, error, warn};
use oauth2::basic::{BasicClient, BasicTokenResponse};
use oauth2::reqwest::async_http_client;
use oauth2::url::Url;
use oauth2::{AuthUrl, ClientId, ClientSecret, Scope, TokenResponse, TokenUrl};
use sqlx::PgPool;

use crate::calendar::fetch::CalendarEntryFetcher;
use crate::calendar::models::Event;

pub(super) struct APIRequestor {
pub(in crate::calendar) struct APIRequestor {
client: reqwest::Client,
pool: PgPool,
}

impl CalendarEntryFetcher for APIRequestor {
fn new(pool: &PgPool, _: &Option<DateTime<Utc>>) -> Self {
impl From<&PgPool> for APIRequestor {
fn from(pool: &PgPool) -> Self {
Self {
client: reqwest::Client::new(),
pool: pool.clone(),
}
}
async fn fetch(
&self,
id: &str,
start_after: &DateTime<Utc>,
end_before: &DateTime<Utc>,
) -> Result<super::CalendarEntries, crate::BoxedError> {
}

impl APIRequestor {
pub(crate) async fn refresh(&self, id: &str) -> Result<(), crate::BoxedError> {
let sync_start = Utc::now();
let start = Instant::now();
// Make OAuth2 secured request
Expand All @@ -39,8 +36,8 @@ impl CalendarEntryFetcher for APIRequestor {
.access_token()
.secret()
.clone();
let url = format!("https://campus.tum.de/tumonline/co/connectum/api/rooms/{id}/calendars");

let url = format!("https://campus.tum.de/tumonline/co/connectum/api/rooms/{id}/calendars");
let events: Vec<Event> = self
.client
.get(url)
Expand All @@ -49,7 +46,7 @@ impl CalendarEntryFetcher for APIRequestor {
.await?
.json()
.await?;
info!(
debug!(
"finished fetching for {id}: {cnt} calendar events in {elapsed:?}",
cnt = events.len(),
elapsed = start.elapsed()
Expand All @@ -62,11 +59,7 @@ impl CalendarEntryFetcher for APIRequestor {
})
.collect::<Vec<Event>>();
self.store(&events, &sync_start, id).await?;
let events = events
.into_iter()
.filter(|e| *start_after <= e.start_at && *end_before >= e.end_at)
.collect();
Ok((sync_start, events))
Ok(())
}
}

Expand Down
35 changes: 0 additions & 35 deletions server/main-api/src/calendar/fetch/db.rs

This file was deleted.

108 changes: 0 additions & 108 deletions server/main-api/src/calendar/fetch/mod.rs

This file was deleted.

50 changes: 33 additions & 17 deletions server/main-api/src/calendar/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@ use log::error;
use serde::Deserialize;
use sqlx::PgPool;

use crate::calendar::models::Event;
use crate::models::Location;

mod fetch;
mod connectum;
mod models;

async fn get_location(pool: &PgPool, id: &str) -> Result<Option<Location>, sqlx::Error> {
sqlx::query_as!(Location, "SELECT * FROM de WHERE key = $1", id)
.fetch_optional(pool)
.await
}
pub mod refresh;

#[derive(Deserialize, Debug)]
pub struct QueryArguments {
Expand All @@ -36,7 +32,7 @@ pub async fn calendar_handler(
Err(e) => {
error!("could not refetch due to {e:?}");
return HttpResponse::InternalServerError()
.body("could not get calendar entrys, please try again later");
.body("could not get calendar entries, please try again later");
}
Ok(None) => {
return HttpResponse::NotFound()
Expand All @@ -50,17 +46,37 @@ pub async fn calendar_handler(
.content_type("text/plain")
.body("Room does not have a calendar");
};
let fetching_strategy =
fetch::StrategyExecutor::new(&data.db, &id, &args.start_after, &args.end_before);
match fetching_strategy
.exec_with_retrying(&location.last_calendar_scrape_at)
.await
{
Ok((last_sync, events)) => HttpResponse::Ok().json(models::Events {
match get_from_db(&data.db, &id, &args.start_after, &args.end_before).await {
Ok(events) => HttpResponse::Ok().json(models::Events {
events,
last_sync,
last_sync: location.last_calendar_scrape_at.unwrap(),
calendar_url,
}),
Err(resp) => resp,
Err(e) => {
error!("could not get entries from the db for {id} because {e:?}");
HttpResponse::InternalServerError()
.body("could not get calendar entries, please try again later")
}
}
}

async fn get_location(pool: &PgPool, id: &str) -> Result<Option<Location>, sqlx::Error> {
sqlx::query_as!(Location, "SELECT * FROM de WHERE key = $1", id)
.fetch_optional(pool)
.await
}

async fn get_from_db(
pool: &PgPool,
id: &str,
start_after: &DateTime<Utc>,
end_before: &DateTime<Utc>,
) -> Result<Vec<Event>, crate::BoxedError> {
let events = sqlx::query_as!(Event, r#"SELECT id,room_code,start_at,end_at,stp_title_de,stp_title_en,stp_type,entry_type AS "entry_type!:crate::calendar::models::EventType",detailed_entry_type
FROM calendar
WHERE room_code = $1 AND start_at >= $2 AND end_at <= $3"#,
id, start_after, end_before)
.fetch_all(pool)
.await?;
Ok(events)
}
Loading

0 comments on commit ec353a9

Please sign in to comment.