#!/usr/bin/zx --quiet import { resolve, basename } from "path"; const pwd = (await $`pwd`).stdout.replace("\n", ""); const sexpr = require("sexpr-plus").parse; $`echo $PWD`; const path = resolve(process.env.PWD, process.argv.slice(-1)[0]); const mail_body = (await $`mu view ${path} -o sexp`).stdout; function parse_mail(sexp_string) { const array = sexpr(sexp_string)[0].content; const result = {}; let i = 0; while (i < array.length) { result[array[i].content.slice(1)] = array[i + 1].content; i += 2; } return result; } const mail_obj = parse_mail(mail_body); let html = mail_obj["body-html"] && mail_obj["body-html"].match(/body/i) !== null ? mail_obj["body-html"] : /* HTML */ `
${mail_obj["body-txt"]}
`; const attachments = (await $`mu extract ${path}`).stdout; function getSimpleHeader(body, header_name) { const regexp = new RegExp(`:${header_name} (.*)\n`); console.log("get simple header", header_name, body); return body.match(regexp)[1]; } function formatAddress(sexp) { sexp = sexp .replace(/(^\(\(|\)\)$)/g, "") .replace(/"? \. "/, " <") .replace(/"$/, ">") .replace(/^"/, "") .replace(/^nil <(.*)>$/, "$1"); return sexp; } function escape(str) { return str.replace(/ { //someimtes images have the wrong mime type, like for example in photos from straż miejska confirmation emails if (line.includes(".jpg") && line.includes("application/octet-stream")) { return line.replace("application/octet-stream", "image/jpg"); } else { return line; } }) .filter((line) => line.includes("image")) .map((line) => { return { filename: line.match(/\d+ (.*) image\//)[1], mime: line.match(/image\/[^ ]+/)[0], }; }); const attachment_info = attachments .split("\n") .slice(1) .map((line) => line.split(" ").slice(3)) .filter((e) => e[0] != "") .slice(0, -1) .map(([name, type, role, size1, size2]) => ({ name, type, role, size: (size1 + " " + size2).replace(/[()]/g, ""), })) .filter(({ role }) => role == "[attach]"); const files = await Promise.all( to_download.map(async ({ filename, mime }) => { await $`mu extract --overwrite --target-dir=/tmp ${path} ${filename}`; const base64 = (await $`base64 -w 0 < ${`/tmp/${filename}`}`).stdout; return { filename, base64, mime }; }) ); const attachments_items = files .map( ({ filename, mime, base64 }) => /* HTML */ `
  • ${filename}
  • ` ) .join("\n"); html = html.replace( /<\/body>/i, /* HTML */ `

    Załączniki:

    ${attachment_info.map( (a) => `` )}
    ${a.name}${a.size}${a.type}
    ` ); const subject = getSimpleHeader(mail_body, "subject").slice(1, -1); // slice to remove " const from = formatAddress(getSimpleHeader(mail_body, "from")); const to = formatAddress(getSimpleHeader(mail_body, "to")); const date = await formatDate(getSimpleHeader(mail_body, "date")); html = html.replace( //i, `` + /* HTML */ `

    ${subject}

    Temat wiadomości: ${subject}
    Wysłano: ${escape(date)}
    Od: ${escape(from)}
    Do: ${escape(to)}

    ` ); const output = (await $`mktemp --suffix=.html`).stdout.replace("\n", ""); await fs.writeFile(output, html); const output_file = `${resolve(path, "../")}/${basename(path)}.pdf`.replace( ",", " " ); await $`wkhtmltopdf ${output} ${output_file}`; // console.log(pwd + "output.html"); // console.log(mail_body); async function formatDate(sexp) { const parsed = (await $`emacsclient --eval ${`(decode-time '${sexp})`}`) .stdout; const [, minutes, hours, date, month, year] = parsed.split(" "); return `${year}-${month.padStart(2, "0")}-${date} ${hours}:${minutes.padStart( 2, "0" )}`; }