feat(scraper): added search option
This commit is contained in:
parent
0b17c760cb
commit
ac98af1428
5 changed files with 77 additions and 3 deletions
|
|
@ -135,7 +135,7 @@ impl State {
|
|||
pub async fn get_user(
|
||||
&self,
|
||||
name: &str,
|
||||
) -> Result<Option<crate::types::Profile>, GetUserError> {
|
||||
) -> Result<Option<crate::types::Profile>, FetchJsonError> {
|
||||
let req = self.get(format!("/getuser/{name}"), None).await?;
|
||||
let text = req.text().await?;
|
||||
let json = serde_json::from_str::<crate::types::ProfileRaw>(&text)?;
|
||||
|
|
@ -204,10 +204,31 @@ impl State {
|
|||
self.get("/friends/", None).await?.text().await?,
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn search(
|
||||
&self,
|
||||
keyword: impl AsRef<str>,
|
||||
relation: i32,
|
||||
) -> Result<Option<Vec<crate::types::Search>>, FetchJsonError> {
|
||||
//search/<keyword>/<int:friends_only>
|
||||
let text = self
|
||||
.get(format!("/search/{}/{relation}", keyword.as_ref()), None)
|
||||
.await?
|
||||
.text()
|
||||
.await?;
|
||||
log::debug!("Search result => {text:?}");
|
||||
if text.is_empty() {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let ret = serde_json::from_str(&text)?;
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum GetUserError {
|
||||
pub enum FetchJsonError {
|
||||
#[error("RequestError: {0}")]
|
||||
RequestError(#[from] reqwest::Error),
|
||||
#[error("JsonError: {0}")]
|
||||
|
|
|
|||
|
|
@ -115,3 +115,13 @@ pub struct Profile {
|
|||
pub discord: Option<String>,
|
||||
pub github: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum Search {
|
||||
#[serde(rename = "project")]
|
||||
Project { v: SmolStr, s: SmolStr },
|
||||
|
||||
#[serde(rename = "user")]
|
||||
User { v: SmolStr, s: SmolStr },
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ impl GlobalState {
|
|||
) -> color_eyre::Result<Option<froxy_scraper::types::Profile>> {
|
||||
proxy::getuser(self, login).await
|
||||
}
|
||||
|
||||
pub async fn search(
|
||||
&self,
|
||||
keyword: String,
|
||||
friends_only: i32,
|
||||
) -> color_eyre::Result<Option<Vec<froxy_scraper::types::Search>>> {
|
||||
proxy::search(self, keyword, friends_only).await
|
||||
}
|
||||
}
|
||||
|
||||
impl GlobalState {}
|
||||
|
|
|
|||
|
|
@ -23,3 +23,18 @@ pub async fn getuser(
|
|||
) -> color_eyre::Result<Option<froxy_scraper::types::Profile>> {
|
||||
Ok(self_.scraper.get_user(login.as_str()).await?)
|
||||
}
|
||||
|
||||
#[cached(
|
||||
time = 3,
|
||||
size = 100,
|
||||
result = true,
|
||||
key = "(String, i32)",
|
||||
convert = "{ (keyword.clone(), friends_only) }"
|
||||
)]
|
||||
pub async fn search(
|
||||
self_: &GlobalState,
|
||||
keyword: String,
|
||||
friends_only: i32,
|
||||
) -> color_eyre::Result<Option<Vec<froxy_scraper::types::Search>>> {
|
||||
Ok(self_.scraper.search(keyword, friends_only).await?)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ use axum::{
|
|||
};
|
||||
|
||||
pub fn router() -> Router<crate::GlobalState> {
|
||||
Router::new().route("/getuser/{login}", get(getuser_handler))
|
||||
Router::new()
|
||||
.route("/getuser/{login}", get(getuser_handler))
|
||||
.route("/search/{keyword}/{friends_only}", get(search_handler))
|
||||
}
|
||||
|
||||
#[cfg_attr(debug_assertions, axum::debug_handler)]
|
||||
|
|
@ -22,3 +24,21 @@ async fn getuser_handler(
|
|||
.map_err(|()| StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.and_then(|o| o.ok_or(StatusCode::NOT_FOUND).map(Json))
|
||||
}
|
||||
|
||||
// /search/<keyword>/<int:friends_only>
|
||||
async fn search_handler(
|
||||
State(state): State<crate::GlobalState>,
|
||||
Path((keyword, friends_only)): Path<(String, i32)>,
|
||||
) -> Result<Json<Vec<froxy_scraper::types::Search>>, StatusCode> {
|
||||
log::info!(
|
||||
"Searching `{keyword}` (friends_only: {})",
|
||||
friends_only == 1,
|
||||
);
|
||||
state
|
||||
.search(keyword, friends_only)
|
||||
.await
|
||||
.map_err(crate::report_error)
|
||||
.map_err(|()| StatusCode::INTERNAL_SERVER_ERROR)?
|
||||
.ok_or(StatusCode::BAD_REQUEST)
|
||||
.map(Json)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue