Documentation ¶
Index ¶
- Variables
- func ChannelID(channel string) pubsub.Channel
- func CompleteEvent(author, title, text string) pubsub.Event
- func ForceAvailableDatesToBeLoaded(t *testing.T, filename string)
- func ForceErrorDuringAvailableDatesLoad(t *testing.T, err error)
- func ForceErrorDuringPuzzleLoad(t *testing.T, err error)
- func ForceErrorDuringSettingsLoad(t *testing.T, err error)
- func ForceErrorDuringSettingsSave(t *testing.T, err error)
- func ForceErrorDuringStateLoad(t *testing.T, err error)
- func ForceErrorDuringStateSave(t *testing.T, err error)
- func ForcePuzzleToBeLoaded(t *testing.T, filename string)
- func GetAllChannels(conn db.Connection) ([]model.Channel, error)
- func GetAvailableDates() http.HandlerFunc
- func GetClueLetter(index int) (string, error)
- func GetEvents(pool *redis.Pool, registry *pubsub.Registry) http.HandlerFunc
- func LoadAvailableNewYorkTimesDates() ([]time.Time, error)
- func LoadTestAvailableDates(t *testing.T, filename string) []time.Time
- func NewEventSubscription(t *testing.T, registry *pubsub.Registry, channel string) <-chan pubsub.Event
- func NewRedisConnection(t *testing.T, pool *redis.Pool) redis.Conn
- func NewTestRouter(t *testing.T) (chi.Router, *redis.Pool, *pubsub.Registry)
- func ParseAuthorAndTitle(s string) (string, string)
- func ParseInts(s string) ([]int, error)
- func ParseQuote(s string) string
- func ParseXWordInfoAvailableDatesResponse(in io.Reader) ([]time.Time, error)
- func RegisterRoutes(r chi.Router, pool *redis.Pool, registry *pubsub.Registry)
- func SetSettings(conn redis.Conn, channel string, settings Settings) error
- func SetState(conn db.Connection, channel string, state State) error
- func SettingsEvent(settings Settings) pubsub.Event
- func SettingsKey(name string) string
- func ShowClue(registry *pubsub.Registry) http.HandlerFunc
- func ShowClueEvent(clue string) pubsub.Event
- func StateEvent(state State) pubsub.Event
- func StateKey(name string) string
- func ToggleStatus(pool *redis.Pool, registry *pubsub.Registry) http.HandlerFunc
- func UpdateAnswer(pool *redis.Pool, registry *pubsub.Registry) http.HandlerFunc
- func UpdatePuzzle(pool *redis.Pool, registry *pubsub.Registry) http.HandlerFunc
- func UpdateSetting(pool *redis.Pool, registry *pubsub.Registry) http.HandlerFunc
- type Puzzle
- type Settings
- type State
- type XWordInfoPuzzle
- type XWordInfoPuzzleWrapper
Constants ¶
This section is empty.
Variables ¶
var AuthorTitleRegexps = []*regexp.Regexp{ regexp.MustCompile(`^(?P<author>[^,:]+)[,:] (?P<title>[^—]+) —`), regexp.MustCompile(`^(?P<author>[^,:]+)[,:] (?P<title>[^-]+) -`), regexp.MustCompile(`(?P<author>)(?P<title>[^—]+) —`), }
A set of regular expressions to use to extract the author and title of an acrostic. These will be tried in order and the first one to return a match is the one that is used.
var ClueLetters = []string{
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
}
var QuoteRegexps = []*regexp.Regexp{ regexp.MustCompile(`^(?P<author_and_title>[^—]+) — (?P<quote>.+)$`), }
A set of regular expressions to use to extract the quote of an acrostic.
var StateTTL = 4 * time.Hour
StateTTL determines how long a particular crossword's solve state should remain in redis in the absence of any activity.
var XWordInfoHeaders = map[string]string{
"Referer": "https://www.xwordinfo.com/Acrostic",
}
Functions ¶
func CompleteEvent ¶
func ForceAvailableDatesToBeLoaded ¶
ForceAvailableDatesToBeLoaded sets up a cached version of a available dates using a file from the testdata directory.
func ForceErrorDuringAvailableDatesLoad ¶
ForceErrorDuringAvailableDatesLoad sets up an error to be returned when an attempt is made to load a set of available dates.
func ForceErrorDuringPuzzleLoad ¶
ForceErrorDuringLoad sets up an error to be returned when an attempt is made to load a puzzle.
func ForceErrorDuringSettingsLoad ¶
ForceErrorDuringSettingsLoad sets up an error to be returned when an attempt is made to load settings.
func ForceErrorDuringSettingsSave ¶
ForceErrorDuringSettingsSave sets up an error to be returned when an attempt is made to save settings.
func ForceErrorDuringStateLoad ¶
ForceErrorDuringStateLoad sets up an error to be returned when an attempt is made to load state.
func ForceErrorDuringStateSave ¶
ForceErrorDuringStateSave sets up an error to be returned when an attempt is made to save state.
func ForcePuzzleToBeLoaded ¶
ForcePuzzleToBeLoaded sets up a cached version of a puzzle using a file from the testdata directory.
func GetAllChannels ¶
func GetAllChannels(conn db.Connection) ([]model.Channel, error)
GetAllChannels returns a slice of model.Channel instances for each acrostic that contains state in the database. If there are no active channels then an empty slice is returned. This method does not update the expiration times of any state instance.
func GetAvailableDates ¶
func GetAvailableDates() http.HandlerFunc
GetAvailableDates returns the available acrostic dates across all puzzle sources.
In order to minimize load on external data sources the response is cached for several hours.
func GetClueLetter ¶
func GetEvents ¶
GetEvents establishes an event stream with a client. An event stream is server side event stream (SSE) with a client's browser that allows one way communication from the server to the client. Clients that call into this handler will keep an open connection open to the server waiting to receive events as JSON objects. The server can send events to all clients of a channel using the pubsub.Registry's Publish method.
func LoadAvailableNewYorkTimesDates ¶
LoadAvailableNewYorkTimesDates determines all of the historical dates that have acrostic puzzles.
This method uses the https://www.xwordinfo.com/SelectAcrostic page and parses the HTML on the page to determine the available puzzle dates.
If the dates cannot be determined then an error is returned.
func LoadTestAvailableDates ¶
LoadTestAvailableDates loads a set of available dates from the testdata directory.
func NewEventSubscription ¶
func NewEventSubscription(t *testing.T, registry *pubsub.Registry, channel string) <-chan pubsub.Event
NewEventSubscription will return a channel of events that are subscribed to the specified channel. The subscription will be configured to automatically unsubscribe when the test completes.
func NewRedisConnection ¶
NewRedisConnection will return a connection to the provided connection pool. The returned connection will be configured to automatically close when the test completes.
func NewTestRouter ¶
NewTestRouter will return a router configured with a redis pool and pubsub registry and wired together along with all of the routes for a spelling bee puzzle.
func ParseAuthorAndTitle ¶
ParseAuthorAndTitle extracts the author name and title from the quote field of the xwordinfo.com JSON API response.
func ParseQuote ¶
func ParseXWordInfoAvailableDatesResponse ¶
ParseXWordInfoAvailableDatesResponse converts an HTML response from the select acrostic page on xwordinfo.com into a list of available dates.
func RegisterRoutes ¶
func SetSettings ¶
SetSettings will write settings for the provided channel name. If the settings can't be properly written then an error will be returned.
func SetState ¶
func SetState(conn db.Connection, channel string, state State) error
SetState writes the state for a channel's crossword solve to redis. If the state can't be property written then an error will be returned.
func SettingsEvent ¶
func SettingsKey ¶
SettingsKey returns the key that should be used in redis to store a particular channel's acrostic settings.
func ShowClue ¶
func ShowClue(registry *pubsub.Registry) http.HandlerFunc
ShowClue sends an event to all clients of a channel requesting that they update their view to make the specified clue visible. If the specified clue isn't structured as a proper clue letter than an error will be returned.
func ShowClueEvent ¶
func StateEvent ¶
func StateKey ¶
StateKey returns the key that should be used in redis to store a particular crossword solve's state.
func ToggleStatus ¶
ToggleStatus changes the status of the current acrostic solve to a new status. This effectively toggles between the solving and paused statuses as long as the solve is in a state that can be paused or resumed.
func UpdateAnswer ¶
UpdateAnswer applies an answer to either a given clue or given set of cells in the current acrostic solve.
func UpdatePuzzle ¶
UpdatePuzzle changes the acrostic puzzle that's currently being solved for a channel.
func UpdateSetting ¶
UpdateSetting changes a specified acrostic setting to a new value.
Types ¶
type Puzzle ¶
type Puzzle struct { // A human readable description of the puzzle Description string `json:"description"` // The number of rows in the acrostic grid. Rows int `json:"rows"` // The number of columns in the acrostic grid. Cols int `json:"cols"` // The publisher of the acrostic. Publisher string `json:"publisher"` // The date that the acrostic was published. PublishedDate time.Time `json:"published"` // The author of the acrostic. Author string `json:"author"` // The title of the book the acrostic is from. Title string `json:"title"` // The quote that the acrostic is from. Quote string `json:"quote"` // The cells of the acrostic as a 2D list, entries are the letter that belongs // in the cell. If a cell cannot be inputted into then it will contain the // empty string. The lists are first indexed by the row coordinate of the // cell and then by the column coordinate of the cell. Cells [][]string `json:"cells,omitempty"` // The givens of the acrostic as a 2D list. A given is a cell in the acrostic // that has a value, but no cell number or corresponding clue letter. If a // cell is not a given then it will contain the empty string. Like cells the // 2D list is first indexed by the row coordinate of the cell and then by the // column coordinate. Givens [][]string `json:"givens,omitempty"` // The block attribute for each of the cells in the acrostic as a 2D list. // Cells that cannot be inputted into will contain an entry of true, all other // cells will contain an entry of false. Like cells the 2D list is first // indexed by the row coordinate of the cell and then by the column // coordinate. CellBlocks [][]bool `json:"cell_blocks"` // The numbers for each of the cells in the acrostic as a 2D list. Cells that // cannot be inputted into will contain an entry of 0. Like cells the 2D list // is first indexed by the row coordinate of the cell and then by the column // coordinate. CellNumbers [][]int `json:"cell_clue_numbers"` // The clue letter for each of the cells in the acrostic as a 2D list. // Cells that cannot be inputted into or that don't have a clue letter will // contain an empty string. Like cells the 2D list is first indexed by the // row coordinate of the cell and then by the column coordinate. CellClueLetters [][]string `json:"cell_clue_letters"` // The clues indexed by the clue letter. Clues map[string]string `json:"clues"` // The clue numbers indexed by the clue letter. ClueNumbers map[string][]int `json:"clue_numbers"` }
Puzzle represents an acrostic puzzle. The puzzle is comprised of a grid which has dimensions (rows x cols) and demonstrates which cells of the acrostic are available for placing letters into and which are not. Additionally the puzzle contains a set of lettered clues and a mapping of answer letters their position within the grid. Lastly a puzzle has various bits of interesting metadata such as the publication that the acrostic is from, the date that it was published as well as the author(s).
func LoadFromNewYorkTimes ¶
LoadFromNewYorkTimes loads an acrostic puzzle from the New York Times for a particular date.
This method uses the xwordinfo.com JSON API to load a New York Times acrostic puzzle. Unfortunately the JSON API for acrostics is not documented.
If the puzzle cannot be loaded or parsed then an error is returned.
func LoadTestPuzzle ¶
LoadTestPuzzle loads a puzzle from the testdata directory.
func ParseXWordInfoPuzzleResponse ¶
ParseXWordInfoPuzzleResponse converts a JSON response from xwordinfo.com into a puzzle object.
func ParseXWordInfoWrappedPuzzleResponse ¶
ParseXWordInfoWrappedPuzzleResponse unwraps and decompresses a JSON response from xwordinfo.com and then parses it into a puzzle object.
func (*Puzzle) GetCellCoordinates ¶
GetCellCoordinates returns the x, y coordinates for a numbered cell. If the cell doesn't exist then an error is returned.
func (*Puzzle) WithoutSolution ¶
WithoutSolution returns a copy of the puzzle that has the solution cells missing. This makes it suitable to pass to a client that shouldn't know the answers to the puzzle.
type Settings ¶
type Settings struct { // When enabled only correct answers will be filled into the puzzle grid. OnlyAllowCorrectAnswers bool `json:"only_allow_correct_answers"` // What font size should the clues be rendered with. ClueFontSize model.FontSize `json:"clue_font_size"` }
Settings represents the optional behaviors that can be enabled or disabled by a streamer for their channel's acrostic solves.
type State ¶
type State struct { // The status of the channel's acrostic solve. Status model.Status `json:"status"` // The acrostic puzzle that's being solved. May not always be present, for // example when the state is being serialized to be sent to the browser. Puzzle *Puzzle `json:"puzzle,omitempty"` // The currently filled in cells of the acrostic. Cells [][]string `json:"cells"` // Whether or not a clue with a given clue letter has had an answer filled in. CluesFilled map[string]bool `json:"clues_filled"` // The time that we last started or resumed solving the puzzle. If the // channel has not yet started solving the puzzle or is in a non-playing state // this will be nil. LastStartTime *time.Time `json:"last_start_time,omitempty"` // The total time spent on solving the puzzle up to the last start time. TotalSolveDuration model.Duration `json:"total_solve_duration"` }
State represents the state of an active channel that is attempting to solve an acrostic.
func GetState ¶
func GetState(conn db.Connection, channel string) (State, error)
GetState loads the state for a crossword solve from redis. If the state can't be loaded then an error will be returned. If there is no state, then the zero value will be returned. After a state is read, its expiration time is automatically updated.
func NewState ¶
NewState creates a new acrostic puzzle state that has been properly initialized with the puzzle corresponding to the provided filename.
func (*State) ApplyCellAnswer ¶
ApplyCellAnswer applies an answer to the cells to the state. If the starting cell number specified outside the bounds of the puzzle or the answer doesn't fit within the bounds of the puzzle then an error will be returned. If the onlyCorrect parameter is true then only correct values will be permitted and an error is returned if any part of the answer is incorrect or would remove a correct cell.
func (*State) ApplyClueAnswer ¶
ApplyClueAnswer applies an answer for a clue to the state. If the clue cannot be identified or the answer doesn't fit property (too short or too long) then an error will be returned. If the onlyCorrect parameter is true then only correct values will be permitted and an error is returned if any part of the answer is incorrect or would remove a correct cell.
func (*State) ClearIncorrectCells ¶
ClearIncorrectCells will look at each filled in cell of the acrostic and clear it if it is filled in with an incorrect answer. The CluesFilled field will also be updated to indicate any clues that are now unanswered due to cleared cells.
func (*State) UpdateFilledClues ¶
UpdateFilledClues looks at each clue in the puzzle and determines if a complete answer has been provided for the clue, if so then the corresponding entry in CluesFilled will be set to true. This method doesn't check that the provided answer is correct, just that one is present.
type XWordInfoPuzzle ¶
type XWordInfoPuzzle struct { AnswerKey string `json:"answerKey"` ClueData []string `json:"clueData"` Clues []string `json:"clues"` Cols int `json:"cols"` Copyright string `json:"copyright"` Date string `json:"date"` FullQuote string `json:"fullQuote"` GridLetters string `json:"gridLetters"` GridNumbers []int `json:"gridNumbers"` TitleNumbers []int `json:"mapTitle"` Quote string `json:"quote"` Rows int `json:"rows"` }
XWordInfoPuzzle is a representation of the response from the xwordinfo.com JSON API when querying for a puzzle.
type XWordInfoPuzzleWrapper ¶
type XWordInfoPuzzleWrapper struct {
Data string `json:"data"`
}