Skip to content
Snippets Groups Projects
Select Git revision
  • 561977c3c4a49d99ce7e6369d0de75af25320211
  • release default protected
  • more-testing
  • attempt-vax90b1
  • attempt-1
  • conversion protected
  • linux
  • v0.9.1 protected
  • v0.9.0 protected
9 results

messages.go

Blame
  • messages.go 8.05 KiB
    // Package repl implements the main event loop.
    package repl
    
    import (
    	"errors"
    	"fmt"
    	"strconv"
    	"strings"
    	"time"
    
    	"git.lyda.ie/kevin/bulletin/ask"
    	"git.lyda.ie/kevin/bulletin/dclish"
    	"git.lyda.ie/kevin/bulletin/editor"
    	"git.lyda.ie/kevin/bulletin/folders"
    	"git.lyda.ie/kevin/bulletin/pager"
    	"git.lyda.ie/kevin/bulletin/this"
    )
    
    // ActionDirectory handles the `DIRECTORY` command.  This lists all the
    // messages in the current folder.
    func ActionDirectory(cmd *dclish.Command) error {
    	// TODO: flag parsing.
    	showExpiration := false
    	if cmd.Flags["/EXPIRATION"].Value == "true" {
    		showExpiration = true
    	}
    	if len(cmd.Args) == 1 {
    		folder, err := folders.ValidFolder(cmd.Args[0])
    		if err != nil {
    			return err
    		}
    		this.Folder = folder
    	}
    	msgs, err := folders.ListMessages(this.Folder.Name)
    	if err != nil {
    		return err
    	}
    	if len(msgs) == 0 {
    		fmt.Println("There are no messages present.")
    		return nil
    	}
    	fmt.Printf("%4s %-43s %-12s %-10s\n", "#", "Subject", "From", "Date")
    	for _, msg := range msgs {
    		fmt.Printf("%s\n", msg.OneLine(showExpiration))
    	}
    
    	return nil
    }
    
    // ActionAdd handles the `ADD` command.  This adds a message to a folder.
    func ActionAdd(cmd *dclish.Command) error {
    	optAll := 0
    	optBell := 0
    	optBroadcast := 0
    	optEdit := 0
    	optExpiration := &time.Time{}
    	optExtract := 0
    	optFolder := []string{}
    	optIndent := 0
    	optPermanent := 0
    	optShutdown := 0
    	optSignature := 0
    	optSubject := ""
    	optSystem := 0
    
    	if cmd.Flags["/ALL"].Value == "true" {
    		optAll = 1
    	}
    	if cmd.Flags["/BELL"].Value == "true" {
    		optBell = 1
    	}
    	if cmd.Flags["/BROADCAST"].Value == "true" {
    		optBroadcast = 1
    	}
    	if cmd.Flags["/EDIT"].Value == "true" {
    		optEdit = 1
    	}
    	if cmd.Flags["/EXPIRATION"].Value != "" {
    		// dd-mmm-yyyy, or delta time: dddd
    		exp, err := time.Parse("2006-01-02", cmd.Flags["/EXPIRATION"].Value)
    		if err != nil {
    			days, err := strconv.Atoi(cmd.Flags["/EXPIRATION"].Value)
    			if err != nil {
    				optExpiration = nil
    			}
    			exp := time.Now().AddDate(0, 0, days)
    			optExpiration = &exp
    		} else {
    			optExpiration = &exp
    		}
    	}
    	if cmd.Flags["/EXTRACT"].Value == "true" {
    		optExtract = 1
    	}
    	if cmd.Flags["/FOLDER"].Value != "" {
    		fmt.Printf("/FOLDER = %s\n", cmd.Flags["/FOLDER"].Value)
    		optFolder = strings.Split(cmd.Flags["/FOLDER"].Value, ",")
    	}
    	if cmd.Flags["/INDENT"].Value == "true" {
    		optIndent = 1
    	}
    	if cmd.Flags["/PERMANENT"].Value == "true" {
    		optPermanent = 1
    	}
    	if cmd.Flags["/SHUTDOWN"].Value == "true" {
    		optShutdown = 1
    	}
    	if cmd.Flags["/SIGNATURE"].Value == "true" {
    		optSignature = 1
    	}
    	if cmd.Flags["/SUBJECT"].Value != "" {
    		optSubject = cmd.Flags["/SUBJECT"].Value
    	}
    	if cmd.Flags["/SYSTEM"].Value == "true" {
    		optSystem = 1
    	}
    
    	fmt.Printf("TODO: optAll is not yet implemented - you set it to %d\n", optAll)
    	fmt.Printf("TODO: optBell is not yet implemented - you set it to %d\n", optBell)
    	fmt.Printf("TODO: optBroadcast is not yet implemented - you set it to %d\n", optBroadcast)
    	fmt.Printf("TODO: optEdit is not yet implemented - you set it to %d\n", optEdit)
    	fmt.Printf("TODO: optExtract is not yet implemented - you set it to %d\n", optExtract)
    	fmt.Printf("TODO: optIndent is not yet implemented - you set it to %d\n", optIndent)
    	fmt.Printf("TODO: optSignature is not yet implemented - you set it to %d\n", optSignature)
    	fmt.Printf("TODO: optSystem is not yet implemented - you set it to %d\n", optSystem)
    
    	if len(optFolder) == 0 {
    		optFolder = []string{this.Folder.Name}
    	}
    	// TODO: check if folders exist.
    	if optSubject == "" {
    		optSubject, _ = ask.GetLine("Enter subject of message: ")
    		if optSubject == "" {
    			return errors.New("Must enter a subject")
    		}
    	}
    	// TODO: check we have permission for shutdown and permanent
    
    	message, err := editor.Editor(fmt.Sprintf("Enter message for '%s'...", optSubject), "Edit message")
    	if err != nil {
    		return err
    	}
    	for i := range optFolder {
    		err = folders.CreateMessage(this.User.Login, optSubject, message,
    			optFolder[i], optPermanent, optShutdown, optExpiration)
    	}
    	return nil
    }
    
    // ActionCurrent handles the `CURRENT` command.
    func ActionCurrent(_ *dclish.Command) error {
    	// TODO: handle flags.
    	msg, err := folders.ReadMessage(this.User.Login, this.Folder.Name, this.MsgID)
    	if err != nil {
    		return err
    	}
    	lines := strings.Split(msg.String(), "\n")
    	if len(lines) > 10 {
    		lines = lines[:10]
    	}
    	fmt.Printf("%s\n", strings.Join(lines, "\n"))
    	return nil
    }
    
    // ActionBack handles the `BACK` command.
    func ActionBack(_ *dclish.Command) error {
    	// TODO: handle flags.
    	msgid := folders.PrevMsgid(this.User.Login, this.Folder.Name, this.MsgID)
    	if msgid == 0 {
    		fmt.Println("No previous messages")
    		return nil
    	}
    	msg, err := folders.ReadMessage(this.User.Login, this.Folder.Name, msgid)
    	if err != nil {
    		return err
    	}
    	// TODO: pager needs to report if the whole message was read
    	// and only increment if not.
    	pager.Pager(msg.String())
    	this.MsgID = msgid
    	return nil
    }
    
    // ActionChange handles the `CHANGE` command.
    func ActionChange(cmd *dclish.Command) error {
    	fmt.Printf("TODO: unimplemented...\n%s\n", cmd.Description)
    	return nil
    }
    
    // ActionFirst handles the `FIRST` command.
    func ActionFirst(_ *dclish.Command) error {
    	msgid := folders.FirstMessage(this.Folder.Name)
    	if msgid == 0 {
    		fmt.Println("No messages in folder")
    		return nil
    	}
    	this.MsgID = msgid
    	return nil
    }
    
    // ActionNext handles the `NEXT` command.
    func ActionNext(_ *dclish.Command) error {
    	// TODO: handle flags.
    	msgid := folders.NextMsgid(this.User.Login, this.Folder.Name, this.MsgID)
    	if msgid == 0 {
    		fmt.Println("No next messages")
    		return nil
    	}
    	msg, err := folders.ReadMessage(this.User.Login, this.Folder.Name, msgid)
    	if err != nil {
    		return err
    	}
    	// TODO: pager needs to report if the whole message was read
    	// and only increment if not.
    	pager.Pager(msg.String())
    	this.MsgID = msgid
    	return nil
    }
    
    // ActionRead handles the `READ` command.
    func ActionRead(cmd *dclish.Command) error {
    	// TODO: handle flags.
    	msgid := this.MsgID
    	if len(cmd.Args) == 1 {
    		var err error
    		msgid, err = strconv.ParseInt(cmd.Args[0], 10, 64)
    		if err != nil {
    			return err
    		}
    	}
    	msg, err := folders.ReadMessage(this.User.Login, this.Folder.Name, msgid)
    	if err != nil {
    		return err
    	}
    	// TODO: pager needs to report if the whole message was read
    	// and only increment if not.
    	pager.Pager(msg.String())
    	msgid = folders.NextMsgid(this.User.Login, this.Folder.Name, msgid)
    	this.MsgID = max(this.MsgID, msgid)
    	return nil
    }
    
    // ActionReply handles the `REPLY` command.
    func ActionReply(cmd *dclish.Command) error {
    	fmt.Printf("TODO: unimplemented...\n%s\n", cmd.Description)
    	return nil
    }
    
    // ActionForward handles the `FORWARD` command.
    func ActionForward(cmd *dclish.Command) error {
    	fmt.Printf("TODO: unimplemented...\n%s\n", cmd.Description)
    	return nil
    }
    
    // ActionSeen handles the `SEEN` command.
    func ActionSeen(cmd *dclish.Command) error {
    	var err error
    	msgids := []int64{this.MsgID}
    	if len(cmd.Args) == 1 {
    		msgids, err = ParseNumberList(cmd.Args[0])
    		if err != nil {
    			return err
    		}
    	}
    	err = folders.MarkSeen(msgids)
    	if err != nil {
    		fmt.Printf("ERROR: %s.\n", err)
    	}
    	return nil
    }
    
    // ActionUnseen handles the `UNSEEN` command.
    func ActionUnseen(cmd *dclish.Command) error {
    	var err error
    	msgids := []int64{this.MsgID}
    	if len(cmd.Args) == 1 {
    		msgids, err = ParseNumberList(cmd.Args[0])
    		if err != nil {
    			return err
    		}
    	}
    	err = folders.MarkUnseen(msgids)
    	if err != nil {
    		fmt.Printf("ERROR: %s.\n", err)
    	}
    	return nil
    }
    
    // ActionDelete handles the `DELETE` command.
    func ActionDelete(cmd *dclish.Command) error {
    	// TODO: Follow permissions.
    	var err error
    
    	all := false
    	if cmd.Flags["/ALL"].Value == "true" {
    		all = true
    	}
    	if all {
    		if len(cmd.Args) == 1 {
    			fmt.Println("ERROR: Can't specify both message numbers and /ALL flag.")
    			return nil
    		}
    		err := folders.DeleteAllMessages()
    		if err != nil {
    			fmt.Printf("ERROR: %s.\n", err)
    		}
    		return nil
    	}
    
    	msgids := []int64{this.MsgID}
    	if len(cmd.Args) == 1 {
    		msgids, err = ParseNumberList(cmd.Args[0])
    		if err != nil {
    			fmt.Printf("ERROR: %s.\n", err)
    			return nil
    		}
    	}
    	err = folders.DeleteMessages(msgids)
    	if err != nil {
    		fmt.Printf("ERROR: %s.\n", err)
    	}
    	return nil
    }