shithub: hell

ref: 57b338cb6111cc440b2e8074678d18d2eec65fdf
dir: /commands.go/

View raw version
package main

import (
	"fmt"
	"strings"

	mastodon "codeberg.org/penny64/hellclient-go-mastodon"
)

var commands = []string{"examine", "reply", "like", "thread", "open", "prev", "download", "dm", "rt", "hrt", "parent", "children", "rm", "mark", "unmark", "account", "import", "pause", "resume", "url", "fpost", "ufpost", "edit", "notice", "stats", "next", "view", "bookmarks", "follow", "unfollow", "likes", "help", "reload", "attach", "detach", "pinned", "cat", "play", "translate", "read", "version", "local", "public", "block", "unblock", "unlike", "home", "page", "profile"}

func processInput(input string) (command string, arguments string, found bool) {

	if input == "" {
		command = ""
		arguments = ""
		return
	}

	if input[0] != '/' {
		command = ""
		arguments = input
		return
	}

	inputcommand, _, hasargument := strings.Cut(input[1:], " ")

	if !hasargument {
		inputcommand = input[1:]
	}

	for _, choice := range commands {
		if strings.HasPrefix(choice, inputcommand) {
			command = choice
			_, arguments, _ = strings.Cut(input, " ")
			found = true
			break
		}
	}

	if command == "" {
		command = inputcommand
	}

	return
}

func pullParameter(input string) (parameter string, remainder string) {
	if strings.HasPrefix(input, "?") {
		parameter, _, _ = strings.Cut(input, " ")
		if len(parameter) == len(input) {
			remainder = ""
			parameter = input
		} else {
			remainder = input[len(parameter)+1:]
		}
	} else {
		return "", input
	}

	prefix, _, cut := strings.Cut(parameter, "\"")

	if cut {
		quote, _, _ := strings.Cut(input[len(prefix)+1:], "\"")
		parameter = prefix + quote
		if len(parameter)+3 <= len(input) {
			remainder = input[len(parameter)+3:]
		} else {
			remainder = input[len(parameter)+2:]
		}
	}
	return
}

func splitParameter(input string) (parameter []string) {
	if len(input) < 2 {
		//nothing here
		return nil
	}
	input = input[1:]
	key, value, _ := strings.Cut(input, "=")
	return []string{key, value}
}

func extractInputParameters(input string) (remainder string, parameters [][]string) {
	parameter := " "
	remainder = input
	for parameter != "" {
		parameter, remainder = pullParameter(remainder)
		if parameter != " " && parameter != "" {
			parameters = append(parameters, splitParameter(parameter))
		}
	}
	return
}


type cmdflag uint8

const (
	status   cmdflag = 1 << iota
	account
	argument
)

type cmddata struct {
	status *mastodon.Status
	account *mastodon.Account
	reblogger *mastodon.Status
	raw_argument string
	command string
	content string
	index string
	hc *Hellclient
}

type cmd struct {
	data *cmddata
	cmder cmder
}

type cmder interface {
	name() string
	flags() cmdflag
	result(data *cmddata) string
}

func (cmd *cmd) String() string {
	return cmd.cmder.result(cmd.data)
}

func (cmd *cmd) checkReqs() (err error) {
	if (cmd.cmder.flags()&status != 0) && (cmd.cmder.flags()&account != 0) {
		if cmd.data.status == nil && cmd.data.account == nil {
			return fmt.Errorf("%s requires a status or an account", cmd.cmder.name())
		}
	} else {
		if (cmd.cmder.flags()&status != 0) && (cmd.data.status == nil) {
			return fmt.Errorf("%s requires a status", cmd.cmder.name())
		}
		if (cmd.cmder.flags()&account != 0) && (cmd.data.account == nil) {
			return fmt.Errorf("%s requires an account", cmd.cmder.name())
		}
	}

	if (cmd.cmder.flags()&argument != 0) && (cmd.data.raw_argument == "") {
		return fmt.Errorf("%s requires an argument", cmd.cmder.name())
	}

	return nil
}

type dmcmd struct {}

func (cmd *dmcmd) name() string {
	return "dm"
}

func (cmd *dmcmd) flags() cmdflag {
	return argument
}

func (cmd *dmcmd) result(data *cmddata) string {
	hc :=data.hc
	if data.raw_argument != "" {
		hc.dispatchStatus(data.raw_argument, "direct")
		return ""
	}
	hc.page = &Page{}
	getter := &BasicStatusGetter{getter: hc.client.GetTimelineDirect}
	hc.page.loader = &StatusPages{hc: hc, getter: getter}
	fmt.Print(hc.page.String())
	hc.pause(true)
	return ""
}