Last active
August 6, 2023 06:47
-
-
Save ckruse/d09910083f06b764eb8203d3bc04af65 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub async fn create_mention( | |
source_url: String, | |
target_url: String, | |
object_type: &str, | |
id: i32, | |
author: String, | |
title: String, | |
conn: &mut PgConnection, | |
) -> Result<Mention, sqlx::Error> { | |
let now = chrono::Utc::now().naive_utc(); | |
let mut data = NewMention { | |
source_url, | |
target_url, | |
author, | |
title, | |
mention_type: "TODO:".to_owned(), | |
inserted_at: Some(now), | |
updated_at: Some(now), | |
..Default::default() | |
}; | |
match object_type { | |
"note" => { | |
data.note_id = Some(id); | |
} | |
"picture" => { | |
data.picture_id = Some(id); | |
} | |
"article" => { | |
data.article_id = Some(id); | |
} | |
_ => {} | |
}; | |
query_as!( | |
Mention, | |
r#" | |
INSERT INTO mentions (source_url, target_url, author, title, mention_type, inserted_at, updated_at, note_id, picture_id, article_id) | |
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) | |
RETURNING * | |
"#, | |
data.source_url, | |
data.target_url, | |
data.author, | |
data.title, | |
data.mention_type, | |
data.inserted_at, | |
data.updated_at, | |
data.note_id, | |
data.picture_id, | |
data.article_id | |
) | |
.fetch_one(conn) | |
.await | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
error[E0277]: the trait bound `fn(axum::extract::State<AppState>, axum::Form<MentionValues>) -> impl Future<Output = Result<impl IntoResponse, AppError>> {receive_webmention}: Handler<_, _, _>` is not satisfied | |
--> src/webmentions.rs:19:36 | |
| | |
19 | app.route("/webmentions", post(receive_webmention)) | |
| ---- ^^^^^^^^^^^^^^^^^^ the trait `Handler<_, _, _>` is not implemented for fn item `fn(axum::extract::State<AppState>, axum::Form<MentionValues>) -> impl Future<Output = Result<impl IntoResponse, AppError>> {receive_webmention}` | |
| | | |
| required by a bound introduced by this call | |
| | |
= help: the following other types implement trait `Handler<T, S, B>`: | |
<MethodRouter<S, B> as Handler<(), S, B>> | |
<axum::handler::Layered<L, H, T, S, B, B2> as Handler<T, S, B2>> | |
<axum_extra::handler::IntoHandler<H, T, S, B> as Handler<T, S, B>> | |
<axum_extra::handler::or::Or<L, R, Lt, Rt, S, B> as Handler<(M, Lt, Rt), S, B>> | |
note: required by a bound in `post` | |
--> /Users/ckruse/.cargo/registry/src/index.crates.io-6f17d22bba15001f/axum-0.6.19/src/routing/method_routing.rs:407:1 | |
| | |
407 | top_level_handler_fn!(post, POST); | |
| ^^^^^^^^^^^^^^^^^^^^^^----^^^^^^^ | |
| | | | |
| | required by a bound in this function | |
| required by this bound in `post` | |
= note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use axum::{ | |
extract::{Form, State}, | |
response::IntoResponse, | |
routing::post, | |
}; | |
use serde::{Deserialize, Serialize}; | |
use url::Url; | |
use visdom::{types::IAttrValue, Vis}; | |
use self::actions::{create_mention, mention_exists, target_exists}; | |
use crate::{errors::AppError, uri_helpers::root_uri, AppRouter, AppState}; | |
pub mod actions; | |
pub mod send; | |
mod mail_sender; | |
pub fn configure(app: AppRouter) -> AppRouter { | |
app.route("/webmentions", post(receive_webmention)) | |
} | |
#[derive(Deserialize, Serialize, Debug, Clone, Default)] | |
pub struct MentionValues { | |
pub source: String, | |
pub target: String, | |
} | |
pub async fn receive_webmention( | |
State(state): State<AppState>, | |
Form(values): Form<MentionValues>, | |
) -> Result<impl IntoResponse, AppError> { | |
let mut conn = state.pool.acquire().await?; | |
let root_url = Url::parse(&root_uri()).unwrap(); | |
let source_url = | |
Url::parse(&values.source).map_err(|_| AppError::InternalError("source url invalid".to_owned()))?; | |
let target_url = | |
Url::parse(&values.target).map_err(|_| AppError::InternalError("target url invalid".to_owned()))?; | |
if target_url.host_str() != root_url.host_str() { | |
return Err(AppError::BadRequest("target url invalid".to_owned())); | |
} | |
let (object_type, id) = target_exists(&target_url, &mut conn) | |
.await | |
.unwrap_or_else(|| ("".to_owned(), 0)); | |
let surl = source_url.to_string(); | |
let body = reqwest::get(surl) | |
.await | |
.map_err(|e| AppError::InternalError(format!("request error: {}", e)))? | |
.text() | |
.await | |
.map_err(|e| AppError::InternalError(format!("request error: {}", e)))?; | |
if !body.contains(&target_url.to_string()) { | |
return Err(AppError::BadRequest("source url invalid".to_owned())); | |
} | |
let mention_exists = mention_exists(source_url.as_ref(), target_url.as_ref(), &mut conn).await; | |
if mention_exists { | |
return Ok("OK"); | |
} | |
let tree = Vis::load(&body).map_err(|_| AppError::BadRequest("could not parse source document".to_owned()))?; | |
let title = tree.find("title").text(); | |
let author = match tree.find("meta[name=author]").attr("content") { | |
Some(IAttrValue::Value(author, _)) => author, | |
_ => "unknown".to_owned(), | |
}; | |
// | |
// commenting this out fixes the compile error | |
// | |
let mention = create_mention( | |
source_url.to_string(), | |
target_url.to_string(), | |
&object_type, | |
id, | |
author, | |
title, | |
&mut conn, | |
) | |
.await?; | |
if source_url.host() != root_url.host() { | |
tokio::task::spawn_blocking(move || mail_sender::send_mail(mention)); | |
} | |
Ok("OK") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment