Save client pickle automatically (messenger)
This commit is contained in:
parent
f9e0c58f3c
commit
7c39436eda
4 changed files with 76 additions and 40 deletions
81
account.go
81
account.go
|
@ -39,41 +39,40 @@ func SetAccount(mxid string, name string, protocol string, config map[string]str
|
||||||
}
|
}
|
||||||
accounts := registeredAccounts[mxid]
|
accounts := registeredAccounts[mxid]
|
||||||
|
|
||||||
if prev_acct, ok := accounts[name]; ok {
|
// Check we can create connector
|
||||||
if protocol != prev_acct.Protocol {
|
proto, ok := Protocols[protocol]
|
||||||
return fmt.Errorf("Wrong protocol")
|
if !ok {
|
||||||
}
|
return fmt.Errorf("Invalid protocol: %s", protocol)
|
||||||
if !reflect.DeepEqual(config, prev_acct.Config) {
|
|
||||||
go func() {
|
|
||||||
prev_acct.Conn.Close()
|
|
||||||
prev_acct.JoinedRooms = map[RoomID]bool{}
|
|
||||||
|
|
||||||
prev_acct.Config = config
|
|
||||||
prev_acct.connect()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
proto, ok := Protocols[protocol]
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Invalid protocol: %s", protocol)
|
|
||||||
}
|
|
||||||
conn := proto.NewConnector()
|
|
||||||
if conn == nil {
|
|
||||||
return fmt.Errorf("Could not create connector for protocol %s", protocol)
|
|
||||||
}
|
|
||||||
account := &Account{
|
|
||||||
MatrixUser: mxid,
|
|
||||||
AccountName: name,
|
|
||||||
Protocol: protocol,
|
|
||||||
Config: config,
|
|
||||||
Conn: conn,
|
|
||||||
JoinedRooms: map[RoomID]bool{},
|
|
||||||
}
|
|
||||||
conn.SetHandler(account)
|
|
||||||
|
|
||||||
accounts[name] = account
|
|
||||||
go account.connect()
|
|
||||||
}
|
}
|
||||||
|
conn := proto.NewConnector()
|
||||||
|
if conn == nil {
|
||||||
|
return fmt.Errorf("Could not create connector for protocol %s", protocol)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the account existed already, close and drop connector
|
||||||
|
if prev_acct, ok := accounts[name]; ok {
|
||||||
|
if prev_acct.Protocol == protocol && reflect.DeepEqual(config, prev_acct.Config) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
go prev_acct.Conn.Close()
|
||||||
|
delete(accounts, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure and connect
|
||||||
|
account := &Account{
|
||||||
|
MatrixUser: mxid,
|
||||||
|
AccountName: name,
|
||||||
|
Protocol: protocol,
|
||||||
|
Config: config,
|
||||||
|
Conn: conn,
|
||||||
|
JoinedRooms: map[RoomID]bool{},
|
||||||
|
}
|
||||||
|
conn.SetHandler(account)
|
||||||
|
|
||||||
|
accounts[name] = account
|
||||||
|
go account.connect()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,6 +231,20 @@ func (a *Account) delAutojoin(roomId RoomID) {
|
||||||
|
|
||||||
// ---- Begin event handlers ----
|
// ---- Begin event handlers ----
|
||||||
|
|
||||||
|
func (a *Account) SaveConfig(config Configuration) {
|
||||||
|
a.Config = config
|
||||||
|
if key, ok := userKeys[a.MatrixUser]; ok {
|
||||||
|
var entry DbAccountConfig
|
||||||
|
db.Where(&DbAccountConfig{
|
||||||
|
MxUserID: a.MatrixUser,
|
||||||
|
Name: a.AccountName,
|
||||||
|
}).Assign(&DbAccountConfig{
|
||||||
|
Protocol: a.Protocol,
|
||||||
|
Config: encryptAccountConfig(a.Config, key),
|
||||||
|
}).FirstOrCreate(&entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Account) Joined(roomId RoomID) {
|
func (a *Account) Joined(roomId RoomID) {
|
||||||
err := a.joinedInternal(roomId)
|
err := a.joinedInternal(roomId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -76,6 +76,9 @@ type Connector interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
|
// Called to save updated configuration parameters
|
||||||
|
SaveConfig(config Configuration)
|
||||||
|
|
||||||
// Called when a room was joined (automatically or by call to Connector.Join)
|
// Called when a room was joined (automatically or by call to Connector.Join)
|
||||||
Joined(roomId RoomID)
|
Joined(roomId RoomID)
|
||||||
|
|
||||||
|
|
19
connector/external/external.go
vendored
19
connector/external/external.go
vendored
|
@ -54,6 +54,7 @@ const (
|
||||||
CLOSE = "close"
|
CLOSE = "close"
|
||||||
|
|
||||||
// external -> ezbr
|
// external -> ezbr
|
||||||
|
SAVE_CONFIG = "save_config"
|
||||||
JOINED = "joined"
|
JOINED = "joined"
|
||||||
LEFT = "left"
|
LEFT = "left"
|
||||||
USER_INFO_UPDATED = "user_info_updated"
|
USER_INFO_UPDATED = "user_info_updated"
|
||||||
|
@ -198,6 +199,16 @@ func (m *extMessageWithData) UnmarshalJSON(jj []byte) error {
|
||||||
}
|
}
|
||||||
*m = extMessageWithData{extMessage: c}
|
*m = extMessageWithData{extMessage: c}
|
||||||
switch c.MsgType {
|
switch c.MsgType {
|
||||||
|
case SAVE_CONFIG:
|
||||||
|
var cf struct {
|
||||||
|
Data Configuration `json:"data"`
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(jj, &cf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m.Data = cf.Data
|
||||||
|
return nil
|
||||||
case USER_INFO_UPDATED:
|
case USER_INFO_UPDATED:
|
||||||
var ui struct {
|
var ui struct {
|
||||||
Data UserInfo `json:"data"`
|
Data UserInfo `json:"data"`
|
||||||
|
@ -229,14 +240,14 @@ func (m *extMessageWithData) UnmarshalJSON(jj []byte) error {
|
||||||
m.Data = &ev.Data
|
m.Data = &ev.Data
|
||||||
return nil
|
return nil
|
||||||
case REP_SEARCH_RESULTS:
|
case REP_SEARCH_RESULTS:
|
||||||
var ev struct {
|
var sr struct {
|
||||||
Data []UserSearchResult `json:"data"`
|
Data []UserSearchResult `json:"data"`
|
||||||
}
|
}
|
||||||
err := json.Unmarshal(jj, &ev)
|
err := json.Unmarshal(jj, &sr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
m.Data = ev.Data
|
m.Data = sr.Data
|
||||||
return nil
|
return nil
|
||||||
case JOINED, LEFT, CACHE_PUT, CACHE_GET, REP_OK, REP_ERROR:
|
case JOINED, LEFT, CACHE_PUT, CACHE_GET, REP_OK, REP_ERROR:
|
||||||
return nil
|
return nil
|
||||||
|
@ -364,6 +375,8 @@ func (ext *External) Close() {
|
||||||
|
|
||||||
func (ext *External) handleCmd(msg *extMessageWithData) {
|
func (ext *External) handleCmd(msg *extMessageWithData) {
|
||||||
switch msg.MsgType {
|
switch msg.MsgType {
|
||||||
|
case SAVE_CONFIG:
|
||||||
|
ext.handler.SaveConfig(msg.Data.(Configuration))
|
||||||
case JOINED:
|
case JOINED:
|
||||||
ext.handler.Joined(msg.Room)
|
ext.handler.Joined(msg.Room)
|
||||||
case LEFT:
|
case LEFT:
|
||||||
|
|
13
external/messenger.py
vendored
13
external/messenger.py
vendored
|
@ -1,7 +1,5 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# @FIXME: store the client pickle in the config automatically
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import signal
|
import signal
|
||||||
|
@ -34,6 +32,7 @@ SEND = "send"
|
||||||
CLOSE = "close"
|
CLOSE = "close"
|
||||||
|
|
||||||
# external -> ezbr
|
# external -> ezbr
|
||||||
|
SAVE_CONFIG = "save_config"
|
||||||
JOINED = "joined"
|
JOINED = "joined"
|
||||||
LEFT = "left"
|
LEFT = "left"
|
||||||
USER_INFO_UPDATED = "user_info_updated"
|
USER_INFO_UPDATED = "user_info_updated"
|
||||||
|
@ -228,7 +227,8 @@ class MessengerBridge:
|
||||||
if ty == CONFIGURE:
|
if ty == CONFIGURE:
|
||||||
self.init_backlog_length = int(cmd["data"]["initial_backlog"])
|
self.init_backlog_length = int(cmd["data"]["initial_backlog"])
|
||||||
|
|
||||||
if "client_pickle" in cmd["data"] and len(cmd["data"]["client_pickle"]) > 0:
|
has_pickle = "client_pickle" in cmd["data"] and len(cmd["data"]["client_pickle"]) > 0
|
||||||
|
if has_pickle:
|
||||||
data = base64.b64decode(cmd["data"]["client_pickle"])
|
data = base64.b64decode(cmd["data"]["client_pickle"])
|
||||||
data = zlib.decompress(data)
|
data = zlib.decompress(data)
|
||||||
self.client = pickle.loads(data)
|
self.client = pickle.loads(data)
|
||||||
|
@ -240,6 +240,13 @@ class MessengerBridge:
|
||||||
if not self.client.isLoggedIn():
|
if not self.client.isLoggedIn():
|
||||||
return {"_type": REP_ERROR, "error": "Unable to login (invalid pickle?)"}
|
return {"_type": REP_ERROR, "error": "Unable to login (invalid pickle?)"}
|
||||||
|
|
||||||
|
if not has_pickle:
|
||||||
|
new_config = cmd["data"]
|
||||||
|
data = pickle.dumps(self.client)
|
||||||
|
data = zlib.compress(data)
|
||||||
|
new_config["client_pickle"] = base64.b64encode(data).decode('ascii')
|
||||||
|
self.write({"_type": SAVE_CONFIG, "data": new_config})
|
||||||
|
|
||||||
self.client.setBridge(self)
|
self.client.setBridge(self)
|
||||||
|
|
||||||
self.my_user_id = self.getUserIdFromUid(self.client.uid)
|
self.my_user_id = self.getUserIdFromUid(self.client.uid)
|
||||||
|
|
Loading…
Reference in a new issue