Compare commits

...

3 Commits

Author SHA1 Message Date
89cb1e4e75 chore: Release
All checks were successful
Continuous integration / Check (push) Successful in 2m8s
Continuous integration / Test Suite (push) Successful in 2m10s
Continuous integration / Trunk (push) Successful in 1m18s
Continuous integration / Rustfmt (push) Successful in 52s
Continuous integration / build (push) Successful in 2m46s
Continuous integration / Disallow unused dependencies (push) Successful in 2m30s
2025-09-02 19:27:38 -07:00
46021c5d2c server: remove dupe and move code to more idomatic layout 2025-09-02 19:27:14 -07:00
4243f7b77d chore: Release 2025-09-02 19:25:24 -07:00
6 changed files with 88 additions and 97 deletions

52
Cargo.lock generated
View File

@ -3155,6 +3155,20 @@ dependencies = [
[[package]]
name = "letterbox-notmuch"
version = "0.17.38"
source = "sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/"
checksum = "30c0d92d929ce67e832d2dea079289b211dc79b4b138857518da2ce3cf50f53a"
dependencies = [
"log",
"mailparse",
"serde",
"serde_json",
"thiserror 2.0.16",
"tracing",
]
[[package]]
name = "letterbox-notmuch"
version = "0.17.40"
dependencies = [
"itertools",
"log",
@ -3167,28 +3181,14 @@ dependencies = [
"tracing",
]
[[package]]
name = "letterbox-notmuch"
version = "0.17.38"
source = "sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/"
checksum = "30c0d92d929ce67e832d2dea079289b211dc79b4b138857518da2ce3cf50f53a"
dependencies = [
"log",
"mailparse",
"serde",
"serde_json",
"thiserror 2.0.16",
"tracing",
]
[[package]]
name = "letterbox-procmail2notmuch"
version = "0.17.38"
version = "0.17.40"
dependencies = [
"anyhow",
"clap",
"letterbox-notmuch 0.17.38 (sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/)",
"letterbox-shared 0.17.38 (sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/)",
"letterbox-notmuch 0.17.38",
"letterbox-shared 0.17.38",
"serde",
"sqlx",
"tokio 1.47.1",
@ -3196,7 +3196,7 @@ dependencies = [
[[package]]
name = "letterbox-server"
version = "0.17.38"
version = "0.17.40"
dependencies = [
"ammonia",
"anyhow",
@ -3219,8 +3219,8 @@ dependencies = [
"html-escape",
"html2text",
"ical",
"letterbox-notmuch 0.17.38",
"letterbox-shared 0.17.38",
"letterbox-notmuch 0.17.40",
"letterbox-shared 0.17.40",
"linkify",
"lol_html",
"mailparse",
@ -3247,6 +3247,8 @@ dependencies = [
[[package]]
name = "letterbox-shared"
version = "0.17.38"
source = "sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/"
checksum = "1bf39370ba5e17772b3920b7928e710462eac16b58afa00771c1e25c11fdb9ac"
dependencies = [
"build-info",
"letterbox-notmuch 0.17.38",
@ -3259,12 +3261,10 @@ dependencies = [
[[package]]
name = "letterbox-shared"
version = "0.17.38"
source = "sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/"
checksum = "1bf39370ba5e17772b3920b7928e710462eac16b58afa00771c1e25c11fdb9ac"
version = "0.17.40"
dependencies = [
"build-info",
"letterbox-notmuch 0.17.38 (sparse+https://git.z.xinu.tv/api/packages/wathiede/cargo/)",
"letterbox-notmuch 0.17.40",
"regex",
"serde",
"sqlx",
@ -3274,7 +3274,7 @@ dependencies = [
[[package]]
name = "letterbox-web"
version = "0.17.38"
version = "0.17.40"
dependencies = [
"build-info",
"build-info-build",
@ -3286,7 +3286,7 @@ dependencies = [
"graphql_client",
"human_format",
"itertools",
"letterbox-shared 0.17.38",
"letterbox-shared 0.17.40",
"log",
"seed",
"seed_hooks",

View File

@ -8,7 +8,7 @@ authors = ["Bill Thiede <git@xinu.tv>"]
edition = "2021"
license = "UNLICENSED"
publish = ["xinu"]
version = "0.17.38"
version = "0.17.40"
repository = "https://git.z.xinu.tv/wathiede/letterbox"
[profile.dev]

View File

@ -32,8 +32,8 @@ futures = "0.3.31"
headers = "0.4.0"
html-escape = "0.2.13"
ical = "0.11"
letterbox-notmuch = { path = "../notmuch", version = "0.17.38", registry = "xinu" }
letterbox-shared = { path = "../shared", version = "0.17.38", registry = "xinu" }
letterbox-notmuch = { path = "../notmuch", version = "0.17.40", registry = "xinu" }
letterbox-shared = { path = "../shared", version = "0.17.40", registry = "xinu" }
linkify = "0.10.0"
lol_html = "2.3.0"
mailparse = "0.16.1"

View File

@ -1,3 +1,60 @@
use std::io::{Cursor, Read};
use askama::Template;
use chrono::{Datelike, Local, LocalResult, TimeZone, Utc};
use chrono_tz::Tz;
use mailparse::{parse_content_type, parse_mail, MailHeader, MailHeaderMap, ParsedMail};
use quick_xml::de::from_str as xml_from_str;
use tracing::{error, info, warn};
use zip::ZipArchive;
use crate::{
error::ServerError,
graphql::{Attachment, Body, DispositionType, Email, Html, PlainText, UnhandledContentType},
linkify_html,
};
const APPLICATION_GZIP: &'static str = "application/gzip";
const APPLICATION_ZIP: &'static str = "application/zip";
const IMAGE_JPEG: &'static str = "image/jpeg";
const IMAGE_PJPEG: &'static str = "image/pjpeg";
const IMAGE_PNG: &'static str = "image/png";
const MESSAGE_RFC822: &'static str = "message/rfc822";
const MULTIPART_ALTERNATIVE: &'static str = "multipart/alternative";
const MULTIPART_MIXED: &'static str = "multipart/mixed";
const MULTIPART_RELATED: &'static str = "multipart/related";
const MULTIPART_REPORT: &'static str = "multipart/report";
const TEXT_CALENDAR: &'static str = "text/calendar";
const TEXT_HTML: &'static str = "text/html";
const TEXT_PLAIN: &'static str = "text/plain";
// Inline Askama filters module for template use
mod filters {
// Usage: {{ items|batch(7) }}
pub fn batch<T: Clone>(
items: &[T],
_: &dyn ::askama::Values,
size: usize,
) -> askama::Result<Vec<Vec<T>>> {
if size == 0 {
return Ok(vec![]);
}
let mut out = Vec::new();
let mut chunk = Vec::with_capacity(size);
for item in items {
chunk.push(item.clone());
if chunk.len() == size {
out.push(chunk);
chunk = Vec::with_capacity(size);
}
}
if !chunk.is_empty() {
out.push(chunk);
}
Ok(out)
}
}
#[derive(Debug, PartialEq)]
pub struct ExtractedCalendarMetadata {
pub is_google_calendar_event: bool,
@ -443,72 +500,6 @@ pub fn extract_calendar_metadata_from_mail(
body_html,
}
}
#[derive(Debug, PartialEq)]
pub struct ExtractedCalendarMetadata {
pub is_google_calendar_event: bool,
pub summary: Option<String>,
pub organizer: Option<String>,
pub start_date: Option<String>,
pub end_date: Option<String>,
pub body_html: Option<String>,
}
// Inline Askama filters module for template use
mod filters {
// Usage: {{ items|batch(7) }}
pub fn batch<T: Clone>(
items: &[T],
_: &dyn ::askama::Values,
size: usize,
) -> askama::Result<Vec<Vec<T>>> {
if size == 0 {
return Ok(vec![]);
}
let mut out = Vec::new();
let mut chunk = Vec::with_capacity(size);
for item in items {
chunk.push(item.clone());
if chunk.len() == size {
out.push(chunk);
chunk = Vec::with_capacity(size);
}
}
if !chunk.is_empty() {
out.push(chunk);
}
Ok(out)
}
}
use std::io::{Cursor, Read};
use askama::Template;
use chrono::{Datelike, Local, LocalResult, TimeZone, Utc};
use chrono_tz::Tz;
use mailparse::{parse_content_type, parse_mail, MailHeader, MailHeaderMap, ParsedMail};
use quick_xml::de::from_str as xml_from_str;
use tracing::{error, info, warn};
use zip::ZipArchive;
use crate::{
error::ServerError,
graphql::{Attachment, Body, DispositionType, Email, Html, PlainText, UnhandledContentType},
linkify_html,
};
const APPLICATION_GZIP: &'static str = "application/gzip";
const APPLICATION_ZIP: &'static str = "application/zip";
const IMAGE_JPEG: &'static str = "image/jpeg";
const IMAGE_PJPEG: &'static str = "image/pjpeg";
const IMAGE_PNG: &'static str = "image/png";
const MESSAGE_RFC822: &'static str = "message/rfc822";
const MULTIPART_ALTERNATIVE: &'static str = "multipart/alternative";
const MULTIPART_MIXED: &'static str = "multipart/mixed";
const MULTIPART_RELATED: &'static str = "multipart/related";
const MULTIPART_REPORT: &'static str = "multipart/report";
const TEXT_CALENDAR: &'static str = "text/calendar";
const TEXT_HTML: &'static str = "text/html";
const TEXT_PLAIN: &'static str = "text/plain";
pub fn email_addresses(
_path: &str,
m: &ParsedMail,

View File

@ -12,7 +12,7 @@ version.workspace = true
[dependencies]
build-info = "0.0.41"
letterbox-notmuch = { path = "../notmuch", version = "0.17.38", registry = "xinu" }
letterbox-notmuch = { path = "../notmuch", version = "0.17.40", registry = "xinu" }
regex = "1.11.1"
serde = { version = "1.0.219", features = ["derive"] }
sqlx = "0.8.5"

View File

@ -33,7 +33,7 @@ wasm-bindgen = "=0.2.100"
uuid = { version = "1.16.0", features = [
"js",
] } # direct dep to set js feature, prevents Rng issues
letterbox-shared = { path = "../shared/", version = "0.17.38", registry = "xinu" }
letterbox-shared = { path = "../shared/", version = "0.17.40", registry = "xinu" }
seed_hooks = { version = "0.4.1", registry = "xinu" }
strum_macros = "0.27.1"
gloo-console = "0.3.0"