diff --git a/README.md b/README.md index 8e5759a..71aa6ac 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,19 @@ # go-hyperfocus -> Work-In-Progress: Not tested on Windows; there are some file paths I need to fix before it can work. +> Work-In-Progress: Not tested on macOS, *BSD, or Solaris. 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 be cleaner and simpler than its predecessor. ## Installation + ```bash go install git.envs.net/hyperreal/go-hyperfocus@latest ``` + +## Usage + +```bash +sudo go-hyperfocus --help +``` diff --git a/main.go b/main.go index b7686c9..c1ee1af 100644 --- a/main.go +++ b/main.go @@ -17,11 +17,7 @@ import ( "github.com/akamensky/argparse" ) -var ( - distractorsFile string = "/etc/hf_distractors" - predefDistractorsFile string = "/etc/hf_predef_distractors" -) - +// TODO: Figure out what to do with this const resetDNSMsg string = ` Note that you may need to flush your system's DNS cache for changes to take effect. In most cases this could be done by restarting the resolver daemon. @@ -30,6 +26,8 @@ macOS: open terminal and run "sudo dscacheutil -flushcache" Linux with Systemd: open terminal and run "sudo systemctl restart systemd-resolved" Other init systems or *BSD: You probably already know how to do this.` +var localFilePaths = make(map[string]string, 4) + // Check if exists on the host filesystem func fileExists(path string) bool { @@ -37,15 +35,32 @@ func fileExists(path string) bool { return !errors.Is(err, os.ErrNotExist) } +func getLocalFilePaths() { + + switch runtime.GOOS { + case "windows": + localFilePaths["hosts"] = filepath.Clean("C:\\Windows\\System32\\drivers\\etc\\hosts") + localFilePaths["hostsBackup"] = filepath.Clean("C:\\Windows\\System32\\drivers\\etc\\hosts.backup") + localFilePaths["uDistractors"] = filepath.Clean(os.Getenv("HOME") + "\\.hf_distractors") + localFilePaths["pDistractors"] = filepath.Clean(os.Getenv("HOME") + "\\.hf_predef_distractors") + + default: + localFilePaths["hosts"] = filepath.Clean("/etc/hosts") + localFilePaths["hostsBackup"] = filepath.Clean("/etc/.hosts.backup") + localFilePaths["uDistractors"] = filepath.Clean("/etc/hf_distractors") + localFilePaths["pDistractors"] = filepath.Clean("/etc/hf_predef_distractors") + } +} + // Copy src to dest func copyFile(src string, dest string) error { - origFile, err := os.Open(filepath.Clean(src)) + origFile, err := os.Open(src) if err != nil { return fmt.Errorf("could not open original file %s for copying: %s", src, err) } - backupFile, err := os.OpenFile(filepath.Clean(dest), os.O_CREATE|os.O_WRONLY, 0666) + backupFile, err := os.OpenFile(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) } @@ -58,49 +73,54 @@ func copyFile(src string, dest string) error { return nil } -// Return system's host file as string -func getHostFile() string { - - var hostFile string - switch runtime.GOOS { - case "windows": - hostFile = "/Windows/System32/drivers/etc/hosts" - - default: - hostFile = "/etc/hosts" - } - - return hostFile -} - // Check if running as super user func isRoot() bool { - currUser, err := user.Current() - if err != nil { - log.Fatalf("[Super user check] Unable to get current user: %s\n", err) + var isSu bool + switch runtime.GOOS { + case "windows": + _, err := os.Open("\\\\.\\PHYSICALDRIVE0") + if err != nil { + isSu = false + } else { + isSu = true + } + + default: + currUser, err := user.Current() + if err != nil { + log.Fatalf("[Super user check] Unable to get current user: %s\n", err) + } + isSu = currUser.Username == "root" } - return currUser.Username == "root" + return isSu } // Disables access to websites that are defined as 'distractors' func improveFocus() { + var displayMsg bool = false + + // If first run, display resetDNSMsg + if !fileExists(localFilePaths["hostsBackup"]) { + displayMsg = true + } + // Backup host file if a backup does not already exist - if !fileExists("/etc/.hosts.backup") { - if err := copyFile(getHostFile(), "/etc/.hosts.backup"); err != nil { + if !fileExists(localFilePaths["hostsBackup"]) { + if err := copyFile(localFilePaths["hosts"], localFilePaths["hostsBackup"]); err != nil { log.Fatalln(err) } } // Open host file for writing/appending - hostFile, err := os.OpenFile(getHostFile(), os.O_APPEND|os.O_WRONLY, 0666) + hostFileObj, err := os.OpenFile(localFilePaths["hosts"], os.O_APPEND|os.O_WRONLY, 0666) if err != nil { log.Fatalln(err) } defer func() { - if err := hostFile.Close(); err != nil { + if err := hostFileObj.Close(); err != nil { log.Printf("Error closing file: %s\n", err) } }() @@ -114,9 +134,9 @@ func improveFocus() { // 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(filepath.Clean(distractorsFile)) { + if fileExists(localFilePaths["uDistractors"]) { - distractorsFileObj, err := os.Open(filepath.Clean(distractorsFile)) + distractorsFileObj, err := os.Open(localFilePaths["uDistractors"]) if err != nil { log.Fatalln(err) } @@ -129,7 +149,7 @@ func improveFocus() { scanner := bufio.NewScanner(distractorsFileObj) for scanner.Scan() { var hostLine string = fmt.Sprintf("127.0.0.1\t%s\n", scanner.Text()) - if _, err := hostFile.WriteString(hostLine); err != nil { + if _, err := hostFileObj.WriteString(hostLine); err != nil { log.Fatalln(err) } } @@ -139,9 +159,9 @@ func improveFocus() { // 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(filepath.Clean(predefDistractorsFile)) { + if fileExists(localFilePaths["pDistractors"]) { - predefDistractorsFileObj, err := os.Open(filepath.Clean(predefDistractorsFile)) + predefDistractorsFileObj, err := os.Open(localFilePaths["pDistractors"]) if err != nil { log.Fatalln(err) } @@ -154,7 +174,7 @@ func improveFocus() { scanner := bufio.NewScanner(predefDistractorsFileObj) for scanner.Scan() { var hostLine string = fmt.Sprintf("127.0.0.1\t%s\n", scanner.Text()) - if _, err := hostFile.WriteString(hostLine); err != nil { + if _, err := hostFileObj.WriteString(hostLine); err != nil { log.Fatalln(err) } } @@ -169,18 +189,21 @@ func improveFocus() { } fmt.Println("Focus is now improved 😊") + if displayMsg { + fmt.Println(resetDNSMsg) + } } // Enables access to websites that are defined as 'distractors' func loseFocus() { // Remove the current /etc/hosts file before restoring the backup. - if err := os.Remove(getHostFile()); err != nil { + if err := os.Remove(localFilePaths["hosts"]); err != nil { log.Fatalln(err) } // Restore the backup of /etc/hosts - if err := copyFile("/etc/.hosts.backup", getHostFile()); err != nil { + if err := copyFile(localFilePaths["hostsBackup"], localFilePaths["hosts"]); err != nil { log.Fatalln(err) } @@ -213,37 +236,37 @@ func takeBreak(minutes int) { func listDistractors() { // Open /etc/hf_distractors and store it as *os.File type - userDistractorsFile, err := os.Open(filepath.Clean(distractorsFile)) + userDistractorsFileObj, err := os.Open(localFilePaths["uDistractors"]) if err != nil { fmt.Println(err) } defer func() { - if err := userDistractorsFile.Close(); err != nil { - log.Printf("Error closing file: %s\n", err) + if err := userDistractorsFileObj.Close(); err != nil { + fmt.Printf("Error closing file: %s\n", err) } }() // Initialize a new scanner, scan /etc/hf_distractors, and print to // stdout line by line. - scanner := bufio.NewScanner(userDistractorsFile) + scanner := bufio.NewScanner(userDistractorsFileObj) for scanner.Scan() { fmt.Println(scanner.Text()) } // Open /etc/hf_predef_distractors and store it as *os.File type - predefDistractorsFile, err := os.Open(filepath.Clean(predefDistractorsFile)) + predefDistractorsFileObj, err := os.Open(localFilePaths["pDistractors"]) if err != nil { fmt.Println(err) } defer func() { - if err := predefDistractorsFile.Close(); err != nil { - log.Printf("Error closing file: %s\n", err) + if err := predefDistractorsFileObj.Close(); err != nil { + fmt.Printf("Error closing file: %s\n", err) } }() // Initialize a new scanner, scan /etc/hf_predef_distractors, and print to // stdout line by line. - scanner = bufio.NewScanner(predefDistractorsFile) + scanner = bufio.NewScanner(predefDistractorsFileObj) for scanner.Scan() { fmt.Println(scanner.Text()) } @@ -376,7 +399,8 @@ func addPredefinedDistractors() { } // Open or create /etc/hf_predef_distractors and store it in *os.File type - predefDistractorsFileObj, err := os.OpenFile(filepath.Clean(predefDistractorsFile), os.O_CREATE|os.O_WRONLY, 0666) + fmt.Println(localFilePaths["pDistractors"]) + predefDistractorsFileObj, err := os.OpenFile(localFilePaths["pDistractors"], os.O_CREATE|os.O_WRONLY, 0666) if err != nil { log.Fatalln(err) } @@ -414,6 +438,8 @@ func main() { if isRoot() { + getLocalFilePaths() + err := parser.Parse(os.Args) if err != nil { fmt.Print(parser.Usage(err))