Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions .env.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ FLASK_ENV=production
# Change the following values for local development.
SECRET_KEY={{ secret_key }}

# Change these values for your Trello environment
API_KEY={{ trello_api_key }}
TOKEN={{ trello_token }}

# Change these values for your Trello board
BOARD_ID=xRzO95hQ
TO_DO_LIST_ID=62ff6a8396e27c0018225b3e
DOING_LIST_ID=6335777c3711480061bf2a59
DONE_LIST_ID=62ff6a85ecf4d000d4528e15
# Change these values for your DB
DB_CONNECTION_STRING={{ db_connection_string }}
DB_NAME={{ db_name }}
12 changes: 3 additions & 9 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ FLASK_ENV=development
# Change the following values for local development.
SECRET_KEY=secret-key

# Change these values for your Trello environment
API_KEY=trello-api-key
TOKEN=trello-token

# Change these values for your Trello board
BOARD_ID=trello-board-id
TO_DO_LIST_ID=trello-to-do-list-id
DOING_LIST_ID=trello-doing-list-id
DONE_LIST_ID=trello-done-list-id
# Change these values for your DB
DB_CONNECTION_STRING=db-connection-string
DB_NAME=db-name
14 changes: 4 additions & 10 deletions .env.test
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
# Flask server configuration.
FLASK_SKIP_DOTENV=true
FLASK_SKIP_DOTENV=True

# Change the following values for local development.
SECRET_KEY=test-secret-key

# Change these values for your Trello environment
API_KEY=test-api-key
TOKEN=test-token

# Change these values for your Trello board
BOARD_ID=test-board-id
TO_DO_LIST_ID=test-to-do-list-id
DOING_LIST_ID=test-doing-list-id
DONE_LIST_ID=test-done-list-id
# Change these values for your DB
DB_CONNECTION_STRING=mongodb://fakemongo.com
DB_NAME=name
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ $ cp .env.template .env # (first time only)

The `.env` file is used by flask to set environment variables when running `flask run`. This enables things like development mode (which also enables features like hot reloading when you make a file change). There's also a [SECRET_KEY](https://flask.palletsprojects.com/en/1.1.x/config/#SECRET_KEY) variable which is used to encrypt the flask session cookie.

## Trello integration
## Database integration

This app uses a Trello board to store the items. You should set up a Trello board, with three lists for 'To Do', 'Doing' and 'Done'. Update your `.env` file with the board and list id's, as well as your Trello API Key and Token.
This app uses a MongoDB database to store the items. You should update your `.env` file with your MongoDB's primary connection string and database name.

## Running the App locally

Expand Down
8 changes: 4 additions & 4 deletions ansible-playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
- name: secret_key
prompt: What is the app secret key?

- name: trello_api_key
prompt: What is the Trello API key?
- name: db_connection_string
prompt: What is the primary database connection string?

- name: trello_token
prompt: What is the Trello token?
- name: db_name
prompt: What is the database name?

tasks:
- name: Install git
Expand Down
149 changes: 146 additions & 3 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Flask = "^2.0.3"
python-dotenv = "^0.14.0"
requests = "^2.28.1"
gunicorn = "^20.1.0"
pymongo = "^4.3.3"
mongomock = "^4.1.2"

[tool.poetry.dev-dependencies]
pytest = "^7.2.0"
Expand Down
35 changes: 9 additions & 26 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,24 @@
import pytest
from dotenv import load_dotenv, find_dotenv
from todo_app import app
import requests
import os
import mongomock

from todo_app.data.db_items import add_card

@pytest.fixture
def client():
file_path = find_dotenv('.env.test')

load_dotenv(file_path, override=True)
test_app = app.create_app()

with test_app.test_client() as client:
yield client
with mongomock.patch(servers=(('fakemongo.com', 27017),)):
test_app = app.create_app()
with test_app.test_client() as client:
yield client

def test_index_page(monkeypatch, client):
def test_index_page(client):
add_card('Test card')

monkeypatch.setattr(requests, 'get', get_lists_stub)
response = client.get('/')

assert response.status_code == 200
assert 'Test card' in response.data.decode()

class StubResponse():
def __init__(self, fake_response_data):
self.fake_response_data = fake_response_data

def json(self):
return self.fake_response_data

def get_lists_stub(url):
fake_response_data = None
query_string = f'?key={os.environ.get("API_KEY")}&token={os.environ.get("TOKEN")}&cards=open'
if url == f'https://api.trello.com/1/boards/{os.environ.get("BOARD_ID")}/lists{query_string}':
fake_response_data = [{
'id': '123abc',
'name': 'To Do',
'cards': [{'id': '456', 'name': 'Test card'}]
}]
return StubResponse(fake_response_data)
6 changes: 3 additions & 3 deletions todo_app/app.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from flask import Flask, redirect, render_template, request
from todo_app.flask_config import Config
from todo_app.models.ViewModel import ViewModel
from todo_app.data.trello_items import get_cards, add_card, move_card_to_list
from todo_app.data.db_items import get_cards, add_card, change_card_status
import os

def create_app():
Expand All @@ -24,9 +24,9 @@ def submit_form():
@app.route('/update-status/<card_id>/<current_list>', methods=["POST"])
def update_status(card_id, current_list):
if current_list == 'To Do':
move_card_to_list(card_id, os.getenv('DOING_LIST_ID'))
change_card_status(card_id, "Doing")
if current_list == 'Doing':
move_card_to_list(card_id, os.getenv('DONE_LIST_ID'))
change_card_status(card_id, "Done")
return redirect('/')

return app
21 changes: 21 additions & 0 deletions todo_app/data/db_items.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import os
from todo_app.models.Item import Item
import pymongo

def get_collection():
client = pymongo.MongoClient(f'{os.getenv("DB_CONNECTION_STRING")}')
db = client[f'{os.getenv("DB_NAME")}']
return db.card

def get_cards():
collection = get_collection()
cards = collection.find()
return [Item.from_db_card(card) for card in cards]

def add_card(card_name):
collection = get_collection()
collection.insert_one({"name": card_name, "status": "To Do"})

def change_card_status(card_id, status):
collection = get_collection()
collection.update_one({"_id": card_id}, {"$set": {"status": status}})
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor, but it's a good habit to convert the string card_id here to an ObjectId (like below) since some versions of MongoDB will refuse to do the type conversion for you, although CosmosDB does

from bson import ObjectId

...

collection.update_one({"_id": ObjectId(card_id)}, {"$set": {"status": status}})

15 changes: 0 additions & 15 deletions todo_app/data/trello_items.py

This file was deleted.

6 changes: 3 additions & 3 deletions todo_app/models/Item.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ def __init__(self, id, name, status = 'To Do'):
self.id = id
self.name = name
self.status = status

@classmethod
def from_trello_card(cls, card, list):
return cls(card['id'], card['name'], list['name'])
def from_db_card(cls, card):
return cls(card['_id'], card['name'], card['status'])