♻️ update
This commit is contained in:
parent
9f95060806
commit
e9d9ac4d9a
4 changed files with 55 additions and 22 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -202,7 +202,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "based"
|
name = "based"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.hydrar.de/jmarya/based?branch=ui#519c2d3e28040601ac37812c9882e54532036b53"
|
source = "git+https://git.hydrar.de/jmarya/based?branch=ui#069a293e78cfdcda7be8413c25557c9592dbbc9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|
|
@ -300,13 +300,26 @@ pub async fn index_document(doc: &Document) {
|
||||||
pub struct DocumentIndex {}
|
pub struct DocumentIndex {}
|
||||||
|
|
||||||
impl DocumentIndex {
|
impl DocumentIndex {
|
||||||
pub async fn get_documents_of_day(day: NaiveDate) -> HashMap<String, Vec<String>> {
|
pub async fn get_documents_of_day(
|
||||||
let res: Vec<(String, String)> =
|
day: NaiveDate,
|
||||||
|
domain: Option<&str>,
|
||||||
|
) -> HashMap<String, Vec<String>> {
|
||||||
|
let res: Vec<(String, String)> = if let Some(domain) = domain {
|
||||||
|
sqlx::query_as(
|
||||||
|
"SELECT domain, path FROM document_index WHERE version = $1 WHERE domain = $2",
|
||||||
|
)
|
||||||
|
.bind(day)
|
||||||
|
.bind(domain)
|
||||||
|
.fetch_all(get_pg!())
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
} else {
|
||||||
sqlx::query_as("SELECT domain, path FROM document_index WHERE version = $1")
|
sqlx::query_as("SELECT domain, path FROM document_index WHERE version = $1")
|
||||||
.bind(day)
|
.bind(day)
|
||||||
.fetch_all(get_pg!())
|
.fetch_all(get_pg!())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
let mut ret = HashMap::new();
|
let mut ret = HashMap::new();
|
||||||
|
|
||||||
|
|
|
@ -183,14 +183,11 @@ pub fn get_shell() -> Shell {
|
||||||
Shell::new(
|
Shell::new(
|
||||||
Nothing(),
|
Nothing(),
|
||||||
Nothing(),
|
Nothing(),
|
||||||
Background(MinHeight(
|
Background(MinHeight(ScreenValue::screen, Text("").white())).color(Zinc::_950),
|
||||||
ScreenValue::screen,
|
|
||||||
Padding(Text("").white()).top(ScreenValue::_8),
|
|
||||||
))
|
|
||||||
.color(Zinc::_950),
|
|
||||||
)
|
)
|
||||||
.use_ui()
|
.use_ui()
|
||||||
.with_navbar(NavBar("Web Archive"))
|
.with_navbar(NavBar("Web Archive"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : archive cleanup code
|
// TODO : archive cleanup code
|
||||||
|
// TODO : archive pkg code -> tar.gz
|
||||||
|
|
|
@ -8,7 +8,7 @@ use based::{
|
||||||
},
|
},
|
||||||
ui::{
|
ui::{
|
||||||
components::{
|
components::{
|
||||||
prelude::{InfinityScroll, Timeline, TimelineElement},
|
prelude::{InfinityScroll, Timeline, TimelineElement, Tooltip},
|
||||||
ColoredSpinner, Search, Shell,
|
ColoredSpinner, Search, Shell,
|
||||||
},
|
},
|
||||||
primitives::flex::Column,
|
primitives::flex::Column,
|
||||||
|
@ -34,6 +34,7 @@ use webarc::{
|
||||||
|
|
||||||
const SEARCH_BAR_STYLE: &str = "w-full px-4 mb-4 py-2 text-white bg-black border-2 border-neon-blue placeholder-neon-blue focus:ring-2 focus:ring-neon-pink focus:outline-none font-mono text-lg";
|
const SEARCH_BAR_STYLE: &str = "w-full px-4 mb-4 py-2 text-white bg-black border-2 border-neon-blue placeholder-neon-blue focus:ring-2 focus:ring-neon-pink focus:outline-none font-mono text-lg";
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
pub fn WebsiteIcon(domain: &str) -> PreEscaped<String> {
|
pub fn WebsiteIcon(domain: &str) -> PreEscaped<String> {
|
||||||
html! {
|
html! {
|
||||||
h2 class="text-xl font-bold mb-4 -ml-2 flex items-center w-fit" {
|
h2 class="text-xl font-bold mb-4 -ml-2 flex items-center w-fit" {
|
||||||
|
@ -43,6 +44,25 @@ pub fn WebsiteIcon(domain: &str) -> PreEscaped<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn time_ago(naive_datetime: &chrono::NaiveDate) -> String {
|
||||||
|
let now = chrono::Local::now().date_naive();
|
||||||
|
let duration = now.signed_duration_since(*naive_datetime);
|
||||||
|
|
||||||
|
if duration.num_seconds() < 60 {
|
||||||
|
format!("{} seconds ago", duration.num_seconds())
|
||||||
|
} else if duration.num_minutes() < 60 {
|
||||||
|
format!("{} minutes ago", duration.num_minutes())
|
||||||
|
} else if duration.num_hours() < 24 {
|
||||||
|
format!("{} hours ago", duration.num_hours())
|
||||||
|
} else if duration.num_days() < 30 {
|
||||||
|
format!("{} days ago", duration.num_days())
|
||||||
|
} else if duration.num_days() < 365 {
|
||||||
|
format!("{} months ago", duration.num_days() / 30)
|
||||||
|
} else {
|
||||||
|
format!("{} years ago", duration.num_days() / 365)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build_timeline(
|
pub fn build_timeline(
|
||||||
domains: HashMap<String, Vec<String>>,
|
domains: HashMap<String, Vec<String>>,
|
||||||
the_day: NaiveDate,
|
the_day: NaiveDate,
|
||||||
|
@ -58,7 +78,7 @@ pub fn build_timeline(
|
||||||
for key in sorted_keys {
|
for key in sorted_keys {
|
||||||
let (domain, paths) = (key, domains.get(key).unwrap());
|
let (domain, paths) = (key, domains.get(key).unwrap());
|
||||||
tl = tl.add_element(TimelineElement::new(
|
tl = tl.add_element(TimelineElement::new(
|
||||||
&the_day.to_string(),
|
Tooltip(time_ago(&the_day), Text(&the_day.to_string())),
|
||||||
WebsiteIcon(domain),
|
WebsiteIcon(domain),
|
||||||
Column(
|
Column(
|
||||||
paths
|
paths
|
||||||
|
@ -82,18 +102,19 @@ pub fn build_timeline(
|
||||||
tl.render_with_class("")
|
tl.render_with_class("")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_domains(before: &str) -> HashMap<String, Vec<String>> {
|
pub async fn get_domains(before: &str, domain: Option<&str>) -> HashMap<String, Vec<String>> {
|
||||||
let today = NaiveDate::parse_from_str(before, "%Y-%m-%d").unwrap();
|
let today = NaiveDate::parse_from_str(before, "%Y-%m-%d").unwrap();
|
||||||
DocumentIndex::get_documents_of_day(today).await
|
DocumentIndex::get_documents_of_day(today, domain).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_domains_lookback(
|
pub async fn get_domains_lookback(
|
||||||
before: &str,
|
before: &str,
|
||||||
mut days: u64,
|
mut days: u64,
|
||||||
|
domain: Option<&str>,
|
||||||
) -> (HashMap<String, Vec<String>>, NaiveDate) {
|
) -> (HashMap<String, Vec<String>>, NaiveDate) {
|
||||||
let mut the_day = NaiveDate::parse_from_str(before, "%Y-%m-%d").unwrap();
|
let mut the_day = NaiveDate::parse_from_str(before, "%Y-%m-%d").unwrap();
|
||||||
while days > 0 {
|
while days > 0 {
|
||||||
let domains = get_domains(&the_day.to_string()).await;
|
let domains = get_domains(&the_day.to_string(), domain).await;
|
||||||
|
|
||||||
if !domains.is_empty() {
|
if !domains.is_empty() {
|
||||||
return (domains, the_day);
|
return (domains, the_day);
|
||||||
|
@ -106,18 +127,19 @@ pub async fn get_domains_lookback(
|
||||||
(HashMap::new(), the_day)
|
(HashMap::new(), the_day)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/timeline?<before>")]
|
#[get("/timeline?<before>&<domain>")]
|
||||||
pub async fn timeline_route(
|
pub async fn timeline_route(
|
||||||
ctx: RequestContext,
|
ctx: RequestContext,
|
||||||
shell: &State<Shell>,
|
shell: &State<Shell>,
|
||||||
before: Option<&str>,
|
before: Option<&str>,
|
||||||
|
domain: Option<&str>,
|
||||||
) -> StringResponse {
|
) -> StringResponse {
|
||||||
let today = chrono::Local::now().date_naive();
|
let today = chrono::Local::now().date_naive();
|
||||||
|
|
||||||
let (domains, day) = if let Some(before) = before {
|
let (domains, day) = if let Some(before) = before {
|
||||||
get_domains_lookback(before, 30 * 12).await
|
get_domains_lookback(before, 30 * 12, domain).await
|
||||||
} else {
|
} else {
|
||||||
get_domains_lookback(&today.to_string(), 30 * 12).await
|
get_domains_lookback(&today.to_string(), 30 * 12, domain).await
|
||||||
};
|
};
|
||||||
|
|
||||||
if domains.is_empty() {
|
if domains.is_empty() {
|
||||||
|
@ -382,7 +404,7 @@ pub async fn render_website(
|
||||||
|
|
||||||
if time.is_none() {
|
if time.is_none() {
|
||||||
let versions = document.versions();
|
let versions = document.versions();
|
||||||
let latest_version = versions.first()?;
|
if let Some(latest_version) = versions.first() {
|
||||||
if let Some(outdated) = get_config().get_outdated(domain) {
|
if let Some(outdated) = get_config().get_outdated(domain) {
|
||||||
if is_older_than(latest_version, outdated) {
|
if is_older_than(latest_version, outdated) {
|
||||||
log::info!("Document {domain} / {path} is outdated, redownloading");
|
log::info!("Document {domain} / {path} is outdated, redownloading");
|
||||||
|
@ -390,6 +412,7 @@ pub async fn render_website(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let content = document
|
let content = document
|
||||||
.render_local(time.map(|time| time.to_string()), &shell)
|
.render_local(time.map(|time| time.to_string()), &shell)
|
||||||
|
|
Loading…
Add table
Reference in a new issue