Skip to content

Commit

Permalink
Epic last-day refactoring, just like we always do in the last day, wo…
Browse files Browse the repository at this point in the history
…rk-in-progress

- get rid of subtypes
- separate talks and master-classes (MC not ready yet)
- markdown replies and bold event titles
  • Loading branch information
beevee committed Dec 1, 2016
1 parent 0cca693 commit 3811bd4
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 357 deletions.
171 changes: 50 additions & 121 deletions cmd/konfurbot/schedule.yml

Large diffs are not rendered by default.

25 changes: 0 additions & 25 deletions konfurbot.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@ type ScheduleStorage interface {
SetNightCutoff(time.Time)
AddEvent(Event)
GetEventsByType(string) []Event
GetEventsByTypeAndSubtype(string, string) []Event
GetCurrentEventsByType(string, time.Time) []Event
GetNextEventsByType(string, time.Time, time.Duration) []Event
GetNextEventsByTypeAndSubtype(string, string, time.Time, time.Duration) []Event
GetDayEventsByType(string) []Event
GetNightEventsByType(string) []Event
}

// Event is a single event in conference
type Event struct {
Type string
Subtype string
Speaker string
Venue string
Short string
Expand Down Expand Up @@ -51,17 +48,6 @@ func (s *Schedule) GetEventsByType(kind string) []Event {
return s.events[kind]
}

// GetEventsByTypeAndSubtype returns unfiltered list of events by type
func (s *Schedule) GetEventsByTypeAndSubtype(kind, subkind string) []Event {
events := make([]Event, 0, len(s.events[kind]))
for _, event := range s.events[kind] {
if event.Subtype == subkind {
events = append(events, event)
}
}
return events
}

// GetCurrentEventsByType returns list of events by type, and only events that have started and not have finished yet
func (s *Schedule) GetCurrentEventsByType(kind string, now time.Time) []Event {
events := make([]Event, 0, len(s.events[kind]))
Expand All @@ -84,17 +70,6 @@ func (s *Schedule) GetNextEventsByType(kind string, now time.Time, interval time
return events
}

// GetNextEventsByTypeAndSubtype returns list of events by type, and only events that will start in the next interval
func (s *Schedule) GetNextEventsByTypeAndSubtype(kind string, subkind string, now time.Time, interval time.Duration) []Event {
events := make([]Event, 0, len(s.events[kind]))
for _, event := range s.events[kind] {
if event.Subtype == subkind && event.Start.After(now) && event.Start.Before(now.Add(interval)) {
events = append(events, event)
}
}
return events
}

// GetDayEventsByType returns list of events by type, and only events that will start before the night time
func (s *Schedule) GetDayEventsByType(kind string) []Event {
events := make([]Event, 0, len(s.events[kind]))
Expand Down
41 changes: 5 additions & 36 deletions konfurbot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ func TestSchedule(t *testing.T) {
schedule.AddEvent(food1)

talk0 := Event{
Type: "talk",
Subtype: "talk",
Short: "WAT",
Long: "В докладе пойдет речь о том,\nчему равна сумма объекта и пустой строки.\n",
Start: &start,
Finish: &finish,
Type: "talk",
Short: "WAT",
Long: "В докладе пойдет речь о том,\nчему равна сумма объекта и пустой строки.\n",
Start: &start,
Finish: &finish,
}
schedule.AddEvent(talk0)

Expand Down Expand Up @@ -79,21 +78,6 @@ func TestSchedule(t *testing.T) {
So(foodEvents[1], ShouldResemble, food1)
})

Convey("а потом получаем текущие события определенного типа и подтипа", func() {
Convey("если они есть", func() {
talkEvents := schedule.GetEventsByTypeAndSubtype("talk", "talk")

So(talkEvents, ShouldHaveLength, 1)
So(talkEvents[0], ShouldResemble, talk0)
})

Convey("если их нет", func() {
talkEvents := schedule.GetEventsByTypeAndSubtype("talk", "gibberish")

So(talkEvents, ShouldHaveLength, 0)
})
})

Convey("а потом получаем текущие события определенного типа", func() {
Convey("если они есть", func() {
talkEvents := schedule.GetCurrentEventsByType("talk", time.Now())
Expand Down Expand Up @@ -124,21 +108,6 @@ func TestSchedule(t *testing.T) {
})
})

Convey("а потом получаем ближайшие события определенного типа и подтипа", func() {
Convey("если они есть", func() {
talkEvents := schedule.GetNextEventsByTypeAndSubtype("talk", "talk", time.Now().Add(-time.Hour), time.Hour)

So(talkEvents, ShouldHaveLength, 1)
So(talkEvents[0], ShouldResemble, talk0)
})

Convey("если их нет", func() {
talkEvents := schedule.GetNextEventsByTypeAndSubtype("talk", "talk", time.Now(), time.Hour)

So(talkEvents, ShouldHaveLength, 0)
})
})

Convey("а потом получаем события, которые начинаются раньше определенного времени", func() {
funDayEvents := schedule.GetDayEventsByType("fun")

Expand Down
20 changes: 0 additions & 20 deletions mock/konfurbot.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,6 @@ func (_mr *_MockScheduleStorageRecorder) GetEventsByType(arg0 interface{}) *gomo
return _mr.mock.ctrl.RecordCall(_mr.mock, "GetEventsByType", arg0)
}

func (_m *MockScheduleStorage) GetEventsByTypeAndSubtype(_param0 string, _param1 string) []konfurbot.Event {
ret := _m.ctrl.Call(_m, "GetEventsByTypeAndSubtype", _param0, _param1)
ret0, _ := ret[0].([]konfurbot.Event)
return ret0
}

func (_mr *_MockScheduleStorageRecorder) GetEventsByTypeAndSubtype(arg0, arg1 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "GetEventsByTypeAndSubtype", arg0, arg1)
}

func (_m *MockScheduleStorage) GetNextEventsByType(_param0 string, _param1 time.Time, _param2 time.Duration) []konfurbot.Event {
ret := _m.ctrl.Call(_m, "GetNextEventsByType", _param0, _param1, _param2)
ret0, _ := ret[0].([]konfurbot.Event)
Expand All @@ -88,16 +78,6 @@ func (_mr *_MockScheduleStorageRecorder) GetNextEventsByType(arg0, arg1, arg2 in
return _mr.mock.ctrl.RecordCall(_mr.mock, "GetNextEventsByType", arg0, arg1, arg2)
}

func (_m *MockScheduleStorage) GetNextEventsByTypeAndSubtype(_param0 string, _param1 string, _param2 time.Time, _param3 time.Duration) []konfurbot.Event {
ret := _m.ctrl.Call(_m, "GetNextEventsByTypeAndSubtype", _param0, _param1, _param2, _param3)
ret0, _ := ret[0].([]konfurbot.Event)
return ret0
}

func (_mr *_MockScheduleStorageRecorder) GetNextEventsByTypeAndSubtype(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "GetNextEventsByTypeAndSubtype", arg0, arg1, arg2, arg3)
}

func (_m *MockScheduleStorage) GetNightEventsByType(_param0 string) []konfurbot.Event {
ret := _m.ctrl.Call(_m, "GetNightEventsByType", _param0)
ret0, _ := ret[0].([]konfurbot.Event)
Expand Down
66 changes: 28 additions & 38 deletions telegram/fsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const (

foodCommand = "🌶 Еда"

talkCommand = "🔥 Доклады / МК"
talkCommand = "🔥 Доклады"
talkNowCommand = "Которые идут сейчас"
talkNextCommand = "Которые начнутся скоро"
talkAllCommand = "Все"
Expand All @@ -25,6 +25,8 @@ const (
talkTalkCommand = "Доклады"
talkMasterCommand = "Мастер-классы"

masterCommand = "💥 Мастер-классы"

funCommand = "🍾 Развлечения"
funDayCommand = "🍼 Утром"
funNightCommand = "🍸 Вечером"
Expand All @@ -51,11 +53,13 @@ var stateMessageOptions = map[string]*telebot.SendOptions{
startState: &telebot.SendOptions{
ReplyMarkup: telebot.ReplyMarkup{
CustomKeyboard: [][]string{
[]string{foodCommand, talkCommand},
[]string{funCommand, transferCommand},
[]string{talkCommand, masterCommand},
[]string{funCommand, foodCommand},
[]string{transferCommand},
},
ResizeKeyboard: true,
},
ParseMode: telebot.ModeMarkdown,
},

talkState: &telebot.SendOptions{
Expand All @@ -67,6 +71,7 @@ var stateMessageOptions = map[string]*telebot.SendOptions{
},
ResizeKeyboard: true,
},
ParseMode: telebot.ModeMarkdown,
},

talkNowState: &telebot.SendOptions{
Expand All @@ -77,6 +82,7 @@ var stateMessageOptions = map[string]*telebot.SendOptions{
},
ResizeKeyboard: true,
},
ParseMode: telebot.ModeMarkdown,
},

talkNextState: &telebot.SendOptions{
Expand All @@ -87,16 +93,7 @@ var stateMessageOptions = map[string]*telebot.SendOptions{
},
ResizeKeyboard: true,
},
},

talkAllState: &telebot.SendOptions{
ReplyMarkup: telebot.ReplyMarkup{
CustomKeyboard: [][]string{
[]string{talkTalkCommand},
[]string{talkMasterCommand},
},
ResizeKeyboard: true,
},
ParseMode: telebot.ModeMarkdown,
},

transferState: &telebot.SendOptions{
Expand All @@ -106,6 +103,7 @@ var stateMessageOptions = map[string]*telebot.SendOptions{
},
ResizeKeyboard: true,
},
ParseMode: telebot.ModeMarkdown,
},

transferMainState: &telebot.SendOptions{
Expand All @@ -115,6 +113,7 @@ var stateMessageOptions = map[string]*telebot.SendOptions{
},
ResizeKeyboard: true,
},
ParseMode: telebot.ModeMarkdown,
},

transferColorState: &telebot.SendOptions{
Expand All @@ -124,6 +123,7 @@ var stateMessageOptions = map[string]*telebot.SendOptions{
},
ResizeKeyboard: true,
},
ParseMode: telebot.ModeMarkdown,
},

funState: &telebot.SendOptions{
Expand All @@ -133,6 +133,7 @@ var stateMessageOptions = map[string]*telebot.SendOptions{
},
ResizeKeyboard: true,
},
ParseMode: telebot.ModeMarkdown,
},
}

Expand All @@ -148,9 +149,7 @@ func initStateMachine() *fsm.FSM {
{Name: talkNextCommand, Src: []string{talkState}, Dst: talkNextState},
{Name: talkLongCommand, Src: []string{talkNowState, talkNextState}, Dst: startState},
{Name: talkShortCommand, Src: []string{talkNowState, talkNextState}, Dst: startState},
{Name: talkAllCommand, Src: []string{talkState}, Dst: talkAllState},
{Name: talkTalkCommand, Src: []string{talkAllState}, Dst: startState},
{Name: talkMasterCommand, Src: []string{talkAllState}, Dst: startState},
{Name: talkAllCommand, Src: []string{talkState}, Dst: startState},
{Name: transferCommand, Src: []string{startState}, Dst: transferState},
{Name: transferMainCommand, Src: []string{transferState}, Dst: transferMainState},
{Name: transferColorCommand, Src: []string{transferState}, Dst: transferColorState},
Expand All @@ -162,7 +161,7 @@ func initStateMachine() *fsm.FSM {
{Name: returnToStartCommand, Src: []string{startState}, Dst: startState},
{
Name: unknownCommand,
Src: []string{welcomeState, startState, talkState, talkNowState, talkNextState, talkAllState, transferState, transferMainState, transferColorState, funState},
Src: []string{welcomeState, startState, talkState, talkNowState, talkNextState, transferState, transferMainState, transferColorState, funState},
Dst: startState,
},
},
Expand All @@ -178,7 +177,7 @@ func initStateMachine() *fsm.FSM {
}),

