Skip to content

Commit 3bf22bf

Browse files
committed
Fixed this horrendous
1 parent b4a1eb0 commit 3bf22bf

File tree

7 files changed

+226
-34
lines changed

7 files changed

+226
-34
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@
1919

2020
# Go workspace file
2121
go.work
22+
23+
.vscode
24+
go.sum

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
# MobiAPI
22
WIP scraping library for Polish e-register [mobiDziennik](https://mobidziennik.pl) made in Go
3-
If you want to see example usage if this library, check out my scuffed desktop client, [mobiNG](https://github.com/dark-steveneq/mobing)
3+
4+
# Examples
5+
Check out [examples/](https://github.com/dark-steveneq/blob/main/examples/) folder for individual examples, however if you want to see reference implementation, check out my abomination of a desktop app - [mobiNG](https://github.com/dark-steveneq/mobing) (hehe funny name).
6+
7+
# Development
8+
For developing MobiAPI you'll first of all need access to mobiDziennik, a web browser and a basic understanding of Go and probably how various web technologies work and a proxy for intercepting network trafic. I can recommend [ZAP](https://zaproxy.org) since it's what I've been using but it's cross-platform and open source but you can use anything. `MobiAPI` type already has a function for connecting to a proxy server you can use.

auth.go

+21-2
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,28 @@ import (
44
"errors"
55
"net/http"
66
"net/url"
7+
"strconv"
8+
9+
"github.com/PuerkitoBio/goquery"
710
)
811

12+
func (api *MobiAPI) postlogin(doc *goquery.Document) {
13+
if val, exists := doc.Find("body").Attr("uid"); exists {
14+
api.uid, _ = strconv.Atoi(val)
15+
api.name = doc.Find("#botton div strong").Text()
16+
}
17+
}
18+
919
// Authenticate with password.
1020
func (api *MobiAPI) PasswordAuth(login, password string) (bool, error) {
11-
resp, _, err := api.request("POST", "logowanie", "login="+login+"&haslo="+password)
21+
resp, doc, err := api.request("POST", "logowanie", "login="+login+"&haslo="+password)
1222
if err != nil {
1323
return false, err
1424
}
1525

1626
if resp.Request.Response.StatusCode == 302 {
27+
api.signedin = true
28+
api.postlogin(doc)
1729
return true, nil
1830
}
1931

@@ -40,7 +52,7 @@ func (api *MobiAPI) TokenAuth(token string) (bool, error) {
4052
}
4153
}
4254

43-
resp, _, err := api.request("GET", "logowanie", "")
55+
resp, doc, err := api.request("GET", "logowanie", "")
4456
if err != nil {
4557
return false, err
4658
}
@@ -49,6 +61,7 @@ func (api *MobiAPI) TokenAuth(token string) (bool, error) {
4961
return false, errors.New("AuthUnable")
5062
} else if resp.Request.Response.StatusCode == 302 {
5163
api.signedin = true
64+
api.postlogin(doc)
5265
return true, nil
5366
}
5467

@@ -65,3 +78,9 @@ func (api *MobiAPI) LoggedIn(noprecache bool) bool {
6578
}
6679
return api.signedin
6780
}
81+
82+
// Does a random request to extend session
83+
func (api *MobiAPI) ExtendSession() error {
84+
_, _, err := api.request("POST", "", "")
85+
return err
86+
}

examples/token-extender/main.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"time"
7+
8+
"github.com/dark-steveneq/mobiapi"
9+
)
10+
11+
/*
12+
"Token" in this context is a value from a uniquely named cookie.
13+
Each domain uses a different name, so make sure not to include it
14+
if you don't want to dox yourself.
15+
*/
16+
func main() {
17+
if len(os.Args) != 3 {
18+
fmt.Printf("Usage: %s <domain> <token>\n", os.Args[0])
19+
os.Exit(1)
20+
}
21+
22+
api, err := mobiapi.New(os.Args[1])
23+
if err != nil {
24+
fmt.Println(err)
25+
os.Exit(1)
26+
}
27+
28+
signedin, err := api.TokenAuth(os.Args[2])
29+
if err != nil {
30+
fmt.Println(err)
31+
os.Exit(1)
32+
} else if !signedin {
33+
fmt.Println("Couldn't sign in!")
34+
}
35+
36+
for {
37+
time.Sleep(5 * time.Minute)
38+
if err := api.ExtendSession(); err != nil {
39+
fmt.Println(err)
40+
os.Exit(1)
41+
}
42+
}
43+
}

examples/unread-messages/main.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"os"
7+
"strings"
8+
9+
"github.com/dark-steveneq/mobiapi"
10+
)
11+
12+
func main() {
13+
if len(os.Args) != 4 {
14+
fmt.Printf("Usage: %s <domain> <login> <package>\n", os.Args[0])
15+
os.Exit(1)
16+
}
17+
reader := bufio.NewReader(os.Stdin)
18+
19+
api, err := mobiapi.New(os.Args[1])
20+
if err != nil {
21+
fmt.Println(err)
22+
os.Exit(1)
23+
}
24+
25+
signedin, err := api.PasswordAuth(os.Args[2], os.Args[3])
26+
if err != nil {
27+
fmt.Println(err)
28+
os.Exit(1)
29+
} else if !signedin {
30+
fmt.Println("Couldn't log in!")
31+
os.Exit(1)
32+
}
33+
defer api.Logout()
34+
35+
messages, err := api.GetReceivedMessages(false)
36+
if err != nil {
37+
fmt.Println(err)
38+
os.Exit(1)
39+
}
40+
unread := map[int]mobiapi.MessageInfo{}
41+
for _, message := range messages {
42+
if message.Read == true {
43+
unread[len(unread)] = message
44+
}
45+
}
46+
47+
fmt.Printf("Hello, %s!\nYou Have %d unread messages. Do you want to read them one by one? [Y/n]\n", api.GetName(), len(unread))
48+
text, _ := reader.ReadString('\n')
49+
text = strings.ToLower(text)
50+
if text == "n" || text == "no" {
51+
fmt.Println("Okeh.")
52+
os.Exit(0)
53+
}
54+
for _, message := range unread {
55+
messagecontent, err := api.GetMessageContent(message)
56+
if err != nil {
57+
fmt.Println("Couldn't read message!")
58+
} else {
59+
fmt.Printf("Title: %s\nFrom: %s\nRead: %t\n'''\n%s\n'''\nDownloads: %d", message.Title, message.Author, message.Read, messagecontent.Content, len(messagecontent.Downloads))
60+
fmt.Printf("\n")
61+
for name := range messagecontent.Downloads {
62+
fmt.Printf("- %s\n", name)
63+
}
64+
}
65+
reader.ReadString('\n')
66+
}
67+
}

