-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accelerate-Christina S #10
base: master
Are you sure you want to change the base?
Changes from all commits
8018ced
a7bd9d4
4a62453
ca03781
47ecda9
90b9d2a
a6edb3f
7a36bd6
24b7f63
020267f
c40bf9c
0d48fce
2d90aa0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: gunicorn 'app:create_app()' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
from flask import current_app | ||
from app import db | ||
from sqlalchemy import ForeignKey, update | ||
from sqlalchemy.orm import relationship | ||
|
||
|
||
class Goal(db.Model): | ||
goal_id = db.Column(db.Integer, primary_key=True) | ||
title = db.Column(db.String) | ||
tasks = db.relationship('Task', backref='tasks', lazy=True) |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,13 @@ | ||||||
from flask import current_app | ||||||
from app import db | ||||||
from sqlalchemy.orm import relationship | ||||||
from sqlalchemy import ForeignKey, update | ||||||
Comment on lines
+3
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove these imports |
||||||
|
||||||
|
||||||
class Task(db.Model): | ||||||
task_id = db.Column(db.Integer, primary_key=True) | ||||||
title = db.Column(db.VARCHAR(50)) | ||||||
description = db.Column(db.String) | ||||||
completed_at = db.Column(db.DateTime, nullable=True, default=None) | ||||||
is_complete = db.Column(db.Boolean, default=False) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think adding this here creates confusion and is why some of your tests for mark complete/incomplete are failing. I would remove this line and just add an instance method for self.completed_at. It could be here in the Task model or in routes.py.
Suggested change
an example of how that could look |
||||||
goal_id = db.Column(db.Integer, db.ForeignKey('goal.goal_id'), nullable=True) |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,2 +1,261 @@ | ||||||
from flask import Blueprint | ||||||
from app import db | ||||||
from app.models.task import Task | ||||||
from app.models.goal import Goal | ||||||
from flask import request, Blueprint, make_response, jsonify | ||||||
from datetime import datetime | ||||||
import os | ||||||
import json, requests | ||||||
from dotenv import load_dotenv | ||||||
|
||||||
|
||||||
tasks_bp = Blueprint("tasks", __name__, url_prefix="/tasks") | ||||||
goals_bp = Blueprint("goals", __name__, url_prefix="/goals") | ||||||
|
||||||
load_dotenv() | ||||||
|
||||||
def post_message_to_slack(text): | ||||||
SLACK_TOKEN = os.environ.get('SLACKBOT_TOKEN') | ||||||
slack_path = "https://slack.com/api/chat.postMessage" | ||||||
query_params ={ | ||||||
'channel': 'task-notifications', | ||||||
'text': text | ||||||
} | ||||||
headers = {'Authorization': f"Bearer {SLACK_TOKEN}"} | ||||||
requests.post(slack_path, params=query_params, headers=headers) | ||||||
|
||||||
@goals_bp.route("", methods=["GET", "POST"]) | ||||||
def handle_goals(): | ||||||
if request.method == "GET": | ||||||
goals = Goal.query.all() | ||||||
goal_response = [] | ||||||
for goal in goals: | ||||||
goal_response.append({ | ||||||
"title": goal.title, | ||||||
"id": goal.goal_id | ||||||
}) | ||||||
return jsonify(goal_response), 200 | ||||||
|
||||||
elif request.method == "POST": | ||||||
request_body = request.get_json() | ||||||
title = request_body.get("title") | ||||||
if not title: | ||||||
return jsonify({"details": "Invalid data"}), 400 | ||||||
|
||||||
new_goal = Goal(title=request_body["title"]) | ||||||
db.session.add(new_goal) | ||||||
db.session.commit() | ||||||
|
||||||
commited_goal = {"goal": | ||||||
{"id": new_goal.goal_id, | ||||||
"title": new_goal.title | ||||||
}} | ||||||
|
||||||
return (commited_goal), 201 | ||||||
Comment on lines
+27
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💃🏽 |
||||||
|
||||||
@goals_bp.route("/<goal_id>", methods=["GET", "PUT", "DELETE"]) | ||||||
def handle_goal(goal_id): | ||||||
goal = Goal.query.get_or_404(goal_id) | ||||||
|
||||||
if request.method == "GET": | ||||||
selected_goal = {"goal": | ||||||
{"id": goal.goal_id, | ||||||
"title": goal.title | ||||||
} | ||||||
} | ||||||
return selected_goal | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just to be consistent I would add
Suggested change
|
||||||
|
||||||
elif request.method == "PUT": | ||||||
form_data = request.get_json() | ||||||
|
||||||
goal.title = form_data["title"] | ||||||
|
||||||
db.session.commit() | ||||||
|
||||||
commited_goal = {"goal": | ||||||
{"id": goal.goal_id, | ||||||
"title": goal.title | ||||||
} | ||||||
} | ||||||
return jsonify(commited_goal), 200 | ||||||
|
||||||
elif request.method == "DELETE": | ||||||
db.session.delete(goal) | ||||||
db.session.commit() | ||||||
return jsonify( | ||||||
{f"details": f'Goal {goal.goal_id} "{goal.title}" successfully deleted'} | ||||||
) | ||||||
|
||||||
@goals_bp.route("/<goal_id>/tasks", methods=["GET", "POST"]) | ||||||
def handle_goal_tasks(goal_id): | ||||||
goal = Goal.query.get_or_404(goal_id) | ||||||
if request.method == "GET": | ||||||
tasks = [] | ||||||
for task in goal.tasks: | ||||||
single_task= { | ||||||
"id": task.task_id, | ||||||
"goal_id": goal.goal_id, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here I would add a check if the task has a goal id. Something like |
||||||
"title": task.title, | ||||||
"description": task.description, | ||||||
"is_complete": bool(task.completed_at) | ||||||
} | ||||||
tasks.append(single_task) | ||||||
return make_response ({ | ||||||
"id": goal.goal_id, | ||||||
"title": goal.title, | ||||||
"tasks": tasks | ||||||
}) | ||||||
|
||||||
if request.method == "POST": | ||||||
goal.tasks =[] | ||||||
|
||||||
form_data = request.get_json() | ||||||
task_ids = form_data['task_ids'] | ||||||
|
||||||
for t_id in task_ids: | ||||||
task = Task.query.get_or_404(t_id) | ||||||
goal.tasks.append(task) | ||||||
|
||||||
db.session.add(goal) | ||||||
db.session.commit() | ||||||
|
||||||
response_task_ids = [] | ||||||
for task in goal.tasks: | ||||||
response_task_ids.append(task.task_id) | ||||||
|
||||||
return { | ||||||
"id": goal.goal_id, | ||||||
"task_ids": response_task_ids | ||||||
} | ||||||
|
||||||
@tasks_bp.route("", methods=["POST", "GET"]) | ||||||
def handle_tasks(): | ||||||
if request.method == "GET": | ||||||
title_query = request.args.get("title") | ||||||
if title_query: | ||||||
tasks = Task.query.filter(Task.title.ilike(f'%{title_query}%')) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ouu interesting what made you choose |
||||||
else: | ||||||
sort = request.args.get("sort") | ||||||
if not sort: | ||||||
tasks = Task.query.all() | ||||||
elif sort == "asc": | ||||||
tasks = Task.query.order_by(Task.title.asc()).all() | ||||||
elif sort == "desc": | ||||||
tasks = Task.query.order_by(Task.title.desc()).all() | ||||||
else: | ||||||
tasks = Task.query.all() | ||||||
|
||||||
tasks_response = [] | ||||||
for task in tasks: | ||||||
tasks_response.append({ | ||||||
"description": task.description, | ||||||
"is_complete": bool(task.completed_at), | ||||||
"id": task.task_id, | ||||||
"title": task.title | ||||||
}) | ||||||
return jsonify(tasks_response) | ||||||
|
||||||
elif request.method == "POST": | ||||||
request_body = request.get_json() | ||||||
title = request_body.get("title") | ||||||
description = request_body.get("description") | ||||||
if not title or not description or "completed_at" not in request_body: | ||||||
return jsonify({"details": "Invalid data"}), 400 | ||||||
new_task = Task(title=request_body["title"], | ||||||
description=request_body["description"], | ||||||
completed_at=request_body["completed_at"]) | ||||||
|
||||||
db.session.add(new_task) | ||||||
db.session.commit() | ||||||
commited_task = {"task": | ||||||
{"id": new_task.task_id, | ||||||
"title": new_task.title, | ||||||
"description": new_task.description, | ||||||
"is_complete": bool(new_task.completed_at)}} | ||||||
|
||||||
return jsonify(commited_task), 201 | ||||||
|
||||||
@tasks_bp.route("/<task_id>", methods=["GET", "PUT", "DELETE"]) | ||||||
def handle_task(task_id): | ||||||
task = Task.query.get_or_404(task_id) | ||||||
|
||||||
if request.method == "GET": | ||||||
if task == None: | ||||||
return make_response("No matching task found", 404) | ||||||
if request.method == "GET": | ||||||
if task.goal_id == None: | ||||||
selected_task = {"task": | ||||||
{"task_id": task.task_id, | ||||||
"title": task.title, | ||||||
"description": task.description, | ||||||
"is_complete": task.is_complete | ||||||
} | ||||||
} | ||||||
return selected_task | ||||||
else: | ||||||
return make_response ({ | ||||||
"task": { | ||||||
"id": task.task_id, | ||||||
"goal_id": task.goal_id, | ||||||
"title": task.title, | ||||||
"description": task.description, | ||||||
"is_complete": task.is_complete | ||||||
} | ||||||
}) | ||||||
Comment on lines
+181
to
+203
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good check |
||||||
|
||||||
elif request.method == "PUT": | ||||||
form_data = request.get_json() | ||||||
|
||||||
task.title = form_data["title"] | ||||||
task.description = form_data["description"] | ||||||
task.completed_at = form_data["completed_at"] | ||||||
|
||||||
db.session.commit() | ||||||
|
||||||
commited_task = {"task": | ||||||
{"id": task.task_id, | ||||||
"title": task.title, | ||||||
"description": task.description, | ||||||
"is_complete": bool(task.completed_at) | ||||||
} | ||||||
} | ||||||
return jsonify(commited_task), 200 | ||||||
|
||||||
elif request.method == "DELETE": | ||||||
db.session.delete(task) | ||||||
db.session.commit() | ||||||
return jsonify( | ||||||
{f"details": 'Task 1 "Go on my daily walk 🏞" successfully deleted'} | ||||||
) | ||||||
|
||||||
@tasks_bp.route("/<task_id>/mark_complete", methods=["PATCH"]) | ||||||
def mark_task_completed(task_id): | ||||||
task = Task.query.get_or_404(task_id) | ||||||
task.completed_at = datetime.now() | ||||||
|
||||||
db.session.commit() | ||||||
slack_message = f"Someone just completed the task {task.title}" | ||||||
post_message_to_slack(slack_message) | ||||||
|
||||||
completed_task = {"task": | ||||||
{"id": task.task_id, | ||||||
"title": task.title, | ||||||
"description": task.description, | ||||||
"is_complete": bool(task.completed_at) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if this is marked complete then |
||||||
} | ||||||
} | ||||||
return (completed_task), 200 | ||||||
|
||||||
@tasks_bp.route("/<task_id>/mark_incomplete", methods=["PATCH"]) | ||||||
def mark_task_incomplete(task_id): | ||||||
task = Task.query.get_or_404(task_id) | ||||||
task.completed_at = None | ||||||
|
||||||
db.session.commit() | ||||||
incomplete_task = {"task": | ||||||
{"id": task.task_id, | ||||||
"title": task.title, | ||||||
"description": task.description, | ||||||
"is_complete": bool(task.completed_at) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if this is marked incomplete then |
||||||
} | ||||||
} | ||||||
return jsonify(incomplete_task), 200 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Generic single-database configuration. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# A generic, single database configuration. | ||
|
||
[alembic] | ||
# template used to generate migration files | ||
# file_template = %%(rev)s_%%(slug)s | ||
|
||
# set to 'true' to run the environment during | ||
# the 'revision' command, regardless of autogenerate | ||
# revision_environment = false | ||
|
||
|
||
# Logging configuration | ||
[loggers] | ||
keys = root,sqlalchemy,alembic | ||
|
||
[handlers] | ||
keys = console | ||
|
||
[formatters] | ||
keys = generic | ||
|
||
[logger_root] | ||
level = WARN | ||
handlers = console | ||
qualname = | ||
|
||
[logger_sqlalchemy] | ||
level = WARN | ||
handlers = | ||
qualname = sqlalchemy.engine | ||
|
||
[logger_alembic] | ||
level = INFO | ||
handlers = | ||
qualname = alembic | ||
|
||
[handler_console] | ||
class = StreamHandler | ||
args = (sys.stderr,) | ||
level = NOTSET | ||
formatter = generic | ||
|
||
[formatter_generic] | ||
format = %(levelname)-5.5s [%(name)s] %(message)s | ||
datefmt = %H:%M:%S |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove these imports