package backend import ( "encoding/json" "errors" "fmt" "os" "os/exec" "path/filepath" "time" "git.noctra.dev/noctra/servtex/globals" ) // Returns the current time in the timezone specified in the config file func GetLocalTime() time.Time { timezone, _ := time.LoadLocation(globals.AppConfig.Timezone) return time.Now().In(timezone) } // Returns the current localtime in the RFC3339 format func GetLocalTimeRFC() string { return GetLocalTime().Format(time.RFC3339) } func GetLocalTimeLog() string { return GetLocalTime().Format("2006/01/02 15:04:05") } // Returns the current localtime in custom pretty print format func GetLocalTimePretty() string { return GetLocalTime().Format("02.01.2006 15:04") } // Writes to log and prints to screen func LogLine(message string) { logline := GetLocalTimeLog() + " ServTeX: " + message + "\n" fmt.Print(logline) globals.LogFile.WriteString(logline) } // Helper for configReader() that does the actual reading // // Also validates the populated fields func configReaderParse(filePath string, configOptionStorage *globals.Config) error { jsonData, err := os.ReadFile(filePath) if err == nil { if err = json.Unmarshal(jsonData, &configOptionStorage); err != nil { return errors.New("Config file could not be read") } } else { return errors.New("Config file does not exist") } return configValidator(*configOptionStorage) } func configValidator(config globals.Config) error { return nil } // Reads config file and stores the options in configOptionStorage // // Tries the following paths // executable/path/configFileName // %LOCALAPPDATA%\servtex\configFileName // ~/.config/servtex/configFileName func ConfigReader(configFileName string, configOptionStorage *globals.Config) error { exePath, err := os.Executable() if err == nil { path := filepath.Join(filepath.Dir(exePath), configFileName) err = configReaderParse(path, configOptionStorage) if err == nil { return nil } } localappdata := os.Getenv("LOCALAPPDATA") if localappdata != "" { path := filepath.Join(localappdata, "servtex", configFileName) err = configReaderParse(path, configOptionStorage) if err == nil { return nil } } path := filepath.Join("~", ".config", "servtex", configFileName) err = configReaderParse(path, configOptionStorage) if err == nil { return nil } return err } // Watches a specified directory and calls a function on change // // Optionally, a minimum time to wait for consecutive changes can be specified func ChangeWatch(path string, callOnChange func()) { LogLine("File change noticed") } // Intended to be run as goroutine func LatexCompile(config globals.Config, execution *globals.LatexExecution) error { if execution.ExecutionLock.TryLock() { defer execution.ExecutionLock.Unlock() } else { LogLine("LaTeX execution already underway") return errors.New("Execution already in progress") } LogLine("LaTeX execution started") execution.ExecutionState = "Started" var latexCommand *exec.Cmd switch config.LatexEngine { case "lualatex": latexCommand = exec.Command( "lualatex", "-output-directory=" + config.LatexOutputPath, "-jobname=servtex", config.LatexSourceFilePath, ) default: execution.ExecutionState = "Unknown Latex Engine" execution.Output = []byte{} execution.Timestamp = GetLocalTimePretty() return errors.New("Unknown Latex Engine") } execution.ExecutionState = "Running" stdout, err := latexCommand.Output() if err != nil { execution.ExecutionState = "Failed" return err } execution.Output = stdout execution.Timestamp = GetLocalTimePretty() execution.ExecutionState = "Done" return nil }