treewide: upgrading to latest mautrix standards

Signed-off-by: Sumner Evans <sumner@beeper.com>
This commit is contained in:
Sumner Evans
2022-10-21 14:02:33 -05:00
parent e843faf9b4
commit 715107f5a2
52 changed files with 1887 additions and 6449 deletions

98
groupmeext/client.go Normal file
View File

@ -0,0 +1,98 @@
package groupmeext
import (
"context"
"github.com/karmanyaahm/groupme"
)
type Client struct {
*groupme.Client
}
// NewClient creates a new GroupMe API Client
func NewClient(authToken string) *Client {
n := Client{
Client: groupme.NewClient(authToken),
}
return &n
}
func (c Client) IndexAllGroups() ([]*groupme.Group, error) {
return c.IndexGroups(context.TODO(), &groupme.GroupsQuery{
// Omit: "memberships",
PerPage: 100, //TODO: Configurable and add multipage support
})
}
func (c Client) IndexAllRelations() ([]*groupme.User, error) {
return c.IndexRelations(context.TODO())
}
func (c Client) IndexAllChats() ([]*groupme.Chat, error) {
return c.IndexChats(context.TODO(), &groupme.IndexChatsQuery{
PerPage: 100, //TODO?
})
}
func (c Client) LoadMessagesAfter(groupID groupme.ID, lastMessageID string, lastMessageFromMe bool, private bool) ([]*groupme.Message, error) {
if private {
ans, e := c.IndexDirectMessages(context.TODO(), groupID.String(), &groupme.IndexDirectMessagesQuery{
SinceID: groupme.ID(lastMessageID),
//Limit: num,
})
//fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
}
for i, j := 0, len(ans.Messages)-1; i < j; i, j = i+1, j-1 {
ans.Messages[i], ans.Messages[j] = ans.Messages[j], ans.Messages[i]
}
return ans.Messages, nil
} else {
i, e := c.IndexMessages(context.TODO(), groupID, &groupme.IndexMessagesQuery{
AfterID: groupme.ID(lastMessageID),
//20 for consistency with dms
Limit: 20,
})
//fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
}
return i.Messages, nil
}
}
func (c Client) LoadMessagesBefore(groupID, lastMessageID string, private bool) ([]*groupme.Message, error) {
if private {
i, e := c.IndexDirectMessages(context.TODO(), groupID, &groupme.IndexDirectMessagesQuery{
BeforeID: groupme.ID(lastMessageID),
//Limit: num,
})
//fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
}
return i.Messages, nil
} else {
//TODO: limit max 100
i, e := c.IndexMessages(context.TODO(), groupme.ID(groupID), &groupme.IndexMessagesQuery{
BeforeID: groupme.ID(lastMessageID),
//20 for consistency with dms
Limit: 20,
})
//fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
}
return i.Messages, nil
}
}
func (c *Client) RemoveFromGroup(uid, groupID groupme.ID) error {
group, err := c.ShowGroup(context.TODO(), groupID)
if err != nil {
return err
}
return c.RemoveMember(context.TODO(), groupID, group.GetMemberByUserID(uid).ID)
}

129
groupmeext/message.go Normal file
View File

