connecting and sending messages working

This commit is contained in:
Aaron Bieber 2020-01-29 16:57:42 -07:00
parent ca6cedde29
commit d3577e574c
9 changed files with 401 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.todo
*.db
mcchunkie

39
errata.go Normal file
View File

@ -0,0 +1,39 @@
package main
import (
"net/http"
"golang.org/x/net/html"
)
// ParseErrata grabs all of the OpenBSD errata from an html page
func ParseErrata(s string) ([]string, error) {
var data []string
resp, err := http.Get(s)
if err != nil {
return nil, err
}
defer resp.Body.Close()
doc, err := html.Parse(resp.Body)
if err != nil {
return nil, err
}
var f func(*html.Node)
f = func(node *html.Node) {
if node.Type == html.ElementNode && node.Data == "strong" {
if node.FirstChild != nil {
data = append(data, node.FirstChild.Data)
return
}
}
for child := node.FirstChild; child != nil; child = child.NextSibling {
f(child)
}
}
f(doc)
return data, nil
}

16
errata_test.go Normal file
View File

@ -0,0 +1,16 @@
package main
import (
"testing"
)
func TestParseErrata(t *testing.T) {
got, err := ParseErrata("https://www.openbsd.org/errata66.html")
if err != nil {
t.Error(err)
}
l := len(got)
if l == 0 {
t.Errorf("errata count %d; want > 0", l)
}
}

8
go.mod
View File

@ -1,3 +1,11 @@
module git.sr.ht/~qbit/mcchunkie
go 1.13
require (
github.com/matrix-org/gomatrix v0.0.0-20200128155335-9e7906b6766d
go.etcd.io/bbolt v1.3.3
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
)

14
go.sum Normal file
View File

@ -0,0 +1,14 @@
github.com/matrix-org/gomatrix v0.0.0-20200128155335-9e7906b6766d h1:Vf/EQgAfg8/CBUQv9te7UJreZ9iKKouB2gb8UIRM4jQ=
github.com/matrix-org/gomatrix v0.0.0-20200128155335-9e7906b6766d/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
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-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

153
main.go Normal file
View File

@ -0,0 +1,153 @@
package main
import (
"flag"
"fmt"
"log"
"net/http"
"time"
"github.com/matrix-org/gomatrix"
)
var (
username string
)
func sendMessage(c *gomatrix.Client, roomID, message string) error {
_, err := c.UserTyping(roomID, true, 3)
if err != nil {
return err
}
c.SendText(roomID, message)
_, err = c.UserTyping(roomID, false, 0)
if err != nil {
return err
}
return nil
}
func main() {
var store, err = NewStore("mcchunkie.db")
if err != nil {
log.Fatalf("%s\n", err)
}
var password, userID, accessToken, server string
var setup bool
flag.StringVar(&username, "user", "", "username to connect to matrix server with")
flag.StringVar(&server, "server", "", "matrix server")
flag.BoolVar(&setup, "s", false, "setup account")
flag.Parse()
if server == "" {
server, _ = store.get("config", "server")
if server == "" {
log.Fatalln("please specify a server")
}
store.set("config", "server", server)
}
log.Printf("connecting to %s\n", server)
cli, err := gomatrix.NewClient(
server,
"",
"",
)
if setup {
log.Println("requesting access token")
password, err = prompt(fmt.Sprintf("Password for '%s': ", username))
if err != nil {
log.Fatalln(err)
}
fmt.Println()
log.Printf("'%s' : '%s'\n", username, password)
resp, err := cli.Login(&gomatrix.ReqLogin{
Type: "m.login.password",
User: username,
Password: password,
})
if err != nil {
log.Fatalln(err)
}
store.set("account", "username", username)
store.set("account", "access_token", resp.AccessToken)
store.set("account", "user_id", resp.UserID)
} else {
accessToken, _ = store.get("account", "access_token")
userID, _ = store.get("account", "user_id")
}
cli.SetCredentials(userID, accessToken)
cli.Store = store
syncer := gomatrix.NewDefaultSyncer(username, store)
cli.Client = http.DefaultClient
cli.Syncer = syncer
/*
if _, err := cli.JoinRoom("!tmCVBJAeuKjCfihUjb:cobryce.com", "", nil); err != nil {
log.Fatalln(err)
}
if _, err := cli.JoinRoom("!sFPUeGfHqjiItcjNIN:matrix.org", "", nil); err != nil {
log.Fatalln(err)
}
if _, err := cli.JoinRoom("!ALCZnrYadLGSySIFZr:matrix.org", "", nil); err != nil {
log.Fatalln(err)
}
*/
if _, err := cli.JoinRoom("!LTxJpLHtShMVmlpwmZ:tapenet.org", "", nil); err != nil {
log.Fatalln(err)
}
syncer.OnEventType("m.room.message", func(ev *gomatrix.Event) {
fmt.Printf("'%s' == '%s'\n", ev.Sender, username)
if ev.Sender == fmt.Sprintf("@%s", username) {
return
}
if mtype, ok := ev.MessageType(); ok {
switch mtype {
case "m.text":
if post, ok := ev.Body(); ok {
log.Printf("%s: '%s'", ev.Sender, post)
}
}
}
})
//cli.SendText("!tmCVBJAeuKjCfihUjb:cobryce.com", "Butts")
sendMessage(cli, "!LTxJpLHtShMVmlpwmZ:tapenet.org", "Typing hi!")
sendMessage(cli, "!tmCVBJAeuKjCfihUjb:cobryce.com", "Butts")
avatar := "https://deftly.net/mcchunkie.png"
aurl, err := cli.GetAvatarURL()
if aurl != avatar {
log.Printf("Setting avatar to: '%s'", avatar)
err = cli.SetAvatarURL(avatar)
if err != nil {
fmt.Println("Unable to set avatar: ", err)
}
} else {
log.Printf("avatar already set")
}
for {
log.Println("syncing..")
if err := cli.Sync(); err != nil {
fmt.Println("Sync() returned ", err)
}
time.Sleep(1 * time.Second)
}
}

BIN
mcchunkie.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

18
pass_reader.go Normal file
View File

@ -0,0 +1,18 @@
package main
import (
"os"
"golang.org/x/crypto/ssh/terminal"
)
func prompt(p string) (string, error) {
oldState, err := terminal.MakeRaw(0)
if err != nil {
panic(err)
}
defer terminal.Restore(0, oldState)
t := terminal.NewTerminal(os.Stdin, p)
return t.ReadPassword(p)
}

150
store.go Normal file
View File

@ -0,0 +1,150 @@
package main
import (
"bytes"
"encoding/gob"
"log"
"github.com/matrix-org/gomatrix"
bolt "go.etcd.io/bbolt"
)
// MCStore implements a gomatrix.Storer and exposes a bbolt db to be used for
// application storage (account info, config info etc).
type MCStore struct {
db *bolt.DB
}
// NewStore creates a new MCStore instance populated with the proper buckets.
func NewStore(path string) (*MCStore, error) {
db, err := bolt.Open(path, 0666, nil)
if err != nil {
return nil, err
}
s := &MCStore{db: db}
err = s.db.Update(func(tx *bolt.Tx) error {
buckets := []string{"filter", "batch", "room", "account", "config", "errata"}
for _, b := range buckets {
if _, err := tx.CreateBucketIfNotExists([]byte(b)); err != nil {
return err
}
}
return nil
})
if err != nil {
s.db.Close()
return nil, err
}
return s, nil
}
func (s *MCStore) set(bucket, key, value string) error {
err := s.db.Update(func(tx *bolt.Tx) error {
bkt, err := tx.CreateBucketIfNotExists([]byte(bucket))
if err != nil {
return err
}
err = bkt.Put([]byte(key), []byte(value))
if err != nil {
return err
}
return nil
})
if err != nil {
log.Fatal(err)
}
return nil
}
func (s *MCStore) get(bucket, key string) (string, error) {
var result string
return result, s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(bucket))
data := bkt.Get([]byte(key))
if data == nil {
return nil
}
result = string(data)
return nil
})
}
func (s *MCStore) getBytes(bucket, key string) ([]byte, error) {
var result []byte
return result, s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(bucket))
data := bkt.Get([]byte(key))
if data == nil {
return nil
}
result = data
return nil
})
}
func (s *MCStore) encodeRoom(room *gomatrix.Room) ([]byte, error) {
buf := new(bytes.Buffer)
enc := gob.NewEncoder(buf)
err := enc.Encode(room)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (s *MCStore) decodeRoom(room []byte) (*gomatrix.Room, error) {
var r *gomatrix.Room
buf := bytes.NewBuffer(room)
dec := gob.NewDecoder(buf)
err := dec.Decode(&r)
if err != nil {
return nil, err
}
return r, nil
}
// SaveFilterID exposed for gomatrix
func (s *MCStore) SaveFilterID(userID, filterID string) {
_ = s.set("filter", userID, filterID)
}
// LoadFilterID exposed for gomatrix
func (s *MCStore) LoadFilterID(userID string) string {
filter, _ := s.get("filter", userID)
return string(filter)
}
// SaveNextBatch exposed for gomatrix
func (s *MCStore) SaveNextBatch(userID, nextBatchToken string) {
_ = s.set("batch", userID, nextBatchToken)
}
// LoadNextBatch exposed for gomatrix
func (s *MCStore) LoadNextBatch(userID string) string {
batch, _ := s.get("batch", userID)
return string(batch)
}
// SaveRoom exposed for gomatrix
func (s *MCStore) SaveRoom(room *gomatrix.Room) {
b, _ := s.encodeRoom(room)
_ = s.set("room", room.ID, string(b))
}
// LoadRoom exposed for gomatrix
func (s *MCStore) LoadRoom(roomID string) *gomatrix.Room {
b, _ := s.getBytes("room", roomID)
room, _ := s.decodeRoom(b)
return room
}