morpheus

A Matrix client written in Go-QT
git clone git://archive.git.mtrnord.blog/Nordgedanken/morpheus.git
Log | Files | Refs | README | LICENSE

commit 05b216a798a0c81d6a8f1840cb7983750aca1b56
parent c1f645311e7fd4466bd24dda6b730816c59b2231
Author: MTRNord <mtrnord1@gmail.com>
Date:   Wed, 22 Nov 2017 19:02:42 +0100

Fix message CacheLoading

Signed-off-by: MTRNord <mtrnord1@gmail.com>

Diffstat:
Mmain.go | 27+++++++++++++++++++++++++++
Mmatrix/db/db.go | 47+++++++++++++++++++++++------------------------
Mui/MainUI.go | 239+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mui/roomlist.go | 24+++++++++++++-----------
4 files changed, 273 insertions(+), 64 deletions(-)

diff --git a/main.go b/main.go @@ -4,8 +4,10 @@ import ( "fmt" "log" "os" + "os/signal" "runtime" "sync" + "syscall" "github.com/Nordgedanken/Morpheus/matrix" "github.com/Nordgedanken/Morpheus/matrix/db" @@ -23,6 +25,15 @@ var localLog *log.Logger func main() { runtime.GOMAXPROCS(128) + + c := make(chan os.Signal, 2) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + go func() { + <-c + cleanup() + os.Exit(1) + }() + var file *os.File var err error @@ -183,3 +194,19 @@ func main() { defer CacheDB.Close() localLog.Println("Stopping Morpheus") } + +func cleanup() { + fmt.Println("cleanup") + UserDB, DBOpenErr := db.OpenUserDB() + if DBOpenErr != nil { + localLog.Fatalln(DBOpenErr) + } + + CacheDB, DBOpenErr := db.OpenCacheDB() + if DBOpenErr != nil { + localLog.Fatalln(DBOpenErr) + } + + UserDB.Close() + CacheDB.Close() +} diff --git a/matrix/db/db.go b/matrix/db/db.go @@ -104,6 +104,7 @@ func OpenUserDB() (db *badger.DB, err error) { // CacheMessageEvents writes message infos into the cache into the defined room func CacheMessageEvents(id, sender, roomID, message string, timestamp int64) (err error) { + log.Println("start Caching") db, DBOpenErr := OpenCacheDB() if DBOpenErr != nil { err = DBOpenErr @@ -111,35 +112,33 @@ func CacheMessageEvents(id, sender, roomID, message string, timestamp int64) (er } // Update cache - txn := db.NewTransaction(true) // Read-write txn - DBSetIDErr := txn.Set([]byte("room|"+roomID+"|messages|"+id+"|id"), []byte(id)) - if DBSetIDErr != nil { - err = DBSetIDErr - return - } + DBerr := db.Update(func(txn *badger.Txn) error { + log.Println(id) + DBSetIDErr := txn.Set([]byte("room|"+roomID+"|messages|"+id+"|id"), []byte(id)) + if DBSetIDErr != nil { + return DBSetIDErr + } - DBSetSenderErr := txn.Set([]byte("room|"+roomID+"|messages|"+id+"|sender"), []byte(sender)) - if DBSetSenderErr != nil { - err = DBSetSenderErr - return - } + DBSetSenderErr := txn.Set([]byte("room|"+roomID+"|messages|"+id+"|sender"), []byte(sender)) + if DBSetSenderErr != nil { + return DBSetSenderErr + } - DBSetMessageErr := txn.Set([]byte("room|"+roomID+"|messages|"+id+"|message"), []byte(message)) - if DBSetMessageErr != nil { - err = DBSetMessageErr - return - } + DBSetMessageErr := txn.Set([]byte("room|"+roomID+"|messages|"+id+"|messageString"), []byte(message)) + if DBSetMessageErr != nil { + return DBSetMessageErr + } - timestampString := strconv.FormatInt(timestamp, 10) - DBSeTimestampErr := txn.Set([]byte("room|"+roomID+"|messages|"+id+"|timestamp"), []byte(timestampString)) - if DBSeTimestampErr != nil { - err = DBSeTimestampErr + timestampString := strconv.FormatInt(timestamp, 10) + DBSeTimestampErr := txn.Set([]byte("room|"+roomID+"|messages|"+id+"|timestamp"), []byte(timestampString)) + return DBSeTimestampErr + }) + + if DBerr != nil { + log.Println("DBERR: ", DBerr) + err = DBerr return } - CommitErr := txn.Commit(nil) - if CommitErr != nil { - err = CommitErr - } return } diff --git a/ui/MainUI.go b/ui/MainUI.go @@ -3,6 +3,8 @@ package ui import ( "fmt" "log" + "strconv" + "strings" "sync" "github.com/Nordgedanken/Morpheus/matrix" @@ -10,6 +12,7 @@ import ( "github.com/Nordgedanken/Morpheus/util" "github.com/dgraph-io/badger" "github.com/matrix-org/gomatrix" + "github.com/pkg/errors" "github.com/rhinoman/go-commonmark" "github.com/therecipe/qt/core" "github.com/therecipe/qt/gui" @@ -311,7 +314,7 @@ func (m *MainUI) startSync() (err error) { timestamp := ev.Timestamp go db.CacheMessageEvents(id, sender, room, msg, timestamp) if room == m.currentRoom { - m.MessageListLayout.TriggerMessage(msg, sender, timestamp) + go m.MessageListLayout.TriggerMessage(msg, sender, timestamp) } }) @@ -348,6 +351,16 @@ func (m *MainUI) initRoomList(roomListLayout *QRoomVBoxLayoutWithTriggerSlot, ro return } +func contains(slice []string, item string) bool { + set := make(map[string]struct{}, len(slice)) + for _, s := range slice { + set[s] = struct{}{} + } + + _, ok := set[item] + return ok +} + func (m *MainUI) loadCache() (err error) { /*barAtBottom := false bar := m.messageScrollArea.VerticalScrollBar() @@ -360,49 +373,217 @@ func (m *MainUI) loadCache() (err error) { err = DBOpenErr } + log.Println("load cache") + DBerr := db.View(func(txn *badger.Txn) error { MsgOpts := badger.DefaultIteratorOptions MsgOpts.PrefetchSize = 10 MsgIt := txn.NewIterator(MsgOpts) MsgPrefix := []byte("room|" + m.currentRoom + "|messages|") + + var doneMsg []string + for MsgIt.Seek(MsgPrefix); MsgIt.ValidForPrefix(MsgPrefix); MsgIt.Next() { item := MsgIt.Item() - k := item.Key() - value, err := item.Value() - if err != nil { - return err + key := item.Key() + stringKey := fmt.Sprintf("%s", key) + value, ValueErr := item.Value() + if ValueErr != nil { + return ValueErr } - fmt.Sprintf("Value: %s Key: %s", value, k) - //msg := fmt.Sprintf("%s", value) - } - - /*IDErr := tx.AscendKeys("room|"+m.currentRoom+"|messages|*|id", func(_, id string) bool { - msg, GetMsgErr := tx.Get("room|" + m.currentRoom + "|messages|" + id + "|message") - if GetMsgErr != nil { - fmt.Println("GetMsgErr: ", GetMsgErr) - return false + stringValue := fmt.Sprintf("%s", value) + + if strings.HasSuffix(stringKey, "|id") { + if !contains(doneMsg, stringValue) { + // Remember we already added this message to the view + doneMsg = append(doneMsg, stringKey) + + // Get all Data + senderItem, senderErr := txn.Get([]byte(strings.Replace(stringKey, "|id", "|sender", -1))) + if senderErr != nil { + return errors.WithMessage(senderErr, "Key: "+strings.Replace(stringKey, "|id", "|sender", -1)) + } + + senderValue, senderValueErr := senderItem.Value() + if senderValueErr != nil { + return senderValueErr + } + sender := fmt.Sprintf("%s", senderValue) + + messageItem, messageErr := txn.Get([]byte(strings.Replace(stringKey, "|id", "|messageString", -1))) + if messageErr != nil { + return errors.WithMessage(messageErr, "Key: "+strings.Replace(stringKey, "|id", "|messageString", -1)) + } + + messageValue, messageValueErr := messageItem.Value() + if messageValueErr != nil { + return messageValueErr + } + msg := fmt.Sprintf("%s", messageValue) + + timestampItem, timestampErr := txn.Get([]byte(strings.Replace(stringKey, "|id", "|timestamp", -1))) + if timestampErr != nil { + return errors.WithMessage(timestampErr, "Key: "+strings.Replace(stringKey, "|id", "|timestamp", -1)) + } + + timestampValue, timestampValueErr := timestampItem.Value() + if timestampValueErr != nil { + return timestampValueErr + } + timestamp := fmt.Sprintf("%s", timestampValue) + timestampInt, ConvErr := strconv.ParseInt(timestamp, 10, 64) + if ConvErr != nil { + return ConvErr + } + + m.MessageListLayout.TriggerMessage(msg, sender, timestampInt) + } } - sender, GetSenderErr := tx.Get("room|" + m.currentRoom + "|messages|" + id + "|sender") - if GetSenderErr != nil { - return false + if strings.HasSuffix(stringKey, "|sender") { + if !contains(doneMsg, stringValue) { + // Remember we already added this message to the view + idItem, idErr := txn.Get([]byte(strings.Replace(stringKey, "|sender", "|id", -1))) + if idErr != nil { + return errors.WithMessage(idErr, "Key: "+strings.Replace(stringKey, "|sender", "|id", -1)) + } + idValue, idValueErr := idItem.Value() + if idValueErr != nil { + return idValueErr + } + id := fmt.Sprintf("%s", idValue) + doneMsg = append(doneMsg, id) + + // Get all Data + sender := stringValue + + messageItem, messageErr := txn.Get([]byte(strings.Replace(stringKey, "|sender", "|messageString", -1))) + if messageErr != nil { + return errors.WithMessage(messageErr, "Key: "+strings.Replace(stringKey, "|sender", "|messageString", -1)) + } + + messageValue, messageValueErr := messageItem.Value() + if messageValueErr != nil { + return messageValueErr + } + msg := fmt.Sprintf("%s", messageValue) + + timestampItem, timestampErr := txn.Get([]byte(strings.Replace(stringKey, "|sender", "|timestamp", -1))) + if timestampErr != nil { + return errors.WithMessage(timestampErr, "Key: "+strings.Replace(stringKey, "|sender", "|timestamp", -1)) + } + + timestampValue, timestampValueErr := timestampItem.Value() + if timestampValueErr != nil { + return timestampValueErr + } + timestamp := fmt.Sprintf("%s", timestampValue) + + timestampInt, ConvErr := strconv.ParseInt(timestamp, 10, 64) + if ConvErr != nil { + return ConvErr + } + + m.MessageListLayout.TriggerMessage(msg, sender, timestampInt) + } } - timestamp, GetTimestampErr := tx.Get("room|" + m.currentRoom + "|messages|" + id + "|timestamp") - if GetTimestampErr != nil { - return false + if strings.HasSuffix(stringKey, "|messageString") { + if !contains(doneMsg, stringValue) { + // Remember we already added this message to the view + idItem, idErr := txn.Get([]byte(strings.Replace(stringKey, "|messageString", "|id", -1))) + if idErr != nil { + return errors.WithMessage(idErr, "Key: "+strings.Replace(stringKey, "|messageString", "|id", -1)) + } + + idValue, idValueErr := idItem.Value() + if idValueErr != nil { + return idValueErr + } + id := fmt.Sprintf("%s", idValue) + doneMsg = append(doneMsg, id) + + // Get all Data + senderItem, senderErr := txn.Get([]byte(strings.Replace(stringKey, "|messageString", "|sender", -1))) + if senderErr != nil { + return errors.WithMessage(senderErr, "Key: "+strings.Replace(stringKey, "|messageString", "|sender", -1)) + } + + senderValue, senderValueErr := senderItem.Value() + if senderValueErr != nil { + return senderValueErr + } + sender := fmt.Sprintf("%s", senderValue) + + msg := stringValue + + timestampItem, timestampErr := txn.Get([]byte(strings.Replace(stringKey, "|messageString", "|timestamp", -1))) + if timestampErr != nil { + return errors.WithMessage(timestampErr, "Key: "+strings.Replace(stringKey, "|messageString", "|timestamp", -1)) + } + + timestampValue, timestampValueErr := timestampItem.Value() + if timestampValueErr != nil { + return timestampValueErr + } + timestamp := fmt.Sprintf("%s", timestampValue) + + timestampInt, ConvErr := strconv.ParseInt(timestamp, 10, 64) + if ConvErr != nil { + return ConvErr + } + + m.MessageListLayout.TriggerMessage(msg, sender, timestampInt) + } } - timestampInt, ConvErr := strconv.ParseInt(timestamp, 10, 64) - if ConvErr != nil { - return false + + if strings.HasSuffix(stringKey, "|timestamp") { + if !contains(doneMsg, stringValue) { + // Remember we already added this message to the view + idItem, idErr := txn.Get([]byte(strings.Replace(stringKey, "|timestamp", "|id", -1))) + if idErr != nil { + return errors.WithMessage(idErr, "Key: "+strings.Replace(stringKey, "|timestamp", "|id", -1)) + } + idValue, idValueErr := idItem.Value() + if idValueErr != nil { + return idValueErr + } + id := fmt.Sprintf("%s", idValue) + doneMsg = append(doneMsg, id) + + // Get all Data + senderItem, senderErr := txn.Get([]byte(strings.Replace(stringKey, "|timestamp", "|sender", -1))) + if senderErr != nil { + return errors.WithMessage(senderErr, "Key: "+strings.Replace(stringKey, "|timestamp", "|sender", -1)) + } + senderValue, senderValueErr := senderItem.Value() + if senderValueErr != nil { + return senderValueErr + } + sender := fmt.Sprintf("%s", senderValue) + + messageItem, messageErr := txn.Get([]byte(strings.Replace(stringKey, "|timestamp", "|messageString", -1))) + if messageErr != nil { + return errors.WithMessage(messageErr, "Key: "+strings.Replace(stringKey, "|timestamp", "|messageString", -1)) + } + messageValue, messageValueErr := messageItem.Value() + if messageValueErr != nil { + return messageValueErr + } + msg := fmt.Sprintf("%s", messageValue) + + timestamp := stringValue + + timestampInt, ConvErr := strconv.ParseInt(timestamp, 10, 64) + if ConvErr != nil { + return ConvErr + } + + m.MessageListLayout.TriggerMessage(msg, sender, timestampInt) + } } + } - return true - }) - if IDErr != nil { - fmt.Println("IDErr: ", IDErr) - return IDErr - }*/ return nil }) if DBerr != nil { diff --git a/ui/roomlist.go b/ui/roomlist.go @@ -78,21 +78,23 @@ func (roomViewLayout *QRoomVBoxLayoutWithTriggerSlot) NewRoom(room *matrix.Room, var mouseEvent = gui.NewQMouseEventFromPointer(event.Pointer()) if mouseEvent.Button() == core.Qt__LeftButton { - mainUIStruct.SetCurrentRoom(room.RoomID) - mainUIStruct.MainWidget.SetWindowTitle("Morpheus - " + room.GetRoomTopic()) + if mainUIStruct.currentRoom != room.RoomID { + mainUIStruct.SetCurrentRoom(room.RoomID) + mainUIStruct.MainWidget.SetWindowTitle("Morpheus - " + room.GetRoomTopic()) - mainUIStruct.RoomAvatar.SetPixmap(roomAvatar) + mainUIStruct.RoomAvatar.SetPixmap(roomAvatar) - mainUIStruct.RoomTitle.SetText(room.GetRoomName()) + mainUIStruct.RoomTitle.SetText(room.GetRoomName()) - mainUIStruct.RoomTopic.SetText(room.GetRoomTopic()) - count := mainUIStruct.MessageListLayout.Count() - for i := 0; i < count; i++ { - widgetScroll := mainUIStruct.MessageListLayout.ItemAt(i).Widget() - widgetScroll.DeleteLater() - } + mainUIStruct.RoomTopic.SetText(room.GetRoomTopic()) + count := mainUIStruct.MessageListLayout.Count() + for i := 0; i < count; i++ { + widgetScroll := mainUIStruct.MessageListLayout.ItemAt(i).Widget() + widgetScroll.DeleteLater() + } - go mainUIStruct.loadCache() + go mainUIStruct.loadCache() + } return true }