talkCommand: wrapCallback(func(e *fsm.Event, chat telebot.Chat, bot *Bot) error {
return bot.telebot.SendMessage(chat, "Окей, какие доклады и мастер-классы?", stateMessageOptions[e.Dst])
return bot.telebot.SendMessage(chat, "Окей, какие доклады?", stateMessageOptions[e.Dst])
}),

talkNowCommand: wrapCallback(func(e *fsm.Event, chat telebot.Chat, bot *Bot) error {
Expand Down Expand Up @@ -211,18 +210,9 @@ func initStateMachine() *fsm.FSM {
return bot.telebot.SendMessage(chat, makeResponseFromEvents(events, false), stateMessageOptions[e.Dst])
}),

talkTalkCommand: wrapCallback(func(e *fsm.Event, chat telebot.Chat, bot *Bot) error {
events := bot.ScheduleStorage.GetEventsByTypeAndSubtype("talk", "talk")
return bot.telebot.SendMessage(chat, makeResponseFromEvents(events, false), stateMessageOptions[e.Dst])
}),

talkMasterCommand: wrapCallback(func(e *fsm.Event, chat telebot.Chat, bot *Bot) error {
events := bot.ScheduleStorage.GetEventsByTypeAndSubtype("talk", "master")
return bot.telebot.SendMessage(chat, makeResponseFromEvents(events, false), stateMessageOptions[e.Dst])
}),

talkAllCommand: wrapCallback(func(e *fsm.Event, chat telebot.Chat, bot *Bot) error {
return bot.telebot.SendMessage(chat, "Полное расписание довольно длинное. Давай посмотрим отдельно, доклады или мастер-классы? С тизерами вообще не буду предлагать :)", stateMessageOptions[e.Dst])
events := bot.ScheduleStorage.GetEventsByType("talk")
return bot.telebot.SendMessage(chat, makeResponseFromEvents(events, false), stateMessageOptions[e.Dst])
}),

transferCommand: wrapCallback(func(e *fsm.Event, chat telebot.Chat, bot *Bot) error {
Expand All @@ -241,9 +231,9 @@ func initStateMachine() *fsm.FSM {
var events []konfurbot.Event
switch e.Src {
case transferMainState:
events = bot.ScheduleStorage.GetNextEventsByTypeAndSubtype("transfer", "main", time.Now().In(bot.Timezone), time.Hour)
events = bot.ScheduleStorage.GetNextEventsByType("transfer_main", time.Now().In(bot.Timezone), time.Hour)
case transferColorState:
events = bot.ScheduleStorage.GetNextEventsByTypeAndSubtype("transfer", "color", time.Now().In(bot.Timezone), time.Hour)
events = bot.ScheduleStorage.GetNextEventsByType("transfer_color", time.Now().In(bot.Timezone), time.Hour)
}
return bot.telebot.SendMessage(chat, makeResponseFromEvents(events, false), stateMessageOptions[e.Dst])
}),
Expand All @@ -252,9 +242,9 @@ func initStateMachine() *fsm.FSM {
var events []konfurbot.Event
switch e.Src {
case transferMainState:
events = bot.ScheduleStorage.GetEventsByTypeAndSubtype("transfer", "main")
events = bot.ScheduleStorage.GetEventsByType("transfer_main")
case transferColorState:
events = bot.ScheduleStorage.GetEventsByTypeAndSubtype("transfer", "color")
events = bot.ScheduleStorage.GetEventsByType("transfer_color")
}
return bot.telebot.SendMessage(chat, makeResponseFromEvents(events, false), stateMessageOptions[e.Dst])
}),
Expand Down Expand Up @@ -313,20 +303,20 @@ func makeResponseFromEvents(events []konfurbot.Event, long bool) string {
}

if event.Venue != "" {
response += fmt.Sprintf(" [%s]", event.Venue)
response += fmt.Sprintf(" \\[%s]", event.Venue)
}

response += fmt.Sprintf(": %s", event.Short)
response += fmt.Sprintf(": *%s*", event.Short)

if event.Speaker != "" {
response += fmt.Sprintf(" (%s)", event.Speaker)
}

response += "\n"

if long && event.Long != "" {
response += fmt.Sprintf("%s\n\n", event.Long)
response += fmt.Sprintf("\n%s", event.Long)
}

response += "\n\n"
}

if response == "" {
Expand Down
Loading

0 comments on commit 3811bd4

Please sign in to comment.