-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #77 from wildjames/dev
Implement One-Shot tasks. Some Readme update
- Loading branch information
Showing
20 changed files
with
781 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,58 @@ | ||
# ToDoQu | ||
|
||
Life is full of small tasks that don't need to be done very often, but do need to be done. The natural solution is to batch these jobs together, and knock them out in chunks - most people would call this "chores", or "cleaning". However, sometimes it's easier to do small parts of these jobs every now and then, sacrificing the time equivalent of pocket change daily, rather than putting aside a lump sum on payday. No-one wants to sacrifice all of a Saturday cleaning a house, but a few minutes a day can eliminate the need to do it at all. | ||
Life is full of small tasks that don't need to be done very often, but do need to be done. The natural solution is to batch these jobs together, and knock them out in chunks - most people would call this "chores", or "cleaning". However, sometimes it's easier to do small parts of these jobs every now and then, sacrificing the time equivalent of pocket change daily, rather than putting aside a lump sum on payday. No-one wants to sacrifice all of a Saturday cleaning a house, but a few minutes a day can eliminate the feeling of spending time cleaning. | ||
|
||
ToDoQu is a flexible queue of what needs to be done. You can atomize chores, and be reminded to do them at your own pace when you get the time. Jobs are marked as done, and after some time become "**stale**". Stale tasks need to be completed, and become **overdue** after some window. Each job has its own schedule, and a scoreboard tracks who's done how much. | ||
|
||
Atomizing and distributing chores across both people and time makes it easier to maintain a high level of order in a home. | ||
|
||
To see a live version of this app, please take a look at the [instance I host on my home server](https://todoqu.wildjames.com/). | ||
|
||
# Live deployment | ||
|
||
## An example | ||
There is a live version of this site, deployed automatically from the `main` branch. A Github workflow automatically builds [this docker image](https://hub.docker.com/repository/docker/wizenedchimp/todoqueue/general), which is hosted on my [home server](https://todoqu.wildjames.com/). Feel free to sign up and try it out. | ||
|
||
Personally, I believe the task of properly cleaning a house to be impossible. Any sane person gets bored, and inevitably half-asses the last hour or two. Even if they didn't, not everything always needs to be done. To illustrate, consider a single room. | ||
|
||
Cleaning the living room is actually several tasks. We need to clear debris from the coffeetable and put it away, and we need to fold the throw blanket and plump the pillows. However, this is only surface level - the skirting boards need to be wiped down every now and again, the room needs to be vacuumed, and the sofa needs to be scrubbed of cat hair. Notice that some of these things need to be done only infrequently. Most people would call them "Spring cleaning", and realistically not bother. | ||
# Running your own server | ||
|
||
Using ToDoQu, we could set the vacuuming to be done at least every 5 days, and at most every 9. You would get a nudge 5 days after marking the task as done, suggesting it needs doing again. Leaving it more than 9 days will start it pulsing, and raise it to the top of the screen. Something like clearing the coffeetable can be set to be done daily, but allow a week or more since it may not always need doing, and wiping the skirting board can be set to need doing after several months, with a month or two to get done. | ||
ToDoQu is made up of four components. A Django backend, a React frontend, a SQL database for persistent storage, and a Redis cache. The redis cache currently only tracks excessive requests from users, so this can optionally be ignored and local memory used instead. | ||
|
||
ToDoQu works better the more you can break down tasks. However - I recommend not splitting a chore across two tasks! For example, "Do the laundry" is good, "Put the laundry in" and "Take the laundry out" is not. | ||
## Docker Compose | ||
|
||
The simplest way to run an instance of ToDoQu is to use the provided docker compose stack. This starts the fontend and backend in the `web` container, along with a Redis cache and a MySQL database. From the top directory of this repo, run | ||
```bash | ||
docker compose up --build | ||
``` | ||
This will run an instance of the site that should become available at `http://localhost` | ||
|
||
## Brownie Points | ||
|
||
ToDoQu is able to track the core contributions from its users. Completing tasks awards brownie points based on three factors: | ||
- The time it took | ||
- How gross was it to do | ||
- Some random jitter | ||
## Separating concerns | ||
|
||
The advantage of running the codes outside of docker is that changes to the code will be reflected as they are made. | ||
|
||
To configure Django you will need to set some environment variables. This is set up to load a `.env` file, or get variables directly from the environment. | ||
To see what variables need to be set, along with reasonable defaults, please examine the given [.env](./todoqueue_backend/.env) file, or the `docker-compose.yml` configuration. | ||
|
||
Note that you will need a MySQL database already running. The redis cache is optional, and can comfortably be omitted for local development. | ||
|
||
### Django | ||
|
||
First, install the prerequisites. From the backend directory, [./todoqueue_backend](./todoqueue_backend/), run | ||
```bash | ||
pip install -r requirements.txt | ||
``` | ||
It's best to do this in a fresh virtual environment (e.g. anaconda). | ||
|
||
To launch the backend itself, configure the [.env](./todoqueue_backend/.env) file and run the server, instructing it to use the development mode values: | ||
```bash | ||
DEV=true python3 manage.py runserver | ||
``` | ||
|
||
When running in production mode (i.e. without `DEV=true`), variables will be simply fetched from the system environment. | ||
|
||
### React frontend | ||
|
||
Simply enter the frontend directory, and run the frontend server | ||
```bash | ||
npm start | ||
``` | ||
|
||
The random jitter is just there to keep the numbers more interesting. Note that multiple people can be credited with doing a task, and tasks can be dismissed without crediting anyone at all. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,34 +6,47 @@ services: | |
ports: | ||
- "80:80" | ||
environment: | ||
DJANGO_DB_NAME: todoqueue | ||
DJANGO_DB_USER: todo_user | ||
DJANGO_DB_PASSWORD: todo_password | ||
DJANGO_DB_HOST: db | ||
DJANGO_DB_PORT: "3306" | ||
|
||
EMAIL_HOST: smtp-mail.outlook.com | ||
EMAIL_PORT: 587 | ||
EMAIL_USE_TLS: "1" | ||
EMAIL_HOST_USER: | ||
DEFAULT_FROM_EMAIL: | ||
EMAIL_HOST_PASSWORD: | ||
EMAIL_HOST_USER: [email protected] | ||
DEFAULT_FROM_EMAIL: [email protected] | ||
EMAIL_HOST_PASSWORD: MyPassword! | ||
|
||
DJANGO_DEBUG: true | ||
DJANGO_LOGGING_LEVEL: debug | ||
|
||
DJANGO_HOST_PORT: "8000" | ||
DJANGO_DB_NAME: | ||
DJANGO_DB_USER: | ||
DJANGO_DB_PASSWORD: | ||
DJANGO_DB_HOST: | ||
DJANGO_DB_PORT: | ||
|
||
DJANGO_CACHE_BACKEND: "redis" | ||
DJANGO_CACHE_LOCATION: "redis://cache:8379/1" | ||
DJANGO_CACHE_LOCATION: "redis://cache:6379/1" | ||
|
||
DJANGO_SUPERUSER_EMAIL: | ||
DJANGO_SUPERUSER_USERNAME: | ||
DJANGO_SUPERUSER_PASSWORD: | ||
DJANGO_SUPERUSER_EMAIL: [email protected] | ||
DJANGO_SUPERUSER_USERNAME: James | ||
DJANGO_SUPERUSER_PASSWORD: MyPassword! | ||
depends_on: | ||
- db | ||
- cache | ||
|
||
cache: | ||
image: "redis:alpine" | ||
ports: | ||
- "8379:6379" | ||
|
||
|
||
db: | ||
image: mysql:8.2 | ||
volumes: | ||
- mysql_data:/var/lib/mysql | ||
environment: | ||
MYSQL_DATABASE: todoqueue | ||
MYSQL_USER: todo_user | ||
MYSQL_PASSWORD: todo_password | ||
MYSQL_ROOT_PASSWORD: root_password | ||
|
||
|
||
volumes: | ||
mysql_data: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
EMAIL_HOST=smtp-mail.outlook.com | ||
EMAIL_PORT=587 | ||
EMAIL_USE_TLS=1 | ||
EMAIL_HOST_USER=[email protected] | ||
DEFAULT_FROM_EMAIL=[email protected] | ||
EMAIL_HOST_PASSWORD=MyPassword! | ||
|
||
DJANGO_DEBUG=true | ||
DJANGO_LOGGING_LEVEL=debug | ||
DJANGO_HOST_PORT=8000 | ||
|
||
DJANGO_DB_NAME=todoqueue | ||
DJANGO_DB_USER=root | ||
DJANGO_DB_PASSWORD=password | ||
DJANGO_DB_HOST=localhost | ||
DJANGO_DB_PORT=3306 | ||
|
||
DJANGO_CACHE_BACKEND=redis | ||
DJANGO_CACHE_LOCATION=redis://127.0.0.1:6379/1 | ||
|
||
DJANGO_SUPERUSER_EMAIL=[email protected] | ||
DJANGO_SUPERUSER_USERNAME=admin | ||
DJANGO_SUPERUSER_PASSWORD=MyPassword! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Generated by Django 4.2.5 on 2023-11-06 14:28 | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
import tasks.models | ||
import uuid | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('tasks', '0005_invitation'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='OneShotTask', | ||
fields=[ | ||
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), | ||
('task_name', models.CharField(max_length=255, validators=[tasks.models.validate_profanity])), | ||
('description', models.TextField(default='', validators=[tasks.models.validate_profanity])), | ||
('due_date', models.DateField()), | ||
('due_before', models.BooleanField(default=False)), | ||
('time_to_complete', models.DurationField(default='0:0')), | ||
('frozen', models.BooleanField(default=False)), | ||
('has_completed', models.BooleanField(default=False)), | ||
('household', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='oneshot_tasks', to='tasks.household')), | ||
], | ||
), | ||
] |
18 changes: 18 additions & 0 deletions
18
todoqueue_backend/tasks/migrations/0007_alter_oneshottask_due_date.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Generated by Django 4.2.5 on 2023-11-06 14:33 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('tasks', '0006_oneshottask'), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name='oneshottask', | ||
name='due_date', | ||
field=models.DateTimeField(), | ||
), | ||
] |
20 changes: 20 additions & 0 deletions
20
todoqueue_backend/tasks/migrations/0008_oneshottask_last_completed.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Generated by Django 4.2.5 on 2023-11-06 20:50 | ||
|
||
import datetime | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('tasks', '0007_alter_oneshottask_due_date'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='oneshottask', | ||
name='last_completed', | ||
field=models.DateTimeField(auto_now_add=True, default=datetime.datetime(2023, 11, 6, 20, 50, 34, 981370, tzinfo=datetime.timezone.utc)), | ||
preserve_default=False, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.