This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues or pull requests.
l9_stud_bot/modules/notify/notify.go

243 lines
5.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package notify
import (
"log"
"time"
"git.l9labs.ru/anufriev.g.a/l9_stud_bot/modules/database"
"git.l9labs.ru/anufriev.g.a/l9_stud_bot/modules/ssau_parser"
"git.l9labs.ru/anufriev.g.a/l9_stud_bot/modules/tg"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"golang.org/x/exp/slices"
"xorm.io/xorm"
)
type Next struct {
Lesson []database.Lesson
Day []database.Lesson
Week []database.Lesson
}
type NotifyType string
const (
NextLesson NotifyType = "nextnote"
NextDay NotifyType = "nextday"
NextWeek NotifyType = "nextweek"
Changes NotifyType = "changes"
Military NotifyType = "mil"
)
type Notify struct {
NotifyType
IsGroup bool
SheduleId int64
Lesson database.Lesson
}
// Поиск следующей пары, дня, недели
func CheckNext(db *xorm.Engine, now time.Time) ([]Notify, error) {
now = now.Truncate(time.Minute)
var completed []database.Lesson
if err := db.
Find(&completed, &database.Lesson{End: now}); err != nil {
return nil, err
}
var nums []int
for i := range completed {
new_num := completed[i].NumInShedule + 1
if !slices.Contains(nums, new_num) {
nums = append(nums, new_num)
}
}
var next []database.Lesson
if err := db.
Where("date(`begin`) = ?", now.Format("2006-01-02")).
In("numinshedule", nums).
Find(&next); err != nil {
return nil, err
}
var notify []Notify
for _, n := range next {
notify = append(notify, Notify{
NotifyType: NextLesson,
IsGroup: true,
SheduleId: n.GroupId,
Lesson: n,
})
if n.TeacherId != 0 {
notify = append(notify, Notify{
NotifyType: NextLesson,
IsGroup: false,
SheduleId: n.TeacherId,
Lesson: n,
})
}
}
// Отсеиваем последние пары дня
last := ssau_parser.Diff(completed, next)
for _, l := range last {
var next_lesson database.Lesson
if _, err := db.
Where(
"groupid = ? and begin > ?",
l.GroupId, l.Begin.Format("2006-01-02 15:04:03"),
).
Asc("begin").
Get(&next_lesson); err != nil {
return nil, err
}
// Разделяем, какие пары на этой неделе, какие на следующей
_, nl_week := next_lesson.Begin.ISOWeek()
_, now_week := now.ISOWeek()
note := Notify{
IsGroup: true,
SheduleId: next_lesson.GroupId,
Lesson: next_lesson,
}
if nl_week == now_week {
note.NotifyType = NextDay
} else {
note.NotifyType = NextWeek
}
if !slices.Contains(notify, note) {
notify = append(notify, note)
}
}
return notify, nil
}
// Текст уведомления о следующей паре
func StrNext(db *xorm.Engine, note Notify) (string, error) {
// TODO: перескакивать окна
// Подкачиваем группы и подгруппы
var pair []database.Lesson
if !note.IsGroup {
query := database.Lesson{
Begin: note.Lesson.Begin,
TeacherId: note.SheduleId,
}
if err := db.Find(&pair, query); err != nil {
return "", err
}
} else {
pair = append(pair, note.Lesson)
}
str := "Следующая пара:\n\n"
strPair, err := tg.PairToStr(pair, db, note.IsGroup)
if err != nil {
return "", err
}
str += strPair
return str, nil
}
// Текст уведомления о следующем дне
func StrNextDay(bot *tg.Bot, note Notify) (string, error) {
begin := note.Lesson.Begin
day := time.Date(begin.Year(), begin.Month(), begin.Day(), 0, 0, 0, 0, begin.Location())
shedules := []database.ShedulesInUser{
{
IsGroup: true,
SheduleId: note.Lesson.GroupId,
},
}
lessons, err := bot.GetLessons(shedules, day)
if err != nil {
return "", err
}
if len(lessons) != 0 {
pairs := tg.GroupPairs(lessons)
dayStr, err := bot.StrDayShedule(pairs, shedules[0].IsGroup)
if err != nil {
return "", err
}
str := "Сегодня больше ничего нет\n"
str += "Следующие занятия в " + tg.DayStr(day) + ":\n\n" + dayStr
return str, nil
}
return "", nil
}
// Рассылка всех уведомлений
func Mailing(bot *tg.Bot, notes []Notify, now time.Time) {
var ids []int64
for _, note := range notes {
var users []database.TgUser
query := database.ShedulesInUser{
IsGroup: note.IsGroup,
SheduleId: note.SheduleId,
}
var txt string
var err error
var tempTime time.Time
switch note.NotifyType {
case NextLesson:
query.NextNote = true
txt, err = StrNext(bot.DB, note)
tempTime = note.Lesson.Begin.Add(15 * time.Minute)
case NextDay:
query.NextDay = true
txt, err = StrNextDay(bot, note)
tempTime = note.Lesson.Begin.Add(-60 * time.Minute)
case NextWeek:
query.NextWeek = true
}
if err != nil {
log.Println(err)
}
if err := bot.DB.
UseBool(string(note.NotifyType)).
Table("ShedulesInUser").
Cols("tgid").
Join("INNER", "tguser", "tguser.l9id = ShedulesInUser.l9id").
Where("subgroup in (0, ?)", note.Lesson.SubGroup).
Find(&users, &query); err != nil {
log.Println(err)
}
for _, user := range users {
if !slices.Contains(ids, user.TgId) {
msg := tgbotapi.NewMessage(user.TgId, txt)
msg.ParseMode = tgbotapi.ModeHTML
m, err := bot.TG.Send(msg)
if err != nil {
log.Println(err)
}
temp := database.TempMsg{
TgId: m.Chat.ID,
MessageId: m.MessageID,
Destroy: tempTime,
}
if _, err := bot.DB.InsertOne(temp); err != nil {
log.Println(err)
}
ids = append(ids, user.TgId)
}
}
}
}
// Удаление временных сообщений
func ClearTemp(bot *tg.Bot, now time.Time) {
var temp []database.TempMsg
if err := bot.DB.Where("destroy < ?", now.Format("2006-01-02 15:04:03")).Find(&temp); err != nil {
log.Println(err)
}
for _, msg := range temp {
del := tgbotapi.NewDeleteMessage(msg.TgId, msg.MessageId)
if _, err := bot.TG.Request(del); err != nil {
log.Println(err)
}
if _, err := bot.DB.Delete(&msg); err != nil {
log.Println(err)
}
}
}