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
|
||||
|
||||
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