Immaculater is a simple to-do list, a website and a command-line interface (CLI).
Immaculater is a Django project (a website) configured for use on Heroku (a
cloud hosting provider). It's a Python implementation of Yet Another
To-Do List. Immaculater is the application; pyatdl (pronounced "PEE-ott")
is the Python library underneath it (see the pyatdllib/
subdirectory).
Why yet another to-do list? This one is inspired by David Allen's book Getting Things Done, so it has Next Actions, Projects, Contexts and support for Reviews. It is open source. It has a command-line interface. It is meant to be a literate program, a teaching tool. It has a snappy, lightweight web user interface (UI) that's great on your phone as well as your desktop.
To get an Immaculater account, or for general help, e-mail immaculaterhelp@gmail.com.
There is a prominent "Help" page under the 'Other' drop-down on the top
navigation bar, and there is a
40-minute screencast. If you
want to be a power user, try running help
in the command-line interface on
the website (it's a prominent button on the home page). For a real command-line
interface that uses the same database as the website, see
cli/README.md
.
The remainder of this document is for you. To get started, watch this screencast. Then watch this screencast on protocol buffers. There's also a screencast on unguessable base64 URL slugs and django modeling of a nascent sharing feature. And a screencast on a jquery-pjax tweak related to flash messages and the quick capture box on the home page. And a screencast coding up the "Delete Completed" feature.
Next, forget about Heroku
and Django and focus on the original command-line interface (as opposed to
cli/todo.py
which requires the Django server). You'll find it in the
pyatdllib
subdirectory -- see
pyatdllib/README.md
. You
will need to run pip install -r requirements.txt
inside a virtualenv
(see
below) before make test
will pass or the CLI will run. You can use runme.sh
to start the original CLI.
- Create a virtualenv with
virtualenv venv
source venv/bin/activate
- Install postgresql. On OS X,
brew install postgresql
after installing Homebrew. On Linux,apt-get install postgresql postgresql-contrib
- On Linux,
apt-get Install python-dev python3-dev
- Run
pip install -r requirements.txt
(again, after activating the virtualenv) - Install the Heroku CLI
- Create a Heroku account
- Run
heroku login
python manage.py migrate
python manage.py createsuperuser
heroku create -a <yourprj>
- Or, if you already created your project but you're working from a new
pyatdl
directory, runheroku git:remote -a <yourprj>
and then rungit remote add
as directed. - Folow the steps below for 'Heroku Deployment'
- Generate two encryption keys as follows:
$ heroku run python manage.py shell
Python 2.7.14 (default, Sep 26 2017, 13:42:32)
from cryptography.fernet import Fernet
Fernet.generate_key()
'cLlDneYkn69ZePyWcU9_mltFy4MwYf5pyqUnP-M8PxE='
Fernet.generate_key()
'mVb2CBYEwFi4sc8B7jpeDiIesuk6L7k1d_DI0sLC7PU='
heroku config:set FERNET_PROTOBUF_KEY=cLlDneYkn69ZePyWcU9_mltFy4MwYf5pyqUnP-M8PxE=
heroku config:set FERNET_COOKIE_KEY=mVb2CBYEwFi4sc8B7jpeDiIesuk6L7k1d_DI0sLC7PU=
heroku run python manage.py createsuperuser
- Log into https://.herokuapp.com/
- Go to https://.herokuapp.com/admin to create additional user accounts
- Consider signing up for https://papertrailapp.com/ e.g. to see your HTTP 500s' stack traces
git checkout master
git pull
git push heroku master
- See below about
heroku run python manage.py migrate
, necessary only rarely when the database schema changes
- Edit the models.
python manage.py makemigrations todo
- Test locally with
python manage.py migrate
git checkout master
git pull
git checkout -b migration_branch
git add <new file>
git commit
git push origin migration_branch
- Make a pull request and get it merged
git checkout master
git pull
git push heroku master
heroku run python manage.py migrate
The source code lives at https://github.com/chandler37/immaculater.
See above for the magical git clone
incantation and git documentation.
Our practice is never to push directly to master
. Instead, create a feature
branch and push to it (for details on the 'feature branch' idiom see
https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow/). You
can do a remote commit with the following:
git checkout master
git pull
git checkout -b your_feature_branch_goes_here
- Make your edits
source venv/bin/activate
(cd pyatdllib && make test)
- Test using
heroku local web
orDJANGO_DEBUG="True" python manage.py runserver 5000
- Navigate to the local server and log in as the superuser you created above under 'One-Time Local Server Setup'
git status
to see any new files and confirm what branch you're on. If you seepyatdllib/core/pyatdl_pb2.py
in the diff but you didn't editpyatdl.proto
, that's because of differences in the version of the protocol buffer compiler. You can revert withgit checkout -- pyatdllib/core/pyatdl_pb2.py
git diff
git add X Y Z
for any new files X Y and Zgit commit --all
git push origin your_feature_branch_goes_here
- Go to
the pull requests page at github
and choose 'New pull request' to create a request to merge your feature
branch into
master
. - Now find a code reviewer and work with your reviewer towards consensus (making
commits to your feature branch that the pull request will automagically
incorporate after
git push origin your_feature_branch_goes_here
). When ready, just press the 'Merge' button and let the website do the actual change tomaster
. You can then close the source branch on github and delete your local branch withgit checkout master && git pull && git branch -d your_feature_branch_goes_here
When done with your feature, ensure all tests pass ((cd pyatdllib && make test)
and run pylint (make pylint
after pip install pylint
(inside an
activated virtualenv)). The very best practice is to run make cov
(first
pip install coverage
(inside an activated virtualenv)) and ensure that your
change has optimal unittest code coverage. You get bonus points for installing
pychecker and running make pychecker
.
The above practices give us the benefit of easy code reviews and ensure that your buggy works in progress doesn't interfere with other developers. Try to make your feature branch (and thus the code review) as short and sweet as you can. E.g., if you had to refactor something as part of your change, create one feature branch for the refactoring and another that builds on it.
There are two CLIs, one which uses local files and one which uses secure HTTP
to DJango running atop Heroku. The former is in pyatdllib/ui/immaculater.py
;
the latter is in cli/todo.py
.
Oops, and there's a third -- it's built into the Django UI, the /todo/cli
endpoint.
The to-do list is stored in a Fernet-encrypted field in the database. The key is stored in a Heroku config variable. An attacker would have to break into both places to read your data.
The Django server is set up to require the use of SSL (HTTPS) at all times.
This installation was built with the help of
https://github.com/heroku/heroku-django-template so see README-heroku-django.md
.
You'll find here code from https://github.com/yiisoft/jquery-pjax, a fork of defunkt's jquery-pjax.
You'll find here code from https://github.com/eventials/django-pjax.
You'll find here code from https://craig.is/killing/mice / https://github.com/ccampbell/mousetrap
You'll find as dependencies the following:
- https://github.com/google/google-apputils
- https://github.com/sparksuite/simplemde-markdown-editor
- https://github.com/google/python-gflags
- https://github.com/abseil/abseil-py
- https://github.com/google/protobuf
grep the code for TODOs using grepme.sh
.
Wouldn't it be nice if we had the following:
- A login page that doesn't change style upon an invalid login
- Docker support
- Voice integration with Alexa, Siri, Google Home, etc.
- A better web app than the one found here, something slick like the 'mail.google.com' interface to GMail
- Expanding the setup.py magic built around cli/todo.py into a proper PyPI package listed publicly
- An iOS app
- An Android app
- Perhaps SL4A scripting layer for android
- See kivy.org which uses python-for-android under the hood, particularly the
'notes' tutorial app.
- Dependence: Cython-0.22
- Beware of https://www.bountysource.com/issues/7397452-cython-0-22-does-not-compile-master
- Workaround: Replace 'except *' with ''
~/git/kivy/examples/tutorials/notes/final$ buildozer -v android debug
~/git/kivy/examples/tutorials/notes/final$ buildozer -v android debug deploy run
- An actual filesystem (remember how Plan 9 made pretty much everything pretend to be a filesystem? We already are pretending.) Starting with a linux filesystem (see FUSE) and an OS X filesystem (see FUSE for macOS)
- Per-user encryption. We already use Fernet to encrypt the to-do list, but some users would prefer a second layer of encryption such that an attacker would have to break a user's password to see the user's data. Resetting passwords would erase all data.
- Login with Google/Facebook
Copyright 2017 David L. Chandler
See the LICENSE file in this directory.
Immaculater is not affiliated with, approved or endorsed by David Allen or the David Allen Company. David Allen is the creator of the Getting Things Done® system. GTD® and Getting Things Done® are registered trademarks of the David Allen Company. For more information on that company and its products, visit GettingThingsDone.com