Second commit

This commit is contained in:
Jeffrey Serio 2021-10-26 11:13:24 -05:00
parent 623213e765
commit cea4163dd6
4 changed files with 259 additions and 1 deletions

View File

@ -1,3 +1,7 @@
# go-hyperfocus # go-hyperfocus
> Work-In-Progress: Do not use this software. It doesn't work yet. I haven't even compiled it once, so there are likely to be logic errors, and some features aren't fully implemented.
Block distracting websites and hyperfocus on your tasks! 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 memory-efficient and to allow the user somewhat more freedom in defining distractors than its predecessor.

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module git.envs.net/hyperreal/go-hyperfocus
go 1.17
require github.com/akamensky/argparse v1.3.1

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/akamensky/argparse v1.3.1 h1:kP6+OyvR0fuBH6UhbE6yh/nskrDEIQgEA1SUXDPjx4g=
github.com/akamensky/argparse v1.3.1/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA=

247
main.go Normal file
View File

@ -0,0 +1,247 @@
package main
import (
"bufio"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"os/signal"
"os/user"
"runtime"
"strings"
"time"
"github.com/akamensky/argparse"
)
const (
redirectTo = "127.0.0.1"
marker = "## MANAGED BY HYPERFOCUS ##\n"
runningOS = runtime.GOOS
)
var distractorsFile string = os.Getenv("HOME") + ".hyperfocus_distractors"
func getHostFile() string {
var hostFile string
switch runningOS {
case "windows":
hostFile = "/Windows/System32/drivers/etc/hosts"
default:
hostFile = "/etc/hosts"
}
return hostFile
}
func resetNetwork(message string) {
switch runningOS {
case "windows":
cmd := exec.Command("ipconfig /flushdns")
if err := cmd.Run(); err != nil {
log.Fatalln(err)
}
fmt.Println(message)
case "darwin":
cmd := exec.Command("dscacheutil", "-flushcache")
if err := cmd.Run(); err != nil {
log.Fatalln(err)
}
fmt.Println(message)
case "linux":
var (
usingDnsmasq bool = false
usingResolved bool = false
)
// Detect if using dnsmasq
out, err := exec.Command("systemctl", "is-active", "dnsmasq").Output()
if err != nil {
log.Fatalln(err)
}
if string(out) == "active" {
usingDnsmasq = true
}
// Detect if using systemd-resolved
out, err = exec.Command("systemctl", "is-active", "systemd-resolved").Output()
if err != nil {
log.Fatalln(err)
}
if string(out) == "active" {
usingResolved = true
}
// Restart networking service
if usingDnsmasq {
cmd := exec.Command("systemctl", "restart", "dnsmasq")
if err := cmd.Run(); err != nil {
log.Fatalln(err)
}
}
if usingResolved {
cmd := exec.Command("resolvectl", "flush-caches")
if err := cmd.Run(); err != nil {
log.Fatalln(err)
}
}
fmt.Println(message)
}
}
func isRoot() bool {
currUser, err := user.Current()
if err != nil {
log.Fatalf("[Super user check] Unable to get current user: %s\n", err)
}
return currUser.Username == "root"
}
// Disables access to websites that are defined as 'distractors'
func improveFocus() {
hostFile, err := os.OpenFile(getHostFile(), os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
log.Fatalln(err)
}
defer hostFile.Close()
userDistractorsFile, err := os.Open(distractorsFile)
if err != nil {
log.Fatalln(err)
}
defer userDistractorsFile.Close()
if _, err := hostFile.WriteString(marker); err != nil {
log.Fatalln(err)
}
scanner := bufio.NewScanner(userDistractorsFile)
for scanner.Scan() {
var hostLine string = fmt.Sprintf("127.0.0.1\t%s\n", scanner.Text())
if _, err := hostFile.WriteString(hostLine); err != nil {
log.Fatalln(err)
}
}
if _, err := hostFile.WriteString(marker); err != nil {
log.Fatalln(err)
}
resetNetwork("Focus is now improved 😊")
}
// Enables access to websites that are defined as 'distractors'
func loseFocus() {
hostFileContent, err := ioutil.ReadFile(getHostFile())
if err != nil {
log.Fatalln(err)
}
hostFileSlice := strings.Split(string(hostFileContent), marker)
hostFileSlice = append(hostFileSlice[:1], hostFileSlice[2:]...)
hostFileBytes := []byte(strings.Join(hostFileSlice, ""))
if err := ioutil.WriteFile(getHostFile(), hostFileBytes, 0666); err != nil {
log.Fatalln(err)
}
resetNetwork("Focus is now lost 🤪")
}
// Enables temporarily breaking concentration
func takeBreak(minutes int) {
fmt.Println()
fmt.Println("Your (probably) well-deserved break is commencing...")
loseFocus()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
s := <-c
t := minutes * 60
for i := t; i > 0; i-- {
fmt.Printf("%d seconds remaining", i)
time.Sleep(time.Second)
if s == os.Interrupt {
break
}
}
improveFocus()
fmt.Println("Welcome back to hyperfocus mode 😊 ")
}
// Prints the current list of distractors to be blocked
func listDistractors() {
userDistractorsFile, err := os.Open(distractorsFile)
if err != nil {
log.Fatalln(err)
}
defer userDistractorsFile.Close()
scanner := bufio.NewScanner(userDistractorsFile)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
// Adds predefined distractors to .hyperfocus_distractors file
func addPredefinedDistractors() {
}
func main() {
parser := argparse.NewParser("hf", "Block distracting websites and hyperfocus on your work")
improveCmd := parser.NewCommand("improve", "Improve focus, block the distractors")
loseCmd := parser.NewCommand("lose", "Lose focus, unblock the distractors")
breakCmd := parser.NewCommand("break", "Take a break for a number of minutes")
minutesForBreak := breakCmd.Int("", "minutes", &argparse.Options{Help: "Number of minutes to break for."})
listCmd := parser.NewCommand("list", "List the distractors defined in the block file (~/.hyperfocus_distractors)")
predefinedCmd := parser.NewCommand("predefined", "Add predefined set of distractors to block file")
err := parser.Parse(os.Args)
if err != nil {
fmt.Print(parser.Usage(err))
}
if improveCmd.Happened() {
improveFocus()
} else if loseCmd.Happened() {
loseFocus()
} else if breakCmd.Happened() {
takeBreak(*minutesForBreak)
} else if listCmd.Happened() {
listDistractors()
} else if predefinedCmd.Happened() {
addPredefinedDistractors()
} else {
log.Fatalln("Unknown command")
}
}