Skip to content

Commit

Permalink
Complete refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderWillner committed Jan 2, 2018
1 parent 0ff9386 commit d84294a
Show file tree
Hide file tree
Showing 30 changed files with 1,160 additions and 760 deletions.
5 changes: 5 additions & 0 deletions .gitattributes
@@ -0,0 +1,5 @@
/.travis.yml export-ignore
/.gitignore export-ignore
/.gitattributes export-ignore
/img export-ignore

4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -22,14 +22,14 @@ feedback:

test: check
@echo "Running shell checks..."
@shellcheck things.sh
@shellcheck -x things.sh
@echo "Running unit tests..."
@bashcov -s shunit2 test/thingsTest.sh
@file coverage/index.html||true

style:
@type shfmt >/dev/null 2>&1 || (echo "Run 'go get -u mvdan.cc/sh/cmd/shfmt' first." >&2 ; exit 1)
@shfmt -i 2 -w things.sh
@shfmt -i 2 -w *.sh

check:
@type shellcheck >/dev/null 2>&1 || (echo "Run 'brew install shellcheck' first." >&2 ; exit 1)
Expand Down
97 changes: 47 additions & 50 deletions README.md
Expand Up @@ -39,79 +39,76 @@ Note that you could override the location of the database used by setting the TH
$ things.sh --limitBy 5 help
usage: things.sh <OPTIONS> [COMMAND]
List to do items from your Things database given a focus area.
COMMAND:
inbox
today
upcoming
next / anytime
someday
completed
cancelled
trashed
all (show all tasks)
nextish (show 5 next tasks that are also in someday projects)
old (show 5 tasks ordered by 'creationDate')
due (show 5 tasks ordered by due date)
waiting (show 5 tasks with the tag 'Waiting for' ordered by 'creationDate')
repeating (show 5 repeating tasks orderd by 'creationDate')
subtasks (show 5 subtasks)
projects (show 5 projects ordered by creation date)
headings (show 5 headings ordered by creation date)
notes (show 5 notes as <headings>: <notes> ordered by creation date)
csv (export all tasks as semicolon seperated values incl. notes and Excel friendly)
stat (provide an overview of the numbers of tasks)
statcsv (export some statistics as semicolon seperated values for '-1 year')
mostClosed (show 5 days on which most tasks were closed)
mostCreated (show 5 days on which most tasks were created)
mostCancelled (show 5 days on which most tasks were cancelled)
mostTrashed (show 5 days on which most tasks were trashed)
mostTasks (show 5 projects which have most tasks)
mostCharacters(show 5 tasks which have most characters)
search (provide details about specific tasks)
feedback (give feedback, request and propose changes)
OPTIONS:
-l|--limitBy <number> Limit output by <number> of results
-w|--waitingTag <tag> Set waiting tag to <tag>
-o|--orderBy <column> Sort output by <column> (e.g. 'userModificationDate' or 'creationDate')
-s|--string <string> String <string> to search for
-r|--range <string> Limit CSV statistic export by <string>
COMMANDS:
inbox Shows 5 inbox tasks ordered by creationDate
today Shows 5 todays tasks ordered by index
upcoming Shows 5 upcoming tasks ordered by date
next Shows 5 next tasks ordered by creationDate
someday Shows 5 someday tasks ordered by creationDate
completed Shows 5 completed tasks ordered by creationDate
cancelled Shows 5 cancelled tasks ordered by cancel date
trashed Shows 5 trashed tasks ordered by creationDate
feedback Opens the feedback web page to request and propose changes
all Shows 5 tasks ordered by creationDate
csv Exports all tasks as semicolon seperated values incl. notes and Excel friendly
due Shows 5 tasks ordered by due date
headings Shows 5 headings ordered by creationDate
mostClosed Shows 5 days on which most tasks were closed
mostCancelled Shows 5 days on which most tasks were cancelled
mostTrashed Shows 5 days on which most tasks were trashed
mostCreated Shows 5 days on which most tasks were created
mostTasks Shows 5 projects that have most tasks
mostCharacters Shows 5 tasks that have most characters
nextish Shows 5 nextish tasks ordered by creationDate
old Shows 5 old tasks ordered by creationDate
projects Shows 5 projects ordered by creationDate
repeating Shows 5 repeating tasks ordered by creationDate
search Searches for a specific task
stat Provides a number of statistics about all tasks
statcsv Exports some statistics as semicolon separated values for -1 year
subtasks Shows 5 subtasks ordered by creationDate
waiting Shows 5 tasks with the tag Waiting
```

## Examples

### CSV export and open with Excel

```things.sh csv > Things3Export.csv ; open Things3Export.csv```
```things.sh csv > Things3Export.csv && open Things3Export.csv```

### Statistics

```
$ things.sh stat
Inbox : 0
Today : 2
Today : 7
Upcoming : 156
Next : 6
Someday : 823
Next : 15
Someday : 822
Completed : 11964
Cancelled : 9245
Trashed : 541
Completed : 11976
Cancelled : 9250
Trashed : 545
Tasks : 968
Subtasks : 56
Waiting : 114
Projects : 97
Repeating : 91
Nextish : 145
Headings : 41
Waiting : 111
Projects : 89
Repeating : 89
Nextish : 146
Headings : 53
Oldest : 2010-09-28|XXX
Farest : 2021-01-04|XXX
Longest : 167|XXXXXXXXXX
Largest : 127|XXXXXXXXXX
Oldest : 2010-09-28|XXX|XXX
Farest : 2021-01-04|XXX|XXX
Longest : 167|XXXXXXXXXXXXXX
Largest : 128|XXXXXXXXXXXXXX
Created : 147|2017-07-04
Closed : 124|2017-12-30
Expand All @@ -122,7 +119,7 @@ Days/Task : 41.0

