vote

package
v0.0.0-...-bf34452 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 25, 2023 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// MsgAlreadyVoted returns that the user already voted
	MsgAlreadyVoted = "%v already voted"
	// MsgVotedAgainst returns that the user voted against the vote
	MsgVotedAgainst = "%v voted no"
	// MsgVotedInFavor returns that the user voted for the vote
	MsgVotedInFavor = "%v voted yes"
)
View Source
const (
	// MsgHelpBallotInFavor is help text for ?yes
	MsgHelpBallotInFavor = "Casts a ballot in favor of the current vote, if one is active"
	// MsgHelpBallotAgainst is help text for ?no
	MsgHelpBallotAgainst = "Casts a ballot against the current vote, if one is active"
)
View Source
const (
	// KeyMostRecentVoteID is the key/value store key for the vote
	KeyMostRecentVoteID = "most-recent-vote-id-channel-%v"
	// RedisMostRecentVoteID is the vote id of the most recent vote
	RedisMostRecentVoteID = "most-recent-vote-id-channel-*"
	// KeyVoteTemplate is the map from vote to channel
	KeyVoteTemplate = "vote-%v-channel-%v"
	// VoteDuration is the duration of a vote
	VoteDuration = time.Duration(30) * time.Minute
)
View Source
const (
	// MsgActiveVote prints that a vote is already active
	MsgActiveVote = "Cannot start a vote while another is in progress. Type `?votestatus` for more info"
	// MsgBroadcastNewVote prints that a new vote is happening
	MsgBroadcastNewVote = "@everyone -- %s started a new vote: %s\n\nType `?yes` or `?no` to vote. 30 minutes remaining."
)
View Source
const (
	// MsgNoActiveVote prints that there was no active vote
	MsgNoActiveVote = "No active vote"
	// MsgOneVoteAgainst is the unpluralized message for vote against
	MsgOneVoteAgainst = "1 vote against"
	// MsgOneVoteFor is the unpluralized message for vote for
	MsgOneVoteFor = "1 vote for"
	// MsgSpacer is used to separate parts of the output string
	MsgSpacer = "-----"
	// MsgStatusInconclusive prints that a vote was inconclusive
	MsgStatusInconclusive = "Not enough votes were cast."
	// MsgStatusVoteFailed prints that a vote has failed
	MsgStatusVoteFailed = "Vote Failed."
	// MsgStatusVoteFailing prints that a vote is currently failing
	MsgStatusVoteFailing = "Vote is failing"
	// MsgStatusVotePassed indicates that the vote has passed
	MsgStatusVotePassed = "Vote Passed!"
	// MsgStatusVotePassing prints whether the vote is passing
	MsgStatusVotePassing = "Vote is passing"
	// MsgStatusVotesNeeded prints how many votes are needed
	MsgStatusVotesNeeded = "5 votes must be cast before vote can pass"
	// MsgVoteOwner prints who started the vote
	MsgVoteOwner = "Vote started by %s: "
	// MsgVotesAgainst prints the votes against
	MsgVotesAgainst = "%d votes against"
	// MsgVotesFor prints the votes for
	MsgVotesFor = "%d votes for"
)
View Source
const (
	// MsgNoTimeRemaining prints that there is no time left
	MsgNoTimeRemaining = "No time remaining in vote"
	// MsgMinutesRemaining prints the minutes remaining
	MsgMinutesRemaining = "%v minutes remaining"
	// MsgSecondsRemaining prints the seconds remaining
	MsgSecondsRemaining = "%v seconds remaining"
	// MsgMillisecondsRemaining is a time output for a few milliseconds remaining
	MsgMillisecondsRemaining = "%v milliseconds remaining"
)
View Source
const (
	// MsgHelpStatus is the help text for ?votestatus
	MsgHelpStatus = "Prints the status of the current vote, or a message indicating that no vote is active"
)
View Source
const (
	// MsgHelpVote is the help text for ?vote
	MsgHelpVote = "" /* 222-byte string literal not displayed */
)
View Source
const (
	// MsgVoteConcluded is the header for a concluded vote
	MsgVoteConcluded = "@here -- Vote started by %s has concluded"
)

Variables

View Source
var ErrorAlreadyVoted = errors.New("user already voted")

ErrorAlreadyVoted indicates that the user can't vote twice

View Source
var ErrorNoVoteActive = errors.New("cannot vote when there is no active vote")

ErrorNoVoteActive indicates that the user can't vote if no vote is active

View Source
var ErrorOnlyOneVote = errors.New("tried to start vote when one is already active")

ErrorOnlyOneVote indicates that a second vote cannot be started

View Source
var ErrorVoteHasOutcome = errors.New("cannot change vote outcome")

ErrorVoteHasOutcome indicates that the application already set the vote outcome, and to give up

Functions

