Beeminder Forum

My simple TaskRatchet-esque cron job

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:

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.)
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:

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.)

2 Likes

Love it! :smiley: 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?

1 Like
  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.)

2 Likes

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.
3 Likes

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.

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

:joy: :joy: :joy_cat: Love that you copyrighted and licensed a while loop with one curl command in it!

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.

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.

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.)

3 Likes

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.

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?

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

Or put it in the public domain.

Just curious, why didn’t you GPL it? :stuck_out_tongue:

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

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

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

Yeah, probably not. :wink:

Software should be free!!

https://www.gnu.org/philosophy/shouldbefree.en.html

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?

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.

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.

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.

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.

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.

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.

1 Like