Add export-messages command
Right now only supports exporting conversations, and doesn't support attachments.
This commit is contained in:
parent
ea188ff133
commit
bd861cdb00
|
@ -12,6 +12,7 @@ import (
|
|||
imapmove "github.com/emersion/go-imap-move"
|
||||
imapspacialuse "github.com/emersion/go-imap-specialuse"
|
||||
imapserver "github.com/emersion/go-imap/server"
|
||||
"github.com/emersion/go-mbox"
|
||||
"github.com/emersion/go-smtp"
|
||||
"github.com/howeyc/gopass"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
|
@ -20,6 +21,7 @@ import (
|
|||
"github.com/emersion/hydroxide/auth"
|
||||
"github.com/emersion/hydroxide/carddav"
|
||||
"github.com/emersion/hydroxide/events"
|
||||
"github.com/emersion/hydroxide/exports"
|
||||
imapbackend "github.com/emersion/hydroxide/imap"
|
||||
"github.com/emersion/hydroxide/imports"
|
||||
"github.com/emersion/hydroxide/protonmail"
|
||||
|
@ -116,6 +118,7 @@ Commands:
|
|||
export-secret-keys <username> Export secret keys
|
||||
imap Run hydroxide as an IMAP server
|
||||
import-messages <username> <file> Import messages
|
||||
export-messages [options...] <username> Export messages
|
||||
serve Run all servers
|
||||
smtp Run hydroxide as an SMTP server
|
||||
status View hydroxide status
|
||||
|
@ -151,6 +154,7 @@ func main() {
|
|||
authCmd := flag.NewFlagSet("auth", flag.ExitOnError)
|
||||
exportSecretKeysCmd := flag.NewFlagSet("export-secret-keys", flag.ExitOnError)
|
||||
importMessagesCmd := flag.NewFlagSet("import-messages", flag.ExitOnError)
|
||||
exportMessagesCmd := flag.NewFlagSet("export-messages", flag.ExitOnError)
|
||||
|
||||
flag.Parse()
|
||||
|
||||
|
@ -335,6 +339,38 @@ func main() {
|
|||
if err := imports.ImportMessage(c, f); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
case "export-messages":
|
||||
var convID string
|
||||
exportMessagesCmd.StringVar(&convID, "conversation-id", "", "conversation ID")
|
||||
exportMessagesCmd.Parse(flag.Args()[1:])
|
||||
username := exportMessagesCmd.Arg(0)
|
||||
log.Println(convID, username)
|
||||
if convID == "" || username == "" {
|
||||
log.Fatal("usage: hydroxide export-messages -conversation-id <id> <username>")
|
||||
}
|
||||
|
||||
var bridgePassword string
|
||||
fmt.Fprintf(os.Stderr, "Bridge password: ")
|
||||
if pass, err := gopass.GetPasswd(); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
bridgePassword = string(pass)
|
||||
}
|
||||
|
||||
c, privateKeys, err := auth.NewManager(newClient).Auth(username, bridgePassword)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
mboxWriter := mbox.NewWriter(os.Stdout)
|
||||
|
||||
if err := exports.ExportConversation(c, privateKeys, mboxWriter, convID); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := mboxWriter.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
case "smtp":
|
||||
addr := *smtpHost + ":" + *smtpPort
|
||||
authManager := auth.NewManager(newClient)
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package exports
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"bufio"
|
||||
"strings"
|
||||
|
||||
"github.com/emersion/go-mbox"
|
||||
"github.com/emersion/go-message"
|
||||
"github.com/emersion/go-message/mail"
|
||||
"github.com/emersion/go-message/textproto"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
|
||||
"github.com/emersion/hydroxide/protonmail"
|
||||
)
|
||||
|
||||
func ExportMessage(c *protonmail.Client, privateKeys openpgp.KeyRing, w io.Writer, id string) error {
|
||||
msg, err := c.GetMessage(id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch message: %v", err)
|
||||
}
|
||||
|
||||
mimeType := msg.MIMEType
|
||||
if mimeType == "" {
|
||||
mimeType = "text/html"
|
||||
}
|
||||
|
||||
br := bufio.NewReader(strings.NewReader(msg.Header))
|
||||
th, err := textproto.ReadHeader(br)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read message header: %v", err)
|
||||
}
|
||||
|
||||
mh := mail.Header{message.Header{th}}
|
||||
mh.SetContentType(mimeType, nil)
|
||||
mh.Set("Content-Transfer-Encoding", "quoted-printable")
|
||||
|
||||
// TODO: add support for attachments
|
||||
mw, err := mail.CreateSingleInlineWriter(w, mh)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create message writer: %v", err)
|
||||
}
|
||||
|
||||
md, err := msg.Read(privateKeys, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: check signature
|
||||
if _, err := io.Copy(mw, md.UnverifiedBody); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mw.Close()
|
||||
}
|
||||
|
||||
func ExportConversation(c *protonmail.Client, privateKeys openpgp.KeyRing, mbox *mbox.Writer, id string) error {
|
||||
_, msgs, err := c.GetConversation(id, "")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch conversation: %v", err)
|
||||
}
|
||||
|
||||
for _, msg := range msgs {
|
||||
w, err := mbox.CreateMessage(msg.Sender.Address, msg.Time.Time())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create mbox message: %v", err)
|
||||
}
|
||||
|
||||
if err := ExportMessage(c, privateKeys, w, msg.ID); err != nil {
|
||||
return fmt.Errorf("failed to export conversation message: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
1
go.mod
1
go.mod
|
@ -8,6 +8,7 @@ require (
|
|||
github.com/emersion/go-imap v1.0.4
|
||||
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342
|
||||
github.com/emersion/go-imap-specialuse v0.0.0-20161227184202-ba031ced6a62
|
||||
github.com/emersion/go-mbox v1.0.0
|
||||
github.com/emersion/go-message v0.11.1
|
||||
github.com/emersion/go-smtp v0.12.1
|
||||
github.com/emersion/go-vcard v0.0.0-20191221110513-5f81fa0d3cc7
|
||||
|
|
2
go.sum
2
go.sum
|
@ -16,6 +16,8 @@ github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342 h1:5p1t3e1Po
|
|||
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342/go.mod h1:QuMaZcKFDVI0yCrnAbPLfbwllz1wtOrZH8/vZ5yzp4w=
|
||||
github.com/emersion/go-imap-specialuse v0.0.0-20161227184202-ba031ced6a62 h1:4ZAfwfc8aDlj26kkEap1UDSwwDnJp9Ie8Uj1MSXAkPk=
|
||||
github.com/emersion/go-imap-specialuse v0.0.0-20161227184202-ba031ced6a62/go.mod h1:/nybxhI8kXom8Tw6BrHMl42usALvka6meORflnnYwe4=
|
||||
github.com/emersion/go-mbox v1.0.0 h1:HN6aKbyqmgIfK9fS/gen+NRr2wXLSxZXWfdAIAnzQPc=
|
||||
github.com/emersion/go-mbox v1.0.0/go.mod h1:Yp9IVuuOYLEuMv4yjgDHvhb5mHOcYH6x92Oas3QqEZI=
|
||||
github.com/emersion/go-message v0.11.1 h1:0C/S4JIXDTSfXB1vpqdimAYyK4+79fgEAMQ0dSL+Kac=
|
||||
github.com/emersion/go-message v0.11.1/go.mod h1:C4jnca5HOTo4bGN9YdqNQM9sITuT3Y0K6bSUw9RklvY=
|
||||
github.com/emersion/go-sasl v0.0.0-20190817083125-240c8404624e h1:ba7YsgX5OV8FjGi5ZWml8Jng6oBrJAb3ahqWMJ5Ce8Q=
|
||||
|
|
Loading…
Reference in New Issue