Skip to content
This repository has been archived by the owner on Apr 9, 2024. It is now read-only.

Commit

Permalink
Use dicts for tags instead of list of tuples
Browse files Browse the repository at this point in the history
  • Loading branch information
EpocDotFr committed Dec 5, 2016
1 parent a772238 commit e008454
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 25 deletions.
38 changes: 21 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,28 @@

A simple Python module to parse, manipulate and write [Todo.txt](http://todotxt.com/) data.

[![PyPI](https://img.shields.io/pypi/v/todotxtio.svg)]() [![PyPI](https://img.shields.io/pypi/l/todotxtio.svg)]()
[![PyPI](https://img.shields.io/pypi/pyversions/todotxtio.svg)]() [![PyPI](https://img.shields.io/pypi/v/todotxtio.svg)]() [![PyPI](https://img.shields.io/pypi/l/todotxtio.svg)]()

This module 100% comply to the [Todo.txt specifications](https://github.com/ginatrapani/todo.txt-cli/wiki/The-Todo.txt-Format). There aren't any unit tests, but trust me.
This module tries to comply to the [Todo.txt specifications](https://github.com/ginatrapani/todo.txt-cli/wiki/The-Todo.txt-Format) (disclaimer: there aren't any unit tests).

## Prerequisites

[![PyPI](https://img.shields.io/pypi/pyversions/todotxtio.svg)]()

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

Firstly, import the module:
Expand All @@ -35,11 +41,9 @@ The functions below all return a plain-old Python list filled with `Todo` object
**Parsing from a file:**

```python
todos = todotxtio.from_file('todo.txt')
todos = todotxtio.from_file('todo.txt', encoding='utf-8') # utf-8 is the default
```

**Note:** The Todo.txt file is assumed to be UTF-8 encoded.

**Parsing from a string:**

```python
Expand Down Expand Up @@ -201,28 +205,28 @@ Of course, inverse is also applicable (setting `completed` to `False` removes th

#### Tags

Tags, also called add-ons metadata, are lists of key/value represented by a tuple. They allow you to easily
define and retrieve custom data:
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:

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

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

todo.tags.append(('due', '2016-12-01')) # Append to existing
todo.tags['due'] = '2016-12-01'

# Remove a tag
del todo.tags[1]
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
todo.tags = {} # Or None
```

#### Searching a todo list
Expand Down Expand Up @@ -257,7 +261,7 @@ At some point you'll need to save your todo list.
```python
# todos is a list of Todo objects

todotxtio.to_file('todo.txt', todos)
todotxtio.to_file('todo.txt', todos, encoding='utf-8') # utf-8 is the default
```

**Caution:** This will overwrite the whole file. Also, data will be UTF-8 encoded.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
name='todotxtio',
version=todotxtio.__version__,
description='A simple Python module to parse, manipulate and write Todo.txt data',
long_description='All you need to know is located `here <https://github.com/EpocDotFr/todotxtio>`_.',
long_description='You can find the documentation `here <https://github.com/EpocDotFr/todotxtio#readme>`_.',
url='https://github.com/EpocDotFr/todotxtio',
author='Maxime "Epoc" G.',
author_email='[email protected]',
Expand Down
22 changes: 15 additions & 7 deletions todotxtio.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
import re

__version__ = '0.1.0'
__version__ = '0.2.0'

__all__ = [
'from_dicts',
Expand Down Expand Up @@ -99,7 +99,9 @@ def from_string(string):
todo_tags = todo_tag_regex.findall(text)

if len(todo_tags) > 0:
todo.tags = todo_tags
for todo_tag in todo_tags:
todo.tags[todo_tag[0]] = todo_tag[1]

text = todo_tag_regex.sub('', text).strip()

todo.text = text
Expand Down Expand Up @@ -146,7 +148,7 @@ class Todo:
:param str creation_date: A create date, in the YYYY-MM-DD format (default to None)
:param list projects: A list of projects without + (default to an empty list)
:param list contexts: A list of projects without @ (default to an empty list)
:param list tags: A list of tags (default to an empty list)
:param list tags: A dict of tags (default to an empty dict)
"""
text = None
completed = False
Expand All @@ -155,7 +157,7 @@ class Todo:
creation_date = None
projects = []
contexts = []
tags = []
tags = {}

def __init__(self, text=None, completed=False, completion_date=None, priority=None, creation_date=None, projects=None, contexts=None, tags=None):
self.text = text
Expand Down Expand Up @@ -192,12 +194,18 @@ def __setattr__(self, name, value):
super().__setattr__('completed', True) # Setting the completion date must set this todo as completed...
else:
super().__setattr__('completed', False) # ...and vice-versa
elif name in ['projects', 'contexts', 'tags']:
elif name in ['projects', 'contexts']:
if not value:
super().__setattr__(name, []) # Force contexts, projects and tags to be lists when setting them to a falsely value
super().__setattr__(name, []) # Force contexts, projects to be lists when setting them to a falsely value
return
elif type(value) is not list: # Make sure, otherwise, that the provided value is a list
raise ValueError(name + ' should be a list')
elif name == 'tags':
if not value:
super().__setattr__(name, {}) # Force tags to be a dict when setting them to a falsely value
return
elif type(value) is not dict: # Make sure, otherwise, that the provided value is a dict
raise ValueError(name + ' should be a dict')

super().__setattr__(name, value)

Expand Down Expand Up @@ -226,7 +234,7 @@ def __str__(self):
ret.append(''.join([' @' + context for context in self.contexts]).strip())

if self.tags:
ret.append(''.join([' ' + tag[0] + ':' + tag[1] for tag in self.tags]).strip())
ret.append(''.join([' ' + tag_name + ':' + tag_value for tag_name, tag_value in self.tags.items()]).strip())

return ' '.join(ret)

Expand Down

0 comments on commit e008454

Please sign in to comment.