morpheus

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

commit be63dfbb1552f2139d678dc177fefc5ed1f50d22
parent 76f0ef1b20bc6a5408ff8fbd28ffd39612348011
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sun, 22 Oct 2017 13:18:52 +0200

Prepare tests and move db too own package to not depend on the qt binding

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

Diffstat:
Mmain.go | 3++-
Dmatrix/db.go | 89-------------------------------------------------------------------------------
Amatrix/db/db.go | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amatrix/db/matrix_suite_test.go | 13+++++++++++++
Amatrix/db/userDataDB_test.go | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmatrix/login.go | 5+++--
Mmatrix/rooms.go | 3++-
Mmatrix/user.go | 5++---
Mui/MainUI.go | 34++++++++++++++++++++++------------
Mui/messageList.go | 17+++++++++++++----
Mui/types.go | 1+
11 files changed, 212 insertions(+), 112 deletions(-)

diff --git a/main.go b/main.go @@ -6,6 +6,7 @@ import ( "sync" "github.com/Nordgedanken/Morpheus/matrix" + "github.com/Nordgedanken/Morpheus/matrix/db" "github.com/Nordgedanken/Morpheus/ui" "github.com/Nordgedanken/Morpheus/util" "github.com/matrix-org/gomatrix" @@ -29,7 +30,7 @@ func main() { } defer file.Close() - db, DBOpenErr := matrix.OpenUserDB() + db, DBOpenErr := db.OpenUserDB() if DBOpenErr != nil { localLog.Fatalln(DBOpenErr) } diff --git a/matrix/db.go b/matrix/db.go @@ -1,89 +0,0 @@ -package matrix - -import ( - "os" - "path/filepath" - "strconv" - - "github.com/shibukawa/configdir" - "github.com/tidwall/buntdb" -) - -// OpenCacheDB opens or generates the Database file for settings and Cache -func OpenCacheDB() (db *buntdb.DB, err error) { - // Open the data.db file. It will be created if it doesn't exist. - configDirs := configdir.New("Nordgedanken", "Morpheus") - if _, StatErr := os.Stat(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/data/"); os.IsNotExist(StatErr) { - MkdirErr := os.MkdirAll(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path)+"/data/", 0666) - if MkdirErr != nil { - err = MkdirErr - return - } - } - expDB, DBErr := buntdb.Open(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/data/cache.db") - if DBErr != nil { - err = DBErr - return - } - - db = expDB - return -} - -// OpenUserDB opens or generates the Database file for settings and Cache -func OpenUserDB() (db *buntdb.DB, err error) { - // Open the data.db file. It will be created if it doesn't exist. - configDirs := configdir.New("Nordgedanken", "Morpheus") - if _, StatErr := os.Stat(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/data/"); os.IsNotExist(StatErr) { - MkdirErr := os.MkdirAll(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path)+"/data/", 0666) - if MkdirErr != nil { - err = MkdirErr - return - } - } - expDB, DBErr := buntdb.Open(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/data/userData.db") - if DBErr != nil { - err = DBErr - return - } - - db = expDB - return -} - -// CacheMessageEvents writes message infos into the cache into the defined room -func CacheMessageEvents(id, sender, roomID, message string, timestamp int64) (err error) { - db, DBOpenErr := OpenCacheDB() - if DBOpenErr != nil { - localLog.Fatalln(DBOpenErr) - } - defer db.Close() - - // Update cache - DBerr := db.Update(func(tx *buntdb.Tx) error { - _, _, DBSetIDErr := tx.Set("room|"+roomID+"|messages|"+id+"|id", id, nil) - if DBSetIDErr != nil { - return DBSetIDErr - } - - _, _, DBSetSenderErr := tx.Set("room|"+roomID+"|messages|"+id+"|sender", sender, nil) - if DBSetSenderErr != nil { - return DBSetSenderErr - } - - _, _, DBSetMessageErr := tx.Set("room|"+roomID+"|messages|"+id+"|message", message, nil) - if DBSetMessageErr != nil { - return DBSetMessageErr - } - - timestampString := strconv.FormatInt(timestamp, 10) - _, _, DBSeTimestampErr := tx.Set("room|"+roomID+"|messages|"+id+"|timestamp", timestampString, nil) - return DBSeTimestampErr - - }) - if DBerr != nil { - err = DBerr - return - } - return -} diff --git a/matrix/db/db.go b/matrix/db/db.go @@ -0,0 +1,90 @@ +package db + +import ( + "os" + "path/filepath" + "strconv" + + "github.com/shibukawa/configdir" + "github.com/tidwall/buntdb" +) + +// OpenCacheDB opens or generates the Database file for settings and Cache +func OpenCacheDB() (db *buntdb.DB, err error) { + // Open the data.db file. It will be created if it doesn't exist. + configDirs := configdir.New("Nordgedanken", "Morpheus") + if _, StatErr := os.Stat(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/data/"); os.IsNotExist(StatErr) { + MkdirErr := os.MkdirAll(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path)+"/data/", 0666) + if MkdirErr != nil { + err = MkdirErr + return + } + } + expDB, DBErr := buntdb.Open(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/data/cache.db") + if DBErr != nil { + err = DBErr + return + } + + db = expDB + return +} + +// OpenUserDB opens or generates the Database file for settings and Cache +func OpenUserDB() (db *buntdb.DB, err error) { + // Open the data.db file. It will be created if it doesn't exist. + configDirs := configdir.New("Nordgedanken", "Morpheus") + if _, StatErr := os.Stat(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/data/"); os.IsNotExist(StatErr) { + MkdirErr := os.MkdirAll(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path)+"/data/", 0666) + if MkdirErr != nil { + err = MkdirErr + return + } + } + expDB, DBErr := buntdb.Open(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/data/userData.db") + if DBErr != nil { + err = DBErr + return + } + + db = expDB + return +} + +// CacheMessageEvents writes message infos into the cache into the defined room +func CacheMessageEvents(id, sender, roomID, message string, timestamp int64) (err error) { + db, DBOpenErr := OpenCacheDB() + if DBOpenErr != nil { + err = DBOpenErr + return + } + defer db.Close() + + // Update cache + DBerr := db.Update(func(tx *buntdb.Tx) error { + _, _, DBSetIDErr := tx.Set("room|"+roomID+"|messages|"+id+"|id", id, nil) + if DBSetIDErr != nil { + return DBSetIDErr + } + + _, _, DBSetSenderErr := tx.Set("room|"+roomID+"|messages|"+id+"|sender", sender, nil) + if DBSetSenderErr != nil { + return DBSetSenderErr + } + + _, _, DBSetMessageErr := tx.Set("room|"+roomID+"|messages|"+id+"|message", message, nil) + if DBSetMessageErr != nil { + return DBSetMessageErr + } + + timestampString := strconv.FormatInt(timestamp, 10) + _, _, DBSeTimestampErr := tx.Set("room|"+roomID+"|messages|"+id+"|timestamp", timestampString, nil) + return DBSeTimestampErr + + }) + if DBerr != nil { + err = DBerr + return + } + return +} diff --git a/matrix/db/matrix_suite_test.go b/matrix/db/matrix_suite_test.go @@ -0,0 +1,13 @@ +package db + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestMatrix(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Matrix DB Suite") +} diff --git a/matrix/db/userDataDB_test.go b/matrix/db/userDataDB_test.go @@ -0,0 +1,64 @@ +package db + +import ( + "os" + "path/filepath" + + . "github.com/onsi/ginkgo" + //. "github.com/onsi/gomega" + "github.com/shibukawa/configdir" + "github.com/tidwall/buntdb" +) + +// OpenUserDB opens or generates the Database file for settings and Cache +func OpenUserDBTest() (db *buntdb.DB, err error) { + // Open the data.db file. It will be created if it doesn't exist. + configDirs := configdir.New("Nordgedanken", "Morpheus") + if _, StatErr := os.Stat(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/tests/"); os.IsNotExist(StatErr) { + MkdirErr := os.MkdirAll(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path)+"/tests/", 0666) + if MkdirErr != nil { + err = MkdirErr + return + } + } + if _, StatErr := os.Stat(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/tests/data/"); os.IsNotExist(StatErr) { + MkdirErr := os.MkdirAll(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path)+"/tests/data/", 0666) + if MkdirErr != nil { + err = MkdirErr + return + } + } + expDB, DBErr := buntdb.Open(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/tests/data/userData.db") + if DBErr != nil { + err = DBErr + return + } + + db = expDB + return +} + +var _ = Describe("UserDataDB", func() { + var db *buntdb.DB + /*BeforeEach(func() { + DBErr := db.Update(func(tx *buntdb.Tx) error { + DeleteErr := tx.DeleteAll() + return DeleteErr + }) + if DBErr != nil { + Fail(DBErr.Error()) + } + })*/ + + Describe("Test User DB", func() { + Context("opening", func() { + It("should open the DB", func() { + var DBOpenErr error + db, DBOpenErr = OpenUserDBTest() + if DBOpenErr != nil { + Fail(DBOpenErr.Error()) + } + }) + }) + }) +}) diff --git a/matrix/login.go b/matrix/login.go @@ -5,13 +5,14 @@ import ( "strings" "sync" + "github.com/Nordgedanken/Morpheus/matrix/db" "github.com/matrix-org/gomatrix" "github.com/tidwall/buntdb" ) //GetClient returns a Client func GetClient(homeserverURL, userID, accessToken string) (client *gomatrix.Client, err error) { - db, DBOpenErr := OpenUserDB() + db, DBOpenErr := db.OpenUserDB() if DBOpenErr != nil { localLog.Fatalln(DBOpenErr) } @@ -71,7 +72,7 @@ func LoginUser(username, password string) (*gomatrix.Client, error) { return nil, err } - db, DBOpenErr := OpenUserDB() + db, DBOpenErr := db.OpenUserDB() if DBOpenErr != nil { localLog.Fatalln(DBOpenErr) } diff --git a/matrix/rooms.go b/matrix/rooms.go @@ -7,6 +7,7 @@ import ( "image/png" "strings" + "github.com/Nordgedanken/Morpheus/matrix/db" "github.com/matrix-org/gomatrix" "github.com/therecipe/qt/gui" "github.com/tidwall/buntdb" @@ -60,7 +61,7 @@ func (r *Room) GetRoomAvatar() (avatarResp *gui.QPixmap, err error) { } // Get the image Data - db, DBOpenErr := OpenCacheDB() + db, DBOpenErr := db.OpenCacheDB() if DBOpenErr != nil { localLog.Fatalln(DBOpenErr) } diff --git a/matrix/user.go b/matrix/user.go @@ -22,6 +22,7 @@ import ( // image/jpeg needed to load jpeg images _ "image/jpeg" // golang.org/x/image/webp needed to load webp images + "github.com/Nordgedanken/Morpheus/matrix/db" _ "golang.org/x/image/webp" // golang.org/x/image/bmp needed to load bmp images _ "golang.org/x/image/bmp" @@ -76,7 +77,6 @@ func generateGenericImages(displayname string, size int) (imgData string, err er return } - localLog.Println("generatedIMGBounds: ", img.Bounds()) buf := new(bytes.Buffer) EncodeErr := png.Encode(buf, img) if EncodeErr != nil { @@ -95,7 +95,7 @@ func GetOwnUserAvatar(cli *gomatrix.Client) (avatar *gui.QPixmap, err error) { // GetUserAvatar returns a *gui.QPixmap of an UserAvatar func GetUserAvatar(cli *gomatrix.Client, mxid string, size int) (avatarResp *gui.QPixmap, err error) { - db, DBOpenErr := OpenCacheDB() + db, DBOpenErr := db.OpenCacheDB() if DBOpenErr != nil { localLog.Fatalln(DBOpenErr) } @@ -148,7 +148,6 @@ func GetUserAvatar(cli *gomatrix.Client, mxid string, size int) (avatarResp *gui } IMGdata = string(data[:]) } else { - localLog.Println("Generating Avatar") DisplayNameResp, _ := cli.GetDisplayName(mxid) DisplayName := DisplayNameResp.DisplayName var GenerateImgErr error diff --git a/ui/MainUI.go b/ui/MainUI.go @@ -8,6 +8,7 @@ import ( "strconv" "github.com/Nordgedanken/Morpheus/matrix" + "github.com/Nordgedanken/Morpheus/matrix/db" "github.com/Nordgedanken/Morpheus/util" "github.com/matrix-org/gomatrix" "github.com/rhinoman/go-commonmark" @@ -74,7 +75,7 @@ func (m *MainUI) NewUI() (err error) { m.MainWidget = loader.Load(file, m.widget) file.Close() - messageScrollArea := widgets.NewQScrollAreaFromPointer(m.widget.FindChild("messageScroll", core.Qt__FindChildrenRecursively).Pointer()) + m.messageScrollArea = widgets.NewQScrollAreaFromPointer(m.widget.FindChild("messageScroll", core.Qt__FindChildrenRecursively).Pointer()) messagesScrollAreaContent := widgets.NewQWidgetFromPointer(m.widget.FindChild("messagesScrollAreaContent", core.Qt__FindChildrenRecursively).Pointer()) roomScrollArea := widgets.NewQScrollAreaFromPointer(m.widget.FindChild("roomScroll", core.Qt__FindChildrenRecursively).Pointer()) roomScrollAreaContent := widgets.NewQWidgetFromPointer(m.widget.FindChild("roomScrollAreaContent", core.Qt__FindChildrenRecursively).Pointer()) @@ -106,7 +107,7 @@ func (m *MainUI) NewUI() (err error) { //Handle LogoutButton logoutButton := widgets.NewQPushButtonFromPointer(m.widget.FindChild("LogoutButton", core.Qt__FindChildrenRecursively).Pointer()) logoutButton.ConnectClicked(func(_ bool) { - LogoutErr := m.logout(m.widget, messageScrollArea) + LogoutErr := m.logout(m.widget, m.messageScrollArea) if LogoutErr != nil { err = LogoutErr return @@ -114,14 +115,14 @@ func (m *MainUI) NewUI() (err error) { }) // Init Message View - m.MessageListLayout = NewMessageList(messageScrollArea, messagesScrollAreaContent) + m.MessageListLayout = NewMessageList(m.messageScrollArea, messagesScrollAreaContent) // Init Room View roomListLayout := NewRoomList(roomScrollArea, roomScrollAreaContent) - messageScrollArea.SetWidgetResizable(true) - messageScrollArea.SetHorizontalScrollBarPolicy(core.Qt__ScrollBarAlwaysOff) - messageScrollArea.SetContentsMargins(0, 0, 0, 0) + m.messageScrollArea.SetWidgetResizable(true) + m.messageScrollArea.SetHorizontalScrollBarPolicy(core.Qt__ScrollBarAlwaysOff) + m.messageScrollArea.SetContentsMargins(0, 0, 0, 0) //messageScrollArea.SetSizeAdjustPolicy(widgets.QAbstractScrollArea__AdjustToContents) roomScrollArea.SetWidgetResizable(true) @@ -136,7 +137,7 @@ func (m *MainUI) NewUI() (err error) { } else { own = false } - NewMessageErr := m.MessageListLayout.NewMessage(messageBody, m.cli, sender, timestamp, messageScrollArea, own) + NewMessageErr := m.MessageListLayout.NewMessage(messageBody, m.cli, sender, timestamp, m.messageScrollArea, own) if NewMessageErr != nil { err = NewMessageErr return @@ -233,7 +234,7 @@ func (m *MainUI) logout(widget *widgets.QWidget, messageScrollArea *widgets.QScr } cli.ClearCredentials() - db, DBOpenErr := matrix.OpenUserDB() + db, DBOpenErr := db.OpenUserDB() if DBOpenErr != nil { localLog.Fatalln(DBOpenErr) } @@ -300,9 +301,7 @@ func (m *MainUI) startSync() (err error) { sender := ev.Sender id := ev.ID timestamp := ev.Timestamp - go matrix.CacheMessageEvents(id, sender, room, msg, timestamp) - fmt.Println(room) - fmt.Println(m.currentRoom) + go db.CacheMessageEvents(id, sender, room, msg, timestamp) if room == m.currentRoom { m.MessageListLayout.TriggerMessage(msg, sender, timestamp) } @@ -342,7 +341,13 @@ func (m *MainUI) initRoomList(roomListLayout *QRoomVBoxLayoutWithTriggerSlot, ro } func (m *MainUI) loadCache() (err error) { - db, DBOpenErr := matrix.OpenCacheDB() + /*barAtBottom := false + bar := m.messageScrollArea.VerticalScrollBar() + if bar.Value() == bar.Maximum() { + barAtBottom = true + }*/ + + db, DBOpenErr := db.OpenCacheDB() if DBOpenErr != nil { err = DBOpenErr } @@ -383,5 +388,10 @@ func (m *MainUI) loadCache() (err error) { err = DBerr return } + + /*if barAtBottom { + bar.SetValue(bar.Maximum()) + }*/ + return } diff --git a/ui/messageList.go b/ui/messageList.go @@ -46,6 +46,12 @@ func NewMessageList(scrollArea *widgets.QScrollArea, messageView *widgets.QWidge // NewMessage adds a new message object to the view func (messageViewLayout *QVBoxLayoutWithTriggerSlot) NewMessage(body string, cli *gomatrix.Client, sender string, timestamp int64, scrollArea *widgets.QScrollArea, own bool) (err error) { + barAtBottom := false + bar := scrollArea.VerticalScrollBar() + fmt.Println(bar.Value()) + if bar.Value() == bar.Maximum() { + barAtBottom = true + } avatar, AvatarErr := matrix.GetUserAvatar(cli, sender, 61) if err != nil { err = AvatarErr @@ -95,12 +101,9 @@ func (messageViewLayout *QVBoxLayoutWithTriggerSlot) NewMessage(body string, cli var lineLength int lineLength = messageContent.FontMetrics().Width(messageContent.Text(), -1) - 87 - fmt.Println(scrollArea.Widget().Size().Width()) - fmt.Println("lineLengthO: ", lineLength) if lineLength >= scrollArea.Widget().Size().Width() { lineLength = scrollArea.Widget().Size().Width() - 20 - 87 } - fmt.Println("lineLengthN: ", lineLength) messageContent.SetMinimumWidth(lineLength + 10) @@ -110,7 +113,13 @@ func (messageViewLayout *QVBoxLayoutWithTriggerSlot) NewMessage(body string, cli messageViewLayout.SetSpacing(1) messageViewLayout.SetContentsMargins(0, 0, 0, 0) - messageViewLayout.InsertWidget(0, messageWidget, 0, core.Qt__AlignBottom) + messageViewLayout.InsertWidget(messageViewLayout.Count()+1, messageWidget, 0, core.Qt__AlignBottom) + + fmt.Println(barAtBottom) + fmt.Println(bar.Maximum()) + if barAtBottom { + bar.SetValue(bar.Maximum()) + } return } diff --git a/ui/types.go b/ui/types.go @@ -35,6 +35,7 @@ type MainUI struct { RoomTopic *widgets.QLabel MainWidget *widgets.QWidget MessageListLayout *QVBoxLayoutWithTriggerSlot + messageScrollArea *widgets.QScrollArea window *widgets.QMainWindow syncer *gomatrix.DefaultSyncer