1 // mmc -- Mattermost client
2 // Copyright (C) 2023-2024 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
29 "github.com/fsnotify/fsnotify"
30 "github.com/mattermost/mattermost-server/v6/model"
31 "go.cypherpunks.ru/recfile"
32 "go.stargrave.org/mmc"
35 var Threads = make(map[string]string)
37 func rememberPost(post map[string][]string) {
38 text := strings.Split(post["Text"][0], "\n")[0]
41 for i > 0 && !utf8.Valid([]byte{text[i]}) {
44 text = text[:i] + "..."
46 Threads[post["Id"][0]] = text
49 func printPost(m map[string][]string) {
51 if len(m["Event"]) > 0 {
52 switch m["Event"][0] {
53 case model.WebsocketEventPostEdited:
55 case model.WebsocketEventPostDeleted:
60 if len(m["RootId"]) > 0 {
61 thread := Threads[m["RootId"][0]]
63 thread = m["RootId"][0]
65 re = " [RE]: " + thread
69 m["Created"][0], m["Sender"][0],
70 tag, m["Text"][0], re,
73 for i, fileId := range m["File"] {
74 fmt.Printf("\a%s%s (%s)\n", tag, fileId, m["FileName"][i])
79 lastNum := flag.Int("last", 10, "Only that number of messages")
82 lockPth := path.Join(where, mmc.OutRecLock)
83 unlock, err := mmc.Lock(lockPth)
87 pth := path.Join(where, mmc.OutRec)
88 fd, err := os.Open(pth)
93 r := recfile.NewReader(fd)
94 ms := make([]map[string][]string, 0)
96 m, err := r.NextMapWithSlice()
106 for _, m := range ms {
109 if len(ms) > *lastNum {
110 ms = ms[len(ms)-*lastNum:]
112 for _, m := range ms {
116 watcher, err := fsnotify.NewWatcher()
120 if err = watcher.Add(pth); err != nil {
125 case err = <-watcher.Errors:
127 case event := <-watcher.Events:
128 if !event.Has(fsnotify.Write) {
132 unlock, err = mmc.Lock(lockPth)
136 r = recfile.NewReader(fd)
138 m, err := r.NextMapWithSlice()