Deprecated: Return type of I::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 62

Deprecated: Return type of I::next() should either be compatible with Iterator::next(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 91

Deprecated: Return type of I::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 71

Deprecated: Return type of I::valid() should either be compatible with Iterator::valid(): bool, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 101

Deprecated: Return type of I::rewind() should either be compatible with Iterator::rewind(): void, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/i.php on line 53

Deprecated: Return type of Collection::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /home/public/kirby/toolkit/lib/collection.php on line 80

Deprecated: parse_str(): Passing null to parameter #1 ($string) of type string is deprecated in /home/public/kirby/toolkit/lib/url.php on line 135
One Tap Less | Get things done (next saturday)

Get things done (next saturday)


Deprecated: preg_split(): Passing null to parameter #2 ($subject) of type string is deprecated in /home/public/kirby/toolkit/lib/html.php on line 107

Drafts offers several template tags to insert the actual date into an action, you can check the entire list here. Unfortunately, Drafts is still unable to make simple operations on dates, meaning that if you want to set a task in Things with a due date for tomorrow, you won't be able to. We gonna fix this.

We're particularly lucky that Text Expander supports date and time basic operations, meaning that you can easily create a snippet to grab the actual date and add another day to get tomorrow. Drafts allows you to expand Text Expander snippets within an action, so these snippets may come in hand.

Considering the date I'm publishing this article as 2013-8-24, for tomorrow, your snippet must be %Y-%m-%@+1D%d, which will render into 2013-8-25. For next week, you need %Y-%m-%@+7D%d, the outcome will be 2013-8-31. Perhaps you want a middle term, what about three days from today? It would be %Y-%m-%@+3D%d, which will result in 2013-08-27. Maybe you don't want to deal with this task until next month, so you need %Y-%@+1M%m-%d. Easy, right? You can get all these snippets installing this file or install them manually from the cheat sheet down here.

?t = Tomorrow = %Y-%m-%@+1D%d
?w = Next Week = %Y-%m-%@+7D%d
?l = In 3 days = %Y-%m-%@+3D%d
?m = Next Month = %Y-%@+1M%m-%d

What about an example? Get on Drafts and let's create a task with due date for tomorrow in Things:

Tomorrow:

things:add?title=[[title]]&notes=[[body]]&dueDate=<<?t>>

Notice how my snippet is wrapped by chevrons, that's because I enabled this option in Drafts, it'll only expand TextExpander snippets if they're fenced by chevrons. This option is disabled by default, so hit Settings and look for Expand TextExpander snippets in actions, then choose Fenced.

But maybe you use Due, then there's no need for TextExpander since Due allows you to set alarms directly from the actual time in total seconds, minutes or hours, respectively secslater, minslater and hourslater. This will create a reminder exactly 24 hours after you trigger the action and return to Drafts:

Due Tomorrow:

due://x-callback-url/add?title=[[draft]]&hourslater=24&x-success={{drafts://}}

But do you wanna know what none of these workflows do? You can't set a task or a reminder to next weekend, for example, as you would be able to from Mailbox which would bring the email back to you on the saturday. If you're on monday, you gotta add 5 days, wednesday, 3; so there's no way to give an exact value and expect the correct outcome. Unless, of course, we use Pythonista.

We're going to work on a script that grabs the current date and selects the next saturday. Every week day in python has a number, monday is 0, sunday is 6, therefore saturday is 5. It is easy to get current date + 5 days minus the current weekday, this would get the next saturday for most of our week, however, on a saturday the result would be 0, rendering the actual day, while we need it to be 7, pointing to the saturday from the upcoming weekend. Sunday also results in a -1, calling for yesterday. We need it to result in 6. So our hex is 12 instead of 5.

Let's cut the crap lose, paste the following script into Pythonista, I like to call it Weekend.

import datetime

d = datetime.date.today()

next = d + datetime.timedelta(days= 5-d.weekday() if d.weekday()<5 else 12-d.weekday())

This is the basic to achieve what we want, you can do a few things with this, such as running the script and inserting it as the first line of text in Drafts so you can call whatever action you want using our variable:

import datetime
from webbrowser import open

d = datetime.date.today()

next = d + datetime.timedelta(days= 5-d.weekday() if d.weekday()<5 else 12-d.weekday())

open('drafts://x-callback-url/create?text=' + str(next) + '%0A')

Whatever you want to do from this point on is easy, to create a Things task with due date for saturday, just replace the last line of the last script for open('things:add?dueDate=' + str(next)), however, it won't work because it requires, at least, the title parameter. So, let's call a Pythonista action from Drafts with a title and maybe notes and send it to Things with a due date to next saturday. First step is adding the Drafts action:

WeekendThings:

pythonista://WeekendThings?action=run&argv=[[title]]&argv=[[body]]

Since we're dealing with text coming from Drafts, we must also use the urllib module in Pythonista to encode the text when sending it to Things. The final script will look like this:

import datetime
from webbrowser import open
from urllib import quote

d = datetime.date.today()

next = d + datetime.timedelta(days= 5-d.weekday() if d.weekday()<5 else 12-d.weekday())

open('things:add?title=' + quote(sys.argv[1]) + '&notes=' + quote(sys.argv[2]) + '&dueDate=' + str(next))

What if I want to use Due?

If you want to achieve this same aftermath in Due and Due only, you gonna need to tweak this script a little bit. Let's add a new Drafts action to play with this new possibility:

WeekendDue:

pythonista://WeekendDue?action=run&argv=[[draft]]

The next one goes into Pythonista, I named it WeekendDue, as you can see by the Drafts action.

import datetime
from webbrowser import open
from urllib import quote

d = datetime.date.today().weekday()

def saturday(s):
    if s<5:
        return (5 - s)*24
    else:
        return (12 - s)*24

open('due://x-callback-url/add?title=' + quote(sys.argv[1]) + '&hourslater=' + str(saturday(d)) + '&x-source=Drafts&x-success=drafts://')

It works almost as our first script, but we're using the integers for weekday instead of playing with dates, then we multiply the result by 24 and use the hourslater template tag from Due. However, if you active this script at 8 am, it'll create a reminder for next saturday at 8 am, who's awake this early at saturday? what about making it ring at 12pm instead?

import datetime
from webbrowser import open
import time
from urllib import quote

d = datetime.time.today().weekday()
t = (time.localtime().tm_hour*60+time.localtime().tm_min)-720

def saturday(s):
    if s<5:
        return ((5 - s)*1440)-t
    else:
        return ((12 - s)*1440)-t

open('due://x-callback-url/add?title=' + quote(sys.argv[1]) + '&minslater=' + str(saturday(d)) + '&x-source=Drafts&x-success=drafts://')

This last action will create a reminder on next saturday at 12 pm regardless of the time you trigger the action based on what you wrote in Drafts. Now, do you have what it takes to become the time master of URL schemes?