mirror of
https://github.com/garraflavatra/rolens.git
synced 2025-07-19 22:18:03 +00:00
Export/dump... wip
This commit is contained in:
@ -2,6 +2,11 @@ package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/menu"
|
||||
@ -9,8 +14,21 @@ import (
|
||||
wailsRuntime "github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
type EnvironmentInfo struct {
|
||||
Arch string `json:"arch"`
|
||||
BuildType string `json:"buildType"`
|
||||
Platform string `json:"platform"`
|
||||
|
||||
HasMongoExport bool `json:"hasMongoExport"`
|
||||
HasMongoDump bool `json:"hasMongoDump"`
|
||||
|
||||
HomeDirectory string `json:"homeDirectory"`
|
||||
DataDirectory string `json:"dataDirectory"`
|
||||
}
|
||||
|
||||
type App struct {
|
||||
ctx context.Context
|
||||
Env EnvironmentInfo
|
||||
}
|
||||
|
||||
func NewApp() *App {
|
||||
@ -19,6 +37,39 @@ func NewApp() *App {
|
||||
|
||||
func (a *App) Startup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
wailsEnv := wailsRuntime.Environment(a.ctx)
|
||||
|
||||
a.Env.Arch = wailsEnv.Arch
|
||||
a.Env.BuildType = wailsEnv.BuildType
|
||||
a.Env.Platform = wailsEnv.Platform
|
||||
|
||||
_, err := exec.LookPath("mongodump")
|
||||
a.Env.HasMongoDump = err == nil
|
||||
|
||||
_, err = exec.LookPath("mongoexport")
|
||||
a.Env.HasMongoExport = err == nil
|
||||
|
||||
a.Env.HomeDirectory, err = os.UserHomeDir()
|
||||
if err != nil {
|
||||
panic(errors.New("encountered an error while getting home directory"))
|
||||
}
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
a.Env.DataDirectory = filepath.Join(a.Env.HomeDirectory, "/AppData/Local/Rolens")
|
||||
case "darwin":
|
||||
a.Env.DataDirectory = filepath.Join(a.Env.HomeDirectory, "/Library/Application Support/Rolens")
|
||||
case "linux":
|
||||
a.Env.DataDirectory = filepath.Join(a.Env.HomeDirectory, "/.config/Rolens")
|
||||
default:
|
||||
panic(errors.New("unsupported platform"))
|
||||
}
|
||||
|
||||
_ = os.MkdirAll(a.Env.DataDirectory, os.ModePerm)
|
||||
}
|
||||
|
||||
func (a *App) Environment() EnvironmentInfo {
|
||||
return a.Env
|
||||
}
|
||||
|
||||
func menuEventEmitter(a *App, eventName string, data ...interface{}) func(cd *menu.CallbackData) {
|
||||
@ -61,3 +112,26 @@ func (a *App) Menu() *menu.Menu {
|
||||
|
||||
return appMenu
|
||||
}
|
||||
|
||||
func (a *App) OpenDirectory(id, title string) string {
|
||||
if title == "" {
|
||||
title = "Choose a directory"
|
||||
}
|
||||
|
||||
dir, err := wailsRuntime.OpenDirectoryDialog(a.ctx, wailsRuntime.OpenDialogOptions{
|
||||
Title: title,
|
||||
CanCreateDirectories: true,
|
||||
TreatPackagesAsDirectories: false,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
wailsRuntime.MessageDialog(a.ctx, wailsRuntime.MessageDialogOptions{
|
||||
Type: wailsRuntime.ErrorDialog,
|
||||
Title: "Encountered an error while opening directory",
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
return dir
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
type EnvironmentInfo struct {
|
||||
Arch string `json:"arch"`
|
||||
BuildType string `json:"buildType"`
|
||||
Platform string `json:"platform"`
|
||||
|
||||
HasMongoExport bool `json:"hasMongoExport"`
|
||||
HasMongoDump bool `json:"hasMongoDump"`
|
||||
}
|
||||
|
||||
var env EnvironmentInfo
|
||||
var envKnown = false
|
||||
|
||||
func (a *App) Environment() EnvironmentInfo {
|
||||
if !envKnown {
|
||||
wailsEnv := runtime.Environment(a.ctx)
|
||||
env.Arch = wailsEnv.Arch
|
||||
env.BuildType = wailsEnv.BuildType
|
||||
env.Platform = wailsEnv.Platform
|
||||
|
||||
_, err := exec.LookPath("mongodump")
|
||||
env.HasMongoDump = err == nil
|
||||
|
||||
_, err = exec.LookPath("mongoexport")
|
||||
env.HasMongoExport = err == nil
|
||||
|
||||
envKnown = true
|
||||
}
|
||||
return env
|
||||
}
|
113
internal/app/database_export.go
Normal file
113
internal/app/database_export.go
Normal file
@ -0,0 +1,113 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
type ExportType string
|
||||
type FileType string
|
||||
type ExportInfo struct {
|
||||
Type ExportType `json:"type"`
|
||||
FileType FileType `json:"fileType"`
|
||||
OutDir string `json:"outdir"`
|
||||
Filename string `json:"filename"`
|
||||
HostKey string `json:"hostKey"`
|
||||
DbKey string `json:"dbKey"`
|
||||
CollKeys []string `json:"collKeys"`
|
||||
}
|
||||
|
||||
const (
|
||||
ExportTypeExport ExportType = "export"
|
||||
ExportTypeDump ExportType = "dump"
|
||||
|
||||
FileTypeJson FileType = "json"
|
||||
FileTypeBson FileType = "bson"
|
||||
FileTypeCsv FileType = "csv"
|
||||
)
|
||||
|
||||
func (a *App) PerformExport(jsonData string) bool {
|
||||
var info ExportInfo
|
||||
err := json.Unmarshal([]byte(jsonData), &info)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.ErrorDialog,
|
||||
Title: "Could not unmarshal JSON",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
hosts, err := a.Hosts()
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.ErrorDialog,
|
||||
Title: "Could not retrieve hosts",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return false
|
||||
}
|
||||
host := hosts[info.HostKey]
|
||||
|
||||
switch info.Type {
|
||||
case ExportTypeExport:
|
||||
if !a.Env.HasMongoExport {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.ErrorDialog,
|
||||
Title: "You need to install mongoexport to perform an export.",
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
args := make([]string, 0)
|
||||
args = append(args, fmt.Sprintf(`--uri="%v"`, host.URI))
|
||||
args = append(args, fmt.Sprintf(`--type="%v"`, info.FileType))
|
||||
|
||||
if info.DbKey != "" {
|
||||
args = append(args, fmt.Sprintf(`--db="%v"`, info.DbKey))
|
||||
|
||||
if info.CollKeys != nil {
|
||||
args = append(args, fmt.Sprintf(`--collection="%v"`, info.CollKeys[0]))
|
||||
}
|
||||
}
|
||||
|
||||
args = append(args, fmt.Sprintf(`--out="%v.%v"`, path.Join(info.OutDir, info.Filename), info.FileType))
|
||||
cmd := exec.Command("mongoexport", args...)
|
||||
var stdout strings.Builder
|
||||
var stderr strings.Builder
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
err = cmd.Run()
|
||||
|
||||
fmt.Println(args)
|
||||
fmt.Println(stdout.String())
|
||||
fmt.Println(stderr.String())
|
||||
fmt.Println(err)
|
||||
|
||||
case ExportTypeDump:
|
||||
if !a.Env.HasMongoDump {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.ErrorDialog,
|
||||
Title: "You need to install mongodump to perform a dump.",
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
default:
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.ErrorDialog,
|
||||
Title: "Unrecognised export type",
|
||||
Message: string(info.Type),
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
return err == nil
|
||||
}
|
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
@ -16,12 +17,8 @@ type Host struct {
|
||||
URI string `json:"uri"`
|
||||
}
|
||||
|
||||
func updateHostsFile(newData map[string]Host) error {
|
||||
filePath, err := appDataFilePath("hosts.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func updateHostsFile(a *App, newData map[string]Host) error {
|
||||
filePath := path.Join(a.Env.DataDirectory, "hosts.json")
|
||||
jsonData, err := json.MarshalIndent(newData, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
@ -32,12 +29,7 @@ func updateHostsFile(newData map[string]Host) error {
|
||||
}
|
||||
|
||||
func (a *App) Hosts() (map[string]Host, error) {
|
||||
filePath, err := appDataFilePath("hosts.json")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filePath := path.Join(a.Env.DataDirectory, "hosts.json")
|
||||
jsonData, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
// It's ok if the file cannot be opened, for example if it is not accessible.
|
||||
@ -90,7 +82,7 @@ func (a *App) AddHost(jsonData string) error {
|
||||
}
|
||||
|
||||
hosts[id.String()] = newHost
|
||||
err = updateHostsFile(hosts)
|
||||
err = updateHostsFile(a, hosts)
|
||||
if err != nil {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.InfoDialog,
|
||||
@ -123,7 +115,7 @@ func (a *App) UpdateHost(hostKey string, jsonData string) error {
|
||||
}
|
||||
|
||||
hosts[hostKey] = host
|
||||
err = updateHostsFile(hosts)
|
||||
err = updateHostsFile(a, hosts)
|
||||
if err != nil {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.InfoDialog,
|
||||
@ -157,7 +149,7 @@ func (a *App) RemoveHost(key string) error {
|
||||
}
|
||||
|
||||
delete(hosts, key)
|
||||
err = updateHostsFile(hosts)
|
||||
err = updateHostsFile(a, hosts)
|
||||
|
||||
if err != nil {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
|
@ -2,71 +2,33 @@ package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
goRuntime "runtime"
|
||||
"path"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
type Settings struct {
|
||||
DefaultLimit int64 `json:"defaultLimit"`
|
||||
DefaultSort string `json:"defaultSort"`
|
||||
AutosubmitQuery bool `json:"autosubmitQuery"`
|
||||
DefaultLimit int64 `json:"defaultLimit"`
|
||||
DefaultSort string `json:"defaultSort"`
|
||||
AutosubmitQuery bool `json:"autosubmitQuery"`
|
||||
DefaultExportDirectory string `json:"defaultExportDirectory"`
|
||||
}
|
||||
|
||||
func NewSettings() Settings {
|
||||
func NewSettings(a *App) Settings {
|
||||
return Settings{
|
||||
DefaultLimit: 20,
|
||||
DefaultSort: `{ "_id": 1 }`,
|
||||
AutosubmitQuery: true,
|
||||
DefaultLimit: 20,
|
||||
DefaultSort: `{ "_id": 1 }`,
|
||||
AutosubmitQuery: true,
|
||||
DefaultExportDirectory: path.Join(a.Env.HomeDirectory, "Downloads"),
|
||||
}
|
||||
}
|
||||
|
||||
func appDataDirectory() (string, error) {
|
||||
var err error
|
||||
homeDir, err := os.UserHomeDir()
|
||||
prefDir := ""
|
||||
|
||||
switch goRuntime.GOOS {
|
||||
case "windows":
|
||||
prefDir = filepath.Join(homeDir, "/AppData/Local/Rolens")
|
||||
case "darwin":
|
||||
prefDir = filepath.Join(homeDir, "/Library/Application Support/Rolens")
|
||||
case "linux":
|
||||
prefDir = filepath.Join(homeDir, "/.config/Rolens")
|
||||
default:
|
||||
err = errors.New("unsupported platform")
|
||||
}
|
||||
|
||||
_ = os.MkdirAll(prefDir, os.ModePerm)
|
||||
return prefDir, err
|
||||
}
|
||||
|
||||
func appDataFilePath(filename string) (string, error) {
|
||||
dir, err := appDataDirectory()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
path := filepath.Join(dir, filename)
|
||||
return path, nil
|
||||
}
|
||||
|
||||
func (a *App) Settings() Settings {
|
||||
s := NewSettings()
|
||||
filePath, err := appDataFilePath("settings.json")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.ErrorDialog,
|
||||
Title: "Could not retrieve application settings, using defaults!",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return s
|
||||
}
|
||||
s := NewSettings(a)
|
||||
filePath := path.Join(a.Env.DataDirectory, "settings.json")
|
||||
|
||||
jsonData, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
@ -105,16 +67,6 @@ func (a *App) UpdateSettings(jsonData string) Settings {
|
||||
return s
|
||||
}
|
||||
|
||||
filePath, err := appDataFilePath("settings.json")
|
||||
if err != nil {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.InfoDialog,
|
||||
Title: "Could not update settings.json",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
newJson, err := json.MarshalIndent(s, "", "\t")
|
||||
if err != nil {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
@ -125,6 +77,7 @@ func (a *App) UpdateSettings(jsonData string) Settings {
|
||||
return s
|
||||
}
|
||||
|
||||
filePath := path.Join(a.Env.DataDirectory, "settings.json")
|
||||
err = ioutil.WriteFile(filePath, newJson, os.ModePerm)
|
||||
if err != nil {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
@ -54,11 +55,8 @@ var BuiltInListView = View{
|
||||
|
||||
type ViewStore map[string]View
|
||||
|
||||
func updateViewStore(newData ViewStore) error {
|
||||
filePath, err := appDataFilePath("views.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func updateViewStore(a *App, newData ViewStore) error {
|
||||
filePath := path.Join(a.Env.DataDirectory, "settings.json")
|
||||
|
||||
jsonData, err := json.MarshalIndent(newData, "", "\t")
|
||||
if err != nil {
|
||||
@ -71,11 +69,7 @@ func updateViewStore(newData ViewStore) error {
|
||||
|
||||
func (a *App) Views() (ViewStore, error) {
|
||||
views := make(ViewStore, 0)
|
||||
filePath, err := appDataFilePath("views.json")
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
return views, err
|
||||
}
|
||||
filePath := path.Join(a.Env.DataDirectory, "views.json")
|
||||
|
||||
jsonData, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
@ -108,7 +102,7 @@ func (a *App) UpdateViewStore(jsonData string) error {
|
||||
return errors.New("invalid JSON")
|
||||
}
|
||||
|
||||
err = updateViewStore(viewStore)
|
||||
err = updateViewStore(a, viewStore)
|
||||
if err != nil {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
Type: runtime.InfoDialog,
|
||||
@ -142,7 +136,7 @@ func (a *App) RemoveView(viewKey string) error {
|
||||
}
|
||||
|
||||
delete(views, viewKey)
|
||||
err = updateViewStore(views)
|
||||
err = updateViewStore(a, views)
|
||||
|
||||
if err != nil {
|
||||
runtime.MessageDialog(a.ctx, runtime.MessageDialogOptions{
|
||||
|
Reference in New Issue
Block a user