connecting and sending messages working
This commit is contained in:
parent
ca6cedde29
commit
d3577e574c
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.todo
|
||||||
|
*.db
|
||||||
|
mcchunkie
|
39
errata.go
Normal file
39
errata.go
Normal 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
16
errata_test.go
Normal 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
8
go.mod
@ -1,3 +1,11 @@
|
|||||||
module git.sr.ht/~qbit/mcchunkie
|
module git.sr.ht/~qbit/mcchunkie
|
||||||
|
|
||||||
go 1.13
|
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
14
go.sum
Normal 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
153
main.go
Normal 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
BIN
mcchunkie.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
18
pass_reader.go
Normal file
18
pass_reader.go
Normal 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
150
store.go
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user