package main import ( "context" "time" "github.com/adrg/xdg" "github.com/sanbornm/go-selfupdate/selfupdate" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/clause" "gorm.io/gorm/logger" ) type AppConfig struct { Title string Version string } type App struct { ctx context.Context Config AppConfig DB *gorm.DB UserContact Contact } func NewApp(config AppConfig) *App { app := &App{Config: config} db, err := gorm.Open(sqlite.Open(app.GetDataFile()), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), }) if err != nil { panic(err) } app.DB = db app.migrate() return app } func (app *App) startup(ctx context.Context) { app.Log("Running startup."). Stdout() defer app.Log("Startup finished."). Stdout() app.ctx = ctx updater := &selfupdate.Updater{ CurrentVersion: app.GetVersion(), ApiURL: "https://updater.machinetele.com", BinURL: "https://updater.machinetele.com", Dir: "update/", CmdName: app.GetTitle(), ForceCheck: true, CheckTime: 1, RandomizeTime: 0, OnPreFetch: func() { app.Log("Searching for updates...").Stdout().StatusLine() }, OnUpdateAttempt: func() { app.Log("Found a new version! Attempting to update.").Stdout().StatusLine() }, OnSuccessfulUpdate: func() { app.Log("Successfully updated to the newest version of EMessage.").Stdout().StatusLine() }, OnUpdateFailure: func(err error) { app.Log("Update failed: %v.", err.Error()).Stdout().StatusLine() }, } go updater.Update() go func() { ticker := time.NewTicker(1 * time.Hour) defer ticker.Stop() for range ticker.C { if err := updater.Update(); err != nil { log.Printf("Update failed: %v", err) } } }() app.EstablishMailConnections() return } func (app *App) shutdown(ctx context.Context) { app.Log("Running shutdown."). Stdout() defer app.Log("finished shutdown."). Stdout() CloseMailConnections() return } func (app *App) migrate() { app.Log("Starting migration..."). Stdout() defer app.Log("finished migration."). Stdout() app.DB.AutoMigrate(&Contact{}) app.DB.AutoMigrate(&EmailAddress{}) app.DB.AutoMigrate(&PhoneNumber{}) app.DB.AutoMigrate(&URL{}) app.DB.AutoMigrate(&StreetAddress{}) app.DB.AutoMigrate(&Date{}) app.DB.AutoMigrate(&OtherField{}) app.DB.Preload(clause.Associations). FirstOrCreate( &app.UserContact, Contact{Model: gorm.Model{ID: 1}}, ) app.Log("Ensuring contact."). Stdout() app.DB.AutoMigrate(&MailAccountConnection{}) app.DB.AutoMigrate(&Conversation{}) app.DB.AutoMigrate(&Message{}) app.DB.AutoMigrate(&MailHeader{}) app.DB.AutoMigrate(&LastSynced{}) app.DB.AutoMigrate(&MessageContent{}) app.DB.AutoMigrate(&DisplayImage{}) return } func (app *App) GetTitle() string { return app.Config.Title } func (app *App) GetVersion() string { return app.Config.Version } func (app *App) GetDataFile() string { if file, err := xdg.DataFile(app.GetTitle() + "/data.db"); err != nil { panic(err) } else { return file } } func (app *App) GetMailPasswordKeyringService() string { title := app.GetTitle() return title + "-mail-password" }