Compare commits

...

1 commit

Author SHA1 Message Date
5ced6729ce
Add add verb and message subcommand 2021-04-07 00:25:48 +02:00
4 changed files with 226 additions and 0 deletions

149
cli/papero/add.go Normal file
View file

@ -0,0 +1,149 @@
package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"io"
"os"
"git.sr.ht/~blallo/papero/cli"
"git.sr.ht/~blallo/papero/imaputils"
)
var addVerbs cli.CommandMap
func init() {
addVerbs = cli.CommandMap{
"message": PutMessageCmd{},
// "mailbox": CreateMailboxCmd{},
}
}
type AddCmd struct{}
func (a AddCmd) Func(args []string) error {
flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
flagset.Usage = func() { a.Help(os.Stdout, flagset) }
flagset.Parse(args[1:])
subArgs := flagset.Args()
if len(subArgs) == 0 {
a.Help(os.Stderr, flagset)
os.Exit(1)
}
cmd := subArgs[0]
if Session.Info.Opts.Debug {
Log.Debug("add verb:", cmd)
}
return addVerbs[cmd].Func(subArgs)
}
func (a AddCmd) Help(w io.Writer, set *flag.FlagSet) {
fmt.Fprintf(w, "USAGE: %s add VERB [verb opts]\n", Session.Info.Name)
fmt.Fprintf(w, "\nVERBS:\n")
for verb := range addVerbs {
fmt.Fprintf(w, "\t%s\n", verb)
}
}
// VERBS
type PutMessageCmd struct{}
func (pm PutMessageCmd) Func(args []string) error {
var opts imaputils.PutMessageOpts
var err error
var bodyReader io.Reader
var messageTime cli.AbsTimeFlag
var flagSeen, flagAnswered, flagFlagged, flagDeleted, flagDraft bool
if Session.Info.Opts.Debug {
Log.Debug("enter add message")
}
flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
flagset.BoolVar(&flagSeen, "seen", false, "set the seen flag")
flagset.BoolVar(&flagAnswered, "answered", false, "set the answered flag")
flagset.BoolVar(&flagFlagged, "flagged", false, "set the flagged flag")
flagset.BoolVar(&flagDeleted, "deleted", false, "set the deleted flag")
flagset.BoolVar(&flagDraft, "draft", false, "set the draft flag")
flagset.Var(&messageTime, "time", "time at which the message has been sent")
flagset.Usage = func() {
pm.Help(os.Stdout, flagset)
}
flagset.Parse(args[1:])
subArgs := flagset.Args()
if len(subArgs) != 2 {
Log.Debugf("Too few arguments: %s\n", subArgs)
pm.Help(os.Stderr, flagset)
os.Exit(1)
}
opts.Debug = Session.Info.Opts.Debug
opts.Mailbox = subArgs[0]
if subArgs[1] == "-" {
bodyReader = os.Stdin
} else {
file, err := os.Open(subArgs[1])
if err != nil {
return err
}
bodyReader = bufio.NewReader(file)
}
opts.Body, err = readIntoBuffer(bodyReader)
if err != nil {
return err
}
opts.Flags = intoList(flagSeen, flagAnswered, flagFlagged, flagDeleted, flagDraft)
opts.Time = *messageTime.Time
imaputils.PutMessage(Session.Config, &opts)
return nil
}
func (pm PutMessageCmd) Help(w io.Writer, set *flag.FlagSet) {
fmt.Fprintf(w, "USAGE: %s set put MAILBOX PATH_OR_STDIN\n", Session.Info.Name)
fmt.Fprintln(w, "\nPATH_OR_STDIN being either a path to a file or `-` to accept input from stdin")
set.PrintDefaults()
}
func readIntoBuffer(r io.Reader) (*bytes.Buffer, error) {
var b []byte
var empty bytes.Buffer
_, err := io.ReadFull(r, b)
if err != nil {
return &empty, err
}
buff := bytes.NewBuffer(b)
return buff, nil
}
func intoList(flagSeen, flagAnswered, flagFlagged, flagDeleted, flagDraft bool) []string {
var result []string
if flagSeen {
result = append(result, "seen")
}
if flagAnswered {
result = append(result, "answered")
}
if flagFlagged {
result = append(result, "flagged")
}
if flagDeleted {
result = append(result, "deleted")
}
if flagDraft {
result = append(result, "draft")
}
return result
}

View file

@ -18,9 +18,13 @@ var Log *log.Logger
func init() { func init() {
get := GetCmd{} get := GetCmd{}
set := SetCmd{} set := SetCmd{}
add := AddCmd{}
// del := DelCmd{}
Session.Info.Commands = cli.CommandMap{ Session.Info.Commands = cli.CommandMap{
"get": get, "get": get,
"set": set, "set": set,
"add": add,
// "del": del,
} }
Session.Info.Name = "papero" Session.Info.Name = "papero"
flag.Usage = func() { cli.Usage(os.Stdout, Session.Info) } flag.Usage = func() { cli.Usage(os.Stdout, Session.Info) }

View file

@ -5,6 +5,7 @@ import (
"flag" "flag"
"fmt" "fmt"
"io" "io"
"time"
) )
type GlobalOpts struct { type GlobalOpts struct {
@ -84,3 +85,28 @@ func (pf PairFlag) Set(s string) error {
} }
var ErrAllowedPairFlagValues = errors.New("only `set` or `unset` are allowed") var ErrAllowedPairFlagValues = errors.New("only `set` or `unset` are allowed")
type AbsTimeFlag struct {
*time.Time
}
func (t AbsTimeFlag) String() string {
return fmt.Sprint(t.Time)
}
func (t AbsTimeFlag) Set(s string) error {
const layout = "2006-01-02T15:04:05"
var parsedTime time.Time
var err error
if s == "" {
t.Time = &parsedTime
return nil
}
parsedTime, err = time.Parse(layout, s)
if err != nil {
return err
}
t.Time = &parsedTime
return nil
}

47
imaputils/put_message.go Normal file
View file

@ -0,0 +1,47 @@
package imaputils
import (
"bytes"
"time"
"git.sr.ht/~blallo/papero/config"
)
var zeroTime = time.Time{}
type PutMessageOpts struct {
Debug bool
Mailbox string
Body *bytes.Buffer
Flags []string
Time time.Time
}
func PutMessage(conf *config.AccountData, opts *PutMessageOpts) error {
conn := NewConnection(conf)
err := conn.Start(opts.Debug)
if err != nil {
return err
}
defer conn.Close()
return PutMessageInSession(conn, opts)
}
func PutMessageInSession(conn *IMAPConnection, opts *PutMessageOpts) error {
var err error
var msgTime time.Time
_, err = conn.client.Select(opts.Mailbox, false)
if err != nil {
return err
}
if opts.Time == zeroTime {
msgTime = time.Now()
} else {
msgTime = opts.Time
}
return conn.client.Append(opts.Mailbox, opts.Flags, msgTime, opts.Body)
}