use a user-defined list for links shortcut in contact page
All checks were successful
ci/woodpecker/push/publish Pipeline was successful
All checks were successful
ci/woodpecker/push/publish Pipeline was successful
This commit is contained in:
parent
19136f6c81
commit
a43d84de06
1 changed files with 62 additions and 35 deletions
|
@ -2,6 +2,7 @@ use actix_web::{get, routes, web, HttpRequest, HttpResponse, Responder};
|
||||||
use cached::proc_macro::once;
|
use cached::proc_macro::once;
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
use ramhorns::Content;
|
use ramhorns::Content;
|
||||||
|
use std::fs::read_to_string;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
|
@ -32,49 +33,75 @@ async fn page(req: HttpRequest, config: web::Data<Config>) -> impl Responder {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct ContactLink {
|
||||||
|
service: String,
|
||||||
|
scope: Option<String>,
|
||||||
|
link: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[once(time = 60)]
|
||||||
|
fn find_links() -> Vec<ContactLink> {
|
||||||
|
// TOML file location
|
||||||
|
let contacts_dir = "data/contacts";
|
||||||
|
let toml_file = "links.toml";
|
||||||
|
|
||||||
|
// Read the TOML file and parse it
|
||||||
|
let toml_str = read_to_string(format!("{contacts_dir}/{toml_file}")).unwrap_or_default();
|
||||||
|
|
||||||
|
let mut redirections = vec![];
|
||||||
|
match toml::de::from_str::<toml::Value>(&toml_str) {
|
||||||
|
Ok(data) => {
|
||||||
|
if let Some(section) = data.as_table() {
|
||||||
|
section.iter().for_each(|(key, value)| {
|
||||||
|
// Scopes are delimited with `/`
|
||||||
|
let (service, scope) = match key.split_once('/') {
|
||||||
|
Some((service, scope)) => (service.to_owned(), Some(scope.to_owned())),
|
||||||
|
None => (key.to_owned(), None),
|
||||||
|
};
|
||||||
|
|
||||||
|
redirections.push(ContactLink {
|
||||||
|
service,
|
||||||
|
scope,
|
||||||
|
link: value.as_str().unwrap().to_owned(),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => return vec![],
|
||||||
|
}
|
||||||
|
|
||||||
|
redirections
|
||||||
|
}
|
||||||
|
|
||||||
#[routes]
|
#[routes]
|
||||||
#[get("/{service}")]
|
#[get("/{service}")]
|
||||||
#[get("/{service}/{scope}")]
|
#[get("/{service}/{scope}")]
|
||||||
async fn service_redirection(req: HttpRequest) -> impl Responder {
|
async fn service_redirection(req: HttpRequest) -> impl Responder {
|
||||||
let info = req.match_info();
|
let info = req.match_info();
|
||||||
let find_redirection = match info.query("service") {
|
let link = find_links()
|
||||||
// TODO: XML file with link, so it's not hardcoded here
|
.iter()
|
||||||
|
// Find requested service
|
||||||
|
.filter(|&x| x.service == *info.query("service"))
|
||||||
|
// Search for a potential scope
|
||||||
|
.filter(|&x| match (info.get("scope"), x.scope.to_owned()) {
|
||||||
|
// The right scope is accepted
|
||||||
|
(Some(str_value), Some(string_value)) if str_value == string_value.as_str() => true,
|
||||||
|
// No scope provided is accepted
|
||||||
|
(None, None) => true,
|
||||||
|
// Else we reject
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
// Returns the link
|
||||||
|
.map(|data| data.link.clone())
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
/* Socials links */
|
// This shouldn't be more than one link here
|
||||||
"twitter" => Some("https://twitter.com/Mylloon".to_owned()),
|
match link.len() {
|
||||||
"mastodon" => Some("https://piaille.fr/@mylloon".to_owned()),
|
|
||||||
"bluesky" => Some("https://bsky.app/profile/mylloon.fr".to_owned()),
|
|
||||||
"discord" => match info.get("scope") {
|
|
||||||
Some("user") => Some("https://discord.com/users/158260864623968257/".to_owned()),
|
|
||||||
Some("guild") => Some("https://discord.gg/Z5ePxH4".to_owned()),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
"reddit" => Some("https://www.reddit.com/user/mylloon".to_owned()),
|
|
||||||
"instagram" => Some("https://www.instagram.com/mylloon/".to_owned()),
|
|
||||||
"kitsu" => Some("https://kitsu.io/users/Mylloon/library?status=completed".to_owned()),
|
|
||||||
"steam" => Some("https://steamcommunity.com/id/mylloon/".to_owned()),
|
|
||||||
"youtube" => Some("https://www.youtube.com/c/Mylloon".to_owned()),
|
|
||||||
"twitch" => Some("https://www.twitch.tv/mylloon".to_owned()),
|
|
||||||
|
|
||||||
/* Forges */
|
|
||||||
"github" => Some("https://github.com/Mylloon".to_owned()),
|
|
||||||
"gitlab" => Some("https://gitlab.com/Mylloon".to_owned()),
|
|
||||||
"codeberg" => Some("https://codeberg.org/Mylloon".to_owned()),
|
|
||||||
"forgejo" => Some("https://git.mylloon.fr/Anri".to_owned()),
|
|
||||||
|
|
||||||
/* Others */
|
|
||||||
"keyoxide" => {
|
|
||||||
Some("https://keyoxide.org/27024A99057E58B8087A5022A82D63DFF8D1317F".to_owned())
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(redirection) = find_redirection {
|
|
||||||
// Redirect to the desired service
|
// Redirect to the desired service
|
||||||
actix_web::web::Redirect::to(redirection)
|
1 => actix_web::web::Redirect::to(link[0].clone()),
|
||||||
} else {
|
|
||||||
// By default, returns to the contact page
|
// By default, returns to the contact page
|
||||||
actix_web::web::Redirect::to("/contact")
|
_ => actix_web::web::Redirect::to("/contact"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue