Skip to content

Commit 8745a02

Browse files
bot improvements
1 parent 384c0e0 commit 8745a02

File tree

8 files changed

+98
-67
lines changed

8 files changed

+98
-67
lines changed

cmd/main.go

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,22 @@ import (
44
"context"
55
"flag"
66
"log"
7+
"os"
78
"os/signal"
89
"syscall"
910

11+
"go.uber.org/multierr"
12+
1013
"github.com/cool-dudes-alpha-dynamite-wolves/chto-tam-po-peresdacham/internal/bot"
1114
"github.com/cool-dudes-alpha-dynamite-wolves/chto-tam-po-peresdacham/internal/parser"
1215
)
1316

1417
var (
15-
1618
// хранить секреты в коде плохо, поэтому используем флаги
1719
// "1953480583:AAEU7eBaZnCUt525oUkCMRCQxK1TJmaoVd4"
1820
botToken = flag.String("tg.token", "", "token for telegram")
19-
20-
// это не секрет, но для простоты тоже выносим под конфиг
21-
// "https://5872-95-165-1-28.eu.ngrok.io"
22-
WebhookURL = flag.String("tg.webhook", "", "webhook addr for telegram")
23-
2421
// запуск выглядит так:
25-
// go run bot.go -tg.token="1953480583:AAEU7eBaZnCUt525oUkCMRCQxK1TJmaoVd4" -tg.webhook="https://5872-95-165-1-28.eu.ngrok.io"
22+
// go run bot.go -tg.token="1953480583:AAEU7eBaZnCUt525oUkCMRCQxK1TJmaoVd4"
2623
)
2724

2825
func main() {
@@ -44,19 +41,27 @@ func main() {
4441
log.Println("Parsing completed!")
4542

4643
// Инициализация и запуск бота
47-
bot, err := bot.NewTgBot(*botToken)
44+
port := os.Getenv("PORT")
45+
if port == "" {
46+
port = "8081"
47+
}
48+
log.Println("PORT:", port)
49+
if *botToken == "" {
50+
*botToken = os.Getenv("BOT_TOKEN")
51+
}
52+
bot, err := bot.NewTgBot(*botToken, port)
4853
if err != nil {
4954
log.Fatal("failed to initialize bot", err)
5055
}
56+
5157
ctx, stop := signal.NotifyContext(ctx, syscall.SIGTERM, syscall.SIGINT)
5258
defer stop()
5359

54-
err = func() error {
55-
if err = bot.Start(ctx, data); err != nil {
56-
log.Println("failed to start bot:", err.Error())
57-
return err
58-
}
59-
for {
60+
err = run(ctx, stop,
61+
func(ctx context.Context) error {
62+
return bot.Start(ctx, data)
63+
},
64+
func(ctx context.Context) error {
6065
select {
6166
case <-ctx.Done():
6267
log.Println("got stop signal")
@@ -65,12 +70,34 @@ func main() {
6570
log.Println("got err from bot:", err.Error())
6671
return err
6772
}
68-
}
69-
}()
70-
log.Println("app is shutting down...")
71-
stop()
73+
},
74+
)
75+
76+
log.Println("application is shutting down...")
77+
if err != nil {
78+
log.Println("failed to shutdown application", err)
79+
}
7280

7381
if err = bot.Shutdown(ctx); err != nil {
7482
log.Println("got error during bot shutdown:", err.Error())
7583
}
7684
}
85+
86+
func run(ctx context.Context, shutdown func(), startUpFuncs ...func(ctx context.Context) error) error {
87+
errCh := make(chan error)
88+
for i := range startUpFuncs {
89+
go func(i int) { errCh <- startUpFuncs[i](ctx) }(i)
90+
}
91+
92+
var err error
93+
var closed bool
94+
for range startUpFuncs {
95+
err = multierr.Append(err, <-errCh)
96+
if err != nil && !closed {
97+
shutdown()
98+
closed = true
99+
}
100+
}
101+
102+
return err
103+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
github.com/richardlehane/msoleps v1.0.4 // indirect
1414
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
1515
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
16+
go.uber.org/multierr v1.11.0 // indirect
1617
golang.org/x/crypto v0.28.0 // indirect
1718
golang.org/x/net v0.30.0 // indirect
1819
golang.org/x/text v0.19.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ github.com/xuri/excelize/v2 v2.9.0 h1:1tgOaEq92IOEumR1/JfYS/eR0KHOCsRv/rYXXh6YJQ
1919
github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmjiLfBS5hdE=
2020
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
2121
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
22+
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
23+
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
2224
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
2325
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
2426
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=

internal/bot/tg_bot.go

Lines changed: 8 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,7 @@ type TgBot struct {
2121
subjects []*internal.Subject // Данные из парсера
2222
}
2323

24-
type Subject struct {
25-
Name string // Название предмета
26-
Date time.Time // Дата пересдачи
27-
}
28-
29-
func NewTgBot(token string) (*TgBot, error) {
24+
func NewTgBot(token, port string) (*TgBot, error) {
3025
errChan := make(chan error, 1)
3126
bot, err := telegram.NewBotAPI(token)
3227
if err != nil {
@@ -36,7 +31,10 @@ func NewTgBot(token string) (*TgBot, error) {
3631
// bot.Debug = true
3732

3833
return &TgBot{
39-
server: &http.Server{ReadHeaderTimeout: 1 * time.Second},
34+
server: &http.Server{
35+
ReadHeaderTimeout: 1 * time.Second,
36+
Addr: ":" + port,
37+
},
4038
errChan: errChan,
4139
bot: bot,
4240
}, nil
@@ -85,57 +83,23 @@ func (b *TgBot) Start(_ context.Context, subjects []*internal.Subject) error {
8583
}
8684

8785
func (b *TgBot) handleSchedule(chatID int64, instituteFilter, groupFilter string) {
88-
if len(b.subjects) == 0 {
89-
b.sendMessage(chatID, "Нет данных о пересдачах.")
90-
return
91-
}
92-
9386
message := "Расписание пересдач:\n"
9487
for _, subj := range b.subjects {
95-
if subj.Institute != instituteFilter {
88+
if !(subj.Institute == instituteFilter && subj.Group == groupFilter) {
9689
continue
9790
}
98-
if !strings.HasPrefix(subj.Group, groupFilter) {
99-
continue
100-
}
101-
102-
date := "не указана"
103-
timeOfStart := "не указано"
104-
105-
if subj.Date != nil {
106-
date = subj.Date.Format("02.01.2006")
107-
}
108-
if subj.TimeOfStart != nil {
109-
timeOfStart = subj.TimeOfStart.Format("15:04")
110-
}
111-
112-
message += fmt.Sprintf(
113-
"- Дисциплина: %s\n Институт: %s\n Группа: %s\n Дата: %s\n Время: %s\n Аудитория: %s\n\n",
114-
getOrDefault(subj.Discipline, "не указана"),
115-
subj.Institute,
116-
subj.Group,
117-
date,
118-
timeOfStart,
119-
getOrDefault(subj.Classroom, "не указана"),
120-
)
91+
message += b.constructSubjectMsg(subj)
12192
}
12293
if message == "Расписание пересдач:\n" {
12394
message = "Нет данных для выбранных фильтров."
12495
}
12596
b.sendMessage(chatID, message)
12697
}
12798

128-
func getOrDefault(value *string, defaultValue string) string {
129-
if value != nil {
130-
return *value
131-
}
132-
return defaultValue
133-
}
134-
13599
func (b *TgBot) sendMessage(chatID int64, text string) {
136100
msg := telegram.NewMessage(chatID, text)
137101
if _, err := b.bot.Send(msg); err != nil {
138-
log.Printf("Ошибка отправки сообщения: %v", err)
102+
log.Printf("Ошибка отправки сообщения: %v\n", err)
139103
}
140104
}
141105

internal/bot/usecase.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package bot
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/cool-dudes-alpha-dynamite-wolves/chto-tam-po-peresdacham/internal"
7+
)
8+
9+
func (b *TgBot) constructSubjectMsg(subject *internal.Subject) (message string) {
10+
message += fmt.Sprintf("- Институт: %s\n", subject.Institute)
11+
message += fmt.Sprintf(" Группа: %s\n", subject.Group)
12+
if subject.Discipline != nil {
13+
message += fmt.Sprintf(" Дисциплина: %s\n", *subject.Discipline)
14+
}
15+
if subject.Year != nil {
16+
message += fmt.Sprintf(" Курс: %d\n", *subject.Year)
17+
}
18+
if subject.Professor != nil {
19+
message += fmt.Sprintf(" Преподаватель: %s\n", *subject.Professor)
20+
}
21+
if subject.Date != nil {
22+
message += fmt.Sprintf(" Дата: %s\n", subject.Date.Format(internal.DateLayout))
23+
}
24+
if subject.TimeOfStart != nil {
25+
message += fmt.Sprintf(" Время: %s\n", subject.TimeOfStart.Format(internal.TimeOfStartLayout))
26+
}
27+
if subject.Classroom != nil {
28+
message += fmt.Sprintf(" Аудитория: %s\n", *subject.Classroom)
29+
}
30+
if subject.Comment != nil {
31+
message += fmt.Sprintf(" Примечание: %s\n", *subject.Comment)
32+
}
33+
message += "\n"
34+
return
35+
}

internal/models.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ package internal
22

33
import "time"
44

5+
const (
6+
DateLayout = "02.01.2006"
7+
TimeOfStartLayout = "15:04"
8+
)
9+
510
type Subject struct {
611
Discipline *string
712
Institute string

internal/parser/excel_parser.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func (p *ExcelParser) getSubjectOpts(headers []string) (opts []rawSubjectOption)
196196
})
197197
} else if _, ok = validDateFields[cell]; ok {
198198
opts = append(opts, func(s *rawSubject, value string) error {
199-
v, err := time.Parse(dateLayout, value)
199+
v, err := time.Parse(internal.DateLayout, value)
200200
if err != nil {
201201
return fmt.Errorf("can not parse date %s; err: %s", value, err)
202202
}
@@ -205,7 +205,7 @@ func (p *ExcelParser) getSubjectOpts(headers []string) (opts []rawSubjectOption)
205205
})
206206
} else if _, ok = validTimeOfStartFields[cell]; ok {
207207
opts = append(opts, func(s *rawSubject, value string) error {
208-
v, err := time.Parse(timeOfStartLayout, value)
208+
v, err := time.Parse(internal.TimeOfStartLayout, value)
209209
if err != nil {
210210
return fmt.Errorf("can not parse time of start %s; err: %s", value, err)
211211
}

internal/parser/models.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ import (
88
const (
99
requiredFieldsInARowMinimum = 3
1010

11-
dateLayout = "02.01.2006"
12-
timeOfStartLayout = "15:04"
13-
1411
disciplinePatternRegex = "^[А-Я]{3,4}-\\d{2}-\\d$"
1512
)
1613

0 commit comments

Comments
 (0)