mirror of
https://codeberg.org/hyperreal/hyperfocus
synced 2024-11-25 12:13:43 +01:00
Second commit
This commit is contained in:
parent
623213e765
commit
cea4163dd6
@ -1,3 +1,7 @@
|
||||
# go-hyperfocus
|
||||
|
||||
Block distracting websites and hyperfocus on your tasks!
|
||||
> 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!
|
||||
|
||||
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
5
go.mod
Normal 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
2
go.sum
Normal 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
247
main.go
Normal 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")
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user