Добавлено: загрузка и парсинг расписания в одной функции
This commit is contained in:
parent
aea8cb77b2
commit
16f5abc820
|
@ -22,16 +22,15 @@ type ShedulesInUser struct {
|
|||
|
||||
type Group struct {
|
||||
GroupId int64 `xorm:"pk"`
|
||||
GroupName string
|
||||
SpecName string
|
||||
GroupName string // Полный номер группы
|
||||
SpecName string // Шифр и название специальности
|
||||
}
|
||||
|
||||
type Teacher struct {
|
||||
TeacherId int64 `xorm:"pk"`
|
||||
LastName string
|
||||
FirstName string
|
||||
MidName string
|
||||
SpecName string
|
||||
FirstName string // Фамилия
|
||||
LastName string // Имя, отчество и прочие окончания
|
||||
SpecName string // Место работы
|
||||
}
|
||||
|
||||
type Lesson struct {
|
||||
|
|
|
@ -8,8 +8,22 @@ import (
|
|||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func UpdateSchedule(db *xorm.Engine, sh WeekShedule) error {
|
||||
err := checkGroupOrTeacher(db, sh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
first_new := sh.Uncovered[0]
|
||||
_, week := first_new.Begin.ISOWeek()
|
||||
var old []database.Lesson
|
||||
db.Where("WEEK(`Begin`) = ?", week).Asc("Begin").Find(&old)
|
||||
Compare(sh.Uncovered, old)
|
||||
return nil
|
||||
}
|
||||
|
||||
func UploadShedule(db *xorm.Engine, sh WeekShedule) error {
|
||||
err := addGroupOrTeacher(db, sh)
|
||||
err := checkGroupOrTeacher(db, sh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -42,7 +56,7 @@ func UploadShedule(db *xorm.Engine, sh WeekShedule) error {
|
|||
gr.IsGroup = false
|
||||
gr.SheduleId = subLesson.TeacherId[0]
|
||||
GetSheduleInfo(doc.Doc, &gr)
|
||||
addGroupOrTeacher(db, gr)
|
||||
checkGroupOrTeacher(db, gr)
|
||||
}
|
||||
|
||||
for _, groupId := range subLesson.GroupId {
|
||||
|
@ -63,7 +77,7 @@ func UploadShedule(db *xorm.Engine, sh WeekShedule) error {
|
|||
gr.IsGroup = true
|
||||
gr.SheduleId = groupId
|
||||
GetSheduleInfo(doc.Doc, &gr)
|
||||
addGroupOrTeacher(db, gr)
|
||||
checkGroupOrTeacher(db, gr)
|
||||
}
|
||||
|
||||
var existsLessons []database.Lesson
|
||||
|
@ -109,7 +123,9 @@ func isTeacherExists(db *xorm.Engine, teacherId int64) (bool, error) {
|
|||
return len(exists) == 1, nil
|
||||
}
|
||||
|
||||
func addGroupOrTeacher(db *xorm.Engine, sh WeekShedule) error {
|
||||
// Проверка наличия группы или преподавателя в БД и добавление при необходимости
|
||||
// TODO: Добавить проверку изменений в полях данных
|
||||
func checkGroupOrTeacher(db *xorm.Engine, sh WeekShedule) error {
|
||||
if sh.IsGroup {
|
||||
exists, err := isGroupExists(db, sh.SheduleId)
|
||||
if err != nil {
|
||||
|
@ -135,8 +151,8 @@ func addGroupOrTeacher(db *xorm.Engine, sh WeekShedule) error {
|
|||
log.Println(name)
|
||||
teacher := database.Teacher{
|
||||
TeacherId: sh.SheduleId,
|
||||
LastName: name[0],
|
||||
FirstName: strings.Join(name[1:], " "),
|
||||
FirstName: name[0],
|
||||
LastName: strings.Join(name[1:], " "),
|
||||
SpecName: sh.SpecName,
|
||||
}
|
||||
db.InsertOne(teacher)
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
)
|
||||
|
||||
// Раскрытие недельного расписания в список занятий для базы данных и сравнения
|
||||
func UncoverShedule(sh WeekShedule) []database.Lesson {
|
||||
func (sh *WeekShedule) UncoverShedule() {
|
||||
var lessons []database.Lesson
|
||||
for y, line := range sh.Lessons {
|
||||
for x, pair := range line {
|
||||
|
@ -41,7 +41,7 @@ func UncoverShedule(sh WeekShedule) []database.Lesson {
|
|||
}
|
||||
}
|
||||
}
|
||||
return lessons
|
||||
sh.Uncovered = lessons
|
||||
}
|
||||
|
||||
// Сравнивание списков занятий на предмет добавления и удаления
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
package ssau_parser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.l9labs.ru/anufriev.g.a/l9_stud_bot/modules/database"
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// Пара, состоящая из занятий
|
||||
type Pair struct {
|
||||
Begin time.Time
|
||||
End time.Time
|
||||
|
@ -16,6 +19,7 @@ type Pair struct {
|
|||
Lessons []Lesson
|
||||
}
|
||||
|
||||
// Отдельные занятия внутри пары
|
||||
type Lesson struct {
|
||||
Type string
|
||||
Name string
|
||||
|
@ -27,14 +31,16 @@ type Lesson struct {
|
|||
Hash []byte
|
||||
}
|
||||
|
||||
// Недельное расписание
|
||||
type WeekShedule struct {
|
||||
IsGroup bool
|
||||
SheduleId int64
|
||||
FullName string
|
||||
SpecName string
|
||||
Week int
|
||||
WeekBegin int
|
||||
Lessons [][]Pair
|
||||
Week int // Номер недели в семестре
|
||||
WeekBegin int // Номер недели в году начала семестра
|
||||
Lessons [][]Pair // Таблица пар в форме недельного расписания
|
||||
Uncovered []database.Lesson // Раскрытый список всех занятий для дальнейшей обработки в БД
|
||||
}
|
||||
|
||||
// Получить полный номер группы и название специальности (ФИО и место работы для преподавателей)
|
||||
|
@ -58,10 +64,9 @@ func GetSheduleInfo(doc *goquery.Document, sh *WeekShedule) {
|
|||
var hourMap = map[int]int{8: 0, 9: 1, 11: 2, 13: 3, 15: 4, 17: 5, 18: 6, 20: 7}
|
||||
|
||||
// Парсинг страницы с расписанием
|
||||
func Parse(p Page) (*WeekShedule, error) {
|
||||
var sh WeekShedule
|
||||
func (sh *WeekShedule) Parse(p Page, uncover bool) error {
|
||||
doc := p.Doc
|
||||
GetSheduleInfo(doc, &sh)
|
||||
GetSheduleInfo(doc, sh)
|
||||
|
||||
var raw_dates []string
|
||||
doc.Find(".schedule__head-date").Each(func(i int, s *goquery.Selection) {
|
||||
|
@ -88,7 +93,7 @@ func Parse(p Page) (*WeekShedule, error) {
|
|||
if t == 0 {
|
||||
begin, err := time.Parse(" 15:04 -07", raw_times[t])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
firstNum = hourMap[begin.Hour()]
|
||||
}
|
||||
|
@ -98,12 +103,12 @@ func Parse(p Page) (*WeekShedule, error) {
|
|||
begin_raw := date + raw_times[t]
|
||||
begin, err := time.Parse(" 02.01.2006 15:04 -07", begin_raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
end_raw := date + raw_times[t+1]
|
||||
end, err := time.Parse(" 02.01.2006 15:04 -07", end_raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
idx := (len(raw_dates))*t/2 + d
|
||||
lesson := Pair{
|
||||
|
@ -120,7 +125,11 @@ func Parse(p Page) (*WeekShedule, error) {
|
|||
sh.SheduleId = p.ID
|
||||
sh.Week = p.Week
|
||||
sh.Lessons = shedule
|
||||
return &sh, nil
|
||||
|
||||
if uncover {
|
||||
sh.UncoverShedule()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var types = [4]string{"lect", "lab", "pract", "other"}
|
||||
|
@ -212,3 +221,37 @@ func ParseLesson(s *goquery.Selection, isGroup bool, sheduleId int64) []Lesson {
|
|||
|
||||
return lessons
|
||||
}
|
||||
|
||||
// Загрузка, парсинг и раскрытие расписания в одной функции
|
||||
// Обязательно наличие IsGroup, SheduleId, Week в объекте
|
||||
func (sh *WeekShedule) DownloadById(uncover bool) error {
|
||||
if sh.SheduleId == 0 {
|
||||
return errors.New("schedule id not included")
|
||||
}
|
||||
if sh.Week == 0 {
|
||||
return errors.New("week not included")
|
||||
}
|
||||
|
||||
page, err := DownloadSheduleById(sh.SheduleId, sh.IsGroup, sh.Week)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sh.Parse(page, uncover)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Загрузка, парсинг и раскрытие расписания в одной функции по URI и номеру недели
|
||||
func (sh *WeekShedule) Download(uri string, week int, uncover bool) error {
|
||||
page, err := DownloadShedule(uri, week)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = sh.Parse(page, uncover)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package ssau_parser
|
|||
import (
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"git.l9labs.ru/anufriev.g.a/l9_stud_bot/modules/database"
|
||||
)
|
||||
|
||||
var queries = []string{
|
||||
|
@ -21,6 +23,13 @@ var urls = []string{
|
|||
"http://127.0.0.1:5000",
|
||||
}
|
||||
|
||||
// Вывод некритических ошибок тестирования в консоль
|
||||
func handleError(err error) {
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: выдумать и прописать упоротые тесты для всего
|
||||
func TestSearchInRasp(t *testing.T) {
|
||||
// Проверка запросов
|
||||
|
@ -75,68 +84,83 @@ func TestDownloadShedule(t *testing.T) {
|
|||
|
||||
func TestParse(t *testing.T) {
|
||||
headURL = "http://127.0.0.1:5000"
|
||||
page, err := DownloadSheduleById(802440189, true, 3)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
_, err = Parse(page)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
sh := WeekShedule{
|
||||
SheduleId: 802440189,
|
||||
IsGroup: true,
|
||||
Week: 3,
|
||||
}
|
||||
err := sh.DownloadById(false)
|
||||
handleError(err)
|
||||
|
||||
// Ошибки в скелете расписания
|
||||
for i := 1; i < 6; i++ {
|
||||
page, err := DownloadSheduleById(123, true, i)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
_, err = Parse(page)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
sh := WeekShedule{
|
||||
SheduleId: 123,
|
||||
IsGroup: true,
|
||||
Week: i,
|
||||
}
|
||||
err = sh.DownloadById(false)
|
||||
handleError(err)
|
||||
}
|
||||
|
||||
// Ошибки внутри пар
|
||||
for i := 2; i < 3; i++ {
|
||||
page, err := DownloadSheduleById(62806001, false, i)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
sh, err := Parse(page)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
sh := WeekShedule{
|
||||
SheduleId: 62806001,
|
||||
IsGroup: false,
|
||||
Week: i,
|
||||
}
|
||||
err = sh.DownloadById(false)
|
||||
handleError(err)
|
||||
log.Println(sh.FullName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSheduleCompare(t *testing.T) {
|
||||
headURL = "http://127.0.0.1:5000"
|
||||
page, err := DownloadSheduleById(802440189, true, 4)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
sh := WeekShedule{
|
||||
SheduleId: 802440189,
|
||||
IsGroup: true,
|
||||
Week: 4,
|
||||
}
|
||||
sh, err := Parse(page)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
lessons := UncoverShedule(*sh)
|
||||
err := sh.DownloadById(true)
|
||||
handleError(err)
|
||||
|
||||
page, err = DownloadSheduleById(802440189, true, 8)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
new_sh := WeekShedule{
|
||||
SheduleId: 802440189,
|
||||
IsGroup: true,
|
||||
Week: 8,
|
||||
}
|
||||
sh, err = Parse(page)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
new_lessons := UncoverShedule(*sh)
|
||||
err = new_sh.DownloadById(true)
|
||||
handleError(err)
|
||||
|
||||
add, del := Compare(new_lessons, lessons)
|
||||
add, del := Compare(new_sh.Uncovered, sh.Uncovered)
|
||||
log.Println(add, del)
|
||||
}
|
||||
|
||||
func TestCheckGroupOrTeacher(t *testing.T) {
|
||||
db, err := database.Connect("test", "TESTpass1!", "testdb")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
// Очистка всех данных для теста
|
||||
_, err = db.Where("groupid > 0").Delete(&database.Group{})
|
||||
handleError(err)
|
||||
_, err = db.Where("teacherid > 0").Delete(&database.Teacher{})
|
||||
handleError(err)
|
||||
|
||||
headURL = "http://127.0.0.1:5000"
|
||||
sh := WeekShedule{
|
||||
SheduleId: 802440189,
|
||||
IsGroup: true,
|
||||
Week: 4,
|
||||
}
|
||||
err = sh.DownloadById(false)
|
||||
handleError(err)
|
||||
err = checkGroupOrTeacher(db, sh)
|
||||
handleError(err)
|
||||
// Повторяем на предмет наличия
|
||||
err = checkGroupOrTeacher(db, sh)
|
||||
handleError(err)
|
||||
}
|
||||
|
|
|
@ -102,7 +102,6 @@ func (bot *Bot) Find(query string) error {
|
|||
TeacherId: elem.Id,
|
||||
LastName: name[0],
|
||||
FirstName: name[1],
|
||||
MidName: name[2],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -323,8 +323,8 @@ func PairToStr(pair []database.Lesson, db *xorm.Engine) (string, error) {
|
|||
name := GenerateName(t)
|
||||
str += fmt.Sprintf("👤 %s\n", name)
|
||||
}
|
||||
if sublesson.SubGroup != "" {
|
||||
str += fmt.Sprintf("👥 %s\n", sublesson.SubGroup)
|
||||
if sublesson.SubGroup != 0 {
|
||||
str += fmt.Sprintf("👥 %d\n", sublesson.SubGroup)
|
||||
}
|
||||
if sublesson.Comment != "" {
|
||||
str += fmt.Sprintf("💬 %s\n", sublesson.Comment)
|
||||
|
|
|
@ -257,8 +257,8 @@ func (bot *Bot) CreateHTMLShedule(week int, shedule [][6][]database.Lesson, date
|
|||
if l[0].Place != "" {
|
||||
html += fmt.Sprintf("<h3>%s</h3>\n", l[0].Place)
|
||||
}
|
||||
if l[0].SubGroup != "" {
|
||||
html += fmt.Sprintf("<h3>%s</h3>\n", l[0].SubGroup)
|
||||
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)
|
||||
|
@ -278,8 +278,8 @@ func (bot *Bot) CreateHTMLShedule(week int, shedule [][6][]database.Lesson, date
|
|||
if l[1].Place != "" {
|
||||
html += fmt.Sprintf("<h3>%s</h3>\n", l[1].Place)
|
||||
}
|
||||
if l[1].SubGroup != "" {
|
||||
html += fmt.Sprintf("<h3>%s</h3>\n", l[1].SubGroup)
|
||||
if l[1].SubGroup != 0 {
|
||||
html += fmt.Sprintf("<h3>%d</h3>\n", l[1].SubGroup)
|
||||
}
|
||||
if l[1].Comment != "" {
|
||||
html += fmt.Sprintf("<h3>%s</h3>\n", l[1].Comment)
|
||||
|
|
Reference in New Issue