Todo.txt I/O documentation

Welcome! This documentation is about Todo.txt I/O, a simple Python module to parse, manipulate and write Todo.txt data.

pyversion pypiv pypil

This module tries to comply to the Todo.txt specifications (disclaimer: there aren’t any unit tests).

Prerequisites

Should work on any Python 3.x version. Feel free to test with another Python version and give me feedback.

Installation

The usual way:

$ pip install todotxtio

The McGyver way, after cloning/downloading this repo:

$ python setup.py install

Usage

Import the todotxtio module and you are ready to use any of its functions.

Parsing

The functions below all return a plain-old Python list filled with todotxtio.Todo objects (or an empty one if there’s no todos).

import todotxtio

list_of_todos = todotxtio.from_file('todo.txt')
# Or: list_of_todos = todotxtio.from_string(string_full_of_todos)
# Or: list_of_todos = todotxtio.from_stream(stream_full_of_todos)
# Or: list_of_todos = todotxtio.from_dicts(list_of_todos_dict)

The todotxtio.Todo class

Basics

Create a new todo by instantiating a todotxtio.Todo object. You can feed todo data via its constructor arguments (none are required):

todo = todotxtio.Todo(
    text='Thank Guido for such an awesome programming language',
    priority='A',
    creation_date='2016-11-20'
)

print(todo) # (A) 2016-11-20 Thank Guido for such an awesome programming language

Or you also can instantiate an empty (or partially-instantiated) todotxtio.Todo object and define its parameters later:

todo = todotxtio.Todo(
    creation_date='2016-11-20' # For example only, but constructor can be empty and this can be defined later as well
)

todo.text = 'Thank Guido for such an awesome programming language'
todo.priority = 'A'

print(todo) # (A) 2016-11-20 Thank Guido for such an awesome programming language

Once a todotxtio.Todo is instantiated, you can use its attributes to modify its data.

# todo is a Todo instance

todo.text = 'Hello, I\'m the new text'
todo.priority = 'C'
todo.creation_date = None # Deleting the creation date

Playing with todo lists is easy, the same way when manipulating any Python lists:

todos = []

todos.append(todotxtio.Todo(text='A todo in its simplest form!'))

# Updating the completion of the first todo in the todo list (plain Python syntax)
todos[0].completed = True

# Adding a new todo
todos.append(todotxtio.Todo(text='A second todo in its simplest form!'))

# Remove a todo
del todos[0]

Todo dicts

You can export a todotxtio.Todo to a Python dict. Keys and values are exactly the same as the todotxtio.Todo constructor:

# todo is a Todo instance

todo_dict = todo.to_dict()

And vice-versa, you can instantiate a todotxtio.Todo object from a dict using the standard Python way:

todo_dict = {
    'text': 'Hey ho!',
    'completed': True,
    'priority': 'D',
    'projects': ['blah']
}

todo = todotxtio.Todo(**todo_dict)

Projects and contexts

They are both plain-old Python lists without leadings + and @:

todo = todotxtio.Todo(
    text='Thank Guido for such an awesome programming language',
    priority='A',
    creation_date='2016-11-20'
)

# Define some projects and contexts
todo.projects = ['python']
todo.contexts = ['awesomeness', 'ftw']

# Append to existings projects or contexts
todo.projects.append('awesome-project')
todo.contexts.append('cool')

# Remove a context
todo.contexts.remove('cool')

# Empty the projects list
todo.projects = [] # Or None

print(todo) # (A) 2016-11-20 Thank Guido for such an awesome programming language @awesomeness @ftw

Todo completion

You can either mark a todo as completed by setting its completed attribute to True:

todo = todotxtio.Todo(
    text='Thank Guido for such an awesome programming language',
    priority='A',
    creation_date='2016-11-20'
)

todo.completed = True

print(todo) # x (A) 2016-11-20 Thank Guido for such an awesome programming language

Or by defining its completion date, which automatically set its completed attribute to True:

todo = todotxtio.Todo(
    text='Thank Guido for such an awesome programming language',
    priority='A',
    creation_date='2016-11-20'
)

todo.completion_date = '2016-12-01'

print(todo) # x 2016-12-01 (A) 2016-11-20 Thank Guido for such an awesome programming language

This is also applicable to the todotxtio.Todo constructor.

Of course, inverse is also applicable (setting completed to False removes the completion date).

Tags

Tags, also called add-ons metadata, are represented by a simple one-dimension dictionary. They allow you to easily define and retrieve custom formatted data:

todo = todotxtio.Todo(
    text='Thank Guido for such an awesome programming language'
)

todo.tags = { # Define some tags
    'key': 'value',
    'second': 'tag'
}

todo.tags['due'] = '2016-12-01'

# Remove a tag
del todo.tags['second']

print(todo) # Thank Guido for such an awesome programming language key:value due:2016-12-01

# Empty tags
todo.tags = {} # Or None

Searching a todo list

You can search in a given todo list using the handy todotxtio.search() with its filter criteria.

# list_of_todos is a list of Todo objects

results = todotxtio.search(list_of_todos,
    priority=['A', 'C'],
    contexts=['home'],
    projects=['python', 'todo'],
    completed=True,
    completion_date='2016-11-20',
    creation_date='2016-11-15',
    tags={'due': '2016-12-01'},
    text='todo content'
)

Writing

Quite simple.

# list_of_todos is a list of Todo objects

todotxtio.to_file('todo.txt', list_of_todos)
# Or: string_full_of_todos = todotxtio.to_string(list_of_todos)
# Or: todotxtio.to_stream(stream, list_of_todos)
# Or: list_of_todos_dict = todotxtio.to_dicts(list_of_todos)

Gotchas

  • Projects, contexts and tags will always be appended to the end of each todos when exporting them. This means that if you’re parsing such a todo:

I'm in love with +python. due:2016-12-01 Python @ftw guys

And then if you’re writing it to a file (without even modifying it), you’ll end with:

I'm in love with. Python guys +python @ftw due:2016-12-01

Not ideal, I know (at least for projects and contexts).

  • This is my very first PyPI package.

API docs

class todotxtio.Todo(text=None, completed=False, completion_date=None, priority=None, creation_date=None, projects=None, contexts=None, tags=None)

Represent one todo.

Parameters
  • text (str) – The text of the todo

  • completed (bool) – Should this todo be marked as completed?

  • completion_date (str) – A date of completion, in the YYYY-MM-DD format. Setting this property will automatically set the completed attribute to True.

  • priority (str) – The priority of the todo represented by a char between A-Z

  • creation_date (str) – A date of creation, in the YYYY-MM-DD format

  • projects (list) – A list of projects without leading +

  • contexts (list) – A list of projects without leading @

  • tags (dict) – A dict of tags

completed = False
completion_date = None
contexts = []
creation_date = None
priority = None
projects = []
tags = {}
text = None
to_dict()

Return a dict representation of this Todo instance.

Return type

dict

todotxtio.from_dicts(todos)

Convert a list of todo dicts to a list of todotxtio.Todo objects.

Parameters

todos (list) – A list of todo dicts

Return type

list

todotxtio.from_file(file_path, encoding='utf-8')

Load a todo list from a file.

Parameters
  • file_path (str) – Path to the file

  • encoding (str) – The encoding of the file to open

Return type

list

todotxtio.from_stream(stream, close=True)

Load a todo list from an already-opened stream.

Parameters
  • stream (file) – A file-like object

  • close (bool) – Whetever to close the stream or not after all operation are finised

Return type

list

todotxtio.from_string(string)

Load a todo list from a string.

Parameters

string (str) – The string to parse

Return type

list

todotxtio.search(todos, text=None, completed=None, completion_date=None, priority=None, creation_date=None, projects=None, contexts=None, tags=None)

Return a list of todos that matches the provided filters.

It takes the exact same parameters as the todotxtio.Todo object constructor, and return a list of todotxtio.Todo objects as well. All criteria defaults to None which means that the criteria is ignored.

A todo will be returned in the results list if all of the criteria matches. From the moment when a todo is sent in the results list, it will never be checked again.

Parameters
  • text (str) – String to be found in the todo text

  • completed (bool) – Search for completed/uncompleted todos only

  • completion_date (str) – Match this completion date

  • priority (list) – List of priorities to match

  • creation_date (str) – Match this creation date

  • projects (list) – List of projects to match

  • contexts (list) – List of contexts to match

  • tags (dict) – Dict of tag to match

Return type

list

todotxtio.to_dicts(todos)

Convert a list of todotxtio.Todo objects to a list of todo dict.

Parameters

todos (list) – List of todotxtio.Todo objects

Return type

list

todotxtio.to_file(file_path, todos, encoding='utf-8')

Write a list of todos to a file.

Parameters
  • file_path (str) – Path to the file

  • todos (list) – List of todotxtio.Todo objects

  • encoding (str) – The encoding of the file to open

Return type

None

todotxtio.to_stream(stream, todos, close=True)

Write a list of todos to an already-opened stream.

Parameters
  • stream (file) – A file-like object

  • todos (list) – List of todotxtio.Todo objects

  • close (bool) – Whetever to close the stream or not after all operation are finised

Return type

None

todotxtio.to_string(todos)

Convert a list of todos to a string.

Parameters

todos (list) – List of todotxtio.Todo objects

Return type

str