pomo

package module
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 20, 2024 License: MIT Imports: 17 Imported by: 0

README

pomo-cmd

Simple command line interface for having a pomodoro inside a terminal.

Credits

Documentation

Index

Constants

View Source
const (
	Duration    = "25m"
	Break       = "5m"
	LongBreak   = "15m"
	Warn        = "1m"
	Prefix      = "🍅"
	PrefixBreak = "🧘"
	PrefixWarn  = "💢"

	// Goals
	WorkGoal = 8*time.Hour + 20*time.Minute
	RestGoal = 1*time.Hour + 40*time.Minute
)
View Source
const (
	DefaultPerms = 0600
)
View Source
const SESSION_FILENAME = "session.log"

Variables

View Source
var App = &cli.App{
	Name:                 "pomo",
	Usage:                "A pomodoro command line interface 🍅",
	EnableBashCompletion: true,
	Action: func(cCtx *cli.Context) error {
		var arg string
		if cCtx.Args().Present() {
			arg = cCtx.Args().First()
			_, err := time.ParseDuration(arg)
			if err != nil {
				return fmt.Errorf("error: the input must be like 1m, 1h, 1s, 1h30m, etc")
			}
		}

		var duration string
		if arg != "" {
			duration = arg
		} else {
			duration = conf.Query("duration")
		}

		if duration == "" {
			duration = Duration
		}

		dur, err := time.ParseDuration(duration)
		if err != nil {
			return err
		}
		now := time.Now()
		endtime := now.Add(dur).Format(time.RFC3339)

		session := Session{}

		if err := session.Current(); err != nil {
			return err
		}

		if session.isRunning() {
			if session.Type == WorkSession {
				ok := InputConfirm("[WARNING]: A session is already running, do you want to reset it?")
				if ok {
					if err := session.Remove(); err != nil {
						return err
					}
				} else {

					return nil
				}
			} else {

				if err := session.Stop(); err != nil {
					return err
				}
			}
		}

		if err := startSession(now, endtime, WorkSession); err != nil {
			return err
		}

		if err := conf.Set("prefix", Prefix); err != nil {
			return err
		}

		return nil
	},
	Commands: []*cli.Command{
		{
			Name:  "break",
			Usage: "initialize a break session",
			Action: func(cCtx *cli.Context) error {
				var arg string
				if cCtx.Args().Present() {
					arg = cCtx.Args().First()
					_, err := time.ParseDuration(arg)
					if err != nil {
						return fmt.Errorf("error: the input must be like 1m, 1h, 1s, 1h30m, etc")
					}
				}

				var duration string
				if arg != "" {
					duration = arg
				} else {
					duration = conf.Query("break")
				}

				if duration == "" {
					duration = Break
				}

				dur, err := time.ParseDuration(duration)
				if err != nil {
					return err
				}

				now := time.Now()
				endtime := now.Add(dur).Format(time.RFC3339)

				session := Session{}

				if err := session.Current(); err != nil {
					return err
				}

				if session.isRunning() {
					if session.Type == BreakSession {
						ok := InputConfirm("[WARNING]: A session is already running, do you want to reset it?")
						if ok {
							if err := session.Remove(); err != nil {
								return err
							}
						} else {

							return nil
						}
					} else {

						if err := session.Stop(); err != nil {
							return err
						}
					}
				}

				if err := startSession(now, endtime, BreakSession); err != nil {
					return err
				}

				if err := conf.Set("prefix", PrefixBreak); err != nil {
					return err
				}

				return nil
			},
		},
		{
			Name:  "stop",
			Usage: "stop the pomodoro countdown",
			Action: func(_ *cli.Context) error {
				session := Session{}

				if err := session.Current(); err != nil {
					return err
				}

				if !session.isRunning() {
					return fmt.Errorf("no session is running")
				}

				if err := session.Stop(); err != nil {
					return err
				}

				if err := conf.Del("endtime"); err != nil {
					return err
				}

				return nil
			},
		},
		{
			Name:  "print",
			Usage: "print current to standard output",
			Action: func(_ *cli.Context) error {
				endtime := conf.Query("endtime")
				if endtime == "" {
					fmt.Print("No session...")
					return nil
				}

				endt, err := time.Parse(time.RFC3339, endtime)
				if err != nil {
					return err
				}

				var subt time.Duration
				subc := conf.Query("interval")

				if subc != "" {
					subt, err = time.ParseDuration(subc)
					if err != nil {
						return err
					}
				}

				prefix := conf.Query("prefix")
				prefixWarn := conf.Query("prefix_warn")
				warn := conf.Query("warn")

				warnt, err := time.ParseDuration(warn)
				if err != nil {
					return err
				}

				sec := time.Second
				left := time.Until(endt).Round(sec)

				var sub float64
				if subc != "" {
					sub = math.Abs(math.Mod(left.Seconds(), subt.Seconds()))
				}

				if left < warnt && left%(sec*2) == 0 {

					prefix = prefixWarn
				}

				if subc != "" {
					fmt.Printf("%v %v(%02v)", prefix, StopWatchFormat(left), sub)
				} else {
					fmt.Printf("%v %v", prefix, StopWatchFormat(left))
				}

				return nil
			},
		},
		{
			Name: "init",
			Action: func(_ *cli.Context) error {
				err := conf.Init()
				if err != nil {
					log.Fatal(err)
				}

				conf.Set("duration", Duration)
				conf.Set("break", Break)
				conf.Set("long_break", LongBreak)
				conf.Set("warn", Warn)
				conf.Set("prefix", Prefix)
				conf.Set("prefix_warn", PrefixWarn)

				return nil
			},
		},
		{
			Name: "config",
			Action: func(_ *cli.Context) error {
				if err := conf.Print(); err != nil {
					return err
				}
				return nil

			},
			Subcommands: []*cli.Command{
				{
					Name:  "edit",
					Usage: "Opens the editor on the current config",
					Action: func(_ *cli.Context) error {
						return conf.Edit()
					},
				},
			},
		},
		{
			Name:  "status",
			Usage: "Displays an summary of all the sessions that was acomplished today",
			Action: func(_ *cli.Context) error {
				sessions, err := ListSessions()
				if err != nil {
					return err
				}

				todaySessions, err := filterTodaySessions(sessions)
				if err != nil {
					return err
				}

				typeDurations, _ := summarizeSessions(todaySessions)

				workDuration := typeDurations[WorkSession]
				breakDuration := typeDurations[BreakSession]

				green := color.New(color.FgGreen).SprintFunc()
				blue := color.New(color.FgBlue).SprintFunc()
				yellow := color.New(color.FgYellow).SprintFunc()

				workGoalPercent := float64(workDuration) / float64(WorkGoal) * 100

				fmt.Print("\n=== Sessions Today ===\n\n")
				fmt.Printf("Work  -> %s\n", green(formatDurationHm(workDuration)))
				fmt.Printf("Break -> %s\n", blue(formatDurationHm(breakDuration)))

				fmt.Print("\n=== Goals ===\n\n")
				fmt.Printf("Work: %s  =>  %s%%\n", yellow(formatDurationHm(WorkGoal)), yellow(fmt.Sprintf("%.2f", workGoalPercent)))
				fmt.Printf("Break: %s\n\n", yellow(formatDurationHm(RestGoal)))

				return nil
			},
		},
		{
			Name: "sessions",
			Subcommands: []*cli.Command{
				{
					Name:  "edit",
					Usage: "Opens the editor on the current sessions file",
					Action: func(_ *cli.Context) error {
						path, err := sessionPath()
						if err != nil {
							return err
						}
						return Editor(path)
					},
				},
			},
		},
	},
}

