Refactor routes

This commit is contained in:
Leonora Tindall 2022-11-01 13:57:33 -05:00
parent 01fd48e9ca
commit bd012f491a
Signed by: nora
GPG Key ID: 7A8B52EC67E09AAF
1 changed files with 94 additions and 109 deletions

View File

@ -61,74 +61,21 @@ enum ErrorResponse {
InternalError(String), InternalError(String),
} }
#[get("/<project>/feed.rss?<page>")] async fn get_page_data(
async fn syndication_rss_route( client: &mut Client,
project: &str, project_id: &str,
page: Option<u64>, page: u64,
) -> Result<RssResponse, ErrorResponse> { ) -> Result<CohostPostsPage, ErrorResponse> {
let page = page.unwrap_or(0); let posts_url = cohost_posts_api_url(project_id, page);
let project_url = format!("{}{}", COHOST_ACCOUNT_API_URL, project);
let posts_url = cohost_posts_api_url(project, page);
let client = match Client::builder().user_agent(user_agent()).build() {
Ok(v) => v,
Err(e) => {
let err = format!("Couldn't build a reqwest client: {:?}", e);
eprintln!("{}", err);
return Err(ErrorResponse::InternalError(err));
}
};
eprintln!("making request to {}", project_url);
let project_data: CohostAccount = match client.get(project_url).send().await {
Ok(v) => match v.status() {
StatusCode::OK => match v.json::<CohostAccount>().await {
Ok(a) => a,
Err(e) => {
let err = format!("Couldn't deserialize Cohost project '{}': {:?}", project, e);
eprintln!("{}", err);
return Err(ErrorResponse::InternalError(err));
}
},
// TODO NORA: Handle possible redirects
s => {
let err = format!(
"Didn't receive status code 200 for Cohost project '{}'; got {:?} instead.",
project, s
);
eprintln!("{}", err);
return Err(ErrorResponse::NotFound(err));
}
},
Err(e) => {
let err = format!(
"Error making request to Cohost for project '{}': {:?}",
project, e
);
eprintln!("{}", err);
return Err(ErrorResponse::InternalError(err));
}
};
eprintln!("making request to {}", posts_url); eprintln!("making request to {}", posts_url);
match client.get(posts_url).send().await { match client.get(posts_url).send().await {
Ok(v) => match v.status() { Ok(v) => match v.status() {
StatusCode::OK => match v.json::<CohostPostsPage>().await { StatusCode::OK => match v.json::<CohostPostsPage>().await {
Ok(page_data) => { Ok(page_data) => Ok(page_data),
return Ok(RssResponse {
inner: syndication::channel_for_posts_page(
project,
page,
project_data,
page_data,
)
.to_string(),
});
}
Err(e) => { Err(e) => {
let err = format!( let err = format!(
"Couldn't deserialize Cohost posts page for '{}': {:?}", "Couldn't deserialize Cohost posts page for '{}': {:?}",
project, e project_id, e
); );
eprintln!("{}", err); eprintln!("{}", err);
return Err(ErrorResponse::InternalError(err)); return Err(ErrorResponse::InternalError(err));
@ -144,66 +91,104 @@ async fn syndication_rss_route(
Err(e) => { Err(e) => {
let err = format!( let err = format!(
"Error making request to Cohost for posts for project '{}': {:?}", "Error making request to Cohost for posts for project '{}': {:?}",
project, e project_id, e
); );
eprintln!("{}", err); eprintln!("{}", err);
return Err(ErrorResponse::InternalError(err)); return Err(ErrorResponse::InternalError(err));
} }
}; }
} }
#[get("/.well-known/webfinger?<params..>")] #[get("/<project>/feed.rss?<page>")]
async fn webfinger_route(params: HashMap<String, String>) -> Option<Json<CohostWebfingerResource>> { async fn syndication_rss_route(
if params.len() != 1 { project: &str,
eprintln!( page: Option<u64>,
"Too may or too few parameters. Expected 1, got {}", ) -> Result<RssResponse, ErrorResponse> {
params.len() let page = page.unwrap_or(0);
); let mut client = get_client()?;
return None;
let project_data = get_project_data(&mut client, project).await?;
let page_data = get_page_data(&mut client, project, page).await?;
Ok(RssResponse {
inner: syndication::channel_for_posts_page(project, page, project_data, page_data)
.to_string(),
})
} }
let client = match Client::builder().user_agent(user_agent()).build() {
Ok(v) => v, async fn get_project_data(
Err(e) => { client: &mut Client,
let err = format!("Couldn't build a reqwest client: {:?}", e); project_id: &str,
eprintln!("{}", err); ) -> Result<CohostAccount, ErrorResponse> {
return None; let project_url = format!("{}{}", COHOST_ACCOUNT_API_URL, project_id);
} eprintln!("making request to {}", project_url);
}; match client.get(project_url).send().await {
if let Some(param) = params.iter().next() { Ok(v) => match v.status() {
let url = format!("{}{}", COHOST_ACCOUNT_API_URL, param.0);
eprintln!("making request to {}", url);
match client.get(url).send().await {
Ok(v) => {
match v.status() {
StatusCode::OK => match v.json::<CohostAccount>().await { StatusCode::OK => match v.json::<CohostAccount>().await {
Ok(_v) => { Ok(a) => Ok(a),
return Some(Json(CohostWebfingerResource::new(
param.0.as_str(),
&ARGS.domain,
&ARGS.base_url,
)));
}
Err(e) => { Err(e) => {
eprintln!("Couldn't deserialize Cohost project '{}': {:?}", param.0, e); let err = format!(
"Couldn't deserialize Cohost project '{}': {:?}",
project_id, e
);
eprintln!("{}", err);
Err(ErrorResponse::InternalError(err))
} }
}, },
// TODO NORA: Handle possible redirects // TODO NORA: Handle possible redirects
s => { s => {
eprintln!("Didn't receive status code 200 for Cohost project '{}'; got {:?} instead.", param.0, s); let err = format!(
return None; "Didn't receive status code 200 for Cohost project '{}'; got {:?} instead.",
} project_id, s
}
}
Err(e) => {
eprintln!(
"Error making request to Cohost for project '{}': {:?}",
param.0, e
); );
return None; eprintln!("{}", err);
Err(ErrorResponse::NotFound(err))
} }
}; },
Err(e) => {
let err = format!(
"Error making request to Cohost for project '{}': {:?}",
project_id, e
);
eprintln!("{}", err);
Err(ErrorResponse::InternalError(err))
}
}
}
fn get_client() -> Result<Client, ErrorResponse> {
match Client::builder().user_agent(user_agent()).build() {
Ok(v) => Ok(v),
Err(e) => {
let err = format!("Couldn't build a reqwest client: {:?}", e);
eprintln!("{}", err);
Err(ErrorResponse::InternalError(err))
}
}
}
#[get("/.well-known/webfinger?<params..>")]
async fn webfinger_route(
params: HashMap<String, String>,
) -> Result<Json<CohostWebfingerResource>, ErrorResponse> {
if params.len() != 1 {
let err = format!(
"Too may or too few parameters. Expected 1, got {}",
params.len()
);
eprintln!("{}", err);
return Err(ErrorResponse::InternalError(err));
}
let mut client = get_client()?;
if let Some(param) = params.iter().next() {
let _project_data = get_project_data(&mut client, param.0.as_str()).await?;
Ok(Json(CohostWebfingerResource::new(
param.0.as_str(),
&ARGS.domain,
&ARGS.base_url,
)))
} else {
Err(ErrorResponse::NotFound("No project ID provided.".into()))
} }
None
} }
#[rocket::main] #[rocket::main]