diff --git a/README.md b/README.md index 03d1cf3..a3a67d1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,12 @@ # go-hyperfocus -> Work-In-Progress: Do not use this software. It doesn't work yet. There are likely to be logic errors, and some features aren't fully implemented. +> Work-In-Progress: Not tested on Windows; there are some file paths I need to fix before it can work. Block distracting websites and hyperfocus on your tasks! This is a Go implementation of the Python-written [concentration](https://github.com/timothycrosley/concentration) program. This program aims to allow the user somewhat more freedom in defining distractors than its predecessor. + +## Installation +```bash +go install git.envs.net/hyperreal/go-hyperfocus@latest +``` diff --git a/main.go b/main.go index a8053ef..7657ca9 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "context" "errors" "fmt" "io" @@ -9,6 +10,7 @@ import ( "os" "os/signal" "os/user" + "path/filepath" "runtime" "time" @@ -16,9 +18,8 @@ import ( ) var ( - distractorsFile string = "/etc/hyperfocus_distractors" - predefDistractorsFile string = "/etc/hyperfocus_distractors_predefined" - hostBackupFile string = "/etc/.backup_hosts" + distractorsFile string = "/etc/hf_distractors" + predefDistractorsFile string = "/etc/hf_predef_distractors" ) const resetDNSMsg string = ` @@ -39,12 +40,12 @@ func fileExists(path string) bool { // Copy src to dest func copyFile(src string, dest string) error { - origFile, err := os.Open(src) + origFile, err := os.Open(filepath.Clean(src)) if err != nil { return fmt.Errorf("could not open original file %s for copying: %s", src, err) } - backupFile, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY, 0666) + backupFile, err := os.OpenFile(filepath.Clean(dest), os.O_CREATE|os.O_WRONLY, 0666) if err != nil { return fmt.Errorf("could not open backup file %s for writing: %s", dest, err) } @@ -87,8 +88,8 @@ func isRoot() bool { func improveFocus() { // Backup host file if a backup does not already exist - if !fileExists(hostBackupFile) { - if err := copyFile(getHostFile(), hostBackupFile); err != nil { + if !fileExists("/etc/.hosts.backup") { + if err := copyFile(getHostFile(), "/etc/.hosts.backup"); err != nil { log.Fatalln(err) } } @@ -98,7 +99,11 @@ func improveFocus() { if err != nil { log.Fatalln(err) } - defer hostFile.Close() + defer func() { + if err := hostFile.Close(); err != nil { + log.Printf("Error closing file: %s\n", err) + } + }() // For checking if /etc/hyperfocus_distractors or /etc/hyperfocus_distractors_predefined // exist. @@ -107,15 +112,19 @@ func improveFocus() { predefDistractorsFileWarn bool ) - // If /etc/hyperfocus_distractors exists, take each host from it and append it + // If /etc/hf_distractors exists, take each host from it and append it // to /etc/hosts for blocking. Else set distractorsFileWarn to true. - if fileExists(distractorsFile) { + if fileExists(filepath.Clean(distractorsFile)) { - distractorsFileObj, err := os.Open(distractorsFile) + distractorsFileObj, err := os.Open(filepath.Clean(distractorsFile)) if err != nil { log.Fatalln(err) } - defer distractorsFileObj.Close() + defer func() { + if err := distractorsFileObj.Close(); err != nil { + log.Printf("Error closing file: %s\n", err) + } + }() scanner := bufio.NewScanner(distractorsFileObj) for scanner.Scan() { @@ -128,15 +137,19 @@ func improveFocus() { distractorsFileWarn = true } - // If /etc/hyperfocus_distractors_predefined exists, take each host from it and, + // If /etc/hf_predef_distractors exists, take each host from it and, // append it to /etc/hosts for blocking. Else set predefDistractorsFileWarn to true. - if fileExists(predefDistractorsFile) { + if fileExists(filepath.Clean(predefDistractorsFile)) { - predefDistractorsFileObj, err := os.Open(predefDistractorsFile) + predefDistractorsFileObj, err := os.Open(filepath.Clean(predefDistractorsFile)) if err != nil { log.Fatalln(err) } - defer predefDistractorsFileObj.Close() + defer func() { + if err := predefDistractorsFileObj.Close(); err != nil { + log.Printf("Error closing file: %s\n", err) + } + }() scanner := bufio.NewScanner(predefDistractorsFileObj) for scanner.Scan() { @@ -167,7 +180,7 @@ func loseFocus() { } // Restore the backup of /etc/hosts - if err := copyFile(hostBackupFile, getHostFile()); err != nil { + if err := copyFile("/etc/.hosts.backup", getHostFile()); err != nil { log.Fatalln(err) } @@ -181,57 +194,48 @@ func takeBreak(minutes int) { fmt.Println("Your (probably) well-deserved break is commencing...") loseFocus() - // Create a channel to receive os.Interrupt signal from user - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) + defer cancel() - // TODO: Read up on Goroutines and channels and figure how to 'pipe' the os.Signal - // channel to the goroutine below. + ctx, cancel = context.WithTimeout(ctx, time.Duration(minutes*60)*time.Second) + defer cancel() - // Prepare channel to receive signal. Sleep for t minus seconds, - // or break the countdown when interrupt signal is received from user, then - // improve focus again. - ticker := time.NewTicker(1 * time.Second) - done := make(chan bool) - - go func() { - for { - select { - case <-done: - return - case t := <-ticker.C: - // TODO: Figure how to get the number of seconds as integers from t - fmt.Println(t) - case <-c: - return - } - } - }() - - time.Sleep(time.Duration(minutes*60) * time.Second) - ticker.Stop() - done <- true + <-ctx.Done() improveFocus() - fmt.Println("Welcome back to hyperfocus mode 😊 ") } // Prints the current list of distractors to be blocked func listDistractors() { - for _, v := range []string{distractorsFile, predefDistractorsFile} { - - userDistractorsFile, err := os.Open(v) - if err != nil { - fmt.Println(err) + userDistractorsFile, err := os.Open(filepath.Clean(distractorsFile)) + if err != nil { + fmt.Println(err) + } + defer func() { + if err := userDistractorsFile.Close(); err != nil { + log.Printf("Error closing file: %s\n", err) } - defer userDistractorsFile.Close() + }() - scanner := bufio.NewScanner(userDistractorsFile) + scanner := bufio.NewScanner(userDistractorsFile) + for scanner.Scan() { + fmt.Println(scanner.Text()) + } - for scanner.Scan() { - fmt.Println(scanner.Text()) + predefDistractorsFile, err := os.Open(filepath.Clean(predefDistractorsFile)) + if err != nil { + fmt.Println(err) + } + defer func() { + if err := predefDistractorsFile.Close(); err != nil { + log.Printf("Error closing file: %s\n", err) } + }() + + scanner = bufio.NewScanner(predefDistractorsFile) + for scanner.Scan() { + fmt.Println(scanner.Text()) } } @@ -360,11 +364,15 @@ func addPredefinedDistractors() { "zillow.com", } - predefDistractorsFileObj, err := os.OpenFile(predefDistractorsFile, os.O_CREATE|os.O_WRONLY, 0666) + predefDistractorsFileObj, err := os.OpenFile(filepath.Clean(predefDistractorsFile), os.O_CREATE|os.O_WRONLY, 0666) if err != nil { log.Fatalln(err) } - defer predefDistractorsFileObj.Close() + defer func() { + if err := predefDistractorsFileObj.Close(); err != nil { + log.Printf("Error closing file: %s\n", err) + } + }() dataWriter := bufio.NewWriter(predefDistractorsFileObj) @@ -372,7 +380,10 @@ func addPredefinedDistractors() { _, _ = dataWriter.WriteString(v + "\n") } - dataWriter.Flush() + + if err := dataWriter.Flush(); err != nil { + log.Fatalln(err) + } } func main() {