Compare commits

...

19 Commits

Author SHA1 Message Date
Gina Trapani
c963ba41ae Weekly review: cross-check all project completions are associated with goals 2016-03-18 00:20:01 -04:00
Gina Trapani
b4ef59b637 Weekly Review action: first commit 2016-03-17 23:52:18 -04:00
Gina Trapani
90b80268d3 Birdseye: Update version and changelog 2016-03-17 23:51:44 -04:00
Gina Trapani
7dde1fbab6 Birdseye: Tabs to spaces 2016-03-17 23:51:44 -04:00
Gina Trapani
b3e0f791a7 Birdseye: whitespace 2016-03-17 23:51:44 -04:00
Jonathan Reeve
732e45aeb1 remove unnecessary apostrophes 2015-02-15 14:54:50 -05:00
Jonathan Reeve
a53bb81b4c update for python 3 2015-02-15 14:53:02 -05:00
Jonathan Reeve
29a470f97d make scripts executable 2015-02-15 14:41:26 -05:00
Gina Trapani
6ab0004fe8 Fix IndexError: list index out of range when there's a blank line in todo.txt (like after deleting a task) 2012-02-14 18:02:11 -08:00
bertvv
15acb054f5 Have birdseye plugin use instead of hard-coded directory 2011-07-07 23:45:48 -07:00
ginatrapani
5f3dadee5c Updated to latest in master 2009-04-26 10:04:49 -07:00
Gina Trapani
20c6f44784 Ported README to Textile 2009-04-12 02:43:57 -04:00
Gina Trapani
9bab224a29 Merge branch 'master' of git://github.com/ginatrapani/todo.txt-cli into addons
* 'master' of git://github.com/ginatrapani/todo.txt-cli:
  Bugfix: pri accepted priorities of more than a single letter
  Don't set sort command in default todo.cfg.
  Don't set colors in default todo.cfg.
  Cleanup: removing annoying trailing space on pri tasks
  Cleanup: del/depri/pri: some more $2 -> $item
  Bugfix: handling of priorities in pri/depri/do: no more globbing
  Bugfix, take 2: depri no longer wipes out entire task with other parens http://tech.groups.yahoo.com/group/todotxt/message/1828
  Bugfix: depri no longer wipes out entire task with other parens http://tech.groups.yahoo.com/group/todotxt/message/1828
  Fix misplaced quote that was blocking filename globbing in the action
  Add quotes around $action to handle cases where todo.actions.d path includes embedded spaces.
2009-04-12 02:41:57 -04:00
Gina Trapani
a075adb4ec Merge git://github.com/ginatrapani/todo.txt-cli into addons 2009-04-06 12:37:31 -07:00
Gina Trapani
01a250c702 Added symlink support, tweaked usage message 2009-04-05 18:52:42 -07:00
Gina Trapani
1f17672215 Added birdseye add-on 2009-04-05 18:08:38 -07:00
Gina Trapani
40e0da5108 more info 2009-04-05 11:45:57 -07:00
Gina Trapani
56dfae0486 first commit 2009-04-05 11:42:16 -07:00
Gina Trapani
8549eef46b first commit 2009-04-05 11:21:12 -07:00
8 changed files with 493 additions and 9 deletions

10
.todo.actions.d/README Normal file
View File

@@ -0,0 +1,10 @@
TODO.TXT CLI Add-ons
adda (symlink to aa for fewer keystrokes)
* Adds a task and prioritizes it A in one shot
addx (symlink ax for fewer keystrokes)
* Adds a task and marks it as complete in one shot
birdseye (requires Python in path and birdseye.py file)
* Generates a textual report of open and complete tasks in all contexts and projects

20
.todo.actions.d/adda Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
action=$1
shift
[ "$action" = "usage" ] && {
echo " Add and prioritize A:"
curcmd=`basename $0`
echo " $curcmd \"THING I NEED TO DO +project @context\""
echo " Add an item and prioritize it A in one step"
echo ""
exit
}
if "$TODO_SH" command add "$@"; then
# figure out the line of what we just added, and prioritize it A
line=`sed -n '$ =' "$TODO_FILE"`
echo "$line"
"$TODO_SH" command pri "$line" A
fi

20
.todo.actions.d/addx Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
action=$1
shift
[ "$action" = "usage" ] && {
echo " Add and do:"
curcmd=`basename $0`
echo " $curcmd \"THING I DID +project @context\""
echo " Add an item and mark it as done in one step"
echo ""
exit
}
if "$TODO_SH" command add "$@"; then
# figure out the line of what we just added, and prioritize it A
line=`sed -n '$ =' "$TODO_FILE"`
echo "$line"
"$TODO_SH" command do "$line"
fi