func CompletedStatusLine

func CompletedStatusLine(vote *model.Vote) string

CompletedStatusLine generates the full status line of a concluded vote.

func HandleVotesOnInitialLoad

func HandleVotesOnInitialLoad(s api.DiscordSession, modelHelper *ModelHelper, clock model.UTCClock, timer model.UTCTimer, commandChannel chan<- *model.Command) error

HandleVotesOnInitialLoad iterates through active vote pointers to see if any require timers to be re-fired.

func StatusLine

func StatusLine(clock model.UTCClock, vote *model.Vote) string

StatusLine returns the full status line of an in-progress vote.

func TimeString

func TimeString(clock model.UTCClock, timestampEnd time.Time) string

TimeString generates a user-readable string for the duration calculated from input

Types

type BallotExecutor

type BallotExecutor struct {
	// contains filtered or unexported fields
}

BallotExecutor executes a vote

func NewBallotExecutor

func NewBallotExecutor(modelHelper *ModelHelper) *BallotExecutor

NewBallotExecutor works as advertised

func (*BallotExecutor) Execute

func (e *BallotExecutor) Execute(s api.DiscordSession, channelID model.Snowflake, command *model.Command)

Execute runs the command

func (*BallotExecutor) GetType

func (e *BallotExecutor) GetType() int

GetType returns the type of this feature.

func (*BallotExecutor) PublicOnly

func (e *BallotExecutor) PublicOnly() bool

PublicOnly returns whether the executor should be intercepted in a private channel.

type BallotParser

type BallotParser struct {
	// The message that the parser looks for.
	Message string
	// Whether this message is in favor or against the measure.
	InFavor bool
}

BallotParser parses a vote for or against

func NewBallotParser

func NewBallotParser(message string, inFavor bool) *BallotParser

NewBallotParser works as advertised.

func (*BallotParser) GetName

func (p *BallotParser) GetName() string

GetName returns the named type.

func (*BallotParser) HelpText

func (p *BallotParser) HelpText(command string) (string, error)

HelpText returns the help text.

func (*BallotParser) Parse

func (p *BallotParser) Parse(splitContent []string, m *discordgo.MessageCreate) (*model.Command, error)

Parse parses the given list command.

type ConcludeExecutor

type ConcludeExecutor struct {
	// contains filtered or unexported fields
}

ConcludeExecutor concludes the active vote and prints the results

func NewConcludeExecutor

func NewConcludeExecutor(modelHelper *ModelHelper) *ConcludeExecutor

NewConcludeExecutor works as advertised

func (*ConcludeExecutor) Execute

func (e *ConcludeExecutor) Execute(s api.DiscordSession, channelID model.Snowflake, command *model.Command)

Execute executes the command

func (*ConcludeExecutor) GetType

func (e *ConcludeExecutor) GetType() int

GetType returns the type of this feature.

func (*ConcludeExecutor) PublicOnly

func (e *ConcludeExecutor) PublicOnly() bool

PublicOnly returns whether the executor should be intercepted in a private channel. Since the vote is pinned to a channel, it should have been filtered then. If somehow the channel went private at that point, allow it to conclude.

type Feature

type Feature struct {
	// contains filtered or unexported fields
}

Feature registers feature-specific things for moderation.

func NewFeature

func NewFeature(featureRegistry *feature.Registry, voteMap stringmap.StringMap, clock model.UTCClock, timer model.UTCTimer, commandChannel chan<- *model.Command) *Feature

NewFeature returns a new Feature.

func (*Feature) CommandInterceptors

func (f *Feature) CommandInterceptors() []feature.CommandInterceptor

CommandInterceptors returns command interceptors.

func (*Feature) Executors

func (f *Feature) Executors() []feature.Executor

Executors gets the executors.

func (*Feature) FallbackParser

func (f *Feature) FallbackParser() feature.Parser

FallbackParser returns nil.

func (*Feature) OnInitialLoad

func (f *Feature) OnInitialLoad(s api.DiscordSession) error

OnInitialLoad cleans up from any votes that were already active when crbot shut down.

func (*Feature) Parsers

func (f *Feature) Parsers() []feature.Parser

Parsers returns the parsers.

type ModelHelper

type ModelHelper struct {
	StringMap stringmap.StringMap
	UTCClock  model.UTCClock
}

ModelHelper adds helper functions for using votes with a stringmap. Currently, it handles a majority of business logic. However, if functionality is ever added to allow a moderator to edit a vote after it has happened, the business logic will need to be pulled of here and leave this to be strictly a data structure that only validates its own sanity. The only logic that seems like it should be handled but isn't is the logic for when a vote outcome is recorded, because that is handled in an evented manner (i.e. when a timer ends).

func NewModelHelper

func NewModelHelper(stringMap stringmap.StringMap, utcClock model.UTCClock) *ModelHelper

