This commit is contained in:
parent
907ed2a2ef
commit
3e9808db80
4 changed files with 106 additions and 6 deletions
|
@ -35,3 +35,14 @@ pub async fn get_fragments_of_domain(domain: &str) -> Vec<(String, String)> {
|
|||
|
||||
res.into_iter().map(|x| (x.0, x.1)).collect()
|
||||
}
|
||||
|
||||
pub async fn get_domains_of_fragment(fragment: &str) -> Vec<(String, String, chrono::NaiveDate)> {
|
||||
let res: Vec<(String, String, chrono::NaiveDate)> =
|
||||
sqlx::query_as("SELECT domain, path, version FROM document_fragments WHERE fragment = $1")
|
||||
.bind(fragment)
|
||||
.fetch_all(get_pg!())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
res.into_iter().map(|x| (x.0, x.1, x.2)).collect()
|
||||
}
|
||||
|
|
|
@ -62,7 +62,8 @@ async fn main() {
|
|||
pages::fragment_get,
|
||||
pages::mime_overview,
|
||||
pages::fragments_overview,
|
||||
pages::fragments_domain_overview
|
||||
pages::fragments_domain_overview,
|
||||
pages::fragment_overview
|
||||
],
|
||||
)
|
||||
.manage(arc)
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::{collections::HashMap, io::Read, path::PathBuf, sync::Arc};
|
|||
|
||||
use based::ui::components::prelude::*;
|
||||
use based::ui::prelude::*;
|
||||
use based::ui::primitives::div::Center;
|
||||
use based::{
|
||||
page,
|
||||
request::{
|
||||
|
@ -14,6 +15,7 @@ use based::{
|
|||
use chrono::NaiveDate;
|
||||
use itertools::Itertools;
|
||||
use maud::{html, PreEscaped};
|
||||
use regex::Regex;
|
||||
use rocket::response::Redirect;
|
||||
use rocket::{get, request::FromSegments, State};
|
||||
|
||||
|
@ -22,8 +24,8 @@ use component::*;
|
|||
use serde_json::json;
|
||||
|
||||
use webarc::archive::{
|
||||
domain_has_fragments, get_fragment, get_fragments_of_domain, get_random_fragment_id,
|
||||
internalize_urls, Document, DocumentIndex,
|
||||
domain_has_fragments, get_domains_of_fragment, get_fragment, get_fragments_of_domain,
|
||||
get_random_fragment_id, internalize_urls, Document, DocumentIndex,
|
||||
};
|
||||
use webarc::get_mime_type;
|
||||
use webarc::{
|
||||
|
@ -448,6 +450,17 @@ pub async fn render_website(
|
|||
.as_bytes()
|
||||
.to_vec();
|
||||
}
|
||||
|
||||
// TODO : Fix
|
||||
// This will work if the `Content-Security-Policy` meta tag gets removed from the document
|
||||
// -> Migrate to HTML parser
|
||||
|
||||
/*
|
||||
content = replace_data_urls(
|
||||
&String::from_utf8_lossy(&content),
|
||||
"http://127.0.0.1:8000"
|
||||
).as_bytes().to_vec();
|
||||
*/
|
||||
}
|
||||
|
||||
return Some(DataResponse::new(content, mime, Some(60 * 60 * 24)));
|
||||
|
@ -458,6 +471,24 @@ pub async fn render_website(
|
|||
None
|
||||
}
|
||||
|
||||
pub fn replace_data_urls(input: &str, root: &str) -> String {
|
||||
let data_url_pattern = r#"data:([a-zA-Z0-9]+/[a-zA-Z0-9.+-]+);base64,([a-zA-Z0-9+/=]+)"#;
|
||||
let re_data = Regex::new(data_url_pattern).unwrap();
|
||||
|
||||
re_data
|
||||
.replace_all(input, |caps: ®ex::Captures| {
|
||||
let encoded_data = caps.get(2).unwrap().as_str();
|
||||
|
||||
if let Ok(decoded) = base64::decode(encoded_data) {
|
||||
let hash = webarc::sha256_hash(&decoded);
|
||||
format!("{root}/f/{hash}")
|
||||
} else {
|
||||
caps[0].to_string()
|
||||
}
|
||||
})
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn gen_search_element(x: &SearchResult) -> PreEscaped<String> {
|
||||
html! {
|
||||
div class="text-xl font-bold mt-4 p-4 flex items-center w-full max-w-4xl max-h-40 mx-auto bg-neutral-800 shadow-md rounded-lg overflow-hidden border border-neutral-900 hover:cursor-pointer"
|
||||
|
@ -646,6 +677,60 @@ pub async fn mime_overview(
|
|||
)
|
||||
}
|
||||
|
||||
#[get("/fragment/<fragment>")]
|
||||
pub async fn fragment_overview(
|
||||
fragment: &str,
|
||||
ctx: RequestContext,
|
||||
shell: &State<Shell>,
|
||||
) -> Option<StringResponse> {
|
||||
let fragment_info = get_fragment(fragment).await?;
|
||||
|
||||
let docs = get_domains_of_fragment(fragment).await;
|
||||
|
||||
let content = Margin(
|
||||
Column(vec![
|
||||
Center(Card(
|
||||
Row(vec![
|
||||
Text(fragment).render(),
|
||||
Rounded(
|
||||
Padding(
|
||||
Background(Text(&fragment_info.1).bold().black().xs())
|
||||
.color(Colors::White),
|
||||
)
|
||||
.all(ScreenValue::_2),
|
||||
)
|
||||
.render(),
|
||||
Link(&format!("/f/{fragment}"), Button("Raw")).render(),
|
||||
])
|
||||
.gap(ScreenValue::_4)
|
||||
.items_center(),
|
||||
))
|
||||
.render(),
|
||||
Center(Card(
|
||||
UnorderedList()
|
||||
.push(Text("Referenced on:").bold()._2xl())
|
||||
.push_for_each(&docs, |(domain, path, _): &_| {
|
||||
Link(
|
||||
&format!("/d/{domain}/{path}"),
|
||||
Row(vec![
|
||||
favicon(domain),
|
||||
Text(domain).render(),
|
||||
Text(path).render(),
|
||||
])
|
||||
.items_center(),
|
||||
)
|
||||
}),
|
||||
))
|
||||
.render(),
|
||||
])
|
||||
.gap(ScreenValue::_4),
|
||||
)
|
||||
.top(ScreenValue::_4)
|
||||
.render();
|
||||
|
||||
Some(page!(shell, ctx, "Fragment", content))
|
||||
}
|
||||
|
||||
#[get("/fragments/<domain>")]
|
||||
pub async fn fragments_domain_overview(
|
||||
domain: &str,
|
||||
|
@ -659,12 +744,15 @@ pub async fn fragments_domain_overview(
|
|||
.into_iter()
|
||||
.map(|(fragment, mime)| {
|
||||
if mime.starts_with("image") {
|
||||
return Card(Image(&format!("/f/{fragment}")).height(128).width(128));
|
||||
return Card(Link(
|
||||
&format!("/fragment/{fragment}"),
|
||||
Image(&format!("/f/{fragment}")).height(128).width(128),
|
||||
));
|
||||
}
|
||||
|
||||
Card(
|
||||
Tooltip(
|
||||
Link(&format!("/f/{fragment}"), Text(&fragment)),
|
||||
Link(&format!("/fragment/{fragment}"), Text(&fragment)),
|
||||
Text(&mime),
|
||||
)
|
||||
.white(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue