# My simple TaskRatchet-esque cron job

**URL:** https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432
**Category:** Akrasia
**Created:** [June 9, 2019, 2:16pm UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432 "2019-06-09T14:16:11Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![zzq](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/zzq/32/6471_2.png) [@zzq](https://forum.beeminder.com/u/zzq)
#### Post date: [June 9, 2019, 2:16pm UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/1 "2019-06-09T14:16:11Z")

</div>

When the TaskRatchet alpha started, I thought I had a clever idea of how I’d use it. I really wanted to integrate with it via API, to be able to set myself tasks via the command line.

Now, TaskRatchet didn’t officially expose an API _per se_, but that wasn’t going to stop me. Fine, it doesn’t have a nice clean proper JSON-over-HTTP API, but it _does_ have something which is effectively a plaintext-over-SMTP API! I could write a CLI tool that speaks SMTP, which I could use to set tasks in TaskRatchet for myself!

Well, in retrospect, that was rather overambitious, and by the time I got something half complete, @narthur paused the alpha. Oops. I didn’t even get around to signing up.

But I still wanted to have that CLI tool for setting tasks for myself, so I kept working on what eventually turned into perhaps the simplest possible competitor to TaskRatchet. It’s a very short bash script whose core is something like this:

```bash
while read amount description; do
  curl 'https://www.beeminder.com/api/v1/charges.json' \
    -d auth_token=my_api_token_here \
    -d amount="$amount" \
    -d note="$description"
done < ~myusername/tasks

```

(This code is released under the [MIT license](https://opensource.org/licenses/MIT).)  
I dropped this script into `/etc/cron.daily` on my laptop, so that it will run as a daily cron job. (In my case, via `anacron`.)

In short, what it does is read a file named `tasks` in my home directory, which is formated along the lines of:

```nohighlight
1 Wash the dishes
5 Go to dentist appointment

```

(i.e. a dollar amount and then a description.)

Each time I complete a task, I remove it from this file. For each task left in the file at the end of the day, the above script charges me the listed amount.

This is very simple and quite barebones. It doesn’t even have a way to configure when tasks are due by! And it requires me to clean up failed tasks manually the next morning. (I could easily fix that by adding a line like `truncate -s 0 ~myusername/tasks` to the end of the script, but I actually like the notion of having to pay some attention to considering my failed tasks.)

For all that, it works surprisingly well. I haven’t failed at achieving a task I set myself this way so far (in about a week of use), and I’ve accomplished things which I know I definitely would have procrastinated on otherwise.

I’m looking forward to using TaskRatchet when it’s ready, which from my point of view is when it can clearly beat this script in features and ease of use. (Which shouldn’t be hard: there are _a lot_ of features this lacks. But it definitely needs to have an easy way of setting myself tasks via CLI.)

---

<div class="post-metadata">

### Author: ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)
#### Post date: [June 9, 2019, 2:28pm UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/2 "2019-06-09T14:28:09Z")

</div>

Love it! 😃 This is super relevant to where I’m at with TaskRatchet, as it gives me more data as to what people really need in the service. And scripting is definitely something TaskRatchet will be supporting!

What pain points does this method still leave unsolved?

---

<div class="post-metadata">

### Author: ![zzq](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/zzq/32/6471_2.png) [@zzq](https://forum.beeminder.com/u/zzq)
#### Post date: [June 9, 2019, 2:38pm UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/3 "2019-06-09T14:38:00Z")

</div>

> [@narthur](#):
>
> What pain points does this method still leave unsolved?

1. I’d like to be able to set specific times for tasks: e.g. a task might be due at 3pm, instead of it always being due by end of day.

2. I’d like to be able to enter tasks (and mark them complete) not just from my computer, but also from my (Android) phone. I’d still likely be mostly interacting with it via the command line on my computer, but some fraction of the time doing it via phone is easier.

3. If I fail at multiple tasks, bundling them into one charge for the total amount instead of one charge for each task. (Maybe Beeminder’s charge endpoint already does this, I don’t actually know.)

4. Some sort of lock-in for the tasks. I’m uncertain of what exactly would work best, but perhaps something like half an hour after the task is created, it stops you from lowering the dollar amount or making the due time later. I’d still want it to allow me to edit the text of the task, because it is important to me to be able to refine my thoughts about what exactly the task is, and I don’t find that capability something which includes much of a temptation to use it to cheat. (And remember, as with Beeminder, anyone who is determined to cheat can always mark things off as completed when they haven’t been.)

---

<div class="post-metadata">

### Author: ![zzq](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/zzq/32/6471_2.png) [@zzq](https://forum.beeminder.com/u/zzq)
#### Post date: [June 9, 2019, 2:49pm UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/4 "2019-06-09T14:49:18Z")

</div>

Another very important one I forgot to mention:

1. Reminders! One of the awesome things Beeminder does is its zeno-polling reminders. I really feel the pain from lack of remainders here. That’s probably my largest pain point that this method doesn’t resolve.

---

<div class="post-metadata">

### Author: ![zedmango](https://avatars.discourse-cdn.com/v4/letter/z/c67d28/32.png) [@zedmango](https://forum.beeminder.com/u/zedmango)
#### Post date: [July 23, 2019, 7:50pm UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/5 "2019-07-23T19:50:25Z")

</div>

To solve 2 and 5 you could use some kind of file sharing service to access the file from your phone and display it on your home screen.

Why do you want 3? It gives you less info to bundle.

For 1 it should be a simple addition to the script to add a time to each line in the task file, set the cronjob to run hourly, and run the curl command only if the time in the task file was within the last hour. So:

```
1 3 Wash the dishes

```

means you have to wash the dishes by 3.

> [@zzq](#):
>
> Some sort of lock-in for the tasks. I’m uncertain of what exactly would work best, but perhaps something like half an hour after the task is created, it stops you from lowering the dollar amount or making the due time later.

Yeah, I think this is important. I’ve suggested TaskRatchet lock a task after 10% of the time has gone by.

> [@zzq](#):
>
> (This code is released under the [MIT license](https://opensource.org/licenses/MIT).)

😂 😂 😹 Love that you copyrighted and licensed a while loop with one curl command in it!

---

<div class="post-metadata">

### Author: ![zzq](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/zzq/32/6471_2.png) [@zzq](https://forum.beeminder.com/u/zzq)
#### Post date: [July 24, 2019, 8:49am UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/6 "2019-07-24T08:49:51Z")

</div>

All these are solvable in code, of course. (That’s what TaskRatchet itself is planning to do, after all.) There’s a limit to what I want to write and maintain, and I’d be happy to have TaskRatchet handle this stuff for me.

But yes, if hypothetically @narthur said tomorrow that he’s decided not not do TaskRatchet after all, I may well put the effort into improving this.

> [@zedmango](#):
>
> Yeah, I think this is important. I’ve suggested TaskRatchet lock a task after 10% of the time has gone by.

I have some worries about this. 10% feels like too little, but who knows. And it’s very important to me that “locking the task” includes only the time and dollar amount, and _not_ the task description.

> [@zedmango](#):
>
> 😂 😂 😹 Love that you copyrighted and licensed a while loop with one curl command in it!

Do keep in mind that under modern copyright law, _everything_ copyrightable is automatically under copyright. Copyright is the default, and if you want someone to be able to copy your code you need to license it. Ignoring copyright doesn’t make it go away, unfortunately.

(On the other hand, this snippet might be short enough that even copying it in its entirety counts as fair use. I don’t know, I’m not a copyright lawyer. (Or any other type of lawyer, for that matter.) But I feel that it’s best to be clear and to explicitly state that it’s allowed.)

---

<div class="post-metadata">

### Author: ![zedmango](https://avatars.discourse-cdn.com/v4/letter/z/c67d28/32.png) [@zedmango](https://forum.beeminder.com/u/zedmango)
#### Post date: [July 24, 2019, 11:35pm UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/7 "2019-07-24T23:35:57Z")

</div>

My point wasn’t that it was solvable in code - my point was that it would be really easy to do: you just need a conditional to compare the time. It’s understandable if you just want TR to do it though.

> [@zzq](#):
>
> I have some worries about this. 10% feels like too little, but who knows. And it’s very important to me that “locking the task” includes only the time and dollar amount, and _not_ the task description.

10% is about right for me - past that point I’d want to be Locked In.

Does TR have “task descriptions”? I thought it just had task names. How are you editing the task description in TR?  
I’d be very worried that allowing edits of the task **name** would make it easy to cheat. For me it would be a big temptation.  
Why can’t you keep the task description that was there at creation, and refine your thoughts in a different field/file/location?

> [@zzq](#):
>
> Do keep in mind that under modern copyright law, _everything_ copyrightable is automatically under copyright.

Yes, in the US at least, this is correct. I should have said “Love that you asserted copyright and licensed a while loop…”

> [@zzq](#):
>
> Copyright is the default, and if you want someone to be able to copy your code you need to license it.

Or put it in the public domain.

Just curious, why didn’t you GPL it? 😛

> [@zzq](#):
>
> (On the other hand, this snippet might be short enough that even copying it in its entirety counts as fair use. I don’t know, I’m not a copyright lawyer. (Or any other type of lawyer, for that matter.) But I feel that it’s best to be clear and to explicitly state that it’s allowed.)

It’s too short and generic to be copyrightable, and also probably not original. But I totally thought you were joking and being silly.

---

<div class="post-metadata">

### Author: ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)
#### Post date: [July 25, 2019, 12:09am UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/8 "2019-07-25T00:09:09Z")

</div>

If I see code without an explicit license, I often feel squeamish about using it.

---

<div class="post-metadata">

### Author: ![zedmango](https://avatars.discourse-cdn.com/v4/letter/z/c67d28/32.png) [@zedmango](https://forum.beeminder.com/u/zedmango)
#### Post date: [July 25, 2019, 12:11am UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/9 "2019-07-25T00:11:01Z")

</div>

Even if it’s literally one command in a for loop?

---

<div class="post-metadata">

### Author: ![narthur](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/narthur/32/5113_2.png) [@narthur](https://forum.beeminder.com/u/narthur)
#### Post date: [July 25, 2019, 12:25am UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/10 "2019-07-25T00:25:51Z")

</div>

Yeah, probably not. 😉

---

<div class="post-metadata">

### Author: ![zedmango](https://avatars.discourse-cdn.com/v4/letter/z/c67d28/32.png) [@zedmango](https://forum.beeminder.com/u/zedmango)
#### Post date: [July 25, 2019, 12:31am UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/11 "2019-07-25T00:31:52Z")

</div>

Software should be free!!

[https://www.gnu.org/philosophy/shouldbefree.en.html](https://www.gnu.org/philosophy/shouldbefree.en.html)

---

<div class="post-metadata">

### Author: ![zzq](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.beeminder.com/zzq/32/6471_2.png) [@zzq](https://forum.beeminder.com/u/zzq)
#### Post date: [July 25, 2019, 2:44pm UTC](https://forum.beeminder.com/t/my-simple-taskratchet-esque-cron-job/5432/12 "2019-07-25T14:44:28Z")

</div>

> [@zedmango](#):
>
> 10% is about right for me - past that point I’d want to be Locked In.

I’m not sure. 10% of for instance 6 hours is 36 minutes… I guess that could be reasonable, but maybe twice that would be better. Or maybe it shouldn’t be a percentage, because while maybe 20% of 6 hours is reasonable, 20% of 12 hours feels like a lot. I don’t know. Maybe 20% but not more than 1 hour?

> [@zedmango](#):
>
> Does TR have “task descriptions”? I thought it just had task names. How are you editing the task description in TR?

Sorry, I wasn’t being precise with my words. The task name is the place where you describe the task, so it’s the description for this purpose.

> [@zedmango](#):
>
> I’d be very worried that allowing edits of the task **name** would make it easy to cheat. For me it would be a big temptation.

How is it more so than the temptation to enter fake data points in Beeminder, or to falsely say you accomplished it in TaskRatchet? Note also that in Beeminder you absolutely can change the name, description, slug, fineprint, etc however you want whenever you want. Is that really a problem for you with Beeminder?

I have to say that the idea of not being able to fix a typo or change the wording on a task would be quite the turn-off for me. And to use that power to change the meaning of a task is the same as doing that in Beeminder: yes, it’s possible, the same way that adding fake data is possible, but it’s not really a temptation, because it would ruin the whole point.

But we already know that I and you use Beeminder quite differently from one another. That’s fine, I guess. We’ll probably use TaskRatchet differently from one another too. I guess that means it needs to work in some way that fits us both.

> [@zedmango](#):
>
> Or put it in the public domain.

I could, but especially here I like the explicit disclaimer of liability in the MIT license. If someone accidentally sends all their money to Beeminder with this script, they shouldn’t come complaining to me.

> [@zedmango](#):
>
> Just curious, why didn’t you GPL it? 😛

Well, it’s very short, and as you yourself mention it’s unlikely that for practical purposes any copyright can be enforced on it. The point here is the avoidance of doubt, so that everyone can be sure that the evil spectre of copyright doesn’t cloud it, nothing more.

For many of the longer-form programs that I right I use the GPL. The exact cases in which I prefer copyleft like the GPL and in which I prefer licenses like MIT is a discussion in its own right, but it’s safe to say this comes firmly down on the “permissive” side.

> [@zedmango](#):
>
> It’s too short and generic to be copyrightable, and also probably not original. But I totally thought you were joking and being silly.

I’m not so sure. (And that uncertainty is reason enough to license it, because I know that others might not be sure either, even if your correct.) I actually put in a certain amount of effort and thought into designing it just so (I mean, not a lot, but maybe 10 minutes or so. There were decisions made in crafting this, like whether or not if one of the curl commands fails I want the script to continue, and whether or not I want to truncate the tasks file when the script is done.)

It’s plausible (though by no means guaranteed) that this is enough to make it a “creative work”. Or maybe not! I don’t really like the notion of copyright, and I’d be just as happy either way. So: avoid doubt, include a license, and that’s it.

> [@zedmango](#):
>
> Software should be free!!
> 
> [https://www.gnu.org/philosophy/shouldbefree.en.html](https://www.gnu.org/philosophy/shouldbefree.en.html)

Yes, this. I agree, actually. That’s why I do my best to, whenever able, explicitly make my software be free, under one OSS license or another. Maybe sometimes it isn’t really needed, but I’d prefer to err on the side of freedom.

Maybe I am being silly as you say, but if so it’s not the joking kind of silliness: it’s the being overly meticulous on a subject that doesn’t really matter to most people kind of silliness.