16
.todo.actions.d/birdseye Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/bash
action=$1
shift
[ "$action" = "usage" ] && {
echo " Bird's eye report:"
echo " birdseye"
echo " generates a textual report of pending and completed tasks in all projects and contexts"
echo ""
exit
}
[ "$action" = "birdseye" ] && {
python ${TODO_ACTIONS_DIR}/birdseye.py "$TODO_FILE" "$DONE_FILE"
}

202
.todo.actions.d/birdseye.py Executable file
View File

@@ -0,0 +1,202 @@
#!/usr/bin/python
""" TODO.TXT Bird's Eye View Reporter
USAGE:
birdseye.py [todo.txt] [done.txt]
USAGE NOTES:
Expects two text files as parameters, each of which formatted as follows:
- One todo per line, ie, "call Mom"
- with an optional project association indicated as such: "+projectname"
- with the context in which the tasks should be completed, indicated as such: "@context"
- with the task priority optionally listed at the front of the line, in parens, ie, "(A)"
For example, 4 lines of todo.txt might look like this:
+garagesale @phone schedule Goodwill pickup
(A) @phone Tell Mom I love her
+writing draft Great American Novel
(B) smell the roses
The done.txt file is a list of completed todos from todo.txt.
See more on todo.txt here:
http://todotxt.com
OUTPUT:
Displays a list of:
- working projects and their percentage complete
- contexts in which open todos exist
- contexts and projects with tasks that have been prioritized
- projects which are completely done (don't have any open todos)
CHANGELOG:
2016.03.17 - Update for Python 3. Tx, JonathanReeve!
2006.07.29 - Now supports p:, p- and + project notation. Tx, Pedro!
2006.05.02 - Released
"""
import sys
__version__ = "1.2"
__date__ = "2006/05/02"
__updated__ = "2016/03/17"
__author__ = "Gina Trapani (ginatrapani@gmail.com)"
__copyright__ = "Copyright 2006 - 2016, Gina Trapani"
__license__ = "GPL"
__history__ = """
1.2 - Update for Python 3. Tx, JonathanReeve!
1.1 - Now supports p:, p- and + project notation. Tx, Pedro!
1.0 - Released.
"""
def usage():
print("USAGE: %s [todo.txt] [done.txt]" % (sys.argv[0], ))
def printTaskGroups(title, taskDict, priorityList, percentages):
print("")
print("%s"% (title,))
separator("-")
if not taskDict:
print("No items to list.")
else:
# sort the dictionary by value
# http://python.fyxm.net/peps/pep-0265.html
items = [(v, k) for k, v in list(taskDict.items())]
items.sort()
items.reverse() # so largest is first
items = [(k, v) for v, k in items]
for item in items:
if item[0] in priorityList:
if item[0] not in percentages:
printTaskGroup(item, -1, "*")
else:
printTaskGroup(item, percentages[item[0]], "*")
for item in items:
if item[0] not in priorityList:
if item[0] not in percentages:
printTaskGroup(item, -1, " ")
else:
printTaskGroup(item, percentages[item[0]], " ")
def printTaskGroup(p, pctage, star):
if pctage > -1:
progressBar = ""
numStars = int(pctage//10)
progressBar = "=" * numStars
numSpaces = 10 - numStars
for n in range(numSpaces):
progressBar += " "
if pctage > 9:
displayTotal = " %d%%"% (pctage, );
else:
displayTotal = " %d%%"% (pctage, );
print("%s %s [%s] %s (%d todos)"% (star, displayTotal, progressBar, p[0], p[1],))
else:
print("%s %s (%d todos)"% (star, p[0], p[1], ))
def separator(c):
sep = ""
sep = c * 42
print(sep)
def main(argv):
# make sure you have all your args
if len(argv) < 2:
usage()
sys.exit(2)
# process todo.txt
try:
f = open (argv[0], "r")
projects = {}
contexts = {}
projectPriority = []
contextPriority = []
for line in f:
prioritized = False
words = line.split()
if words and words[0].startswith("("):
prioritized = True
for word in words:
if word[0:2] == "p:" or word[0:2] == "p-" or word[0:1] == "+":
if word not in projects:
projects[word] = 1
else:
projects[word] = projects.setdefault(word,0) + 1
if prioritized:
projectPriority.append(word)
if word[0:1] == "@":
if word not in contexts:
contexts[word] = 1
else:
contexts[word] = contexts.setdefault(word, 0) + 1
if prioritized:
contextPriority.append(word)
f.close()
except IOError:
print("ERROR: The file named %s could not be read."% (argv[0], ))
usage()
sys.exit(2)
# process done.txt
try:
completedTasks = {}
f = open (argv[1], "r")
for line in f:
words = line.split()
for word in words:
if word[0:2] == "p:" or word[0:2] == "p-" or word[0:1] == "+":
if word not in completedTasks:
completedTasks[word] = 1
else:
completedTasks[word] = completedTasks.setdefault(word, 0) + 1
f.close()
except IOError:
print("ERROR: The file named %s could not be read."% (argv[1], ))
usage()
sys.exit(2)
# calculate percentages
projectPercentages = {}
for project in projects:
openTasks = projects[project]
if project in completedTasks:
closedTasks = completedTasks[project]
else:
closedTasks = 0
totalTasks = openTasks + closedTasks
projectPercentages[project] = (closedTasks*100) / totalTasks
# get projects all done
projectsWithNoIncompletes = {}
for task in completedTasks:
if task not in projects:
projectsWithNoIncompletes[task] = 0
# print out useful info
#print "TODO.TXT Bird's Eye View Report %s"% ( datetime.date.today().isoformat(), )
print("")
print("TODO.TXT Bird's Eye View Report")
separator("=")
printTaskGroups("Projects with Open TODOs", projects, projectPriority, projectPercentages)
printTaskGroups("Contexts with Open TODOs", contexts, contextPriority, projectPercentages)
printTaskGroups("Completed Projects (No open TODOs)", projectsWithNoIncompletes, projectPriority, projectPercentages)
print("")
print("* Projects and contexts with an asterisk next to them denote prioritized tasks.")
print("Project with prioritized tasks are listed first, then sorted by number of open todos.")
print("")
if __name__ == "__main__":
main(sys.argv[1:])

View File

@@ -0,0 +1,199 @@
#!/usr/bin/python
""" TODO.TXT Weekly Review
USAGE:
weeklyreview.py [todo.txt] [done.txt] [projects.txt]
USAGE NOTES:
Expects three text files as parameters:
1 & 2. Properly-formatted todo.txt and done.txt files.
3. A projects.txt file which lists one project per line, and any number of #goals associated with it.
See more on todo.txt here:
http://todotxt.com
OUTPUT:
Displays a count of how many tasks were completed associated with a goal.
"""
import sys
import datetime
__version__ = "1.2"
__date__ = "2016/03/17"
__updated__ = "2016/03/17"
__author__ = "Gina Trapani (ginatrapani@gmail.com)"
__copyright__ = "Copyright 2016, Gina Trapani"
__license__ = "GPL"
__history__ = """
0.1 - WIP
"""
def usage():
print("USAGE: %s [todo.txt] [done.txt] [projects.txt]" % (sys.argv[0], ))
def separator(c, r=42):
sep = ""
sep = c * r
print(sep)
def printTitle(text):
print("")
r = len(text)
print(text)
separator("=", r)
def printHeader(text):
r = len(text)
print("")
print(text)
separator("-", r)
def main(argv):
# make sure you have all your args
if len(argv) < 3:
usage()
sys.exit(2)
goal_projects = getGoalProjects(argv)
#print(goal_projects)
last_7_days = getLast7Days()
#print(last_7_days)
last_7_days_of_completions = getLast7DaysOfCompletions(argv, last_7_days)
#print(last_7_days_of_completions)
project_completions = getProjectCompletions(argv, last_7_days_of_completions)
#print(project_completions)
goal_completions = getGoalCompletions(goal_projects, project_completions)
# print(goal_completions)
# Print report: For each item in goal_projects, print the goal, the number of tasks completed,
# then each project and the number of tasks completed
printTitle("Weekly Review for the past 7 days")
goals_not_moved = []
goals_moved = []
for goal in goal_projects:
total_done = 0
if goal in goal_completions:
total_done = len(goal_completions[goal])
goal_header = goal + " - " + str(total_done) + " done"
if total_done > 0:
printHeader(goal_header)
for project in goal_projects[goal]:
if project in project_completions:
print(project + " - " + str(len(project_completions[project])) + " done" )
for task in project_completions[project]:
print(" " + task.strip())
goals_moved.append(goal)
else:
goals_not_moved.append(goal)
# Print a list of goals that had no movement
if len(goals_not_moved) > 0:
printTitle("Goals with no progress")
for goal in goals_not_moved:
print(goal)
# Print summary
print("")
summary = str(len(last_7_days_of_completions)) + " completed tasks moved " + str(len(goals_moved)) + " out of " + str(len(goal_projects)) + " goals forward."
separator("-", len(summary))
print(summary)
separator("-", len(summary))
# Warnings
crossCheckCompletedProjects(project_completions, goal_projects)
# Return an array of goals with total tasks completed.
def getGoalCompletions(goal_projects, project_completions):
goal_completions = {}
goals = goal_projects.keys()
for goal in goal_projects:
for project in project_completions:
if project in goal_projects[goal]:
if goal not in goal_completions:
goal_completions[goal] = project_completions[project]
else:
goal_completions[goal] = goal_completions[goal] + project_completions[project]
return goal_completions
# Return the goal/project list as an array of arrays goalProjects[goal] = projects[]
def getGoalProjects(argv):
try:
goal_projects = {}
f = open (argv[2], "r")
for line in f:
words = line.split()
for word in words:
# Project
if word[0:1] == "+":
current_project = word
# Goal
if word[0:1] == "#":
if word not in goal_projects:
goal_projects[word] = [current_project];
else:
goal_projects[word].append(current_project)
f.close()
return goal_projects
except IOError:
print("ERROR: The file named %s could not be read."% (argv[1], ))
usage()
sys.exit(2)
# Get the last 7 days as an array of todo.txt-formatted dates.
def getLast7Days():
today = datetime.date.today()
last7Days = []
for d in range(8):
day_this_week = today - datetime.timedelta(days=d)
last7Days.append(day_this_week.strftime('%Y-%m-%d'))
return last7Days
# Return last 7 days of completed tasks from done.txt
def getLast7DaysOfCompletions(argv, last_7_days):
try:
last_7_days_of_completions = []
f = open (argv[1], "r")
for line in f:
words = line.split()
if len(words) > 2 and words[1] in last_7_days:
last_7_days_of_completions.append(line)
f.close()
return last_7_days_of_completions
except IOError:
print("ERROR: The file named %s could not be read."% (argv[1], ))
usage()
sys.exit(2)
# Return an array of projects with the total tasks completed.
def getProjectCompletions(argv, last_7_days_of_completions):
project_completions = {}
for task in last_7_days_of_completions:
words = task.split()
for word in words:
if word[0:2] == "p:" or word[0:2] == "p-" or word[0:1] == "+":
if word not in project_completions:
project_completions[word] = [task]
else:
project_completions[word].append(task)
return project_completions
def crossCheckCompletedProjects(project_completions, goal_projects):
for project in project_completions:
goal_in_project = False
for goal in goal_projects:
if project in goal_projects[goal]:
goal_in_project = True
if goal_in_project == False:
print("WARNING: Project " + project + " not in goal.")
if __name__ == "__main__":
main(sys.argv[1:])

9
README
View File

@@ -1,9 +0,0 @@
TODO.TXT Command Line Interface
Latest stable release: http://github.com/ginatrapani/todo.txt-cli/downloads
First release: 5/11/2006
Original conception by: Gina Trapani (http://ginatrapani.org)
Contributors: http://github.com/ginatrapani/todo.txt-cli/network
License: GPL, http://www.gnu.org/copyleft/gpl.html
More information and mailing list at http://todotxt.com
To contribute, fork the repository at http://github.com/ginatrapani/todo.txt-cli/tree/master

26
README.textile Normal file
View File

@@ -0,0 +1,26 @@
h1. TODO.TXT Command Line Interface
A simple and extensible shell script for managing your todo.txt file.
h2. "Downloads":http://github.com/ginatrapani/todo.txt-cli/downloads
"Download the latest stable release":http://github.com/ginatrapani/todo.txt-cli/downloads for use on your desktop or server.
h2. "Documentation":http://wiki.github.com/ginatrapani/todo.txt-cli
* "User Documentation":http://wiki.github.com/ginatrapani/todo.txt-cli/user-documentation - Find out "how to install and use Todo.txt CLI":http://wiki.github.com/ginatrapani/todo.txt-cli/user-documentation, and get tips and tricks.
* "Developer Documentation":http://wiki.github.com/ginatrapani/todo.txt-cli/developer-documentation - "Contribute to Todo.txt CLI":http://wiki.github.com/ginatrapani/todo.txt-cli/developer-documentation and build your own custom add-ons.
h2. "Mailing List":http://groups.yahoo.com/group/todotxt/
Get support from users and developers on the "mailing list":http://groups.yahoo.com/group/todotxt/.
h2. Quick Links
* Original anemic release by "Gina Trapani":http://ginatrapani.org on 5/11/2006.
* Raised to great heights by "brainy and dedicated volunteers":http://github.com/ginatrapani/todo.txt-cli/network.
* Licensed under the "GPL":http://www.gnu.org/copyleft/gpl.html
* "Add-on Directory":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-add-on-directory
* "Changelog":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-changelog
* "Known Bugs":http://wiki.github.com/ginatrapani/todo.txt-cli/known-bugs