server: remove dupe and move code to more idomatic layout

This commit is contained in:
Bill Thiede 2025-09-02 19:27:14 -07:00
parent 4243f7b77d
commit 46021c5d2c

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,