Basic working Run method is added. Small bits of cleanup.

This commit is contained in:
sloumdrone 2019-06-29 13:37:56 -07:00
parent 834cc175ba
commit 917752a0e1
1 changed files with 58 additions and 24 deletions

View File

@ -8,6 +8,8 @@ import (
"fmt" "fmt"
"bufio" "bufio"
"sort" "sort"
"syscall"
"path/filepath"
) )
type Entry map[string]string type Entry map[string]string
@ -17,27 +19,34 @@ type Mailcap struct {
Caps Cap Caps Cap
} }
// Creates and initializes the mailcap struct/db
// Returns a pointer to Mailcap struct
func NewMailcap() *Mailcap { func NewMailcap() *Mailcap {
mc := Mailcap{make(Cap)} mc := Mailcap{make(Cap)}
mc.getCaps() mc.getCaps()
return &mc return &mc
} }
// Prints the mailcap db, returns nothing
func (m *Mailcap) ShowAll() { func (m *Mailcap) ShowAll() {
fmt.Print(m.Caps) fmt.Print(m.Caps)
fmt.Println() fmt.Println()
} }
func (m *Mailcap) Show(mime string) { // Prints the db entries for the mimetype in question.
// Returns Fields (an Entry slice) and an error or nil.
func (m *Mailcap) Show(mime string) (Fields, error) {
if v, ok := m.Caps[mime]; ok { if v, ok := m.Caps[mime]; ok {
fmt.Println(mime + ":") fmt.Println(mime + ":")
fmt.Print(v) fmt.Print(v)
fmt.Println("") fmt.Println("")
} else { return v, nil
fmt.Printf("Cannot find %s\n", mime)
} }
return make(Fields, 0), fmt.Errorf("Cannot find %s\n", mime)
} }
// Utility to print the mailcap files that will
// be searched.
func (m *Mailcap) ShowFiles() { func (m *Mailcap) ShowFiles() {
for _, s := range getMailcapFileList() { for _, s := range getMailcapFileList() {
fmt.Println(s) fmt.Println(s)
@ -45,18 +54,20 @@ func (m *Mailcap) ShowFiles() {
} }
} }
// Finds the program to run for the mimetype in question
// based on the key, common keys: view, edit, and the path.
// Returns the final command as a string and nil, or if error
// an empty string and the error
func (m *Mailcap) FindMatch(mime, key, path string) (string, error) { func (m *Mailcap) FindMatch(mime, key, path string) (string, error) {
entries := m.lookup(mime, key) entries := m.lookup(mime, key)
for _, v := range entries { for _, v := range entries {
exitCode := 0; exitCode := 0;
if _, ok := v["needsterminal"]; ok {
continue
}
if t, ok := v["test"]; ok { if t, ok := v["test"]; ok {
cmdArgs := strings.Split(t, " ") cmdArgs := strings.Split(t, " ")
if len(cmdArgs) < 2 { if len(cmdArgs) < 2 {
continue continue
} }
com := exec.Command(cmdArgs[0], cmdArgs[1:]...) com := exec.Command(cmdArgs[0], cmdArgs[1:]...)
if err := com.Run(); err != nil { if err := com.Run(); err != nil {
if exitError, ok := err.(*exec.ExitError); ok { if exitError, ok := err.(*exec.ExitError); ok {
@ -79,24 +90,40 @@ func (m *Mailcap) FindMatch(mime, key, path string) (string, error) {
return "", fmt.Errorf("Unable to find key %q in entries for %s", key, mime) return "", fmt.Errorf("Unable to find key %q in entries for %s", key, mime)
} }
func (m *Mailcap) RunMatch(mime, key, path string) { // Runs the program that fits the mimetype with the key
// and path. Common keys: view, edit. Returns an error
// or nil if there is no error.
func (m *Mailcap) RunMatch(mime, key, path string) error {
pwd := os.Getenv("PWD")
dir := filepath.Dir(path)
os.Setenv("PWD", dir)
defer os.Setenv("PWD", pwd)
env := os.Environ()
match, err := m.FindMatch(mime, key, path) match, err := m.FindMatch(mime, key, path)
var command *exec.Cmd if err != nil {
if err == nil { return err
matchFields := strings.Fields(match)
if len(matchFields) > 1 {
command = exec.Command(matchFields[0], matchFields[1:]...)
} else {
command = exec.Command(match)
}
e := command.Run()
fmt.Println(err)
if e != nil {
fmt.Println("There was an issue...")
}
} }
matchFields := strings.Fields(match)
binary, lookErr := exec.LookPath(matchFields[0])
if lookErr != nil {
return lookErr
}
execErr := syscall.Exec(binary, []string{matchFields[0], path}, env)
if execErr != nil {
return execErr
}
return nil
} }
// Private method to lookup the items for a particular
// mimetype and key, returns Fields
func (m *Mailcap) lookup(mime, key string) Fields { func (m *Mailcap) lookup(mime, key string) Fields {
f := make(Fields, 0, 5) f := make(Fields, 0, 5)
if val, ok := m.Caps[mime]; ok { if val, ok := m.Caps[mime]; ok {
@ -123,10 +150,12 @@ func (m *Mailcap) lookup(mime, key string) Fields {
return output return output
} }
// Top level private initialization method
// Creates the mailcap db and loads it into the
// Caps paramater of the Mailcap struct in question
func (m *Mailcap) getCaps() { func (m *Mailcap) getCaps() {
lnNum := 0 lnNum := 0
var moreCaps Cap moreCaps := make(Cap)
moreCaps = make(Cap)
for _, mailcapFile := range getMailcapFileList() { for _, mailcapFile := range getMailcapFileList() {
file, err := os.Open(mailcapFile) file, err := os.Open(mailcapFile)
if err != nil { if err != nil {
@ -167,6 +196,8 @@ func getMailcapFileList() (mCapSlice []string) {
return return
} }
// Reads an individual mailcap file and returns a Cap
// and a line number
func readMailcapFile(f *os.File,ln int) (Cap, int) { func readMailcapFile(f *os.File,ln int) (Cap, int) {
caps := make(Cap) caps := make(Cap)
reader := bufio.NewReader(f) reader := bufio.NewReader(f)
@ -216,6 +247,8 @@ func readMailcapFile(f *os.File,ln int) (Cap, int) {
return caps, ln return caps, ln
} }
// Parses an individual mailcap line, returns the key
// as a string, all of the fields, and an error or nil.
func parseLine(ln string) (string, Entry, error) { func parseLine(ln string) (string, Entry, error) {
outputFields := make(Entry) outputFields := make(Entry)
i := 0 i := 0
@ -254,6 +287,7 @@ func parseLine(ln string) (string, Entry, error) {
return key, outputFields, nil return key, outputFields, nil
} }
// Gets one key value pair
func parseField(ln string, i, n int) (string, int) { func parseField(ln string, i, n int) (string, int) {
// get one key-value pair from mailcap entry // get one key-value pair from mailcap entry
start := i start := i