Skip to content

Commit

Permalink
WIP: web: implement search history
Browse files Browse the repository at this point in the history
Signed-off-by: Manos Pitsidianakis <[email protected]>
  • Loading branch information
epilys committed Dec 26, 2023
1 parent 88c5874 commit b537f22
Show file tree
Hide file tree
Showing 14 changed files with 327 additions and 71 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ http = "0.2"
indexmap = { version = "1.9" }
lazy_static = "^1.4"
mailpot = { version = "^0.1", path = "../core" }
minijinja = { version = "0.31.0", features = ["source", ] }
minijinja = { version = "0.31.0", features = ["source", "builtins", "json"] }
percent-encoding = { version = "^2.1" }
rand = { version = "^0.8", features = ["min_const_gen"] }
serde = { version = "^1", features = ["derive", ] }
Expand Down
2 changes: 1 addition & 1 deletion web/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ pub use cal::{calendarize, *};
pub use help::*;
pub use lists::{
list, list_candidates, list_edit, list_edit_POST, list_post, list_post_eml, list_post_raw,
list_subscribers, PostPolicySettings, SubscriptionPolicySettings,
list_search_query_GET, list_subscribers, PostPolicySettings, SubscriptionPolicySettings,
};
pub use minijinja_utils::*;
pub use settings::{
Expand Down
81 changes: 47 additions & 34 deletions web/src/lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ pub async fn list(
};
let post_policy = db.list_post_policy(list.pk)?;
let subscription_policy = db.list_subscription_policy(list.pk)?;
let months = db.months(list.pk)?;
let mut months = db.months(list.pk)?;
months.sort();
let user_context = auth
.current_user
.as_ref()
Expand All @@ -52,7 +53,7 @@ pub async fn list(
.iter()
.map(|p| (p.message_id.as_str(), p))
.collect::<IndexMap<&str, &mailpot::models::DbVal<mailpot::models::Post>>>();
let mut hist = months
let mut hists = months
.iter()
.map(|m| (m.to_string(), [0usize; 31]))
.collect::<HashMap<String, [usize; 31]>>();
Expand All @@ -79,7 +80,7 @@ pub async fn list(
.ok()
.map(|d| d.day())
{
hist.get_mut(&post.month_year).unwrap()[day.saturating_sub(1) as usize] += 1;
hists.get_mut(&post.month_year).unwrap()[day.saturating_sub(1) as usize] += 1;
}
let envelope = melib::Envelope::from_bytes(post.message.as_slice(), None)
.expect("Could not parse mail");
Expand Down Expand Up @@ -108,19 +109,21 @@ pub async fn list(
ret
})
.collect::<Vec<_>>();
let crumbs = vec![
Crumb {
label: "Home".into(),
url: "/".into(),
},
Crumb {
label: list.name.clone().into(),
url: ListPath(list.id.to_string().into()).to_crumb(),
},
];

let crumbs = crumbs![Crumb {
label: list.name.clone().into(),
url: ListPath(list.id.to_string().into()).to_crumb(),
},];
let list_owners = db.list_owners(list.pk)?;
let mut list_obj = MailingList::from(list.clone());
list_obj.set_safety(list_owners.as_slice(), &state.conf.administrators);
let has_more_months = if months.len() > 2 {
let len = months.len();
months.drain(0..(len - 2));
true
} else {
false
};
let context = minijinja::context! {
canonical_url => ListPath::from(&list).to_crumb(),
page_title => &list.name,
Expand All @@ -129,7 +132,8 @@ pub async fn list(
subscription_policy,
preamble => true,
months,
hists => &hist,
has_more_months,
hists,
posts => posts_ctx,
list => Value::from_object(list_obj),
current_user => auth.current_user,
Expand Down Expand Up @@ -185,11 +189,7 @@ pub async fn list_post(
{
subject_ref = subject_ref[2 + list.id.len()..].trim();
}
let crumbs = vec![
Crumb {
label: "Home".into(),
url: "/".into(),
},
let crumbs = crumbs![
Crumb {
label: list.name.clone().into(),
url: ListPath(list.id.to_string().into()).to_crumb(),
Expand Down Expand Up @@ -294,11 +294,7 @@ pub async fn list_edit(
.unwrap_or(0)
};

let crumbs = vec![
Crumb {
label: "Home".into(),
url: "/".into(),
},
let crumbs = crumbs![
Crumb {
label: list.name.clone().into(),
url: ListPath(list.id.to_string().into()).to_crumb(),
Expand Down Expand Up @@ -673,11 +669,7 @@ pub async fn list_subscribers(
ret
};

let crumbs = vec![
Crumb {
label: "Home".into(),
url: "/".into(),
},
let crumbs = crumbs![
Crumb {
label: list.name.clone().into(),
url: ListPath(list.id.to_string().into()).to_crumb(),
Expand Down Expand Up @@ -761,11 +753,7 @@ pub async fn list_candidates(
ret
};

let crumbs = vec![
Crumb {
label: "Home".into(),
url: "/".into(),
},
let crumbs = crumbs![
Crumb {
label: list.name.clone().into(),
url: ListPath(list.id.to_string().into()).to_crumb(),
Expand Down Expand Up @@ -796,3 +784,28 @@ pub async fn list_candidates(
.render(context)?,
))
}

/// Mailing list post search.
#[allow(non_snake_case)]
pub async fn list_search_query_GET(
ListSearchPath(id): ListSearchPath,
//mut session: WritableSession,
Query(query): Query<DateQueryParameter>,
//auth: AuthContext,
State(state): State<Arc<AppState>>,
) -> Result<Html<String>, ResponseError> {
let db = Connection::open_db(state.conf.clone())?.trusted();
let Some(_list) = (match id {
ListPathIdentifier::Pk(id) => db.list(id)?,
ListPathIdentifier::Id(id) => db.list_by_id(id)?,
}) else {
return Err(ResponseError::new(
"List not found".to_string(),
StatusCode::NOT_FOUND,
));
};
Err(ResponseError::new(
format!("{:#?}", query),
StatusCode::NOT_IMPLEMENTED,
))
}
1 change: 1 addition & 0 deletions web/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ fn create_app(shared_state: Arc<AppState>) -> Router {
.typed_get(list_post_raw)
.typed_get(list_topics)
.typed_get(list_post_eml)
.typed_get(list_search_query_GET)
.typed_get(list_edit.layer(RequireAuth::login_with_role_or_redirect(
Role::User..,
Arc::clone(&login_url),
Expand Down
17 changes: 11 additions & 6 deletions web/src/minijinja_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,16 @@ lazy_static::lazy_static! {
settings_path,
help_path,
list_path,
list_calendar_path,
list_search_query,
list_settings_path,
list_edit_path,
list_subscribers_path,
list_candidates_path,
list_post_path,
post_raw_path,
post_eml_path
post_eml_path,
year_month_to_query,
);
add!(filter pluralize);
// Load compressed templates. They are constructed in build.rs. See
Expand Down Expand Up @@ -243,31 +246,33 @@ pub fn calendarize(
}
}};
}
let month = args.as_str().unwrap();
let year_month = args.as_str().unwrap();
let hist = hists
.get_item(&Value::from(month))?
.get_item(&Value::from(year_month))?
.as_seq()
.unwrap()
.iter()
.map(|v| usize::try_from(v).unwrap())
.collect::<Vec<usize>>();
let sum: usize = hists
.get_item(&Value::from(month))?
.get_item(&Value::from(year_month))?
.as_seq()
.unwrap()
.iter()
.map(|v| usize::try_from(v).unwrap())
.sum();
let date = chrono::NaiveDate::parse_from_str(&format!("{}-01", month), "%F").unwrap();
let date = chrono::NaiveDate::parse_from_str(&format!("{}-01", year_month), "%F").unwrap();
// Week = [Mon, Tue, Wed, Thu, Fri, Sat, Sun]
Ok(minijinja::context! {
date,
month_name => month!(date.month()),
month => month,
month => year_month,
month_int => date.month() as usize,
year => date.year(),
weeks => cal::calendarize_with_offset(date, 1),
hist => hist,
sum,
unknown => date.year() == 1970,
})
}

Expand Down
9 changes: 6 additions & 3 deletions web/src/templates/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
{% if c.sum > 0 %}
<table>
<caption align="top">
<!--<a href="{{ root_url_prefix|safe }}/list/{{pk}}/{{ c.month }}">-->
<a href="#" style="color: GrayText;">
{{ c.month_name }} {{ c.year }}
<a href="{{ list_search_query(list.id) }}?month={{ year_month_to_query(date) }}" style="color: GrayText;">
{% if c.unknown %}
Unknown
{% else %}
{{ c.month_name }} {{ c.year }}
{% endif %}
</a>
</caption>
<thead>
Expand Down
22 changes: 10 additions & 12 deletions web/src/templates/css.html
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@
code {
font-family: var(--monospace-system-stack);
overflow-wrap: anywhere;
background: var(--color-tan);
color: black;
border-radius: 4px;
padding-left: 4px;
padding-right: 4px;
}

pre {
Expand Down Expand Up @@ -162,6 +167,7 @@
--code-background: #8fbcbb;
--a-visited-text: var(--a-normal-text);
--tag-border-color: black;
--color-tan: #fef6e9;
}

@media (prefers-color-scheme: light) {
Expand Down Expand Up @@ -445,18 +451,6 @@
font-size: small;
}

/* If only the root crumb is visible, hide it to avoid unnecessary visual clutter */
li.crumb:only-child>span[aria-current="page"] {
--secs: 150ms;
transition: all var(--secs) linear;
color: transparent;
}

li.crumb:only-child>span[aria-current="page"]:hover {
transition: all var(--secs) linear;
color: revert;
}

.crumb, .crumb>a {
display: inline;
}
Expand Down Expand Up @@ -595,6 +589,10 @@
opacity: 0.2;
}

div.calendar a {
place-self: center;
}

div.calendar {
display: flex;
flex-wrap: wrap;
Expand Down
2 changes: 1 addition & 1 deletion web/src/templates/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ <h1>{{ site_title }}</h1>
{% endif %}
{% include "menu.html" %}
<div class="page-header">
{% if crumbs|length > 1 %}<nav aria-labelledby="breadcrumb-menu" class="breadcrumbs">
{% if crumbs|length > 0 %}<nav aria-labelledby="breadcrumb-menu" class="breadcrumbs">
<ol id="breadcrumb-menu" role="menu" aria-label="Breadcrumb menu">{% for crumb in crumbs %}<li class="crumb" aria-describedby="bread_{{ loop.index }}">{% if loop.last %}<span role="menuitem" id="bread_{{ loop.index }}" aria-current="page" title="current page">{{ crumb.label }}</span>{% else %}<a role="menuitem" id="bread_{{ loop.index }}" href="{{ urlize(crumb.url) }}" tabindex="0">{{ crumb.label }}</a>{% endif %}</li>{% endfor %}</ol>
</nav>{% endif %}
{% if page_title %}
Expand Down
3 changes: 3 additions & 0 deletions web/src/templates/lists/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@
{{ heading(3, "Calendar") }}
<div class="calendar">
{%- from "calendar.html" import cal %}
{% if has_more_months %}
<a href="{{ list_calendar_path(list.id) }}">See all history..&mldr;</a>
{% endif %}
{% for date in months %}
{{ cal(date, hists) }}
{% endfor %}
Expand Down
2 changes: 1 addition & 1 deletion web/src/templates/topics.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% include "header.html" %}
<div class="body">
<p style="margin-block-end: 1rem;">Results for <em>{{ term }}</em></p>
{% if term %}<p style="margin-block-end: 1rem;">Results for <em>{{ term }}</em></p>{% endif %}
<div class="entry">
<dl class="lists" aria-label="list of mailing lists">
{% for list in results %}
Expand Down
21 changes: 10 additions & 11 deletions web/src/topics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,21 +127,20 @@ pub async fn list_topics(
}
};

let crumbs = vec![
Crumb {
label: "Home".into(),
url: "/".into(),
},
Crumb {
label: "Search for topics".into(),
url: TopicsPath.to_crumb(),
},
];
let crumbs = crumbs![Crumb {
label: if term.is_some() {
"Search for topics"
} else {
"Topics"
}
.into(),
url: TopicsPath.to_crumb(),
},];
let context = minijinja::context! {
canonical_url => TopicsPath.to_crumb(),
term,
results,
page_title => "Topic Search Results",
page_title => if term.is_some() { "Topic Search Results" } else { "Topics" },
description => "",
current_user => auth.current_user,
messages => session.drain_messages(),
Expand Down
Loading

0 comments on commit b537f22

Please sign in to comment.