This is a unobtrusive, scriptable reminder/habit/todo task-runner.
Probably easiest explained with some examples:
```bash
# remind me to listen to a new album once a week
# interfaces with my spreadsheet where I track my albums
# https://github.com/seanbreckenridge/albums
LISTENCOUNT="$(hpi query -r 1w my.nextalbums.history | jq 'length')" || exit 1
if [[ "${LISTENCOUNT}" == '0' ]]; then
exit 2 # this has 'expired', exit code 2 means print the script name
else
exit 0 # all good, I've listened to a new album recently
fi
```
[`flipflop`](https://sean.fish/d/flipflop.py?redirect) are toggeable todos for things that I need to do often. Think like: re-add a energy bar to my bag, refill medication.
I'll often run `flipflop` when I'm away from my computer using [termux](https://termux.dev/en/) on my phone. The data for that is then synced to my computer with [syncthing](https://syncthing.net/)
Instead of adding some reminder system inside `flipflop`, `reminder-sink` is the 'sink' for the data:
```bash
OUTPUT="$(flipflop.py status -fo json | jq 'keys[]' -r)"
if [[ -n "$OUTPUT" ]]; then
echo "$OUTPUT"
exit 3 # this has 'expired', exit code 3 prints the output of this script
fi
exit 0 # no output, nothing to do from flipflop
```
So, if I was to run `reminder-sink` and all of these had expired, I'd get something like:
```bash
$ reminder-sink run
listen_to_album # from the name of the script
refill_medication # these 2 lines were the output of 'flipflop.py status'
add_energy_bar
```
This does not actually have any way to setup/remind you for specific habits/tasks,
it provides more of a set of rules which make for an unobtrusive reminder/habit tracker
Instead of reminding me once a day to do something, this uses local data (or an API request
if you want -- its just a script, you can do whatever you want!) to determine if I've done
it within the timeframe
I really dislike habit building/reminder apps that interrupt my workflow. When I get the
notification to remind me to do something, it feels like I _have to_ do it at that moment,
else I'll forget or delay it, which is totally antithetical to actually building a habit
But, if there's no reminder, I often forget to do things.
Instead, this displays the number of tasks which have expired in my menu bar. So, its
still visible to me and I'll glance whenever I have a free minute, but I don't
get interrupted or feel like I have to 'snooze'/delay the habit.
I also don't feel too horrible if there's a number there for a couple hours, I get
around to the task eventually
I generally track my habits with my `Self` type using [`ttally`](https://github.com/seanbreckenridge/ttally),
and use [`i3blocks`](https://github.com/vivien/i3blocks) for my status bar. The block this runs for
`reminder-sink` looks like this:
```bash
#!/usr/bin/env bash
# if I left-click the icon, send a notification with what's expired
case "${BLOCK_BUTTON}" in
1)
notify-send "$(reminder-sink)"
;;
esac
reminder-sink run | wc -l
```
You could of course script together a little cron job that _does_ actually remind you once an hour if you have any expired jobs:
```bash
OUT="$(reminder-sink run)"
if [[ -n "${OUT}" ]]; then
notify-send "${OUT}"
fi
```
Or just run `reminder-sink run` when you start up a new terminal or something, this is very flexible
You can see some of my other reminder-sink jobs [in my dotfiles](https://github.com/seanbreckenridge/dotfiles/tree/master/.local/scripts/reminder-sink), but I use this for stuff like:
- reminding me to log my weight at least once a week
- making sure I drink enough water (using [`ttally`](https://github.com/seanbreckenridge/ttally))
- listen to album once a week (by using my [spreadsheet](https://sean.fish/s/albums))
- tracking physical activity
- remind me to re-fill on medication when it runs out
- watch something on my movie/tv show backlog once every couple days (this gets tracked automatically by my [`mpv-history-daemon`](https://github.com/seanbreckenridge/mpv-history-daemon))
## Usage:
```
Usage: reminder-sink [OPTIONS] COMMAND [ARGS]...
reminders-sink is a script that takes other scripts as input and runs them
in parallel. The exit code of each script it runs determines what reminder-
sink does:
0: I've done this task recently, no need to warn
2: I haven't done this task recently, print the script name
3: I haven't done this task recently, print the output of the script
Anything else: Fatal error
You can set the REMINDER_SINK_PATH environment variable to a colon-delimited
list of directories that contain reminder-sink jobs. For example, in your
shell profile, set:
export REMINDER_SINK_PATH="${HOME}/.local/share/reminder-sink:${HOME}/Documents/reminder-sink"
This scans the directories for executables and runs them in parallel. A
script is considered enabled if it is executable or if the file name ends
with '.enabled'.
Options:
-d, --debug print debug information [env var: REMINDER_SINK_DEBUG]
-h, --help Show this message and exit.
Commands:
list list all scripts
run run all scripts in parallel
test test a script
```
This uses the shebang of the script (e.g. `#!/usr/bin/env bash` or `#!/usr/bin/python3`) to determine
what to run the file with. If it can't detect properly, it uses `bash` (you can change that like `REMINDER_SINK_DEFAULT_INTERPRETER=python`)
## Installation
Requires `python3.10+`
To install with pip, run:
```
pip install git+https://github.com/seanbreckenridge/reminder-sink
```
## Usage
```
reminder-sink --help
```
### Tests
```bash
git clone 'https://github.com/seanbreckenridge/reminder-sink'
cd ./reminder-sink
pip install '.[testing]'
pytest
flake8 ./reminder-sink
mypy ./reminder-sink
```
Raw data
{
"_id": null,
"home_page": "https://github.com/seanbreckenridge/reminder-sink",
"name": "reminder-sink",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "",
"keywords": "",
"author": "Sean Breckenridge",
"author_email": "seanbrecke@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/5d/4b/21931c224d3a188ae3ae547d23e9393064a5438dd80d33982fae89b1e146/reminder_sink-0.1.0.tar.gz",
"platform": null,
"description": "This is a unobtrusive, scriptable reminder/habit/todo task-runner.\n\nProbably easiest explained with some examples:\n\n```bash\n# remind me to listen to a new album once a week\n\n# interfaces with my spreadsheet where I track my albums\n# https://github.com/seanbreckenridge/albums\nLISTENCOUNT=\"$(hpi query -r 1w my.nextalbums.history | jq 'length')\" || exit 1\n\nif [[ \"${LISTENCOUNT}\" == '0' ]]; then\n exit 2 # this has 'expired', exit code 2 means print the script name\nelse\n exit 0 # all good, I've listened to a new album recently\nfi\n```\n\n[`flipflop`](https://sean.fish/d/flipflop.py?redirect) are toggeable todos for things that I need to do often. Think like: re-add a energy bar to my bag, refill medication.\n\nI'll often run `flipflop` when I'm away from my computer using [termux](https://termux.dev/en/) on my phone. The data for that is then synced to my computer with [syncthing](https://syncthing.net/)\n\nInstead of adding some reminder system inside `flipflop`, `reminder-sink` is the 'sink' for the data:\n\n```bash\nOUTPUT=\"$(flipflop.py status -fo json | jq 'keys[]' -r)\"\n\nif [[ -n \"$OUTPUT\" ]]; then\n\techo \"$OUTPUT\"\n\texit 3 # this has 'expired', exit code 3 prints the output of this script\nfi\nexit 0 # no output, nothing to do from flipflop\n```\n\nSo, if I was to run `reminder-sink` and all of these had expired, I'd get something like:\n\n```bash\n$ reminder-sink run\nlisten_to_album # from the name of the script\nrefill_medication # these 2 lines were the output of 'flipflop.py status'\nadd_energy_bar\n```\n\nThis does not actually have any way to setup/remind you for specific habits/tasks,\nit provides more of a set of rules which make for an unobtrusive reminder/habit tracker\n\nInstead of reminding me once a day to do something, this uses local data (or an API request\nif you want -- its just a script, you can do whatever you want!) to determine if I've done\nit within the timeframe\n\nI really dislike habit building/reminder apps that interrupt my workflow. When I get the\nnotification to remind me to do something, it feels like I _have to_ do it at that moment,\nelse I'll forget or delay it, which is totally antithetical to actually building a habit\n\nBut, if there's no reminder, I often forget to do things.\n\nInstead, this displays the number of tasks which have expired in my menu bar. So, its\nstill visible to me and I'll glance whenever I have a free minute, but I don't\nget interrupted or feel like I have to 'snooze'/delay the habit.\n\nI also don't feel too horrible if there's a number there for a couple hours, I get\naround to the task eventually\n\nI generally track my habits with my `Self` type using [`ttally`](https://github.com/seanbreckenridge/ttally),\nand use [`i3blocks`](https://github.com/vivien/i3blocks) for my status bar. The block this runs for\n`reminder-sink` looks like this:\n\n```bash\n#!/usr/bin/env bash\n\n# if I left-click the icon, send a notification with what's expired\ncase \"${BLOCK_BUTTON}\" in\n1)\n notify-send \"$(reminder-sink)\"\n ;;\nesac\n\nreminder-sink run | wc -l\n```\n\nYou could of course script together a little cron job that _does_ actually remind you once an hour if you have any expired jobs:\n\n```bash\nOUT=\"$(reminder-sink run)\"\nif [[ -n \"${OUT}\" ]]; then\n notify-send \"${OUT}\"\nfi\n```\n\nOr just run `reminder-sink run` when you start up a new terminal or something, this is very flexible\n\nYou can see some of my other reminder-sink jobs [in my dotfiles](https://github.com/seanbreckenridge/dotfiles/tree/master/.local/scripts/reminder-sink), but I use this for stuff like:\n\n- reminding me to log my weight at least once a week\n- making sure I drink enough water (using [`ttally`](https://github.com/seanbreckenridge/ttally))\n- listen to album once a week (by using my [spreadsheet](https://sean.fish/s/albums))\n- tracking physical activity\n- remind me to re-fill on medication when it runs out\n- watch something on my movie/tv show backlog once every couple days (this gets tracked automatically by my [`mpv-history-daemon`](https://github.com/seanbreckenridge/mpv-history-daemon))\n\n## Usage:\n\n```\nUsage: reminder-sink [OPTIONS] COMMAND [ARGS]...\n\n reminders-sink is a script that takes other scripts as input and runs them\n in parallel. The exit code of each script it runs determines what reminder-\n sink does:\n\n 0: I've done this task recently, no need to warn\n 2: I haven't done this task recently, print the script name\n 3: I haven't done this task recently, print the output of the script\n Anything else: Fatal error\n\n You can set the REMINDER_SINK_PATH environment variable to a colon-delimited\n list of directories that contain reminder-sink jobs. For example, in your\n shell profile, set:\n\n export REMINDER_SINK_PATH=\"${HOME}/.local/share/reminder-sink:${HOME}/Documents/reminder-sink\"\n\n This scans the directories for executables and runs them in parallel. A\n script is considered enabled if it is executable or if the file name ends\n with '.enabled'.\n\nOptions:\n -d, --debug print debug information [env var: REMINDER_SINK_DEBUG]\n -h, --help Show this message and exit.\n\nCommands:\n list list all scripts\n run run all scripts in parallel\n test test a script\n```\n\nThis uses the shebang of the script (e.g. `#!/usr/bin/env bash` or `#!/usr/bin/python3`) to determine\nwhat to run the file with. If it can't detect properly, it uses `bash` (you can change that like `REMINDER_SINK_DEFAULT_INTERPRETER=python`)\n\n## Installation\n\nRequires `python3.10+`\n\nTo install with pip, run:\n\n```\npip install git+https://github.com/seanbreckenridge/reminder-sink\n```\n\n## Usage\n\n```\nreminder-sink --help\n```\n\n### Tests\n\n```bash\ngit clone 'https://github.com/seanbreckenridge/reminder-sink'\ncd ./reminder-sink\npip install '.[testing]'\npytest\nflake8 ./reminder-sink\nmypy ./reminder-sink\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A unobtrusive, scriptable reminder/habit/todo task-runner",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/seanbreckenridge/reminder-sink"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "041078bd729e6d1aae90a543366f5c61472d40c2577917ed3079fd5f67f17be6",
"md5": "a1024ea9f6ebdb7054ee894d95168896",
"sha256": "3e2dcca1aee2fdadf23bcc037d5a239be2e2ef17e0fa7f6eef709f0982028375"
},
"downloads": -1,
"filename": "reminder_sink-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a1024ea9f6ebdb7054ee894d95168896",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 7703,
"upload_time": "2023-10-06T07:46:23",
"upload_time_iso_8601": "2023-10-06T07:46:23.605644Z",
"url": "https://files.pythonhosted.org/packages/04/10/78bd729e6d1aae90a543366f5c61472d40c2577917ed3079fd5f67f17be6/reminder_sink-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5d4b21931c224d3a188ae3ae547d23e9393064a5438dd80d33982fae89b1e146",
"md5": "3f33b639a632af63241c64ba4b89b743",
"sha256": "3cf647f42b145d566748a2343fabeb6bbd908c3c20a9a95450ef47124b8800d9"
},
"downloads": -1,
"filename": "reminder_sink-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "3f33b639a632af63241c64ba4b89b743",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 7054,
"upload_time": "2023-10-06T07:46:24",
"upload_time_iso_8601": "2023-10-06T07:46:24.827264Z",
"url": "https://files.pythonhosted.org/packages/5d/4b/21931c224d3a188ae3ae547d23e9393064a5438dd80d33982fae89b1e146/reminder_sink-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-06 07:46:24",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "seanbreckenridge",
"github_project": "reminder-sink",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "reminder-sink"
}