message.go

+53-8
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,13 @@ import (
88
"github.com/PuerkitoBio/goquery"
99
)
1010

11+
const (
12+
MessageSent = 1
13+
MessageReceived = 2
14+
)
15+
1116
type MessageInfo struct {
12-
Kind string
17+
Kind int
1318
Title string
1419
Author string
1520
ID int
@@ -24,7 +29,7 @@ type MessageContent struct {
2429
}
2530

2631
// Scrapes and returns message IDs and titles from first or every subsequent page in the form of MessageInfo. Use GetMessageContent() with MessageInfo to read it.
27-
func (api *MobiAPI) GetReadMessages(firstpage bool) ([]MessageInfo, error) {
32+
func (api *MobiAPI) GetReceivedMessages(firstpage bool) ([]MessageInfo, error) {
2833
pages := 1
2934
messages := []MessageInfo{}
3035
for i := 1; i <= pages; i++ {
@@ -37,7 +42,41 @@ func (api *MobiAPI) GetReadMessages(firstpage bool) ([]MessageInfo, error) {
3742
pages = doc.Find(".stronnicowanie").Children().Length()
3843
}
3944
doc.Find(".podswietl").Each(func(mi int, s *goquery.Selection) {
40-
message := MessageInfo{Read: s.Find("td span").HasClass("wiadomosc_przeczytana")}
45+
message := MessageInfo{Read: s.Find("td span").HasClass("wiadomosc_przeczytana"), Kind: MessageReceived}
46+
sid, _ := s.Attr("rel")
47+
iid, _ := strconv.Atoi(sid)
48+
message.ID = iid
49+
html, _ := s.Children().Html()
50+
message.Title = strings.TrimSpace(html)
51+
s.Children().First().Remove()
52+
s.Children().First().Remove()
53+
s.Children().First().Remove()
54+
html, _ = s.Children().Html()
55+
message.Author = strings.ReplaceAll(strings.ReplaceAll(html, "<small>", ""), "</small>", "")
56+
messages = append(messages, message)
57+
})
58+
}
59+
if len(messages) > 0 {
60+
return messages, nil
61+
}
62+
return nil, errors.New("Unprocessed")
63+
}
64+
65+
// Scrapes and returns message IDs and titles from first or every subsequent page in the form of MessageInfo. Use GetMessageContent() with MessageInfo to read it.
66+
func (api *MobiAPI) GetSentMessages(firstpage bool) ([]MessageInfo, error) {
67+
pages := 1
68+
messages := []MessageInfo{}
69+
for i := 1; i <= pages; i++ {
70+
resp, doc, err := api.request("GET", "wiadomosci/?sortuj_wg=wysłane&sortuj_typ=desc&wysłane="+strconv.Itoa(i), "")
71+
if err != nil {
72+
return nil, err
73+
}
74+
defer resp.Body.Close()
75+
if !firstpage && i == 1 {
76+
pages = doc.Find(".stronnicowanie").Children().Length()
77+
}
78+
doc.Find(".podswietl").Each(func(mi int, s *goquery.Selection) {
79+
message := MessageInfo{Kind: MessageSent}
4180
sid, _ := s.Attr("rel")
4281
iid, _ := strconv.Atoi(sid)
4382
message.ID = iid
@@ -59,21 +98,26 @@ func (api *MobiAPI) GetReadMessages(firstpage bool) ([]MessageInfo, error) {
5998

6099
// Searches messages using MobiDziennik's built-in search feature.
61100
func (api *MobiAPI) SearchMessages(phrase string) ([]MessageInfo, error) {
62-
resp, doc, err := api.request("GET", "dziennik/wyszukiwarkawiadomosci?q="+phrase, "")
101+
resp, doc, err := api.request("GET", "wyszukiwarkawiadomosci?q="+phrase, "")
63102
if err != nil {
64103
return nil, err
65104
}
66105
defer resp.Body.Close()
67106

68107
messages := []MessageInfo{}
69108
doc.Find(".podswietl").Each(func(i int, s *goquery.Selection) {
70-
if attr, exists := s.Attr("rel"); exists && strings.Contains(attr, "wiadodebrana") {
71-
id, _ := strconv.Atoi(strings.ReplaceAll(attr, "wiadodebrana?id=", ""))
109+
if attr, exists := s.Attr("rel"); exists {
110+
kind := MessageSent
111+
if strings.Contains(attr, "wiadodebrana") {
112+
kind = MessageReceived
113+
}
114+
id, _ := strconv.Atoi(strings.ReplaceAll(strings.ReplaceAll(attr, "wiadwyslana?id=", ""), "wiadodebrana?id=", ""))
72115
messages = append(messages, MessageInfo{
73116
Title: s.Find("td div.ellipsis").Text(),
74117
Author: s.Find("td div.autoTooltip").Text(),
75118
ID: id,
76119
Read: false,
120+
Kind: kind,
77121
})
78122
}
79123
})
@@ -87,7 +131,8 @@ func (api *MobiAPI) SearchMessages(phrase string) ([]MessageInfo, error) {
87131
// Read Received Message from MessageInfo into MessageContent.
88132
func (api *MobiAPI) GetMessageContent(message MessageInfo) (MessageContent, error) {
89133
messagecontent := MessageContent{Info: message}
90-
resp, doc, err := api.request("GET", "dziennik/wiadodebrana/?id="+strconv.Itoa(message.ID), "")
134+
135+
resp, doc, err := api.request("GET", "wiadodebrana/?id="+strconv.Itoa(message.ID), "")
91136
if err != nil {
92137
return messagecontent, err
93138
}
@@ -100,7 +145,7 @@ func (api *MobiAPI) GetMessageContent(message MessageInfo) (MessageContent, erro
100145
if err != nil {
101146
return messagecontent, err
102147
}
103-
messagecontent.Content = strings.ReplaceAll(strings.ReplaceAll(contents.Text(), "<p>", ""), "</p>", "\n")
148+
messagecontent.Content = contents.Text()
104149

105150
if doc.Find("#zalaczniki").Length() == 1 {
106151
messagecontent.Downloads = map[string]string{}

0 commit comments

Comments
 (0)