This repository has been archived by the owner on Oct 7, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathsetup.go
153 lines (129 loc) · 3.31 KB
/
setup.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package main
import (
"context"
"fmt"
"log"
"strconv"
"sync"
"time"
"whapp-irc/bridge"
"whapp-irc/ircconnection"
"whapp-irc/timestampmap"
"whapp-irc/types"
"whapp-irc/util"
"whapp-irc/whapp"
qrcode "github.com/skip2/go-qrcode"
)
func setupConnection(ctx context.Context, irc *ircconnection.Connection) (*Connection, error) {
wi, err := bridge.Start(ctx, pool, conf.LogLevel)
if err != nil {
return nil, err
}
conn := &Connection{
WI: wi,
Chats: &types.ChatList{},
irc: irc,
timestampMap: timestampmap.New(),
}
// if we have the current user in the database, try to relogin using the
// previous localStorage state
var user types.User
found, err := userDb.GetItem(conn.irc.Nick(), &user)
if err != nil {
return nil, err
} else if found {
conn.timestampMap.Swap(user.LastReceivedReceipts)
conn.Chats = types.ChatListFromSlice(user.Chats)
conn.irc.Status("logging in using stored session")
if err := wi.Navigate(ctx); err != nil {
return nil, err
}
if err := wi.SetLocalStorage(
ctx,
user.LocalStorage,
); err != nil {
log.Printf("error while setting local storage: %s\n", err)
}
}
// open site
state, err := wi.Open(ctx)
if err != nil {
return nil, err
}
// if we aren't logged in yet we have to get the QR code and stuff
if state == whapp.Loggedout {
code, err := wi.GetLoginCode(ctx)
if err != nil {
return nil, fmt.Errorf("Error while retrieving login code: %s", err)
}
bytes, err := qrcode.Encode(code, qrcode.High, 512)
if err != nil {
return nil, err
}
timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
qrFile, err := fs.AddBlob("qr-"+timestamp, "png", bytes)
if err != nil {
return nil, err
}
defer func() {
err := fs.RemoveFile(qrFile)
util.LogIfErr("error while removing QR code", err)
}()
if err := conn.irc.Status("Scan this QR code: " + qrFile.URL); err != nil {
return nil, err
}
}
// waiting for login
if err := wi.WaitLogin(ctx); err != nil {
return nil, err
}
conn.irc.Status("logged in")
// get localstorage (that contains new login information), and save it to
// the database
conn.localStorage, err = wi.GetLocalStorage(ctx)
if err != nil {
log.Printf("error while getting local storage: %s\n", err)
} else {
if err := conn.saveDatabaseEntry(); err != nil {
return nil, err
}
}
// get information about the user
conn.me, err = wi.GetMe(ctx)
if err != nil {
return nil, err
}
// get raw chats
rawChats, err := wi.GetAllChats(ctx)
if err != nil {
return nil, err
}
// convert chats to internal reprenstation, we do this using a second slice
// and a WaitGroup to preserve the initial order
chats := make([]*types.Chat, len(rawChats))
var wg sync.WaitGroup
for i, raw := range rawChats {
wg.Add(1)
go func(i int, raw whapp.Chat) {
defer wg.Done()
participants, err := raw.Participants(ctx, conn.WI)
if err != nil {
str := fmt.Sprintf("error while fetching participants for chat with ID %s, skipping", raw.ID)
conn.irc.Status(str)
log.Printf("%s. error: %s", str, err)
return
}
chats[i] = conn.convertChat(raw, participants)
}(i, raw)
}
wg.Wait()
// add all chats to connection
for _, chat := range chats {
if chat == nil {
// there was an error converting this chat, skip it.
continue
}
conn.addChat(chat)
}
return conn, nil
}