web: add basic graphql view thread, no body support.
This commit is contained in:
@@ -7,8 +7,8 @@ use async_graphql::{
|
||||
connection::{self, Connection, Edge},
|
||||
Context, EmptyMutation, EmptySubscription, Error, FieldResult, Object, Schema, SimpleObject,
|
||||
};
|
||||
use log::info;
|
||||
use mailparse::{addrparse, parse_mail, MailHeaderMap, ParsedMail};
|
||||
use log::{info, warn};
|
||||
use mailparse::{parse_mail, MailHeaderMap, ParsedMail};
|
||||
use memmap::MmapOptions;
|
||||
use notmuch::Notmuch;
|
||||
use rayon::prelude::*;
|
||||
@@ -39,6 +39,7 @@ pub struct ThreadSummary {
|
||||
|
||||
#[derive(Debug, SimpleObject)]
|
||||
pub struct Thread {
|
||||
subject: String,
|
||||
messages: Vec<Message>,
|
||||
}
|
||||
|
||||
@@ -174,13 +175,18 @@ impl QueryRoot {
|
||||
let file = File::open(&path)?;
|
||||
let mmap = unsafe { MmapOptions::new().map(&file)? };
|
||||
let m = parse_mail(&mmap)?;
|
||||
let from = if let Some(from) = m.headers.get_first_value("from") {
|
||||
addrparse(&from)?.extract_single_info().map(|si| Email {
|
||||
name: si.display_name,
|
||||
addr: Some(si.addr),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
let from = email_addresses(&path, &m, "from")?;
|
||||
let from = match from.len() {
|
||||
0 => None,
|
||||
1 => from.into_iter().next(),
|
||||
_ => {
|
||||
warn!(
|
||||
"Got {} from addresses in message, truncating: {:?}",
|
||||
from.len(),
|
||||
from
|
||||
);
|
||||
from.into_iter().next()
|
||||
}
|
||||
};
|
||||
let to = email_addresses(&path, &m, "to")?;
|
||||
let cc = email_addresses(&path, &m, "cc")?;
|
||||
@@ -198,7 +204,15 @@ impl QueryRoot {
|
||||
});
|
||||
}
|
||||
messages.reverse();
|
||||
Ok(Thread { messages })
|
||||
// Find the first subject that's set. After reversing the vec, this should be the oldest
|
||||
// message.
|
||||
let subject: String = messages
|
||||
.iter()
|
||||
.skip_while(|m| m.subject.is_none())
|
||||
.next()
|
||||
.and_then(|m| m.subject.clone())
|
||||
.unwrap_or("(NO SUBJECT)".to_string());
|
||||
Ok(Thread { subject, messages })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,8 +242,8 @@ fn email_addresses(path: &str, m: &ParsedMail, header_name: &str) -> Result<Vec<
|
||||
if v.matches('@').count() == 1 {
|
||||
if v.matches('<').count() == 1 && v.ends_with('>') {
|
||||
let idx = v.find('<').unwrap();
|
||||
let addr = &v[idx + 1..v.len() - 1];
|
||||
let name = &v[..idx];
|
||||
let addr = &v[idx + 1..v.len() - 1].trim();
|
||||
let name = &v[..idx].trim();
|
||||
addrs.push(Email {
|
||||
name: Some(name.to_string()),
|
||||
addr: Some(addr.to_string()),
|
||||
|
||||
Reference in New Issue
Block a user