1 // mmc -- Mattermost client
2 // Copyright (C) 2023 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/>.
27 "github.com/davecgh/go-spew/spew"
28 "github.com/mattermost/mattermost-server/v6/model"
29 "go.cypherpunks.ru/recfile"
30 "go.stargrave.org/mmc"
33 func writePosts(where string, users map[string]*model.User, posts []mmc.Post) error {
37 unlock, err := mmc.Lock(path.Join(where, mmc.OutRecLock))
42 fd, err := os.OpenFile(
43 path.Join(where, mmc.OutRec),
44 os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666,
50 w := recfile.NewWriter(fd)
52 for _, post := range posts {
53 if err = mmc.PostToRec(w, users, post); err != nil {
56 lastPostId = post.P.Id
58 tmp, err := os.CreateTemp(where, "last")
62 err = os.Chmod(tmp.Name(), os.FileMode(0666&^UmaskCur))
68 if _, err = tmp.WriteString(lastPostId + "\n"); err != nil {
73 if err = tmp.Close(); err != nil {
77 if err = os.Rename(tmp.Name(), path.Join(where, mmc.Last)); err != nil {
83 exec.Command(*Newwin, where).Run()
88 func updatePosts(c *model.Client4, users map[string]*model.User, where, chId string) error {
89 data, err := os.ReadFile(path.Join(where, mmc.Last))
91 if os.IsNotExist(err) {
96 lastPostId := strings.TrimRight(string(data), "\n")
100 for pageNum := 0; ; pageNum++ {
101 time.Sleep(mmc.SleepTime)
102 postList, resp, err := c.GetPostsAfter(
103 chId, lastPostId, pageNum, PerPage, "", false,
106 spew.Fdump(DebugFd, postList, resp)
108 if resp.StatusCode == http.StatusNotFound {
115 for _, post := range postList.ToSlice() {
116 posts = append(posts, mmc.Post{P: post, E: model.WebsocketEventPosted})
118 if err = writePosts(where, users, posts); err != nil {
121 if len(posts) < PerPage {
128 func makePost(c *model.Client4, chId, text string) (*model.Post, error) {
129 text = strings.TrimRight(text, " \n")
137 if strings.HasPrefix(text, CmdFile) {
138 fn := strings.TrimPrefix(text, CmdFile)
139 data, err := os.ReadFile(fn)
143 resp, _, err := c.UploadFile(data, chId, path.Base(fn))
148 post.FileIds = append(post.FileIds, resp.FileInfos[0].Id)
150 post, _, err := c.CreatePost(post)