Skip to content

Commit

Permalink
init streams
Browse files Browse the repository at this point in the history
  • Loading branch information
drewvolz committed Jan 24, 2025
1 parent 1a64d63 commit 6b2c5b6
Show file tree
Hide file tree
Showing 10 changed files with 315 additions and 1 deletion.
114 changes: 114 additions & 0 deletions 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 ccc-handlers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ thiserror = { version = "2.0.0" }
tracing = "0.1.40"
serde_urlencoded = "0.7.1"
phf = { version = "0.11.2", features = ["macros"] }
chrono = { version = "0.4", features = ["serde"] }
1 change: 1 addition & 0 deletions ccc-handlers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

pub mod bonapp;
pub mod github;
pub mod streams;
158 changes: 158 additions & 0 deletions ccc-handlers/src/streams.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
use axum::{
extract::Query,
response::{IntoResponse, Json, Response},
routing::get,
Router,
};
use chrono::{Duration, Utc};
use http::StatusCode;
use serde::{Deserialize, Serialize};
use tracing::instrument;

#[derive(Debug, Deserialize)]
pub struct StreamParams {
#[serde(default)]
date_from: String,
#[serde(default)]
date_to: String,
#[serde(default = "default_sort")]
sort: String,
}

fn default_sort() -> String {
"ascending".to_string()
}

#[derive(Debug, Serialize)]
enum QueryClass {
Archived,
Upcoming,
}

impl std::fmt::Display for QueryClass {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
QueryClass::Archived => write!(f, "archived"),
QueryClass::Upcoming => write!(f, "current"),
}
}
}

use QueryClass::*;

#[inline]
const fn get_query_base_url_and_entity(query_class: &QueryClass) -> (&str, &str) {
match query_class {
QueryClass::Archived => (
"https://www.stolaf.edu/multimedia/api/collection",
"archived",
),
QueryClass::Upcoming => (
"https://www.stolaf.edu/multimedia/api/collection",
"current",
),
}
}

#[instrument]
async fn send_proxied_query<T>(
query_class: QueryClass,
date_from: &str,
date_to: &str,
sort: &str,
) -> Result<Json<T>, StreamProxyError>
where
T: serde::de::DeserializeOwned,
{
tracing::debug!(
sort,
date_to,
date_from,
?query_class,
"handling proxied Stream request"
);

let (base_url, class) = get_query_base_url_and_entity(&query_class);
let query_type = query_class.to_string();

let request = ccc_proxy::global_proxy()
.client()
.get(base_url)
.query(&[
("class", query_type.as_str()),
("date_from", date_from),
("date_to", date_to),
("sort", sort),
])
.build()
.map_err(ccc_proxy::ProxyError::ProxiedRequest)
.map_err(StreamProxyError::GenericProxy)?;

ccc_proxy::global_proxy()
.send_request_parse_json::<T>(request)
.await
.map(Json)
.map_err(StreamProxyError::GenericProxy)
}

#[instrument(skip(date_from_fn, date_to_fn))]
async fn handle_stream_request(
params: StreamParams,
date_from_fn: impl Fn(chrono::DateTime<Utc>) -> chrono::DateTime<Utc>,
date_to_fn: impl Fn(chrono::DateTime<Utc>) -> chrono::DateTime<Utc>,
query_class: QueryClass,
) -> Result<Json<ccc_types::streams::StreamResponse>, StreamProxyError> {
let now = Utc::now();

let date_from = (!params.date_from.is_empty())
.then(|| params.date_from.clone())
.unwrap_or_else(|| date_from_fn(now).format("%Y-%m-%d").to_string());

let date_to = (!params.date_to.is_empty())
.then(|| params.date_to.clone())
.unwrap_or_else(|| date_to_fn(now).format("%Y-%m-%d").to_string());

send_proxied_query(query_class, &date_from, &date_to, &params.sort).await
}

#[instrument]
pub async fn upcoming_handler(
Query(params): Query<StreamParams>,
) -> Result<Json<ccc_types::streams::StreamResponse>, StreamProxyError> {
handle_stream_request(
params,
|now| now,
|now| now + Duration::days(60),
QueryClass::Upcoming,
)
.await
}

#[instrument]
pub async fn archived_handler(
Query(params): Query<StreamParams>,
) -> Result<Json<ccc_types::streams::StreamResponse>, StreamProxyError> {
handle_stream_request(
params,
|now| now - Duration::days(60),
|now| now,
QueryClass::Archived,
)
.await
}

#[derive(thiserror::Error, Debug)]
pub enum StreamProxyError {
#[error("error from generic proxy: {0}")]
GenericProxy(ccc_proxy::ProxyError),
}

impl IntoResponse for StreamProxyError {
fn into_response(self) -> Response {
let text = self.to_string();
Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(text.into())
.unwrap()
}
}
1 change: 1 addition & 0 deletions ccc-routes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod faqs;
pub mod food;
pub mod printing;
pub mod spaces;
pub mod streams;
pub mod tools;
pub mod transit;
pub mod webcams;
8 changes: 8 additions & 0 deletions ccc-routes/src/streams.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use axum::{routing::get, Router};
use ccc_handlers::streams::{archived_handler, upcoming_handler};

pub fn router() -> Router {
Router::new()
.route("/archived", get(archived_handler))
.route("/upcoming", get(upcoming_handler))
}
1 change: 1 addition & 0 deletions ccc-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ fn init_router() -> Router {
.nest("/food", ccc_routes::food::router())
.nest("/printing", ccc_routes::printing::router())
.nest("/spaces", ccc_routes::spaces::router())
.nest("/streams", ccc_routes::streams::router())
.nest("/tools", ccc_routes::tools::router())
.nest("/transit", ccc_routes::transit::router())
.nest("/webcams", ccc_routes::webcams::router());
Expand Down
4 changes: 3 additions & 1 deletion ccc-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ publish = false
[dependencies]
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114"
ts-rs = {version = "10.0.0" }
ts-rs = { version = "10.0.0" }
chrono = { version = "0.4", features = ["serde"] }
time = { version = "0.3.37" }
1 change: 1 addition & 0 deletions ccc-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod faqs;
pub mod food;
pub mod printing;
pub mod spaces;
pub mod streams;
pub mod tools;
pub mod transit;
pub mod webcams;
Loading

0 comments on commit 6b2c5b6

Please sign in to comment.