Add Header type and use Header list in place of Mail.to
This commit is contained in:
parent
0de1760f8b
commit
0a6e9a0f9d
2 changed files with 85 additions and 42 deletions
|
@ -1,30 +1,30 @@
|
||||||
import birl.{type Time}
|
import birl.{type Time}
|
||||||
import gleam/dict.{type Dict}
|
import gleam/dict.{type Dict}
|
||||||
|
import gleam/io
|
||||||
import gleam/iterator.{type Iterator}
|
import gleam/iterator.{type Iterator}
|
||||||
import gleam/list
|
import gleam/list
|
||||||
|
import gleam/option.{type Option}
|
||||||
import gleam/pair
|
import gleam/pair
|
||||||
import gleam/regex
|
import gleam/regex
|
||||||
import gleam/result
|
import gleam/result
|
||||||
import gleam/string
|
import gleam/string
|
||||||
|
import header.{type Header}
|
||||||
import simplifile
|
import simplifile
|
||||||
|
|
||||||
// import gleam/io
|
|
||||||
|
|
||||||
pub type MBox {
|
pub type MBox {
|
||||||
MBox(headers: Dict(String, String), body: String)
|
MBox(headers: List(Header), body: String)
|
||||||
InvalidMBox
|
InvalidMBox
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Mail {
|
pub type Mail {
|
||||||
Mail(
|
Mail(
|
||||||
from: Result(String, Nil),
|
from: Result(String, Nil),
|
||||||
to: Result(String, Nil),
|
to: List(String),
|
||||||
// TODO: convert to List(String)
|
|
||||||
subject: Result(String, Nil),
|
subject: Result(String, Nil),
|
||||||
message_id: Result(String, Nil),
|
message_id: Result(String, Nil),
|
||||||
date: Result(Time, Nil),
|
date: Result(Time, Nil),
|
||||||
body: Result(String, Nil),
|
body: Result(String, Nil),
|
||||||
headers: Result(Dict(String, String), Nil),
|
headers: Result(List(Header), Nil),
|
||||||
)
|
)
|
||||||
InvalidMail
|
InvalidMail
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ pub fn parse_mbox(mboxcontents: String) -> MBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_headers(mbox: MBox) -> Result(Dict(String, String), Nil) {
|
fn get_headers(mbox: MBox) -> Result(List(Header), Nil) {
|
||||||
case mbox {
|
case mbox {
|
||||||
InvalidMBox -> Error(Nil)
|
InvalidMBox -> Error(Nil)
|
||||||
MBox(headers, _) -> Ok(headers)
|
MBox(headers, _) -> Ok(headers)
|
||||||
|
@ -55,7 +55,7 @@ fn parse_body(mboxcontents: String) -> Result(String, Nil) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_headers(mboxcontents: String) -> Result(Dict(String, String), Nil) {
|
fn parse_headers(mboxcontents: String) -> Result(List(Header), Nil) {
|
||||||
case string.split_once(mboxcontents, "\n\n") {
|
case string.split_once(mboxcontents, "\n\n") {
|
||||||
Ok(pair) ->
|
Ok(pair) ->
|
||||||
pair.first(pair)
|
pair.first(pair)
|
||||||
|
@ -63,14 +63,14 @@ fn parse_headers(mboxcontents: String) -> Result(Dict(String, String), Nil) {
|
||||||
|> fix_multiline_values
|
|> fix_multiline_values
|
||||||
|> string.split("\n")
|
|> string.split("\n")
|
||||||
// convert to dict of headers
|
// convert to dict of headers
|
||||||
|> list.map(get_header_dict)
|
|> list.map(get_header_tuple)
|
||||||
|> dict.from_list
|
|> list.map(header.from_tuple)
|
||||||
|> Ok
|
|> Ok
|
||||||
Error(_) -> Error(Nil)
|
Error(_) -> Error(Nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_header_dict(s: String) -> #(String, String) {
|
fn get_header_tuple(s: String) -> #(String, String) {
|
||||||
s
|
s
|
||||||
|> string.split_once(": ")
|
|> string.split_once(": ")
|
||||||
|> result.unwrap(or: #("", ""))
|
|> result.unwrap(or: #("", ""))
|
||||||
|
@ -97,34 +97,36 @@ fn remove_dead_space(acc: String, matched_content: String) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: better error
|
// TODO: better error
|
||||||
pub fn maildir_iterate(maildir_path: String) -> Iterator(#(String, String)) {
|
// fn maildir_iterate(maildir_path: String) -> Iterator(#(String, String)) {
|
||||||
case simplifile.get_files(maildir_path) {
|
// case simplifile.get_files(maildir_path) {
|
||||||
Ok(maillist) ->
|
// Ok(maillist) ->
|
||||||
iterator.from_list(maillist)
|
// iterator.from_list(maillist)
|
||||||
|> iterator.map(fn(path) { #(path, read_file(path)) })
|
// |> iterator.map(fn(path) { #(path, read_file(path)) })
|
||||||
Error(_) -> #("", "") |> list.wrap |> iterator.from_list
|
// Error(_) -> #("", "") |> list.wrap |> iterator.from_list
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn main() {
|
|
||||||
// maildir_iterate("/home/payas/.mail/Gmail/[Gmail]/All Mail/cur")
|
|
||||||
// |> iterator.each(fn(mboxpair) {
|
|
||||||
// case parse(pair.second(mboxpair)) {
|
|
||||||
// InvalidMBox -> io.debug("ERR MBOX: " <> pair.first(mboxpair))
|
|
||||||
// MBox(headers, body) ->
|
|
||||||
// case mbox_to_mail(MBox(headers, body)) {
|
|
||||||
// InvalidMail -> io.debug("ERR MAIL: " <> pair.first(mboxpair))
|
|
||||||
// _ -> io.debug("SUCCESS: " <> pair.first(mboxpair))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fn read_file(file_path: String) -> String {
|
// pub fn main() {
|
||||||
file_path
|
// maildir_iterate("/home/payas/.mail/Gmail/[Gmail]/All Mail/cur")
|
||||||
|> simplifile.read
|
// |> iterator.each(fn(mboxpair) {
|
||||||
|> result.unwrap(or: "")
|
// case parse_mbox(pair.second(mboxpair)) {
|
||||||
}
|
// InvalidMBox -> io.debug("ERR MBOX: " <> pair.first(mboxpair))
|
||||||
|
// MBox(headers, body) ->
|
||||||
|
// case mbox_to_mail(MBox(headers, body)) {
|
||||||
|
// InvalidMail -> io.debug("ERR MAIL: " <> pair.first(mboxpair))
|
||||||
|
// _ -> io.debug("SUCCESS: " <> pair.first(mboxpair))
|
||||||
|
// Mail(_, to, _, _, _, _, _) ->
|
||||||
|
// io.debug(to) |> list.first |> result.unwrap("")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn read_file(file_path: String) -> String {
|
||||||
|
// file_path
|
||||||
|
// |> simplifile.read
|
||||||
|
// |> result.unwrap(or: "")
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn parse_mail(mboxcontents: String) -> Mail {
|
pub fn parse_mail(mboxcontents: String) -> Mail {
|
||||||
case parse_mbox(mboxcontents) {
|
case parse_mbox(mboxcontents) {
|
||||||
|
@ -138,11 +140,11 @@ fn mbox_to_mail(mbox: MBox) -> Mail {
|
||||||
InvalidMBox -> InvalidMail
|
InvalidMBox -> InvalidMail
|
||||||
MBox(headers, body) ->
|
MBox(headers, body) ->
|
||||||
Mail(
|
Mail(
|
||||||
from: dict.get(headers, "From"),
|
from: header.get_first_by_name(headers, "From"),
|
||||||
to: dict.get(headers, "To"),
|
to: header.get_by_name(headers, "To"),
|
||||||
message_id: dict.get(headers, "Message-ID"),
|
message_id: header.get_first_by_name(headers, "Message-ID"),
|
||||||
subject: dict.get(headers, "Subject"),
|
subject: header.get_first_by_name(headers, "Subject"),
|
||||||
date: case dict.get(headers, "Date") {
|
date: case header.get_first_by_name(headers, "Date") {
|
||||||
Ok(date_str) -> birl.parse(date_str)
|
Ok(date_str) -> birl.parse(date_str)
|
||||||
Error(_) -> Error(Nil)
|
Error(_) -> Error(Nil)
|
||||||
},
|
},
|
||||||
|
|
41
src/header.gleam
Normal file
41
src/header.gleam
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import gleam/iterator
|
||||||
|
import gleam/order
|
||||||
|
import gleam/pair
|
||||||
|
import gleam/string
|
||||||
|
|
||||||
|
pub type Header {
|
||||||
|
Header(name: String, body: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_tuple(tuple: #(String, String)) -> Header {
|
||||||
|
Header(name: pair.first(tuple), body: pair.second(tuple))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_by_name(headers: List(Header), name: String) -> List(String) {
|
||||||
|
headers
|
||||||
|
|> iterator.from_list
|
||||||
|
|> iterator.filter(fn(header) {
|
||||||
|
case string.compare(header.name, name) {
|
||||||
|
order.Eq -> True
|
||||||
|
_ -> False
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|> iterator.map(fn(header) { header.body })
|
||||||
|
|> iterator.to_list
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_first_by_name(
|
||||||
|
headers: List(Header),
|
||||||
|
name: String,
|
||||||
|
) -> Result(String, Nil) {
|
||||||
|
headers
|
||||||
|
|> iterator.from_list
|
||||||
|
|> iterator.filter(fn(header) {
|
||||||
|
case string.compare(header.name, name) {
|
||||||
|
order.Eq -> True
|
||||||
|
_ -> False
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|> iterator.map(fn(header) { header.body })
|
||||||
|
|> iterator.first
|
||||||
|
}
|
Loading…
Reference in a new issue