NewModelHelper works as advertised.

func (*ModelHelper) CastBallot

func (h *ModelHelper) CastBallot(channelID model.Snowflake, userID model.Snowflake, inFavor bool) (*model.Vote, error)

CastBallot casts a ballot against the current poll for the given user. On success, it returns the vote with the ballot incorporated. Returns ErrorNoVoteActive if there is no active poll, or the inner error if a component errored. Returns ErrorAlreadyVoted if the user is present in either list.

func (*ModelHelper) IsVoteActive

func (h *ModelHelper) IsVoteActive(channelID model.Snowflake) (bool, error)

IsVoteActive returns whether there is a most-recent, active vote.

func (*ModelHelper) MostRecentVote

func (h *ModelHelper) MostRecentVote(channelID model.Snowflake) (*model.Vote, error)

MostRecentVote returns the active vote, or nil if none present. Returns an error on i/o problems.

func (*ModelHelper) MostRecentVoteID

func (h *ModelHelper) MostRecentVoteID(channelID model.Snowflake) (int, error)

MostRecentVoteID returns the most recent ID. Returns `0, nil` if no vote has ever been executed.

func (*ModelHelper) MostRecentVotes

func (h *ModelHelper) MostRecentVotes() ([]*model.Vote, error)

MostRecentVotes returns every most recent vote in the database.

func (*ModelHelper) SetVoteOutcome

func (h *ModelHelper) SetVoteOutcome(channelID model.Snowflake, voteOutcome int) error

SetVoteOutcome terminates an active vote with the given outcome

func (*ModelHelper) StartNewVote

func (h *ModelHelper) StartNewVote(channelID, userID model.Snowflake, message string) (*model.Vote, error)

StartNewVote starts and returns a new vote. Returns ErrorOnlyOneVote if another vote was active when trying to start this one.

type StartVoteExecutor

type StartVoteExecutor struct {
	// contains filtered or unexported fields
}

StartVoteExecutor executes a vote begin command

func NewStartVoteExecutor

func NewStartVoteExecutor(modelHelper *ModelHelper, commandChannel chan<- *model.Command, utcTimer model.UTCTimer) *StartVoteExecutor

NewStartVoteExecutor works as advertised

func (*StartVoteExecutor) Execute

func (e *StartVoteExecutor) Execute(s api.DiscordSession, channelID model.Snowflake, command *model.Command)

Execute starts a new vote if one is not already active. It also starts a timer to use to conclude the vote.

func (*StartVoteExecutor) GetType

func (e *StartVoteExecutor) GetType() int

GetType returns the type of this feature.

func (*StartVoteExecutor) PublicOnly

func (e *StartVoteExecutor) PublicOnly() bool

PublicOnly returns whether the executor should be intercepted in a private channel.

type StartVoteParser

type StartVoteParser struct {
}

StartVoteParser parses ?vote commands.

func NewStartVoteParser

func NewStartVoteParser() *StartVoteParser

NewStartVoteParser works as advertised.

func (*StartVoteParser) GetName

func (p *StartVoteParser) GetName() string

GetName returns the named type of this feature.

func (*StartVoteParser) HelpText

func (p *StartVoteParser) HelpText(command string) (string, error)

HelpText explains how to use ?vote.

func (*StartVoteParser) Parse

func (p *StartVoteParser) Parse(splitContent []string, m *discordgo.MessageCreate) (*model.Command, error)

Parse parses the given vote command.

type StatusExecutor

type StatusExecutor struct {
	// contains filtered or unexported fields
}

StatusExecutor allows the user to check on the progress of the current vote

func NewStatusExecutor

func NewStatusExecutor(modelHelper *ModelHelper) *StatusExecutor

NewStatusExecutor works as advertised

func (*StatusExecutor) Execute

func (e *StatusExecutor) Execute(s api.DiscordSession, channel model.Snowflake, command *model.Command)

Execute prints the status of the current vote.

func (*StatusExecutor) GetType

func (e *StatusExecutor) GetType() int

GetType returns the type of this feature.

func (*StatusExecutor) PublicOnly

func (e *StatusExecutor) PublicOnly() bool

PublicOnly returns whether the executor should be intercepted in a private channel.

type StatusParser

type StatusParser struct {
}

StatusParser parses ?votestatus commands

func NewStatusParser

func NewStatusParser() *StatusParser

NewStatusParser works as advertised.

func (*StatusParser) GetName

func (p *StatusParser) GetName() string

GetName returns the named type.

func (*StatusParser) HelpText

func (p *StatusParser) HelpText(command string) (string, error)

HelpText returns the help text.

func (*StatusParser) Parse

func (p *StatusParser) Parse(splitContent []string, m *discordgo.MessageCreate) (*model.Command, error)

Parse parses the given list command.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL