+import sys, re, clipboard, json, webbrowser
+from urllib import parse
+ Extracts task name, note and due date from an OmniFocus task URL
+ and returns a dictionary.
+ # Patterns to match the task name and the
+ # task note in the OmniFocus URL.
+ # The URL will look this:
+ # omnifocus:///task/cahy7K5409b?name=Task%20name¶llel=true&due=2017-05-19%2017:00&project=My%20Project
+ name_pattern = re.compile(r'name=([^&]+)&')
+ note_pattern = re.compile(r'note=([^&]+)&')
+ due_date_pattern = re.compile(r'due=([^&]+)&')
+ # Get the task name from the URL and
+ # replace URL-encoded characters
+ # (e.g., replace %20 with a space)
+ name_match = name_pattern.search(encoded)
+ if name_match is not None:
+ task_name = parse.unquote(name_match.groups()[0])
+ # Get the task note (if present) from the URL and
+ # replace URL-encoded characters
+ note_match = note_pattern.search(encoded)
+ if note_match is not None:
+ task_note = parse.unquote(note_match.groups()[0])
+ # Get the due date (if present) from the URL and
+ # replace URL-encoded characters
+ due_date_match = due_date_pattern.search(encoded)
+ if due_date_match is not None:
+ due_date = parse.unquote(due_date_match.groups()[0])
+ # Create a dictionary with the task name,
+ # task note (if present) and due date (if present).
+ task_info = {'name': task_name}
+ if task_note is not None:
+ task_info['note'] = task_note
+ task_info['note'] = '(None)'
+ if due_date is not None:
+ task_info['due_date'] = due_date
+ task_info['due_date'] = '(None)'
+ # Write the dictionary to a JSON string
+ # and copy the string to the clipboard.
+ task_info_json = json.dumps(task_info)
+ clipboard.set(task_info_json)
+ # Finally, open OmniFocus to continue running the workflow
+ webbrowser.open('omnifocus://')
+if __name__ == "__main__":