server: add functioning download attachment handler
This commit is contained in:
@@ -86,8 +86,10 @@ pub struct Message {
|
||||
// X-Attachment-Id: f_lponoluo1
|
||||
#[derive(Default, Debug, SimpleObject)]
|
||||
pub struct Attachment {
|
||||
pub id: String,
|
||||
pub idx: String,
|
||||
pub filename: Option<String>,
|
||||
pub size: Option<usize>,
|
||||
pub size: usize,
|
||||
pub content_type: Option<String>,
|
||||
pub content_id: Option<String>,
|
||||
pub disposition: DispositionType,
|
||||
@@ -375,7 +377,7 @@ impl QueryRoot {
|
||||
})
|
||||
.collect();
|
||||
// TODO(wathiede): parse message and fill out attachments
|
||||
let attachments = extract_attachments(&m)?;
|
||||
let attachments = extract_attachments(&m, &id)?;
|
||||
messages.push(Message {
|
||||
id,
|
||||
from,
|
||||
@@ -656,17 +658,17 @@ fn walk_attachments<T, F: Fn(&ParsedMail, &[usize]) -> Option<T>>(
|
||||
// TODO(wathiede): make this walk_attachments that takes a closure.
|
||||
// Then implement one closure for building `Attachment` and imlement another that can be used to
|
||||
// get the bytes for serving attachments of HTTP
|
||||
fn extract_attachments(m: &ParsedMail) -> Result<Vec<Attachment>, Error> {
|
||||
fn extract_attachments(m: &ParsedMail, id: &str) -> Result<Vec<Attachment>, Error> {
|
||||
let mut attachments = Vec::new();
|
||||
for sp in &m.subparts {
|
||||
if let Some(attachment) = extract_attachment(sp) {
|
||||
for (idx, sp) in m.subparts.iter().enumerate() {
|
||||
if let Some(attachment) = extract_attachment(sp, id, &[idx]) {
|
||||
attachments.push(attachment);
|
||||
}
|
||||
}
|
||||
Ok(attachments)
|
||||
}
|
||||
|
||||
fn extract_attachment(m: &ParsedMail) -> Option<Attachment> {
|
||||
fn extract_attachment(m: &ParsedMail, id: &str, idx: &[usize]) -> Option<Attachment> {
|
||||
let pcd = m.get_content_disposition();
|
||||
// TODO: do we need to handle empty filename attachments, or should we change the definition of
|
||||
// Attachment::filename?
|
||||
@@ -684,12 +686,15 @@ fn extract_attachment(m: &ParsedMail) -> Option<Attachment> {
|
||||
}
|
||||
};
|
||||
return Some(Attachment {
|
||||
id: id.to_string(),
|
||||
idx: idx
|
||||
.iter()
|
||||
.map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("."),
|
||||
disposition: pcd.disposition.into(),
|
||||
filename: Some(filename),
|
||||
size: pcd
|
||||
.params
|
||||
.get("size")
|
||||
.map(|s| s.parse().unwrap_or_default()),
|
||||
size: bytes.len(),
|
||||
// TODO: what is the default for ctype?
|
||||
// TODO: do we want to use m.ctype.params for anything?
|
||||
content_type: Some(m.ctype.mimetype.clone()),
|
||||
@@ -841,7 +846,7 @@ pub fn attachment_bytes(nm: &Notmuch, id: &str, idx: &[usize]) -> Result<Attachm
|
||||
if let Some(attachment) = walk_attachments(&m, |sp, cur_idx| {
|
||||
info!("checking {cur_idx:?}=={idx:?}");
|
||||
if cur_idx == idx {
|
||||
let attachment = extract_attachment(&sp).unwrap_or(Attachment {
|
||||
let attachment = extract_attachment(&sp, id, idx).unwrap_or(Attachment {
|
||||
..Attachment::default()
|
||||
});
|
||||
return Some(attachment);
|
||||
|
||||
Reference in New Issue
Block a user