## CREDITS
* Author : Arjan van der Gaag (script for Things 2)
* Author : Alexander Willner (updates for Things 3, added many more commands, a lot refactoring)
* Author : Alexander Willner (updates for Things 3, complete rewrite)
* License : Whatever. Use at your own risk.
* Source : https://github.com/AlexanderWillner/things.sh
* Shell checker : https://github.com/koalaman/shellcheck
Expand Down
28 changes: 0 additions & 28 deletions bash_completion/things.sh

This file was deleted.

67 changes: 67 additions & 0 deletions plugins/0_framework.sh
@@ -0,0 +1,67 @@
#!/bin/bash
getNextPluginID() {
idx=0
plugin="plugin$idx"
while [[ ! -z "${!plugin:-}" ]]; do
idx=$((idx + 1))
plugin="plugin$idx"
done
echo $idx
}

getPluginHelp() {
idx=0
plugin="plugin$idx"
while [[ ! -z "${!plugin:-}" ]]; do
command="plugin$idx[0]"
description="plugin$idx[1]"
method="plugin$idx[2]"
cmd=${!command}
line=' '
printf " %s %s ${!description}\n" $cmd "${line:${#cmd}}"
idx=$((idx + 1))
plugin="plugin$idx"
done
}

getCommands() {
idx=0
plugin="plugin$idx"
while [[ ! -z "${!plugin:-}" ]]; do
command="plugin$idx[0]"
echo -n "${!command} "
idx=$((idx + 1))
plugin="plugin$idx"
done
}

invokePlugin() {
idx=0
plugin="plugin$idx"
while [[ ! -z "${!plugin:-}" ]]; do
command="plugin$idx[0]"
description="plugin$idx[1]"
method="plugin$idx[2]"
if [[ "${!command}" == "$1" ]]; then
eval "${!method}"
fi
idx=$((idx + 1))
plugin="plugin$idx"
done
}

hasPlugin() {
idx=0
plugin="plugin$idx"
while [[ ! -z "${!plugin:-}" ]]; do
command="plugin$idx[0]"
description="plugin$idx[1]"
method="plugin$idx[2]"
if [[ "${!command}" == "$1" ]]; then
return 0
fi
idx=$((idx + 1))
plugin="plugin$idx"
done
return 1
}
24 changes: 24 additions & 0 deletions plugins/1_inbox.sh
@@ -0,0 +1,24 @@
#!/bin/bash

myPluginID=$(getNextPluginID)
myPlugin="plugin$myPluginID"
myPluginCommand='inbox'
myPluginDescription="Shows $limitBy inbox tasks ordered by '$orderBy'"
myPluginMethod='queryInbox'

eval "$myPlugin=('$myPluginCommand' '$myPluginDescription' '$myPluginMethod')"

queryInbox() {
sqlite3 "$THINGSDB" "$(getInboxQuery)"
}

getInboxQuery() {
read -rd '' query <<-SQL || true
SELECT title
FROM $TASKTABLE TASK
WHERE $ISNOTTRASHED AND $ISTASK AND $ISNOTSTARTED AND $ISOPEN
ORDER BY TASK.$orderBy
LIMIT $limitBy
SQL
echo "${query}"
}
36 changes: 36 additions & 0 deletions plugins/2_today.sh
@@ -0,0 +1,36 @@
#!/bin/bash

myPluginID=$(getNextPluginID)
myPlugin="plugin$myPluginID"
myPluginCommand='today'
myPluginDescription="Shows $limitBy todays tasks ordered by index"
myPluginMethod='queryToday'

eval "$myPlugin=('$myPluginCommand' '$myPluginDescription' '$myPluginMethod')"

queryToday() {
sqlite3 "$THINGSDB" "$(getTodayQuery)"
}

getTodayQuery() {
read -rd '' query <<-SQL || true
SELECT
CASE
WHEN AREA.title IS NOT NULL THEN AREA.title
WHEN PROJECT.title IS NOT NULL THEN PROJECT.title
WHEN HEADING.title IS NOT NULL THEN HEADING.title
ELSE "(No Context)"
END,
TASK.title
FROM $TASKTABLE as TASK
LEFT OUTER JOIN $TASKTABLE PROJECT ON TASK.project = PROJECT.uuid
LEFT OUTER JOIN $AREATABLE AREA ON TASK.area = AREA.uuid
LEFT OUTER JOIN $TASKTABLE HEADING ON TASK.actionGroup = HEADING.uuid
WHERE TASK.$ISNOTTRASHED AND TASK.$ISOPEN AND TASK.$ISTASK
AND TASK.$ISSTARTED
AND TASK.startdate is NOT NULL
ORDER BY TASK.startdate, TASK.todayIndex
LIMIT $limitBy
SQL
echo "${query}"
}
39 changes: 39 additions & 0 deletions plugins/3_upcoming.sh
@@ -0,0 +1,39 @@
#!/bin/bash

myPluginID=$(getNextPluginID)
myPlugin="plugin$myPluginID"
myPluginCommand='upcoming'
myPluginDescription="Shows $limitBy upcoming tasks ordered by date"
myPluginMethod='queryUpcoming'

eval "$myPlugin=('$myPluginCommand' '$myPluginDescription' '$myPluginMethod')"

queryUpcoming() {
sqlite3 "$THINGSDB" "$(getUpcomingQuery)"
}

getUpcomingQuery() {
read -rd '' query <<-SQL || true
SELECT
CASE
WHEN TASK.startDate IS NULL THEN "0000-00-00"
ELSE date(TASK.startDate,"unixepoch")
END,
CASE
WHEN AREA.title IS NOT NULL THEN AREA.title
WHEN PROJECT.title IS NOT NULL THEN PROJECT.title
WHEN HEADING.title IS NOT NULL THEN HEADING.title
ELSE "(No Context)"
END,
TASK.title
FROM $TASKTABLE as TASK
LEFT OUTER JOIN $TASKTABLE PROJECT ON TASK.project = PROJECT.uuid
LEFT OUTER JOIN $AREATABLE AREA ON TASK.area = AREA.uuid
LEFT OUTER JOIN $TASKTABLE HEADING ON TASK.actionGroup = HEADING.uuid
WHERE TASK.$ISNOTTRASHED AND TASK.$ISOPEN AND TASK.$ISTASK
AND TASK.$ISPOSTPONED AND (TASK.startDate NOT NULL OR TASK.recurrenceRule NOT NULL)
ORDER BY TASK.startdate, TASK.todayIndex
LIMIT $limitBy
SQL
echo "${query}"
}

0 comments on commit d84294a

Please sign in to comment.