Update readme for 2.3 release

This commit is contained in:
Scot Hacker 2019-03-25 23:43:34 -07:00
parent 6996c25842
commit b3d94ab608
2 changed files with 214 additions and 83 deletions

View file

@ -15,6 +15,7 @@ assignment application for Django, designed to be dropped into an existing site
* Mobile-friendly (work in progress)
* Separate view for My Tasks (across lists)
* Batch-import tasks via CSV
* Integrated mail tracking (unify a task list with an email box)
## Requirements
@ -28,7 +29,7 @@ assignment application for Django, designed to be dropped into an existing site
## Overview
The assumption is that your organization/publication/company has multiple groups of employees, each with multiple users (where actual users and groups map to Django Users and Groups). Users may belong to multiple groups, and each group can have multiple todo lists.
We assume that your organization has multiple groups of employees, each with multiple users (where actual users and groups map to Django Users and Groups). Users may belong to multiple groups, and each group can have multiple todo lists.
You must have at least one Group set up in Django admin, and that group must have at least one User as a member. This is true even if you're the sole user of django-todo.
@ -78,23 +79,27 @@ Put django-todo/todo somewhere on your Python path, or install via pip:
Add to your settings:
INSTALLED_APPS = (
...
'todo',
)
```
INSTALLED_APPS = (
...
'todo',
)
```
Create database tables:
Migrate in database tables:
python manage.py migrate todo
`python manage.py migrate todo`
Add to your URL conf:
path('todo/', include('todo.urls', namespace="todo")),
`path('todo/', include('todo.urls', namespace="todo")),`
Add links to your site's navigation system:
<a href="{% url 'todo:lists' %}">Todo Lists</a>
<a href="{% url 'todo:mine' %}">My Tasks</a>
```
<a href="{% url 'todo:lists' %}">Todo Lists</a>
<a href="{% url 'todo:mine' %}">My Tasks</a>
```
django-todo makes use of the Django `messages` system. Make sure you have something like [this](https://docs.djangoproject.com/en/2.0/ref/contrib/messages/#displaying-messages) (link) in your `base.html`.
@ -155,7 +160,7 @@ django-todo has the ability to batch-import ("upsert") tasks from a specifically
**Web Importer**
Link from your navigation to `{url "todo:import_csv"}`
Link from your navigation to `{url "todo:import_csv"}`. Follow the resulting link for the CSV web upload view.
### CSV Formatting
@ -307,9 +312,7 @@ django-todo no longer references a jQuery datepicker, but defaults to native htm
## Version History
**2.4.0** Added ability to batch-import tasks via CSV
**2.3.0** Implement mail tracking system
**2.3.0** Implement mail tracking system. Added ability to batch-import tasks via CSV. Fixed task re-ordering if task deleted behind the scenes.
**2.2.2** Update dependencies

View file

@ -15,6 +15,7 @@ assignment application for Django, designed to be dropped into an existing site
* Mobile-friendly (work in progress)
* Separate view for My Tasks (across lists)
* Batch-import tasks via CSV
* Integrated mail tracking (unify a task list with an email box)
## Requirements
@ -24,10 +25,11 @@ assignment application for Django, designed to be dropped into an existing site
* jQuery (full version, not "slim", for drag/drop prioritization)
* Bootstrap (to work with provided templates, though you can override them)
* bleach (`pip install bleach`)
* django-autocomplete-light (optional, required for task merging)
## Overview
The assumption is that your organization/publication/company has multiple groups of employees, each with multiple users (where actual users and groups map to Django Users and Groups). Users may belong to multiple groups, and each group can have multiple todo lists.
We assume that your organization has multiple groups of employees, each with multiple users (where actual users and groups map to Django Users and Groups). Users may belong to multiple groups, and each group can have multiple todo lists.
You must have at least one Group set up in Django admin, and that group must have at least one User as a member. This is true even if you're the sole user of django-todo.
@ -51,10 +53,9 @@ django-todo is a Django app, not a project site. It needs a site to live in. You
If using your own site, be sure you have jQuery and Bootstrap wired up and working.
django-todo pages that require it will insert additional CSS/JavaScript into page heads,
so your project's base templates must include:
django-todo views that require it will insert additional CSS/JavaScript into page heads, so your project's base templates must include:
```
```jinja
{% block extrahead %}{% endblock extrahead %}
{% block extra_js %}{% endblock extra_js %}
```
@ -78,37 +79,45 @@ Put django-todo/todo somewhere on your Python path, or install via pip:
Add to your settings:
INSTALLED_APPS = (
...
'todo',
)
```
INSTALLED_APPS = (
...
'todo',
)
```
Create database tables:
Migrate in database tables:
python manage.py migrate todo
`python manage.py migrate todo`
Add to your URL conf:
path('todo/', include('todo.urls', namespace="todo")),
`path('todo/', include('todo.urls', namespace="todo")),`
Add links to your site's navigation system:
<a href="{% url 'todo:lists' %}">Todo Lists</a>
<a href="{% url 'todo:mine' %}">My Tasks</a>
```
<a href="{% url 'todo:lists' %}">Todo Lists</a>
<a href="{% url 'todo:mine' %}">My Tasks</a>
```
django-todo makes use of the Django `messages` system. Make sure you have something like [this](https://docs.djangoproject.com/en/2.0/ref/contrib/messages/#displaying-messages) (link) in your `base.html`.
Log in and access `/todo`!
### Customizing Templates
The provided templates are fairly bare-bones, and are meant as starting points only. Unlike previous versions of django-todo, they now ship as Bootstrap examples, but feel free to override them - there is no hard dependency on Bootstrap. To override a template, create a `todo` folder in your project's `templates` dir, then copy the template you want to override from django-todo source and into that dir.
### Filing Public Tickets
If you wish to use the public ticket-filing system, first create the list into which those tickets should be filed, then add its slug to `TODO_DEFAULT_LIST_SLUG` in settings (more on settings below).
## Settings
Optional configuration options:
Optional configuration params, which can be added to your project settings:
```
```python
# Restrict access to ALL todo lists/views to `is_staff` users.
# If False or unset, all users can see all views (but more granular permissions are still enforced
# within views, such as requiring staff for adding and deleting lists).
@ -127,12 +136,162 @@ TODO_DEFAULT_LIST_SLUG = 'tickets'
# Defaults to "/"
TODO_PUBLIC_SUBMIT_REDIRECT = 'dashboard'
# additionnal classes the comment body should hold
# adding "text-monospace" makes comment monospace
TODO_COMMENT_CLASSES = []
# The following two settings are relevant only if you want todo to track a support mailbox -
# see Mail Tracking below.
TODO_MAIL_BACKENDS
TODO_MAIL_TRACKERS
```
The current django-todo version number is available from the [todo package](https://github.com/shacker/django-todo/blob/master/todo/__init__.py):
python -c "import todo; print(todo.__version__)"
## Importing Tasks via CSV
django-todo has the ability to batch-import ("upsert") tasks from a specifically formatted CSV spreadsheet. This ability is provided through both a management command and a web interface.
**Management Command**
`./manage.py import_csv -f /path/to/file.csv`
**Web Importer**
Link from your navigation to `{url "todo:import_csv"}`. Follow the resulting link for the CSV web upload view.
### CSV Formatting
Copy `todo/data/import_example.csv` to another location on your system and edit in a spreadsheet or directly.
**Do not edit the header row!**
The first four columns: `'Title', 'Group', 'Task List', 'Created By'` are required -- all others are optional and should work pretty much exactly like manual task entry via the web UI.
Note: Internally, Tasks are keyed to TaskLists, not to Groups (TaskLists are in Gruops). However, we request the Group in the CSV
because it's possible to have multiple TaskLists with the same name in different groups; i.e. we need it for namespacing and permissions.
### Import Rules
Because data entered via CSV is not going through the same view permissions enforced in the rest of django-todo, and to simplify data dependency logic, and to pre-empt disagreements between django-todo users, the importer will *not* create new users, groups, or task lists. All users, groups, and task lists referenced in your CSV must already exist, and group memberships must be correct.
Any validation error (e.g. unparse-able dates, incorrect group memberships) **will result in that row being skipped.**
A report of rows upserted and rows skipped (with line numbers and reasons) is provided at the end of the run.
### Upsert Logic
For each valid row, we need to decide whether to create a new task or update an existing one. django-todo matches on the unique combination of the four required columns. If we find a task that matches those, we *update* the rest of the columns. In other words, if you import a CSV once, then edit the Assigned To for a task and import it again, the original task will be updated with a new assignee (and same for the other columns).
Otherwise we create a new task.
## Mail Tracking
What if you could turn django-todo into a shared mailbox? Django-todo includes an optional feature that allows emails
sent to a dedicated mailbox to be pushed into todo as new tasks, and responses to be added as comments on those tasks.
This allows support teams to work with a fully unified email + bug tracking system to avoid confusion over who's seen or
responded to what.
To enable mail tracking, you need to:
- Define an email backend for outgoing emails
- Define an email backend for incoming emails
- Start a worker, which will wait for new emails
In settings:
```python
from todo.mail.producers import imap_producer
from todo.mail.consumers import tracker_consumer
from todo.mail.delivery import smtp_backend, console_backend
# email notifications configuration
# each task list can get its own delivery method
TODO_MAIL_BACKENDS = {
# mail-queue is the name of the task list, not the worker name
"mail-queue": smtp_backend(
host="smtp.example.com",
port=465,
use_ssl=True,
username="test@example.com",
password="foobar",
# used as the From field when sending notifications.
# a username might be prepended later on
from_address="test@example.com",
# additionnal headers
headers={}
),
}
# incoming mail worker configuration
TODO_MAIL_TRACKERS = {
# configuration for worker "test_tracker"
"test_tracker": {
"producer": imap_producer(
host="imap.example.com",
username="text@example.com",
password="foobar",
# process_all=False, # by default, only unseen emails are processed
# preserve=False, # delete emails if False
# nap_duration=1, # duration of the pause between polling rounds
# input_folder="INBOX", # where to read emails from
),
"consumer": tracker_consumer(
group="Mail Queuers",
task_list_slug="mail-queue",
priority=1,
task_title_format="[TEST_MAIL] {subject}",
)
}
}
```
A mail worker can be started with:
```sh
./manage.py mail_worker test_tracker
```
Some views and URLs were renamed in 2.0 for logical consistency. If this affects you, see source code and the demo GTD site for reference to the new URL names.
If you want to log mail events, make sure to properly configure django logging:
```python
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
},
}
```
## Running Tests
django-todo uses pytest exclusively for testing. The best way to run the suite is to clone django-todo into its own directory, install pytest, then:
pip install pytest pytest-django
pip install --editable .
pytest -x -v
The previous `tox` system was removed with the v2 release, since we no longer aim to support older Python or Django versions.
## Upgrade Notes
django-todo 2.0 was rebuilt almost from the ground up, and included some radical changes, including model name changes. As a result, it is *not compatible* with data from django-todo 1.x. If you would like to upgrade an existing installation, try this:
@ -151,62 +310,11 @@ That was the plan, but unfortunately, `makemigrations` created new tables and dr
django-todo no longer references a jQuery datepicker, but defaults to native html5 browser datepicker (not supported by Safari, unforunately). Feel free to implement one of your choosing.
### URLs
Some views and URLs were renamed in 2.0 for logical consistency. If this affects you, see source code and the demo GTD site for reference to the new URL names.
## Running Tests
django-todo uses pytest exclusively for testing. The best way to run the suite is to clone django-todo into its own directory, install pytest, then:
pip install pytest pytest-django
pip install --editable .
pytest -x -v
The previous `tox` system was removed with the v2 release, since we no longer aim to support older Python or Django versions.
## Importing Tasks via CSV
django-todo has the ability to batch-import ("upsert") tasks from a specifically formatted CSV spreadsheet. This ability is provided through both a management command and a web interface.
**Management Command**
`./manage.py import_csv -f /path/to/file.csv`
**Web Importer**
Link from your navigation to `{url "todo:import_csv"}`
### Import Rules
Because data entered via CSV is not going through the same view permissions enforced in the rest of django-todo, and to simplify data dependency logic, and to pre-empt disagreements between django-todo users, the importer will *not* create new users, groups, or task lists. All users, groups, and task lists referenced in your CSV must already exist, and group memberships must be correct.
Any validation error (e.g. unparse-able dates, incorrect group memberships) **will result in that row being skipped.**
A report of rows upserted and rows skipped (with line numbers and reasons) is provided at the end of the run.
### CSV Formatting
Copy `todo/data/import_example.csv` to another location on your system and edit in a spreadsheet or directly.
**Do not edit the header row!**
The first four columns: `'Title', 'Group', 'Task List', 'Created By'` are required -- all others are optional and should work pretty much exactly like manual task entry via the web UI.
Note: Internally, Tasks are keyed to TaskLists, not to Groups (TaskLists are in Gruops). However, we request the Group in the CSV
because it's possible to have multiple TaskLists with the same name in different groups; i.e. we need it for namespacing and permissions.
### Upsert Logic
For each valid row, we need to decide whether to create a new task or update an existing one. django-todo matches on the unique combination of the four required columns. If we find a task that matches those, we *update* the rest of the columns. In other words, if you import a CSV once, then edit the Assigned To for a task and import it again, the original task will be updated with a new assignee (and same for the other columns).
Otherwise we create a new task.
## Version History
**2.3.0** Added ability to batch-import tasks via CSV
**2.3.0** Implement mail tracking system. Added ability to batch-import tasks via CSV. Fixed task re-ordering if task deleted behind the scenes.
**2.2.2** Update dependencies
**2.2.1** Convert task delete and toggle_done views to POST only
@ -268,4 +376,24 @@ ALL groups, not just the groups they "belong" to)
**0.9** - First release
## Todo 2.0 Upgrade Notes
django-todo 2.0 was rebuilt almost from the ground up, and included some radical changes, including model name changes. As a result, it is *not compatible* with data from django-todo 1.x. If you would like to upgrade an existing installation, try this:
* Use `./manage.py dumpdata todo --indent 4 > todo.json` to export your old todo data
* Edit the dump file, replacing the old model names `Item` and `List` with the new model names (`Task` and `TaskList`)
* Delete your existing todo data
* Uninstall the old todo app and reinstall
* Migrate, then use `./manage.py loaddata todo.json` to import the edited data
### Why not provide migrations?
That was the plan, but unfortunately, `makemigrations` created new tables and dropped the old ones, making this a destructive update. Renaming models is unfortunately not something `makemigrations` can do, and I really didn't want to keep the badly named original models. Sorry!
### Datepicker
django-todo no longer references a jQuery datepicker, but defaults to native html5 browser datepicker (not supported by Safari, unforunately). Feel free to implement one of your choosing.
### URLs
Some views and URLs were renamed for logical consistency. If this affects you, see source code and the demo GTD site for reference to the new URL names.