2023-08-08 18:36:33 +03:00
|
|
|
|
package tg
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"math"
|
|
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"sort"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"git.l9labs.ru/anufriev.g.a/l9_stud_bot/modules/database"
|
|
|
|
|
"git.l9labs.ru/anufriev.g.a/l9_stud_bot/modules/ssau_parser"
|
|
|
|
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
|
|
|
|
"github.com/icza/gox/timex"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var days = [6]string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}
|
|
|
|
|
|
|
|
|
|
func (bot *Bot) GetWeekSummary(
|
|
|
|
|
now time.Time,
|
|
|
|
|
user *database.TgUser,
|
|
|
|
|
shedule database.ShedulesInUser,
|
|
|
|
|
dw int,
|
|
|
|
|
isPersonal bool,
|
2023-08-11 19:39:46 +03:00
|
|
|
|
caption string,
|
2023-08-09 14:05:51 +03:00
|
|
|
|
editMsg ...tgbotapi.Message,
|
2023-08-08 18:36:33 +03:00
|
|
|
|
) error {
|
|
|
|
|
_, week := now.ISOWeek()
|
|
|
|
|
week += dw - bot.Week
|
|
|
|
|
var image database.File
|
2023-08-14 05:49:12 +03:00
|
|
|
|
var cols []string
|
2023-08-08 18:36:33 +03:00
|
|
|
|
if !isPersonal {
|
|
|
|
|
image = database.File{
|
2023-08-09 14:05:51 +03:00
|
|
|
|
TgId: user.TgId,
|
2023-08-08 18:36:33 +03:00
|
|
|
|
IsPersonal: false,
|
|
|
|
|
IsGroup: shedule.IsGroup,
|
|
|
|
|
SheduleId: shedule.SheduleId,
|
|
|
|
|
Week: week,
|
|
|
|
|
}
|
2023-08-14 05:49:12 +03:00
|
|
|
|
cols = []string{"IsPersonal", "IsGroup"}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
} else {
|
|
|
|
|
image = database.File{
|
2023-08-09 14:05:51 +03:00
|
|
|
|
TgId: user.TgId,
|
2023-08-08 18:36:33 +03:00
|
|
|
|
IsPersonal: true,
|
|
|
|
|
Week: week,
|
|
|
|
|
}
|
2023-08-14 05:49:12 +03:00
|
|
|
|
cols = []string{"IsPersonal"}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
}
|
2023-08-14 05:49:12 +03:00
|
|
|
|
has, err := bot.DB.UseBool(cols...).Get(&image)
|
2023-08-08 18:36:33 +03:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
var lastUpd time.Time
|
|
|
|
|
if shedule.IsGroup {
|
|
|
|
|
var group database.Group
|
|
|
|
|
if _, err := bot.DB.ID(shedule.SheduleId).Get(&group); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
lastUpd = group.LastUpd
|
|
|
|
|
} else {
|
|
|
|
|
var teacher database.Teacher
|
|
|
|
|
if _, err := bot.DB.ID(shedule.SheduleId).Get(&teacher); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
lastUpd = teacher.LastUpd
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !has || image.LastUpd.Before(lastUpd) {
|
2023-08-10 11:22:18 +03:00
|
|
|
|
if _, err := bot.DB.Delete(&image); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
var shedules []database.ShedulesInUser
|
|
|
|
|
if isPersonal {
|
|
|
|
|
shedules = append(shedules, database.ShedulesInUser{L9Id: user.L9Id})
|
2023-08-09 14:05:51 +03:00
|
|
|
|
if _, err := bot.DB.Get(&shedules[0]); err != nil {
|
2023-08-08 18:36:33 +03:00
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
shedules = append(shedules, shedule)
|
|
|
|
|
}
|
2023-08-11 19:39:46 +03:00
|
|
|
|
return bot.CreateWeekImg(now, user, shedules, dw, isPersonal, caption, editMsg...)
|
2023-08-08 18:36:33 +03:00
|
|
|
|
} else {
|
|
|
|
|
var shId int64
|
|
|
|
|
if isPersonal {
|
|
|
|
|
shId = 0
|
|
|
|
|
} else {
|
2023-08-09 14:05:51 +03:00
|
|
|
|
shId = shedule.SheduleId
|
2023-08-08 18:36:33 +03:00
|
|
|
|
}
|
2023-08-11 19:39:46 +03:00
|
|
|
|
markup := tgbotapi.InlineKeyboardMarkup{}
|
|
|
|
|
if caption == "" {
|
|
|
|
|
markup = SummaryKeyboard(
|
|
|
|
|
"sh_week",
|
|
|
|
|
shId,
|
|
|
|
|
shedule.IsGroup,
|
|
|
|
|
dw,
|
|
|
|
|
)
|
|
|
|
|
}
|
2023-08-09 14:05:51 +03:00
|
|
|
|
|
2023-08-11 19:39:46 +03:00
|
|
|
|
_, err := bot.EditOrSend(user.TgId, caption, image.FileId, markup, editMsg...)
|
2023-08-09 14:05:51 +03:00
|
|
|
|
return err
|
|
|
|
|
}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (bot *Bot) GetWeekLessons(shedules []database.ShedulesInUser, week int) ([]database.Lesson, error) {
|
|
|
|
|
condition := CreateCondition(shedules)
|
|
|
|
|
|
|
|
|
|
var lessons []database.Lesson
|
|
|
|
|
err := bot.DB.
|
|
|
|
|
Where("WEEK(`begin`, 1) = ?", week+bot.Week).
|
|
|
|
|
And(condition).
|
|
|
|
|
OrderBy("begin").
|
|
|
|
|
Find(&lessons)
|
|
|
|
|
|
|
|
|
|
return lessons, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (bot *Bot) CreateWeekImg(
|
|
|
|
|
now time.Time,
|
|
|
|
|
user *database.TgUser,
|
|
|
|
|
shedules []database.ShedulesInUser,
|
|
|
|
|
dw int,
|
|
|
|
|
isPersonal bool,
|
2023-08-11 19:39:46 +03:00
|
|
|
|
caption string,
|
2023-08-09 14:05:51 +03:00
|
|
|
|
editMsg ...tgbotapi.Message,
|
2023-08-08 18:36:33 +03:00
|
|
|
|
) error {
|
|
|
|
|
_, week := now.ISOWeek()
|
|
|
|
|
week += dw
|
|
|
|
|
lessons, err := bot.GetWeekLessons(shedules, week-bot.Week)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if len(lessons) == 0 {
|
2023-08-10 11:22:18 +03:00
|
|
|
|
// TODO: сделать костыль поизящнее и предупреждать, если неделя пустая
|
|
|
|
|
next, err := bot.GetWeekLessons(shedules, week-bot.Week+1)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if len(next) > 0 {
|
|
|
|
|
lessons = next
|
|
|
|
|
week += 1
|
|
|
|
|
} else {
|
2023-08-13 14:00:51 +03:00
|
|
|
|
return fmt.Errorf("no lessons: %d, week %d", shedules[0].SheduleId, week-bot.Week)
|
2023-08-10 11:22:18 +03:00
|
|
|
|
}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var dates []time.Time
|
|
|
|
|
begins := make(map[time.Time]bool)
|
|
|
|
|
ends := make(map[time.Time]bool)
|
|
|
|
|
height := 0
|
|
|
|
|
minDay := lessons[0].NumInShedule
|
|
|
|
|
for _, lesson := range lessons {
|
|
|
|
|
t := lesson.Begin
|
|
|
|
|
begin := time.Date(2000, 1, 1, t.Hour(), t.Minute(), 0, 0, t.Location())
|
|
|
|
|
begins[begin] = true
|
|
|
|
|
|
|
|
|
|
e := lesson.End
|
|
|
|
|
end := time.Date(2000, 1, 1, e.Hour(), e.Minute(), 0, 0, e.Location())
|
|
|
|
|
ends[end] = true
|
|
|
|
|
|
|
|
|
|
if lesson.NumInShedule > height {
|
|
|
|
|
height = lesson.NumInShedule
|
|
|
|
|
} else if lesson.NumInShedule < minDay {
|
|
|
|
|
minDay = lesson.NumInShedule
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var times []ssau_parser.Pair
|
|
|
|
|
var beginsSlice []time.Time
|
|
|
|
|
var endsSlice []time.Time
|
|
|
|
|
for b := range begins {
|
|
|
|
|
beginsSlice = append(beginsSlice, b)
|
|
|
|
|
}
|
|
|
|
|
for e := range ends {
|
|
|
|
|
endsSlice = append(endsSlice, e)
|
|
|
|
|
}
|
|
|
|
|
sort.Slice(beginsSlice, func(i, j int) bool {
|
|
|
|
|
return beginsSlice[i].Before(beginsSlice[j])
|
|
|
|
|
})
|
|
|
|
|
sort.Slice(endsSlice, func(i, j int) bool {
|
|
|
|
|
return endsSlice[i].Before(endsSlice[j])
|
|
|
|
|
})
|
|
|
|
|
for i, b := range beginsSlice {
|
|
|
|
|
sh := ssau_parser.Pair{
|
|
|
|
|
Begin: b,
|
|
|
|
|
End: endsSlice[i],
|
|
|
|
|
}
|
|
|
|
|
times = append(times, sh)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
weekBegin := timex.WeekStart(lessons[0].Begin.Year(), week)
|
|
|
|
|
for i := range days {
|
|
|
|
|
dates = append(dates, weekBegin.Add(time.Hour*time.Duration(24*i)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
shedule := make([][6][]database.Lesson, height-minDay+1)
|
|
|
|
|
pairs := GroupPairs(lessons)
|
|
|
|
|
|
|
|
|
|
for _, p := range pairs {
|
|
|
|
|
day := int(math.Floor(p[0].Begin.Sub(weekBegin).Hours() / 24))
|
|
|
|
|
shedule[p[0].NumInShedule-minDay][day] = p
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-09 14:05:51 +03:00
|
|
|
|
// Проверяем пустые строки и эпирическим путём подбираем для них время (или не подбираем вовсе)
|
|
|
|
|
for y, line := range shedule {
|
|
|
|
|
count := 0
|
|
|
|
|
for _, l := range line {
|
|
|
|
|
count += len(l)
|
|
|
|
|
}
|
|
|
|
|
if count == 0 {
|
|
|
|
|
nilPair := ssau_parser.Pair{}
|
|
|
|
|
if y == len(shedule) {
|
|
|
|
|
times = append(times, nilPair)
|
|
|
|
|
} else {
|
|
|
|
|
times = append(times[:y+1], times[y:]...)
|
|
|
|
|
times[y] = nilPair
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-08 18:36:33 +03:00
|
|
|
|
var header string
|
|
|
|
|
if isPersonal {
|
2023-08-09 14:05:51 +03:00
|
|
|
|
header = fmt.Sprintf("Моё расписание, %d неделя", week-bot.Week)
|
2023-08-08 18:36:33 +03:00
|
|
|
|
} else if shedules[0].IsGroup {
|
|
|
|
|
var group database.Group
|
|
|
|
|
if _, err := bot.DB.ID(shedules[0].SheduleId).Get(&group); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-08-09 14:05:51 +03:00
|
|
|
|
header = fmt.Sprintf("%s, %d неделя", group.GroupName, week-bot.Week)
|
2023-08-08 18:36:33 +03:00
|
|
|
|
} else {
|
|
|
|
|
var teacher database.Teacher
|
|
|
|
|
if _, err := bot.DB.ID(shedules[0].SheduleId).Get(&teacher); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
header = fmt.Sprintf("%s %s, %d неделя", teacher.FirstName, teacher.LastName, week-bot.Week)
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-09 16:53:50 +03:00
|
|
|
|
html := bot.CreateHTMLShedule(shedules[0].IsGroup, header, shedule, dates, times)
|
2023-08-08 18:36:33 +03:00
|
|
|
|
|
|
|
|
|
path := GeneratePath(shedules[0], isPersonal, user.L9Id)
|
|
|
|
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
|
|
|
|
err = os.MkdirAll(path, os.ModePerm)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
input := fmt.Sprintf("./%s/week_%d.html", path, week-bot.Week)
|
2023-08-30 08:42:27 +03:00
|
|
|
|
output := fmt.Sprintf("./%s/week_%d.jpg", path, week-bot.Week)
|
2023-08-08 18:36:33 +03:00
|
|
|
|
f, _ := os.Create(input)
|
|
|
|
|
defer f.Close()
|
|
|
|
|
f.WriteString(html)
|
|
|
|
|
|
|
|
|
|
cmd := exec.CommandContext(context.Background(), bot.WkPath, []string{
|
|
|
|
|
"--width",
|
2023-08-30 08:42:27 +03:00
|
|
|
|
"1600",
|
2023-08-08 18:36:33 +03:00
|
|
|
|
input,
|
|
|
|
|
output,
|
|
|
|
|
}...)
|
|
|
|
|
cmd.Stderr = bot.Debug.Writer()
|
|
|
|
|
cmd.Stdout = bot.Debug.Writer()
|
|
|
|
|
err = cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
photoBytes, err := os.ReadFile(output)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
photoFileBytes := tgbotapi.FileBytes{
|
|
|
|
|
Bytes: photoBytes,
|
|
|
|
|
}
|
2023-08-09 14:05:51 +03:00
|
|
|
|
|
|
|
|
|
// TODO: Загнать эту конструкцию внутрь функции
|
|
|
|
|
var shId int64
|
|
|
|
|
if isPersonal {
|
|
|
|
|
shId = 0
|
|
|
|
|
} else {
|
|
|
|
|
shId = shedules[0].SheduleId
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Качаем фото и сохраняем данные о нём в БД
|
2023-08-08 18:36:33 +03:00
|
|
|
|
photo := tgbotapi.NewPhoto(user.TgId, photoFileBytes)
|
2023-08-11 19:39:46 +03:00
|
|
|
|
photo.Caption = caption
|
|
|
|
|
if caption == "" {
|
|
|
|
|
photo.ReplyMarkup = SummaryKeyboard(
|
|
|
|
|
"sh_week",
|
|
|
|
|
shId,
|
|
|
|
|
shedules[0].IsGroup,
|
|
|
|
|
dw,
|
|
|
|
|
)
|
|
|
|
|
}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
resp, err := bot.TG.Send(photo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
file := database.File{
|
|
|
|
|
FileId: resp.Photo[0].FileID,
|
|
|
|
|
TgId: user.TgId,
|
|
|
|
|
IsPersonal: isPersonal,
|
|
|
|
|
IsGroup: shedules[0].IsGroup,
|
|
|
|
|
SheduleId: shedules[0].SheduleId,
|
|
|
|
|
Week: week - bot.Week,
|
|
|
|
|
LastUpd: now,
|
|
|
|
|
}
|
2023-08-09 14:05:51 +03:00
|
|
|
|
_, err = bot.DB.InsertOne(file)
|
2023-08-08 18:36:33 +03:00
|
|
|
|
|
2023-08-09 14:05:51 +03:00
|
|
|
|
// Удаляем старое сообщение
|
|
|
|
|
if len(editMsg) != 0 {
|
|
|
|
|
del := tgbotapi.NewDeleteMessage(
|
|
|
|
|
editMsg[0].Chat.ID,
|
|
|
|
|
editMsg[0].MessageID,
|
2023-08-08 18:36:33 +03:00
|
|
|
|
)
|
2023-08-09 14:05:51 +03:00
|
|
|
|
if _, err := bot.TG.Request(del); err != nil {
|
|
|
|
|
return err
|
2023-08-08 18:36:33 +03:00
|
|
|
|
}
|
2023-08-09 14:05:51 +03:00
|
|
|
|
}
|
|
|
|
|
return err
|
2023-08-08 18:36:33 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GeneratePath(sh database.ShedulesInUser, isPersonal bool, userId int64) string {
|
|
|
|
|
var path string
|
|
|
|
|
if isPersonal {
|
|
|
|
|
path = fmt.Sprintf("personal/%d", userId)
|
|
|
|
|
} else if sh.IsGroup {
|
|
|
|
|
path = fmt.Sprintf("group/%d", sh.SheduleId)
|
|
|
|
|
} else {
|
|
|
|
|
path = fmt.Sprintf("staff/%d", sh.SheduleId)
|
|
|
|
|
}
|
|
|
|
|
return "shedules/" + path
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const head = `<html lang="ru">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<title>Тестовая страница с расписанием</title>
|
|
|
|
|
<meta name='viewport' content='width=device-width,initial-scale=1'/>
|
|
|
|
|
<meta name="mobile-web-app-capable" content="yes">
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<style>
|
2023-08-30 08:42:27 +03:00
|
|
|
|
.subj div,th.head,th.subj,th.time{border-radius:10px}.note,.subj p,th.head,th.time{font-family:monospace}.note div,.rasp div{background-color:#f0f8ff;padding:10px;text-align:center;border-radius:10px}.subj div #text,.subj p{display:none}html{font-size:1.5rem}body{background:#dc14bd}table{table-layout:fixed;width:100%;border-spacing:5px 5px}.note div{margin:10px 0}.head p,.subj p,hr{margin:0}.rasp div{transition:.3s}th.head{background-color:#0ff;padding:5px;font-size:1.05rem}th.subj,th.time{background-color:#f0f8ff;padding:10px}th.time{font-size:1.1rem}.subj h2,.subj p{font-size:.85rem}th.subj:not(.lab,.lect,.pract,.other){background-color:#a9a9a9}.subj div{padding:5px}.subj p{color:#f0f8ff}.subj h2,.subj h3,.subj h5{font-family:monospace;text-align:left;margin:5px}.subj h3{font-size:.65rem}.subj h5{font-size:.7rem;font-weight:400}.lect div{background-color:#7fff00}.pract div{background-color:#dc143c}.lab div{background-color:#8a2be2}.mil div,.other div{background-color:#ff8c00}.window div{background-color:#00f}.cons div{background-color:green}.exam div{background-color:purple}.kurs div{background-color:orange}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<body>
|
|
|
|
|
`
|
|
|
|
|
const lessonHead = `<th class="subj %s" valign="top">
|
|
|
|
|
<div><p></p></div>
|
|
|
|
|
<h2>%s</h2><hr>`
|
|
|
|
|
|
|
|
|
|
var shortWeekdays = [6]string{
|
|
|
|
|
"пн",
|
|
|
|
|
"вт",
|
|
|
|
|
"ср",
|
|
|
|
|
"чт",
|
|
|
|
|
"пт",
|
|
|
|
|
"сб",
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-09 16:53:50 +03:00
|
|
|
|
func (bot *Bot) CreateHTMLShedule(
|
|
|
|
|
isGroup bool,
|
|
|
|
|
header string,
|
|
|
|
|
shedule [][6][]database.Lesson,
|
|
|
|
|
dates []time.Time,
|
|
|
|
|
times []ssau_parser.Pair,
|
|
|
|
|
) string {
|
2023-08-08 18:36:33 +03:00
|
|
|
|
html := head
|
|
|
|
|
html += fmt.Sprintf("<div class=\"note\"><div id=\"week\">%s</div></div>\n", header)
|
|
|
|
|
html += "<table class=\"rasp\">\n<tr><th class=\"head\" style=\"width: 4rem\">Время</th>\n"
|
|
|
|
|
|
|
|
|
|
for i, d := range dates {
|
|
|
|
|
day := d.Format("02")
|
|
|
|
|
html += fmt.Sprintf("<th class=\"head\">%s<p>%s</p></th>", shortWeekdays[i], day)
|
|
|
|
|
}
|
|
|
|
|
html += "</tr>\n"
|
2023-08-10 10:41:28 +03:00
|
|
|
|
|
2023-08-08 18:36:33 +03:00
|
|
|
|
for t, tline := range shedule {
|
2023-08-09 14:05:51 +03:00
|
|
|
|
var begin, end string
|
|
|
|
|
if times[t].Begin.IsZero() {
|
|
|
|
|
begin = ("--:--")
|
|
|
|
|
end = ("--:--")
|
|
|
|
|
} else {
|
|
|
|
|
begin = times[t].Begin.Format("15:04")
|
|
|
|
|
end = times[t].End.Format("15:04")
|
|
|
|
|
}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
html += fmt.Sprintf("<tr>\n<th class=\"time\">%s<hr>%s</th>", begin, end)
|
|
|
|
|
for i, l := range tline {
|
|
|
|
|
|
|
|
|
|
if len(l) > 0 && l[0].Type != "window" {
|
|
|
|
|
html += fmt.Sprintf(lessonHead, l[0].Type, l[0].Name)
|
2023-08-09 16:53:50 +03:00
|
|
|
|
if isGroup && l[0].TeacherId != 0 {
|
2023-08-08 18:36:33 +03:00
|
|
|
|
var t database.Teacher
|
|
|
|
|
bot.DB.ID(l[0].TeacherId).Get(&t)
|
|
|
|
|
html += fmt.Sprintf("<h5 id=\"prep\">%s %s</h5>\n", t.FirstName, t.ShortName)
|
|
|
|
|
}
|
|
|
|
|
if l[0].Place != "" {
|
|
|
|
|
html += fmt.Sprintf("<h3>%s</h3>\n", l[0].Place)
|
|
|
|
|
}
|
2023-08-09 16:53:50 +03:00
|
|
|
|
if !isGroup {
|
|
|
|
|
var t database.Group
|
|
|
|
|
bot.DB.ID(l[0].GroupId).Get(&t)
|
|
|
|
|
html += fmt.Sprintf("<h3>%s</h3>\n", t.GroupName)
|
|
|
|
|
}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
if l[0].SubGroup != 0 {
|
|
|
|
|
html += fmt.Sprintf("<h3>Подгруппа: %d</h3>\n", l[0].SubGroup)
|
|
|
|
|
}
|
|
|
|
|
if l[0].Comment != "" {
|
|
|
|
|
html += fmt.Sprintf("<h3>%s</h3>\n", l[0].Comment)
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-09 16:53:50 +03:00
|
|
|
|
if len(l) == 2 && isGroup {
|
2023-08-08 18:36:33 +03:00
|
|
|
|
html += "<hr>\n"
|
|
|
|
|
if l[0].Name != l[1].Name {
|
|
|
|
|
html += fmt.Sprintf("<div><p></p></div>\n<h2>%s</h2><hr>", l[1].Name)
|
|
|
|
|
}
|
|
|
|
|
if l[1].TeacherId != 0 {
|
|
|
|
|
var t database.Teacher
|
|
|
|
|
bot.DB.ID(l[1].TeacherId).Get(&t)
|
|
|
|
|
html += fmt.Sprintf("<h5 id=\"prep\">%s %s</h5>\n", t.FirstName, t.ShortName)
|
|
|
|
|
}
|
|
|
|
|
if l[1].Place != "" {
|
|
|
|
|
html += fmt.Sprintf("<h3>%s</h3>\n", l[1].Place)
|
|
|
|
|
}
|
|
|
|
|
if l[1].SubGroup != 0 {
|
2023-08-09 14:05:51 +03:00
|
|
|
|
html += fmt.Sprintf("<h3>Подгруппа: %d</h3>\n", l[1].SubGroup)
|
2023-08-08 18:36:33 +03:00
|
|
|
|
}
|
|
|
|
|
if l[1].Comment != "" {
|
|
|
|
|
html += fmt.Sprintf("<h3>%s</h3>\n", l[1].Comment)
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-09 16:53:50 +03:00
|
|
|
|
if len(l) > 1 && !isGroup {
|
|
|
|
|
for _, gr := range l[1:] {
|
|
|
|
|
var t database.Group
|
|
|
|
|
bot.DB.ID(gr.GroupId).Get(&t)
|
|
|
|
|
html += fmt.Sprintf("<h3>%s</h3>\n", t.GroupName)
|
|
|
|
|
if gr.SubGroup != 0 {
|
|
|
|
|
html += fmt.Sprintf("<h3>Подгруппа: %d</h3>\n<hr>\n", l[1].SubGroup)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-08 18:36:33 +03:00
|
|
|
|
|
|
|
|
|
html += "</th>\n"
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
html += "<th class=\"subj\"></th>\n"
|
|
|
|
|
}
|
|
|
|
|
if i%7 == 6 {
|
|
|
|
|
html += "</tr>\n"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
html += "</table></body></html>"
|
|
|
|
|
return html
|
|
|
|
|
}
|