@ -0,0 +1,129 @@
package groupmeext
import (
"bytes"
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"github.com/karmanyaahm/groupme"
)
type Message struct{ groupme.Message }
func (m *Message) Scan(value interface{}) error {
bytes, ok := value.(string)
if !ok {
return errors.New(fmt.Sprint("Failed to unmarshal json value:", value))
}
message := Message{}
err := json.Unmarshal([]byte(bytes), &message)
*m = Message(message)
return err
}
func (m *Message) Value() (driver.Value, error) {
e, err := json.Marshal(m)
if err != nil {
return nil, err
}
return e, nil
}
// DownloadImage helper function to download image from groupme;
// append .large/.preview/.avatar to get various sizes
func DownloadImage(URL string) (bytes *[]byte, mime string, err error) {
//TODO check its actually groupme?
response, err := http.Get(URL)
if err != nil {
return nil, "", errors.New("Failed to download avatar: " + err.Error())
}
defer response.Body.Close()
image, err := ioutil.ReadAll(response.Body)
bytes = &image
if err != nil {
return nil, "", errors.New("Failed to read downloaded image:" + err.Error())
}
mime = response.Header.Get("Content-Type")
if len(mime) == 0 {
mime = http.DetectContentType(image)
}
return
}
func DownloadFile(RoomJID groupme.ID, FileID string, token string) (contents []byte, fname, mime string) {
client := &http.Client{}
b, _ := json.Marshal(struct {
FileIDS []string `json:"file_ids"`
}{
FileIDS: []string{FileID},
})
req, _ := http.NewRequest("POST", fmt.Sprintf("https://file.groupme.com/v1/%s/fileData", RoomJID), bytes.NewReader(b))
req.Header.Add("X-Access-Token", token)
req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
// TODO: FIX
panic(err)
}
defer resp.Body.Close()
data := []ImgData{}
json.NewDecoder(resp.Body).Decode(&data)
fmt.Println(data, RoomJID, FileID, token)
if len(data) < 1 {
return
}
req, _ = http.NewRequest("POST", fmt.Sprintf("https://file.groupme.com/v1/%s/files/%s", RoomJID, FileID), nil)
req.URL.Query().Add("token", token)
req.Header.Add("X-Access-Token", token)
resp, err = client.Do(req)
if err != nil {
// TODO: FIX
panic(err)
}
defer resp.Body.Close()
bytes, _ := ioutil.ReadAll(resp.Body)
return bytes, data[0].FileData.FileName, data[0].FileData.Mime
}
func DownloadVideo(previewURL, videoURL, token string) (vidContents []byte, mime string) {
//preview TODO
client := &http.Client{}
req, _ := http.NewRequest("GET", videoURL, nil)
req.AddCookie(&http.Cookie{Name: "token", Value: token})
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
return nil, ""
}
defer resp.Body.Close()
bytes, _ := ioutil.ReadAll(resp.Body)
mime = resp.Header.Get("Content-Type")
if len(mime) == 0 {
mime = http.DetectContentType(bytes)
}
return bytes, mime
}
type ImgData struct {
FileData struct {
FileName string `json:"file_name"`
FileSize int `json:"file_size"`
Mime string `json:"mime_type"`
} `json:"file_data"`
}

View File

@ -0,0 +1,58 @@
package groupmeext
import (
log "maunium.net/go/maulogger/v2"
"github.com/karmanyaahm/groupme"
"github.com/karmanyaahm/wray"
)
type fayeLogger struct {
log.Logger
}
func (f fayeLogger) Debugf(i string, a ...interface{}) {
f.Logger.Debugfln(i, a...)
}
func (f fayeLogger) Errorf(i string, a ...interface{}) {
f.Logger.Errorfln(i, a...)
}
func (f fayeLogger) Warnf(i string, a ...interface{}) {
f.Logger.Warnfln(i, a...)
}
func (f fayeLogger) Infof(i string, a ...interface{}) {
f.Logger.Infofln(i, a...)
}
type FayeClient struct {
*wray.FayeClient
}
func (fc FayeClient) WaitSubscribe(channel string, msgChannel chan groupme.PushMessage) {
c_new := make(chan wray.Message)
fc.FayeClient.WaitSubscribe(channel, c_new)
//converting between types because channels don't support interfaces well
go func() {
for i := range c_new {
msgChannel <- i
}
}()
}
//for authentication, specific implementation will vary based on faye library
type AuthExt struct{}
func (a *AuthExt) In(wray.Message) {}
func (a *AuthExt) Out(m wray.Message) {
groupme.OutMsgProc(m)
}
func NewFayeClient(logger log.Logger) *FayeClient {
fc := &FayeClient{wray.NewFayeClient(groupme.PushServer)}
fc.SetLogger(fayeLogger{logger.Sub("FayeClient")})
fc.AddExtension(&AuthExt{})
//fc.AddExtension(fc.FayeClient)
return fc
}

6
groupmeext/user.go Normal file
View File

@ -0,0 +1,6 @@
package groupmeext
const (
OldUserSuffix = "@c.groupme.com"
NewUserSuffix = "@groupme.com"
)