diff --git a/doc.go b/doc.go index 414d92c..073f617 100644 --- a/doc.go +++ b/doc.go @@ -1,8 +1,4 @@ -// dnevnik76-api project doc.go - -/* -dnevnik76-api document -*/ +// Package dnevnik76 doc package dnevnik76 /* Сообщения diff --git a/go.mod b/go.mod index ba45d99..1765e87 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/bvp/dnevnik76-api go 1.12 require ( - github.com/PuerkitoBio/goquery v1.6.0 + github.com/PuerkitoBio/goquery v1.6.1 github.com/andybalholm/cascadia v1.2.0 // indirect github.com/bvp/russiantime v0.1.0 - golang.org/x/net v0.0.0-20201010224723-4f7140c49acb + golang.org/x/net v0.0.0-20210119194325-5f4716e94777 ) diff --git a/go.sum b/go.sum index 8a9ff43..9132c06 100644 --- a/go.sum +++ b/go.sum @@ -1,20 +1,18 @@ -github.com/PuerkitoBio/goquery v1.6.0 h1:j7taAbelrdcsOlGeMenZxc2AWXD5fieT1/znArdnx94= -github.com/PuerkitoBio/goquery v1.6.0/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/PuerkitoBio/goquery v1.6.1 h1:FgjbQZKl5HTmcn4sKBgvx8vv63nhyhIpv7lJpFGCWpk= +github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE= github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY= github.com/bvp/russiantime v0.1.0 h1:oXpuB2ooSlexQGJ+Vp0ydjQ2IPgiuqpVwxz3vBVclm0= github.com/bvp/russiantime v0.1.0/go.mod h1:jALOcp8csKwzExdl0Yn4OagrU4PZ1YqJlJIayioeyCE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/main.go b/main.go index 0b8ad39..59c2d7a 100644 --- a/main.go +++ b/main.go @@ -94,9 +94,6 @@ func (cli *Client) Login() (err error) { return } cli.Token, _ = doc.Find(".login__form > input[name='csrfmiddlewaretoken']").First().Attr("value") - if DEBUG { - log.Printf("csrfmiddlewaretoken - %s\n", cli.Token) - } payload := url.Values{ "next": {""}, // /marks/current/ @@ -125,17 +122,6 @@ func (cli *Client) Login() (err error) { return } - if DEBUG { - h1 := doc.Find("#logo > h1").First() - log.Printf("%s", h1.Text()) - } - - // redirected := resp.Request.URL.String() - // log.Printf("redirected: %s", redirected) - // if redirected != urlLoginSuccess { - // return errors.New("redirected to not success url") - // } - err = cli.GetCurrentInfo() return @@ -143,8 +129,6 @@ func (cli *Client) Login() (err error) { // GetCurrentInfo for session func (cli *Client) GetCurrentInfo() (err error) { - // ci := CurrentInfo{} - resp, err := cli.http.Get(urlHomework) doc, err := goquery.NewDocumentFromResponse(resp) @@ -153,18 +137,12 @@ func (cli *Client) GetCurrentInfo() (err error) { if err != nil { return } - if DEBUG { - log.Printf("className - %d%s\n", classNumber, classChar) - } cli.currentInfo.ClassNumber = classNumber cli.currentInfo.ClassChar = classChar classIDText, _ := doc.Find("body").Attr("onload") if classIDText != "" { classIDText = strings.TrimRight(strings.TrimLeft(classIDText, "loadSubjects('/ajax/subj/"), "', true)") - if DEBUG { - log.Printf("class_id - %s\n", classIDText) - } } classID, err := strconv.ParseInt(classIDText, 10, 32) cli.currentInfo.ClassID = classID @@ -176,17 +154,7 @@ func (cli *Client) GetCurrentInfo() (err error) { cli.currentInfo.EduYearStart = int(eys) cli.currentInfo.EduYearEnd = int(eye) - // log.Printf("eduyear - %s\n", eyr) - - // for _, cookie := range cli.http.Jar.Cookies(u) { - // if cookie.Name == "edu_year" { - // cli.currentInfo.EduYearStart = cookie.Value - // } - // } - cli.ToJSON(cli.currentInfo) - // cli.currentInfo = ci - // cli.ToJSON(cli.currentInfo) return } @@ -195,9 +163,6 @@ func (cli *Client) GetCurrentInfo() (err error) { func (cli *Client) ToJSON(o interface{}) (result string) { oj, _ := json.Marshal(o) result = string(oj) - if DEBUG { - log.Printf(":: %s\n", result) - } return } @@ -219,7 +184,6 @@ func (cli *Client) SetCookie(name, value string) { u, _ := url.Parse(urlLogin) var cookies []*http.Cookie - // cookies := cli.http.Jar.Cookies(u) cookies = append(cookies, cookie) cli.http.Jar.SetCookies(u, cookies) cli.GetCurrentInfo() @@ -227,8 +191,6 @@ func (cli *Client) SetCookie(name, value string) { // GetRegions to get client regions func GetRegions() (regions []Region, err error) { - // Get kladr - https://my.dnevnik76.ru/ajax/kladr/?login=true - // 1. get region - select > option resp, err := http.Get(fmt.Sprintf("%s/kladr/?login=true", urlAjax)) if err != nil { return @@ -312,7 +274,6 @@ func (cli *Client) GetMarksPeriods() (periods []Lperiod, err error) { title := strings.TrimSpace(s2.Text()) value, _ := s2.Attr("value") period := Lperiod{ - // RegionID: cli.currentInfo.RegionID, SchoolID: cli.currentInfo.SchoolID, SYear: cli.currentInfo.EduYearStart, EYear: cli.currentInfo.EduYearEnd, @@ -403,9 +364,6 @@ func (cli *Client) GetMarksForMonthWithType(p string, t MarksListType) (marks [] mark.Date = russiantime.ParseDateString(d) mark.Grade = append(mark.Grade, int8(pm)) marks = append(marks, mark) - if DEBUG { - log.Printf("course - %s, d - %s, mark - %d", mark.CourseName, mark.Date, pm) - } } }) }) @@ -429,19 +387,9 @@ func (cli *Client) GetMarksFinal() (marks []Mark, err error) { if err != nil { return } - title := doc.Find("#content > h3").Text() - - ret := regexp.MustCompile(`([^"]*)(\d{4}\s\-\s\d{4})([^"]*)`) - lrange := ret.ReplaceAllString(title, "${2}") - if DEBUG { - log.Printf("%s", lrange) - } - + courses, _ := cli.GetCourses() doc.Find("#marks > #wrap-col > #wrap-marks > div > #mark-row").Each(func(i int, s *goquery.Selection) { courseID, _ := s.Attr("name") - if DEBUG { - log.Printf("course id - %s", courseID) - } s.Find(".mark").Each(func(j int, sj *goquery.Selection) { mark := Mark{} @@ -450,6 +398,12 @@ func (cli *Client) GetMarksFinal() (marks []Mark, err error) { mark.UserID = cli.Username mark.SchoolID = cli.SchoolID mark.CourseID, _ = strconv.ParseInt(courseID, 10, 32) + for _, c := range courses { + if c.ID == mark.CourseID { + mark.CourseName = c.Name + break + } + } data := func() (period string, fmark string) { el := sj.Find("a").First() onClick, _ := el.Attr("onclick") @@ -604,9 +558,6 @@ func (cli *Client) GetHomework() (hws []Homework, err error) { classIDText, _ := doc.Find("body").Attr("onload") if classIDText != "" { classIDText = strings.TrimRight(strings.TrimLeft(classIDText, "loadSubjects('/ajax/subj/"), "', true)") - if DEBUG { - log.Printf("class_id - %s\n", classIDText) - } } classID, err := strconv.ParseInt(classIDText, 10, 64) hwPagesFlag := doc.Find("#homework_list > div.pager > span.page_remark").Text() diff --git a/main_test.go b/main_test.go index 36492ec..ab67315 100644 --- a/main_test.go +++ b/main_test.go @@ -2,9 +2,11 @@ package dnevnik76 import ( "encoding/json" + "fmt" "io/ioutil" "log" "os" + "strings" "testing" ) @@ -21,6 +23,10 @@ type config struct { Password string `json:"password"` } +func arrayToString(a []int8, delim string) string { + return strings.Trim(strings.Replace(fmt.Sprint(a), " ", delim, -1), "[]") +} + func TestClient_Login(t *testing.T) { t.Log("Testing Login") err := client.Login() @@ -44,9 +50,8 @@ func TestClient_GetSchool(t *testing.T) { schools, _ := GetSchools(cfg.RegionID) t.Logf(":: size - %d", len(schools)) if DEBUG { - for _, school := range schools { - sj, _ := json.Marshal(school) - t.Logf(":: %s\n", string(sj)) + for _, s := range schools { + t.Logf(" :: %d - %s", s.ID, s.Name) } } } @@ -54,6 +59,13 @@ func TestClient_GetSchool(t *testing.T) { func TestClient_GetMarks(t *testing.T) { marks, _ := client.GetMarksCurrent() t.Logf(":: size - %d", len(marks)) + if DEBUG { + for _, m := range marks { + if m.Grade != nil { + t.Logf(":: %s: %s - %s", m.Date.Format("2006.01.02"), m.CourseName, arrayToString(m.Grade, ",")) + } + } + } } func TestClient_GetMarksPeriods(t *testing.T) { @@ -61,29 +73,52 @@ func TestClient_GetMarksPeriods(t *testing.T) { t.Logf(":: size - %d", len(periods)) if DEBUG { for _, p := range periods { - t.Logf(":: period - %s", p) + t.Logf(":: %d-%d: %s - %s", p.SYear, p.EYear, p.Name, p.Period) } } } func TestClient_GetMarksNote(t *testing.T) { - marks, _ := client.GetMarksForMonthWithType(Month5.String(), Note) + marks, _ := client.GetMarksForMonthWithType(Month1.String(), Note) t.Logf(":: size - %d", len(marks)) - for _, m := range marks { - t.Logf(":: mark - %s", m) + if DEBUG { + for _, m := range marks { + t.Logf(":: %s: %s - %s", m.Date.Format("2006.01.02"), m.CourseName, arrayToString(m.Grade, ",")) + } } } func TestClient_GetMarksList(t *testing.T) { - marks, _ := client.GetMarksForMonthWithType(Month5.String(), List) + marks, _ := client.GetMarksForMonthWithType(Month1.String(), List) t.Logf(":: size - %d", len(marks)) + if DEBUG { + for _, m := range marks { + t.Logf("%s: %s - %s", m.Date.Format("2006.01.02"), m.CourseName, arrayToString(m.Grade, ",")) + } + } } func TestClient_GetMarksFinal(t *testing.T) { marks, _ := client.GetMarksFinal() t.Logf(":: size - %d", len(marks)) - for _, m := range marks { - t.Logf("%s", m) + if DEBUG { + for _, m := range marks { + var q string + switch m.Quarter { + case 1: + q = "1 четверть" + case 2: + q = "2 четверть" + case 3: + q = "3 четверть" + case 4: + q = "4 четверть" + } + if m.Annual { + q = "Годовая" + } + t.Logf(":: %s (%d-%d): %s - %s", m.CourseName, m.SYear, m.EYear, q, arrayToString(m.Grade, ",")) + } } } @@ -109,8 +144,7 @@ func TestClient_GetHomework(t *testing.T) { t.Logf(":: size - %d", len(hws)) if DEBUG { for _, hw := range hws { - hwj, _ := json.Marshal(hw) - t.Logf(" :: %s\n", string(hwj)) + t.Logf(" :: %s: %s - subject: %s, homework: %s", hw.Date.Format("2006.01.02"), hw.CourseName, hw.Subject, hw.Homework) } } } @@ -121,70 +155,72 @@ func TestClient_GetCourses(t *testing.T) { courses, _ := client.GetCourses() t.Logf(":: size - %d", len(courses)) - client.SetCookie("edu_year", "2018") + client.SetCookie("edu_year", "2020") client.GetMarksPeriods() - courses2018, _ := client.GetCourses() - courses = append(courses, courses2018...) - t.Logf(":: size for 2018 - %d", len(courses)) + courses2020, _ := client.GetCourses() + courses = append(courses, courses2020...) + t.Logf(":: size for 2020 - %d", len(courses)) - client.SetCookie("edu_year", "2017") + client.SetCookie("edu_year", "2019") client.GetCurrentInfo() client.GetMarksPeriods() - courses2017, _ := client.GetCourses() - courses = append(courses, courses2017...) - t.Logf(":: size for 2017 - %d", len(courses2017)) + courses2019, _ := client.GetCourses() + courses = append(courses, courses2019...) + t.Logf(":: size for 2019 - %d", len(courses2019)) - client.SetCookie("edu_year", "2016") + client.SetCookie("edu_year", "2018") client.GetCurrentInfo() client.GetMarksPeriods() - courses2016, _ := client.GetCourses() - courses = append(courses, courses2016...) - t.Logf(":: size for 2016 - %d", len(courses2016)) + courses2018, _ := client.GetCourses() + courses = append(courses, courses2018...) + t.Logf(":: size for 2018 - %d", len(courses2018)) courses = unique(courses) t.Logf(":: total size - %d", len(courses)) if DEBUG { for _, course := range courses { - cj, _ := json.Marshal(course) - t.Logf(" :: %s\n", string(cj)) + t.Logf(" :: %s", course.Name) } } } -func TestClient_GetHomework2017(t *testing.T) { - client.SetCookie("edu_year", "2017") +func TestClient_GetHomework2020(t *testing.T) { + client.SetCookie("edu_year", "2020") hws, _ := client.GetHomework() t.Logf(":: size - %d", len(hws)) - for _, hw := range hws { - hwj, _ := json.Marshal(hw) - t.Logf(" :: %s\n", string(hwj)) + if DEBUG { + for _, hw := range hws { + t.Logf(" :: %s: %s - subject: %s, homework: %s", hw.Date.Format("2006.01.02"), hw.CourseName, hw.Subject, hw.Homework) + } } } -func TestClient_GetHomework2016(t *testing.T) { - client.SetCookie("edu_year", "2016") +func TestClient_GetHomework2019(t *testing.T) { + client.SetCookie("edu_year", "2019") hws, _ := client.GetHomework() t.Logf(":: size - %d", len(hws)) - for _, hw := range hws { - hwj, _ := json.Marshal(hw) - t.Logf(" :: %s\n", string(hwj)) + if DEBUG { + for _, hw := range hws { + t.Logf(" :: %s: %s - subject: %s, homework: %s", hw.Date.Format("2006.01.02"), hw.CourseName, hw.Subject, hw.Homework) + } } } func TestClient_GetTeachers(t *testing.T) { + client.SetCookie("edu_year", "") teachers, err := client.GetTeachers() if err != nil { - t.Logf("%s", err.Error()) + t.Logf("ERR: %s", err.Error()) } t.Logf(":: size - %d", len(teachers)) for _, teacher := range teachers { - tj, _ := json.Marshal(teacher) - t.Logf(" :: %s\n", string(tj)) + t.Logf(" :: %s - %s", teacher.CourseName, teacher.FullName) } client.SetCookie("items_perpage", "") } func setup() { + DEBUG = true file, _ := ioutil.ReadFile("config_test.json") cfg = config{} _ = json.Unmarshal([]byte(file), &cfg) diff --git a/models.go b/models.go index 20ee638..13edc0e 100644 --- a/models.go +++ b/models.go @@ -1,3 +1,4 @@ +// Package dnevnik76 model package dnevnik76 import ( @@ -6,6 +7,7 @@ import ( "time" ) +// Client struct type Client struct { Username string `json:"login"` Password string `json:"password"` @@ -15,6 +17,7 @@ type Client struct { currentInfo CurrentInfo `xorm:"-"` } +// CurrentInfo struct type CurrentInfo struct { //PersonID int64 `json:"personId" xorm:"'person_id'"` SchoolID int64 `json:"schoolId" xorm:"'school_id'"` @@ -25,11 +28,13 @@ type CurrentInfo struct { EduYearEnd int `json:"eduYearEnd"` } +// Region struct type Region struct { ID int64 `json:"id" xorm:"pk 'id'"` Name string `json:"name" xorm:"'name'"` } +// School struct type School struct { ID int64 `json:"id" xorm:"pk 'id'"` RegionID int64 `json:"regionId" xorm:"'region_id'"` @@ -37,6 +42,7 @@ type School struct { Type string `json:"type"` } +// Teacher struct type Teacher struct { ID int64 `json:"id" xorm:"pk autoincr 'id'"` UserID string `json:"userId" xorm:"'user_id'"` @@ -46,11 +52,13 @@ type Teacher struct { CourseName string `json:"courseName"` } +// Course struct type Course struct { ID int64 `json:"id" xorm:"pk 'id'"` Name string `json:"name"` } +// Schedule struct type Schedule struct { ID int64 `json:"id" xorm:"pk autoincr 'id'"` SchoolID int64 `json:"schoolId" xorm:"'school_id'"` @@ -62,6 +70,7 @@ type Schedule struct { Date time.Time `json:"date"` } +// Homework struct type Homework struct { ID int64 `json:"id" xorm:"pk autoincr 'id'"` SchoolID int64 `json:"schoolId" xorm:"'school_id'"` @@ -74,6 +83,7 @@ type Homework struct { Subject string `json:"subject"` } +// Lperiod struct type Lperiod struct { SchoolID int64 `json:"schoolId" xorm:"'school_id'"` SYear int `json:"start_year"` @@ -91,6 +101,7 @@ func (p Lperiod) String() string { return string(out) } +// Mark struct type Mark struct { ID int64 `json:"id" xorm:"pk autoincr 'id'"` UserID string `json:"userId" xorm:"'user_id'"` @@ -117,6 +128,7 @@ func (m Mark) String() string { return string(out) } +// Message struct type Message struct { ID int64 `json:"id" xorm:"pk 'id'"` UserID string `json:"userId" xorm:"'user_id'"` @@ -127,11 +139,15 @@ type Message struct { Body string `json:"body"` } +// MarksListType type type MarksListType int const ( + // Note type Note MarksListType = iota + // List type List + // Date type Date ) @@ -139,20 +155,33 @@ func (s MarksListType) String() string { return [...]string{"note", "list", "date"}[s] } +// MarkRange in month type MarkRange int const ( + // Month9 is September Month9 MarkRange = iota + // Month10 is October Month10 + // Month11 is November Month11 + // Month12 is December Month12 + // Month1 is January Month1 + // Month2 is Febrary Month2 + // Month3 is March Month3 + // Month4 is April Month4 + // Month5 is May Month5 + // Month6 is June Month6 + // Month7 is July Month7 + // Month8 is August Month8 )