Functions

func Create

func Create(path string) error

func Editor

func Editor(path string) error

Editor opens a file with the default $EDITOR from the user system

func Exec

func Exec(command string) error

func Exists

func Exists(path string) bool

func Input

func Input(prompt string) string

func InputConfirm

func InputConfirm(prompt string) bool

func InsertLine

func InsertLine(path, newLine string) error

func InsertLineAtIndex

func InsertLineAtIndex(path, newLine string, index int) error

func List

func List(dir string) []string

List returns all files in a directory, same as `ls`

func Mkdir

func Mkdir(path string) error

func Open

func Open(path string) error

Open opens a file with the default open command from the user system

func Read

func Read(filePath string) (string, error)

Read retrieves content from a file

func ReadLines

func ReadLines(filePath string) ([]string, error)

ReadLines returns all lines from a file

func Remove

func Remove(path string) error

func RemoveAll

func RemoveAll(path string) error

rm -r

func StopWatchFormat

func StopWatchFormat(dur time.Duration) string

func Write

func Write(path string, text string) error

Write writes content to a file. It will overwrite to the file if it already exists and create the file if it does not.

func WriteAppend

func WriteAppend(path string, text string) error

WriteAppend writes content to a file. It will append to the file if it already exists and create the file if it does not.

Types

type Conf

type Conf struct {
	Id   string // usually application name
	Dir  string // usually os.UserConfigDir
	File string // usually config.yaml
}

func (Conf) Data

func (c Conf) Data() []byte

func (Conf) Del

func (c Conf) Del(key string) error

func (Conf) DirPath

func (c Conf) DirPath() string

func (Conf) Edit

func (c Conf) Edit() error

func (Conf) Init

func (c Conf) Init() error

func (Conf) OverWrite

func (c Conf) OverWrite(newconf any) error

func (Conf) Path

func (c Conf) Path() string

func (Conf) Print

func (c Conf) Print() error

func (Conf) Query

func (c Conf) Query(q string) string

Using github.com/thedevsaddam/gojsonq to query json files.

Wiki: https://github.com/thedevsaddam/gojsonq/wiki/Queries

func (Conf) QueryPrint

func (c Conf) QueryPrint(q string)

QueryPrint prints the output of Query.

func (Conf) Set

func (c Conf) Set(key string, val any) error

type Session

type Session struct {
	StartTime string
	EndTime   string
	Type      SessionType
	Filepath  string
}

func ListSessions

func ListSessions() ([]Session, error)

func (*Session) Current

func (s *Session) Current() error

func (*Session) Remove

func (s *Session) Remove() error

func (*Session) Save

func (s *Session) Save() error

func (*Session) Scan

func (s *Session) Scan(line string) error

func (*Session) Start

func (s *Session) Start() error

func (*Session) Stop

func (s *Session) Stop() error

func (*Session) String

func (s *Session) String() string

type SessionType

type SessionType string

create a enum for the session type

const (
	WorkSession      SessionType = "work"
	BreakSession     SessionType = "break"
	LongBreakSession SessionType = "longbreak"
)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL