4.diff (12977B)
1 diff --git a/.circleci/config.yml b/.circleci/config.yml 2 index 5f9a38f..4f0571c 100644 3 --- a/.circleci/config.yml 4 +++ b/.circleci/config.yml 5 @@ -21,12 +21,18 @@ jobs: 6 name: Get Go Dependencies 7 working_directory: /home/user/work/src/github.com/Nordgedanken/Morpheusv2/ 8 command: dep ensure 9 + - run: 10 + name: Setup Code Climate test-reporter 11 + command: | 12 + curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter 13 + chmod +x ./cc-test-reporter 14 - persist_to_workspace: 15 # Must be an absolute path, or relative path from working_directory 16 root: /home/user/work/ 17 # Must be relative path from root 18 paths: 19 - src/ 20 + - ./cc-test-reporter 21 build_linux: 22 docker: 23 - image: therecipe/qt:linux 24 diff --git a/Gopkg.lock b/Gopkg.lock 25 index 6773bcc..7859130 100644 26 --- a/Gopkg.lock 27 +++ b/Gopkg.lock 28 @@ -7,6 +7,12 @@ 29 revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" 30 version = "v1.0" 31 32 +[[projects]] 33 + branch = "master" 34 + name = "github.com/matrix-org/gomatrix" 35 + packages = ["."] 36 + revision = "a7fc80c8060c2544fe5d4dae465b584f8e9b4e27" 37 + 38 [[projects]] 39 branch = "master" 40 name = "github.com/shibukawa/configdir" 41 diff --git a/cmd/root.go b/cmd/root.go 42 index 61a0ac4..148f65a 100644 43 --- a/cmd/root.go 44 +++ b/cmd/root.go 45 @@ -19,19 +19,57 @@ import ( 46 "os" 47 48 "github.com/Nordgedanken/Morpheusv2/pkg/app" 49 + dbImpl "github.com/Nordgedanken/Morpheusv2/pkg/db/implementation" 50 + "github.com/shibukawa/configdir" 51 "github.com/spf13/cobra" 52 + "io" 53 + "log" 54 + "path/filepath" 55 ) 56 57 // rootCmd represents the base command when called without any subcommands 58 var rootCmd = &cobra.Command{ 59 - Use: "Morpheusv2", 60 - Short: "A brief description of your application", 61 - Long: `A longer description that spans multiple lines and likely contains 62 -examples and usage of using your application. For example: 63 - 64 -Cobra is a CLI library for Go that empowers applications. 65 -This application is a tool to generate the needed files 66 -to quickly create a Cobra application.`, 67 + Use: "Morpheusv2", 68 + PreRunE: func(cmd *cobra.Command, args []string) error { 69 + // Init Logs and folders 70 + // configdir.New gets the Config Paths that are available on this system 71 + configDirs := configdir.New("Nordgedanken", "Morpheusv2") 72 + // path holds the global configdir of the system with the log folder appended 73 + path := filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path + "/log/") 74 + logFilePath := filepath.ToSlash(path + "main.log") 75 + 76 + // This checks if the directory is missing and if that's the case to generate the directory 77 + if _, StatErr := os.Stat(path); os.IsNotExist(StatErr) { 78 + MkdirErr := os.MkdirAll(path, os.ModeDir) 79 + if MkdirErr != nil { 80 + return MkdirErr 81 + } 82 + } 83 + 84 + // os.OpenFile opens the file where the log is supposed to be written to 85 + logFile, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) 86 + if err != nil { 87 + return err 88 + } 89 + 90 + // MultiWriter makes it possible to print log to both log File and console 91 + mw := io.MultiWriter(os.Stdout, logFile) 92 + 93 + // SetOutput tells the log where to write to 94 + log.SetOutput(mw) 95 + 96 + // dbImpl.Init() generates the needed tables if needed before the app starts 97 + err = dbImpl.Init() 98 + if err != nil { 99 + return err 100 + } 101 + 102 + log.Println("DB Set Up") 103 + return nil 104 + }, 105 + // TODO add descriptions 106 + Short: "", 107 + Long: ``, 108 // Uncomment the following line if your bare application 109 // has an action associated with it: 110 RunE: func(cmd *cobra.Command, args []string) error { 111 diff --git a/deb.json b/deb.json 112 index f710e5e..3a72561 100644 113 --- a/deb.json 114 +++ b/deb.json 115 @@ -50,7 +50,7 @@ 116 "description":"A Matrix client written in Go-QT ", 117 "generic-name":"Matrix Client", 118 "exec":"/usr/bin/Morpheusv2.sh", 119 - "icon":"pkg/qml/resources/logos/MorpheusBig.png", 120 + "icon":"qml/resources/logos/MorpheusBig.png", 121 "type":"Application", 122 "keywords":"matrix;Morpheusv2", 123 "startup-notify": false, 124 diff --git a/main.go b/main.go 125 index f305e76..06c10b1 100644 126 --- a/main.go 127 +++ b/main.go 128 @@ -16,24 +16,18 @@ package main 129 130 import ( 131 "github.com/Nordgedanken/Morpheusv2/cmd" 132 - "github.com/Nordgedanken/Morpheusv2/pkg" 133 - "runtime" 134 + "os" 135 + "os/signal" 136 + "syscall" 137 ) 138 139 -// Arrange that main.main runs on main thread. 140 -func init() { 141 - runtime.LockOSThread() 142 -} 143 +var c = make(chan os.Signal, 2) 144 145 func main() { 146 - go pkg.Do(cmd.Execute) 147 + signal.Notify(c, os.Interrupt, syscall.SIGTERM) 148 go func() { 149 - for { 150 - pkg.Do(noop) 151 - } 152 + <-c 153 + os.Exit(1) 154 }() 155 - 156 - pkg.Main() 157 + cmd.Execute() 158 } 159 - 160 -func noop() {} 161 diff --git a/pkg/app/main.go b/pkg/app/main.go 162 index 43d28a6..3832900 100644 163 --- a/pkg/app/main.go 164 +++ b/pkg/app/main.go 165 @@ -15,28 +15,37 @@ 166 package app 167 168 import ( 169 - "github.com/shibukawa/configdir" 170 + "github.com/Nordgedanken/Morpheusv2/pkg/mainUI" 171 + "github.com/matrix-org/gomatrix" 172 "github.com/therecipe/qt/core" 173 "github.com/therecipe/qt/gui" 174 "github.com/therecipe/qt/widgets" 175 "log" 176 - "os" 177 - "path/filepath" 178 ) 179 180 +var args []string 181 +var cli *gomatrix.Client 182 +var windowHeight = 600 183 +var windowWidth = 950 184 +var window *widgets.QMainWindow 185 + 186 // Start prepares the Main QT Window and opens it 187 -func Start(args []string) error { 188 +func Start(argsArg []string) error { 189 + args = argsArg 190 log.Println("Starting Morpheus v2") 191 192 - // Init Logs and folders 193 - configDirs := configdir.New("Nordgedanken", "Morpheus") 194 - if _, StatErr := os.Stat(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) + "/log/"); os.IsNotExist(StatErr) { 195 - MkdirErr := os.MkdirAll(filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path)+"/log/", 0700) 196 - if MkdirErr != nil { 197 - return MkdirErr 198 - } 199 - } 200 + initApp() 201 + 202 + mainUIS := mainUI.NewMainUI(windowWidth, windowHeight, window) 203 + SetNewWindow(mainUIS, window) 204 + 205 + widgets.QApplication_Exec() 206 207 + return nil 208 +} 209 + 210 +func initApp() { 211 + log.Println("Create QApp") 212 app := widgets.NewQApplication(len(args), args) 213 214 app.SetAttribute(core.Qt__AA_UseHighDpiPixmaps, true) 215 @@ -44,22 +53,33 @@ func Start(args []string) error { 216 app.SetApplicationVersion("0.1.0") 217 appIcon := gui.NewQIcon5(":/qml/resources/logos/MorpheusBig.png") 218 app.SetWindowIcon(appIcon) 219 + window = widgets.NewQMainWindow(nil, 0) 220 + app.SetActiveWindow(window) 221 222 - window := widgets.NewQMainWindow(nil, 0) 223 - 224 - windowHeight := 600 225 - windowWidth := 950 226 - 227 - desktopApp := widgets.QApplication_Desktop() 228 + desktopApp := app.Desktop() 229 primaryScreen := desktopApp.PrimaryScreen() 230 screen := desktopApp.Screen(primaryScreen) 231 windowX := (screen.Width() - windowHeight) / 2 232 windowY := (screen.Height() - windowWidth) / 2 233 234 window.Resize2(windowWidth, windowHeight) 235 - window.Show() 236 - 237 window.Move2(windowX, windowY) 238 239 + app.ConnectQuit(func() { 240 + log.Println("Morpheus closed") 241 + }) 242 + 243 +} 244 + 245 +// SetNewWindow loads the new UI into the QMainWindow 246 +func SetNewWindow(ui ui, window *widgets.QMainWindow) error { 247 + ui.SetCli(cli) 248 + uiErr := ui.NewUI() 249 + if uiErr != nil { 250 + return uiErr 251 + } 252 + ui.GetWidget().Resize2(windowWidth, windowHeight) 253 + window.SetCentralWidget(ui.GetWidget()) 254 + window.Show() 255 return nil 256 } 257 diff --git a/pkg/app/ui.go b/pkg/app/ui.go 258 new file mode 100644 259 index 0000000..37ced17 260 --- /dev/null 261 +++ b/pkg/app/ui.go 262 @@ -0,0 +1,12 @@ 263 +package app 264 + 265 +import ( 266 + "github.com/matrix-org/gomatrix" 267 + "github.com/therecipe/qt/widgets" 268 +) 269 + 270 +type ui interface { 271 + SetCli(cli *gomatrix.Client) 272 + GetWidget() (widget *widgets.QWidget) 273 + NewUI() error 274 +} 275 diff --git a/pkg/db/db.go b/pkg/db/db.go 276 new file mode 100644 277 index 0000000..0ffaede 278 --- /dev/null 279 +++ b/pkg/db/db.go 280 @@ -0,0 +1,14 @@ 281 +package db 282 + 283 +import "github.com/Nordgedanken/Morpheusv2/pkg/matrix" 284 + 285 +// DB defines a Interface to allow multiple DB Implementations 286 +type DB interface { 287 + SaveRoom(Room matrix.Room) error 288 + GetRooms() (rooms map[string]matrix.Room, err error) 289 + GetRoom(roomID string) (room matrix.Room, err error) 290 + 291 + SaveUser(user matrix.User) error 292 + GetUsers() (map[string]matrix.User, error) 293 + GetCurrentUser() (matrix.User, error) 294 +} 295 diff --git a/pkg/db/implementation/db.go b/pkg/db/implementation/db.go 296 new file mode 100644 297 index 0000000..9429d4b 298 --- /dev/null 299 +++ b/pkg/db/implementation/db.go 300 @@ -0,0 +1,51 @@ 301 +package implementation 302 + 303 +import ( 304 + "database/sql" 305 + "fmt" 306 + _ "github.com/mattn/go-sqlite3" // Go-sqlite3 side effect import needed to use SQLite3 databases 307 + "github.com/shibukawa/configdir" 308 + "log" 309 + "path/filepath" 310 +) 311 + 312 +var db *sql.DB 313 + 314 +// Init prepares the DB by opening it and creating the required tables if needed 315 +// TODO: Make part of the interface 316 +func Init() (err error) { 317 + log.Println("Start setting up DB") 318 + var openErr error 319 + 320 + // Open the data.db file. It will be created if it doesn't exist. 321 + configDirs := configdir.New("Nordgedanken", "Morpheusv2") 322 + filePath := filepath.ToSlash(configDirs.QueryFolders(configdir.Global)[0].Path) 323 + 324 + log.Println("DBFilePath: ", filePath+"/data.db") 325 + db, openErr = sql.Open("sqlite3", filePath+"/data.db") 326 + if openErr != nil { 327 + err = openErr 328 + return 329 + } 330 + 331 + log.Println("Creating DB Tables if needed") 332 + createTables := `CREATE TABLE IF NOT EXISTS users (id integer not null primary key, display_name text, avatar text); 333 + CREATE TABLE IF NOT EXISTS messages (id integer not null primary key, author text, message text, timestamp text, pure_event text); 334 + CREATE TABLE IF NOT EXISTS rooms (id integer not null primary key, room_aliases text, room_id text, room_name text, room_avatar text, room_topic text, room_messages text); 335 + ` 336 + _, execErr := db.Exec(createTables) 337 + if execErr != nil { 338 + err = fmt.Errorf("DB EXEC ERR: %s", execErr) 339 + return 340 + } 341 + log.Println("Finished setting DB Setup") 342 + return 343 +} 344 + 345 +// Open returns the in Init() created db variable 346 +func Open() *sql.DB { 347 + if db != nil { 348 + return db 349 + } 350 + return nil 351 +} 352 diff --git a/pkg/mainUI/mainUI.go b/pkg/mainUI/mainUI.go 353 new file mode 100644 354 index 0000000..7fcaaf9 355 --- /dev/null 356 +++ b/pkg/mainUI/mainUI.go 357 @@ -0,0 +1,63 @@ 358 +package mainUI 359 + 360 +import ( 361 + "github.com/matrix-org/gomatrix" 362 + "github.com/therecipe/qt/core" 363 + "github.com/therecipe/qt/gui" 364 + "github.com/therecipe/qt/uitools" 365 + "github.com/therecipe/qt/widgets" 366 +) 367 + 368 +// MainUI defines the data for the main ui (that one with the chats) 369 +type MainUI struct { 370 + widget *widgets.QWidget 371 + cli *gomatrix.Client 372 + window *widgets.QMainWindow 373 + windowWidth int 374 + windowHeight int 375 +} 376 + 377 +// NewMainUI gives you a MainUI struct with prefilled data 378 +func NewMainUI(windowWidth, windowHeight int, window *widgets.QMainWindow) (mainUI *MainUI) { 379 + mainUI = &MainUI{ 380 + windowWidth: windowWidth, 381 + windowHeight: windowHeight, 382 + window: window, 383 + } 384 + return 385 +} 386 + 387 +// SetCli sets the gomatrix Client for the MainUI 388 +func (m *MainUI) SetCli(cli *gomatrix.Client) { 389 + m.cli = cli 390 +} 391 + 392 +// GetWidget returns the QWidget of the MainUI 393 +func (m *MainUI) GetWidget() (widget *widgets.QWidget) { 394 + return m.widget 395 +} 396 + 397 +// NewUI prepares the new UI 398 +func (m *MainUI) NewUI() error { 399 + m.widget = widgets.NewQWidget(nil, 0) 400 + 401 + var loader = uitools.NewQUiLoader(nil) 402 + var file = core.NewQFile2(":/qml/ui/chat.ui") 403 + 404 + file.Open(core.QIODevice__ReadOnly) 405 + mainWidget := loader.Load(file, m.widget) 406 + file.Close() 407 + 408 + var layout = widgets.NewQHBoxLayout() 409 + m.window.SetLayout(layout) 410 + layout.InsertWidget(0, mainWidget, 0, core.Qt__AlignTop|core.Qt__AlignLeft) 411 + layout.SetSpacing(0) 412 + layout.SetContentsMargins(0, 0, 0, 0) 413 + 414 + m.widget.ConnectResizeEvent(func(event *gui.QResizeEvent) { 415 + mainWidget.Resize(event.Size()) 416 + event.Accept() 417 + }) 418 + 419 + return nil 420 +} 421 diff --git a/pkg/matrix/dataTypes.go b/pkg/matrix/dataTypes.go 422 new file mode 100644 423 index 0000000..8d30e68 424 --- /dev/null 425 +++ b/pkg/matrix/dataTypes.go 426 @@ -0,0 +1,38 @@ 427 +package matrix 428 + 429 +import ( 430 + "github.com/matrix-org/gomatrix" 431 + "time" 432 +) 433 + 434 +// User defines a Interface to allow multiple User type Implementations 435 +type User interface { 436 + SetCli(cli *gomatrix.Client) 437 + SetMXID(id string) 438 + GetDisplayName(roomID string) (string, error) 439 + GetAvatar(roomID string) (string, error) 440 +} 441 + 442 +// Room defines a Interface to allow multiple Room type Implementations 443 +type Room interface { 444 + // Handled using global "own User" 445 + //SetCli(cli *gomatrix.Client) 446 + SetRoomID(id string) 447 + SetRoomAliases(aliases map[int64]string) 448 + GetName() (string, error) 449 + GetAvatar() (string, error) 450 + GetTopic() (string, error) 451 + GetMessages() (map[string]Message, error) 452 +} 453 + 454 +// Message defines a Interface to allow multiple Message type Implementations 455 +type Message interface { 456 + // Handled using global "own User" 457 + //SetCli(cli *gomatrix.Client) 458 + SetEventID(id string) 459 + SetEvent(event *gomatrix.Event) 460 + SetAuthorMXID(mxid string) 461 + SetMessage(message string) 462 + SetTimestamp(ts *time.Time) 463 + Show() error 464 +}