Package: busy
BusyPersonal time management for techiesBuzz through crazy busy days with as little stress as possible. Stay focused by seeing only one task at a time. Use this simple, fast, and fun tool all day with the keyboard in a familiar terminal environment.Bee icon created by Freepik - FlaticonUsing Busy?Contact us!_Usagetl;dr:pipxinstallbusybusyPrinciplesBusy is built with the following usage principles in mind:Monotasking: We each focus better when we work on exactly one task at a time. So busy only shows you one task.Keyboard-driven: Productive people use the keyboard effectively, because muscle memory builds up over time, and it's faster to hit a key than to find an icon on a screen and move the pointer.Offline use: It's designed to run on your laptop or desktop computer, without needing an internet connection, so it works extremely fast under any conditions.Multi-platformBecause Busy is a terminal-based application, it will run on MacOS, Linux, or Windows.Personal: Busy is not a collaboration platform or project management application. It's for managing your personal time, not assigning things to others.Importance over Urgency: Stop stressing out over last-minute tasks and impending deadlines! Busy makes it easy to capture future tasks and remember to do them early enough to reduce the pressure.Editable data: The data is stored in text files, which can easily be edited outside of Busy itself. (In fact, Busy started as a todo.txt type of approach and grew from there.)The idea of Importance over Urgency comes from the book "The 7 Habits of Highly Effective People". Although we firmly disagree with Steven Covey's statements on gay rights, the book contains excellent ideas.InstallationYou'll need a terminal emulator to access a command or shell prompt. Examples include:iTerm2 or Terminal on MacOSGnome Terminal or XTerm on LinuxCMD on WindowsTerminator on all platformsBusy requirespipx, which requires Python 3.6 or later. To check whether you already have the right version of Python on your system, start your terminal emulator and type:python3 -VIf you don't have Python, or your version is out of date, install or upgrade it. In most cases, you'll want to do so using your system's package manager (such as Homebrew on MacOS or APT on Ubuntu). If you're not familiar with package managers, then download Python fromthe Python.org sitedirectly and follow the instructions provided there. When done, use the version check above to confirm it's installed and the version is 3.6.5 or greater.Python comes with PIP, which enables installation of Python packages from a central server called PyPI.Once Python and PIP are installed, type:pip3 install pipx
pipx install busyTo upgrade it later:pipx upgrade busyOverviewBusy ships with two user interfaces, both of them terminal-based and keyboard-driven:Shell UI- A command-line interface (CLI) using shell conventions and called directly from the shell, one command at a time.Curses UI- A faster, more visual interface with one-key commands that remains visible the entire time it's being used.Some commands also use your favorite terminal-based text editor, such as Emacs, vi, or Nano. It's possible to use Busy without a text editor, but functionality is limited.Busy's core model is a collection of Items, which are typically tasks but can also be discussion topics, groceries to buy, or anything else you like. Items are organized into Queues, which are named sets of Items to do. You work on the top Item in a Queue, and when it's done, that Item gets marked as "done", to reveal the next one. There is a default Queue (called "tasks") but you can also create other Queues, for example a shopping list or discussion list.Busy actually moves Items between States within each Queue. Each Queue contains a Collection (ordered list) of Items for each State. The States are:todo: Current Items for you to work on, discuss, or buy now.done: Items that have been done, with the date completed.plan: Items that have been deferred to a future date, with that date.Using the Shell UITo get started, add some tasks to your default Queue.busy add --description "Donate to the Busy project"
busy add --description "Phone mom"
busy add --description "Do the laundry"
busy add --description "Take a shower"Then, when you're ready to start your day, ask Busy what to do first:busy showReturns:Take a showerThat's the last Item you added, because Busy adds items to the top of the queue, turning it into a [LIFO stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type).When you've finished that task, mark it off to find the next task.busy finishIt will ask you to confirm that you're done. Then request the next task:busy showWhich will tell you what to do next:Do the laundryIf you want to see the whole Queue, with sequence numbers, type:busy listHere's the list you will see. Note that the completed Task is gone:1  Do the laundry
2  Phone mom
3  Donate to the Busy projectIf you decide, in the moment, to wait until later today to perform a task, drop it to the bottom of the Queue using thedropcommand:busy dropThenbusy listwill return:1  Phone mom
2  Donate to the Busy project
3  Do the laundryIf you see a task on the list that seems urgent, and you intend to perform it immediately, pop it to the top of the list:busy pop --criteria 2Our use of the term "pop" for a command doesn't quite fit with the computing term "pop". It might change in the future.Thenbusy showwill return:Donate to the Busy projectLet's say you realize that it's not an appropriate task for today, but you want to defer it to tomorrow:busy deferIt will ask you to confirm "tomorrow" as the day for deferral. Agree with it for now. The Item will then be moved into theplanState with tomorrow's date as the plan date.At the start of a new day, tell Busy to add all the previously deferred Items to the current Queue:busy activateCommandsHere's a summary of the commands in Busy.addadds a new item to the top of the queue. The item description may be included after the command or typed on the next line.showgets the top item in the queue, referred to as the "current" item.resourceshows the URL (if any) prefixed with an "@" symbolbaseis likeshow, but removes resources, followons, and tagslistlists the items in the queue in order with their sequence numbers.popmoves a task or set of items to the top of a queue.dropmoves a task or set of items to the bottom of a queue.deletepermanently removes a task or set of items from a queue.editopens a text editor to edit items - the default is to edit only the top item.manageis the same asedit, but defaults to edit the whole collection.finishmoves a task or tasks from thetodostate to thedonestate, so it's complete. Good job!defermoves a task or set of tasks from thetodostate and schedules it or them to reappear at a future date in theplanstate.activatemoves current tasks from theplanstate to thetodostate. Get to work!queuesto list all the queues.tagsto list all the tags.curseslaunches the Curses UI, and is also the default if no command is provided.Here are some of the options which apply to some or all of the commands:A queue name, which does not need an option designation--helpto find out which options apply--criteriato designate items to be acted upon, using sequence numbers or tags--yesto skip confirmation of any command that requires it--descriptionfor the item description (addcommand only)--stateto work on Items of a different state--timingapplies to thedefercommandSequence numbersSequence numbers appear in the output from thelistcommand. Note that the numbering starts with 1, and is not an ID -- the number of a item will change when the collection is modified. So always reference the most recent output from thelistcommand.Sequence numbers are used with the--criteriaoption, which can be shortened to-c. To designate more than one item, separate the sequence numbers with a space.Another choice is ranges. A range of sequence numbers is separated by a hyphen, with no whitespace, and is inclusive. For example,4-6designates items 4, 5, and 6. A hyphen without a number after it includes all the items from that item to the end of the queue. A hyphen on its own indicates the last item in the queue.Below are some examples of task designations by sequence number.busy pop -c 5pops item number 5busy drop -c 3-7drops items 3 through 7 (4 items)busy list -c 3-lists all the items from number 3 through the end of the listbusy delete -c 3 5 7 9deletes only the items designatedbusy defer -c -defers the last taskbusy edit -c -4is an error! Usebusy edit -c 1-4insteadbusy manageallows you to edit the entire queueItems will always be handled in the order they appear in the queue, regardless of the order the criteria are provided. So for example, if apopcommand designates some items, they will be moved to the top of the queue in the order, relative to each other, they currently appear in the queue.The sequence numbers in thelistcommand output are from the collection itself. So thelistcommand does not modify the sequence numbers, even when item designation is applied.TagsItems can have tags, which are space-separated hashtags in the item description. An item can have no tags, one tag, or more than one tag. For example the following item description has the tag "errands":go to the supermarket #errandsThe only punctuation that tags can contain is the hyphen ("-").Hash tags may be used as criteria in addition to sequence numbers. For example, the following command will move all the items with the#errandstag to the top of the queue.busy pop -c #errandsWhitespace-separated criteria are additive -- that is, a logical OR. For example, the following command will delete all the admin tasks, sales tasks, and tasks 3 and 4.busy delete -c #admin #sales 3 4Note to self: why does this work? Shouldn't the hash symbol indicate a comment?Default item designationsFor the most part, commands that accept item designations default to only act on the top item in the queue. The exceptions are:listandmanagedefault to handle the entire collectionpopdefaults to pop the last item in the collection to the topactivatedefaults to activateplanitems for today (more on that below)Alternate queuesBusy will manage any number of queues, which are entirely separate sets of items. For example, you might have ashoppingqueue for items to buy at the store, and amoviesqueue for films you'd like to watch. The default queue is calledtasks.To designate an alternate queue, enter it right after the command. For example:busy add shopping -d "Skimmed Milk"
busy list moviesManaging plansBusy supports several specific commands related to planning -- that is, scheduling tasks for the future. They arefinish,defer, andactivate. The task-specific commands handle items in theplanstate and, in some cases, thedonestate.The task commands accept criteria. Thedeferandfinishcommands reference thetodocollection; theactivatecommand references theplancollection. The default fordeferandfinishis the top item in the collection; the default foractivateis to activate only plans deferred to today or earlier.Planning by datePlanning is by date, not time, and is relative to the current date according to the system clock.In thedefercommand, the date can be specified using the--timingoption. If the option is omitted, then the date can be provided as input during confirmation.The date may take any of the following forms:A specific date inYYYY-MM-DDformat, such as2018-10-28. Slashes are also acceptable, but the order is always year, then month, then day.A specific date without the year inMM-DDformat, such as7-4, which will defer the item to that date in the future (even if it's in the next year).A specific day of the month as a simple integer, such as12, which will defer the item to that day of the month, in either the current month or the next month.An integer, a space, and the worddayordays, such as4 days, which will defer the item to that number of days from today.An integer without a space and the letterd, such as4d, which is a short form of4 days.The wordtomorrow, which is also the default if no date is provided.The wordtoday, which is a little odd but obvious.As an example, the following command will defer tasks 4, 5, and 6 from thetodocollection to the date 4 days from today, keeping them in theplancollection until that date.busy defer -c 4-6 -t "4 days"Note that theplancollection is keeping the task information (verbatim from thetodocollection) along with the date information (as an absolute date).To pull tasks from theplancollection and put them back into thetodocollection, use theactivatecommand. There are two ways to use theactivatecommand:With no criteria, in which case Busy activates all the tasks scheduled for today or earlier, bringing thetodolist up to dateWith designated items from theplancollection; note that theactivatecommand accepts item designation from theplanqueue itself so usebusy list -s planfirst to get the right list.Finishing and following upThefinishcommand removes the designated Task (or the top task if none is designated) from thetodostate  and adds it to thedonestate, with today's date to indicate when it was completed.Optionally, a task can have a "followon", which is another task to be added as atodoafter the first task is finished. Followons are described in a task using an arrow notation. In the following example, the task "eat" has a followon task "drink":eat --> drinkNote that the hyphens and whitespace are optional; really the marker that matters for delimiting a followon is the right angle bracket (">"). Also note that right angle bracket is not a valid character elsewhere in a task description.When thefinishcommand is executed on the task above, the "eat" task will be recorded as "done" and the "drink" task will be added to the top of thetodolist.Note that followons can be chained. For example, when thefinishcommand is run on the task illustrated below, a new task "drink > be merry" will be added to thetodocollection`. Only when that Task is finished will the "be merry" task itself appear.eat > drink > be merryRepeating tasksA special type of followon is the repeat. In this case, instead of adding the next task to the top of thetodolist, the entire current task -- including the followon itself -- is entered into theplancollection at some point in the future. Repeats allow for easy management of repeating tasks. Some examples follow.check email --> repeat in 1 dayphone mom --> repeat on sundaybalance the checkbook --> repeat on 6The exact syntax for a Repeat is the word "repeat" followed by either "on" or "in" and a relative date phrase -- the same phrases that work with thedefercommand.Note that the repetition itself only happens when thefinishcommand is executed. The completed task (i.e. "check email") is entered in thedonelist and then the entire task (with the Repeat) is scheduled in theplanlist for the appropriate time in the future.Editing itemsTheeditandmanagecommands launch the user's default text editor to directly edit a task, the whole queue, or part of a queue. Note thateditandmanageare identical commands except for their default criteria.The definition of the "default text editor" depends on the OS and configuration but here's the logic:Try the EDITOR environment variableIf that doesn't exist, try thesensible-editorcommand (Ubuntu)If that doesn't exist, try theopen -Wcommand (OSX)You must save changes and quit the editor to accept the change back into Busy.Theeditcommand with no criteria will edit the top item in the list, and themanagecommand with no criteria will edit the entire list. But it's also possible to designate items to be edited with both commands using criteria. The commands do their best to replace the edited items in place in the list order. So if youeditormanagea tag whose items are recently popped (at the top of the collection), then the edited items will still appear at the top. Even if you add items, they will be inserted after the last item in the edited set, not at the end of the queue. But all the items brought up in the editor will be edited. So if you remove an item in the editor, it will be deleted and the others will be moved up to take its place.For faster daily use - the Curses UIBusy suports multiple user interfaces. The command line interface described above is the shell interface. The alternative is the curses UI, which draws an entirely new terminal in the same window.We get it - "curses" is a terrible name. It's a reference to the underlying technology.In the Curses UI, commands can be triggered with single keystrokes, and only act on their default items (usually the top task). The UI always displays the current queue (which is alwaystasksfor now) and the current (top)todoitem` at the top of the screen.To invoke the curses UI, type:busy cursesOr it's the default so just type:busyCommands within the UI are shown with a single letter underlined. The underlined letter is the keystroke that will invoke the command. Useqto quit. When inside a command, use ctrl-C to cancel the command and return to the main menu.Data storageBusy keeps the collections in plain text files, so if the tool doesn't do something you want, you may edit the files. The files are in a directory together, referred to as the "root". Each file is the named according to the following convention:<queue>.<state>.psvIf a required file is missing, it will be created automatically. So typically, the root includestasks.todo.psv,tasks.plan.psv,tasks.done.txt, and any number of custom queue files.Technically, Busy data files are pipe-delimited data files, though thetodocollections only have one field ("description") while theplananddonefiles have only two fields (date and description).Busy is not a database (yet). There is no support for managing separate fields in the Busy tool itself.The root is designated in one of the following ways, which are tried in order.The--rootoption on any commandTheBUSY_ROOTenvironment variable, if no--rootoption is providedA directory at~/.busy, which will be generated as needed if no--rootoption orBUSY_ROOTenvironment variable are provided,Note that the--rootoption must come afterbusybut command-specific options (--yes,--to,--for, and--queue) must come after commands.The following example shows the--rootoption with command-specific options on the same command line.busy --root ~/.config/busy defer --t tuesdayNote that Busy does not support concurrency or locking in any form. If two commands are executing at the same time, they might overwrite each other. Overwriting is especially risky with theeditandmanagecommands, which keeps the user's editor open until they close it.The format is designed to be simple but not idiot-proof. Experimentation might result in unintended consequences.DevelopmentThe code is intended to demonstrate some Python best practices:Object-orientedwith classes and subclasses.Dynamic configurationusing a unique approach we call "class families" - for example, the names of the commands are properties of the command classes, not in a big "if" statement.Extensive testingwith high test coverage, guaranteed by CI.Leverage the standard libraryby requiring 3rd party PIP modules for development, but not for usage.To set everything up:Requires Python 3.6.5 or laterClone the repo and CD into itSet up a venv if that's your thingpip install -r requirements/freeze.txtTo run it:python -m busy...We use Visual Studio Code to build Busy, so there is a VS Code configuration file in the repository.Then to run the test suite:make testOr to run test coverage:make coverAnd to check style:make styleNote to self: To publish a new build, use 'vernum' with 'major', 'minor', or 'patch' depending on how major the changes were since the last build. Then push. GitLab allows you to publish to PyPI via CI/CD, and only when Vernum has been run.Command summaryBelow is a reference list of Busy commands, real and imagined.ShortFullInteractiveaaddacactivatecddeletedeeditefdeferfdownjllistmmanagenfinishnopopopprintpquitqrdroprsskipsttagsqueues (list)upuswitch (queues)wcurses