Files
stash/internal/desktop/desktop.go
WithoutPants a6f15273d9 Improve Windows stash behaviour (#2543)
* Rename manager.instance to Manager
* Show dialog message on fatal error on Windows
* Hide console windows explicitly on icon launch

Gets rid of the windowsgui flag, which causes all sorts of issues.
Instead, checks if stash was launched from the icon, and if so hides the console.

* Remove fixconsole
* Add changelog entries
2022-05-04 10:37:32 +10:00

175 lines
3.9 KiB
Go

package desktop
import (
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"runtime"
"strconv"
"strings"
"github.com/pkg/browser"
"github.com/stashapp/stash/internal/manager/config"
"github.com/stashapp/stash/pkg/fsutil"
"github.com/stashapp/stash/pkg/logger"
"golang.org/x/term"
)
type ShutdownHandler interface {
Shutdown(code int)
}
type FaviconProvider interface {
GetFavicon() []byte
GetFaviconPng() []byte
}
// Start starts the desktop icon process. It blocks until the process exits.
// MUST be run on the main goroutine or will have no effect on macOS
func Start(shutdownHandler ShutdownHandler, faviconProvider FaviconProvider) {
if IsDesktop() {
hideConsole()
c := config.GetInstance()
if !c.GetNoBrowser() {
openURLInBrowser("")
}
writeStashIcon(faviconProvider)
startSystray(shutdownHandler, faviconProvider)
}
}
// openURLInBrowser opens a browser to the Stash UI. Path can be an empty string for main page.
func openURLInBrowser(path string) {
// This can be done before actually starting the server, as modern browsers will
// automatically reload the page if a local port is closed at page load and then opened.
serverAddress := getServerURL(path)
err := browser.OpenURL(serverAddress)
if err != nil {
logger.Error("Could not open browser: " + err.Error())
}
}
func SendNotification(title string, text string) {
if IsDesktop() {
c := config.GetInstance()
if c.GetNotificationsEnabled() {
sendNotification(title, text)
}
}
}
func IsDesktop() bool {
if isDoubleClickLaunched() {
fmt.Println("double click launched")
return true
}
// Check if running under root
if os.Getuid() == 0 {
return false
}
// Check if stdin is a terminal
if term.IsTerminal(int(os.Stdin.Fd())) {
return false
}
if isService() {
return false
}
if IsServerDockerized() {
return false
}
return true
}
func IsServerDockerized() bool {
return isServerDockerized()
}
// writeStashIcon writes the current stash logo to config/icon.png
func writeStashIcon(faviconProvider FaviconProvider) {
c := config.GetInstance()
if !c.IsNewSystem() {
iconPath := path.Join(c.GetConfigPath(), "icon.png")
err := ioutil.WriteFile(iconPath, faviconProvider.GetFaviconPng(), 0644)
if err != nil {
logger.Errorf("Couldn't write icon file: %s", err.Error())
}
}
}
// IsAllowedAutoUpdate tries to determine if the stash binary was installed from a
// package manager or if touching the executable is otherwise a bad idea
func IsAllowedAutoUpdate() bool {
// Only try to update if downloaded from official sources
if !config.IsOfficialBuild() {
return false
}
// Avoid updating if installed from package manager
if runtime.GOOS == "linux" {
executablePath, err := os.Executable()
if err != nil {
logger.Errorf("Cannot get executable path: %s", err)
return false
}
executablePath, err = filepath.EvalSymlinks(executablePath)
if err != nil {
logger.Errorf("Cannot get executable path: %s", err)
return false
}
if fsutil.IsPathInDir("/usr", executablePath) || fsutil.IsPathInDir("/opt", executablePath) {
return false
}
if isServerDockerized() {
return false
}
}
return true
}
func getIconPath() string {
return path.Join(config.GetInstance().GetConfigPath(), "icon.png")
}
func RevealInFileManager(path string) {
exists, err := fsutil.FileExists(path)
if err != nil {
logger.Errorf("Error checking file: %s", err)
return
}
if exists && IsDesktop() {
revealInFileManager(path)
}
}
func getServerURL(path string) string {
c := config.GetInstance()
serverAddress := c.GetHost()
if serverAddress == "0.0.0.0" {
serverAddress = "localhost"
}
serverAddress = serverAddress + ":" + strconv.Itoa(c.GetPort())
proto := ""
if c.HasTLSConfig() {
proto = "https://"
} else {
proto = "http://"
}
serverAddress = proto + serverAddress + "/"
if path != "" {
serverAddress += strings.TrimPrefix(path, "/")
}
return serverAddress
}