-
Notifications
You must be signed in to change notification settings - Fork 69
Paper - Kaylyn Cardella #65
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
base: master
Are you sure you want to change the base?
Changes from all commits
6e39426
c686031
e297137
4a772b9
67e39c3
6234a55
74049e1
44aeaf0
136cb41
3486352
74e5b59
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 | ||||
|---|---|---|---|---|---|---|
| @@ -1,6 +1,21 @@ | ||||||
| from flask import current_app | ||||||
| from app import db | ||||||
|
|
||||||
|
|
||||||
| class Goal(db.Model): | ||||||
| goal_id = db.Column(db.Integer, primary_key=True) | ||||||
| title = db.Column(db.Text) | ||||||
| tasks = db.relationship("Task", backref="goals", lazy=True) | ||||||
| __tablename__ = "goals" | ||||||
|
|
||||||
| def to_json(self): | ||||||
| if self.tasks != []: | ||||||
|
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. This can be simplified as:
Suggested change
Since empty lists are falsey. |
||||||
| return { | ||||||
| "id": self.goal_id, | ||||||
| "title": self.title, | ||||||
| "tasks": self.tasks | ||||||
| } | ||||||
| else: | ||||||
| return { | ||||||
| "id": self.goal_id, | ||||||
| "title": self.title, | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,30 @@ | ||||||||||||||
| from flask import current_app | ||||||||||||||
| from app import db | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| class Task(db.Model): | ||||||||||||||
| task_id = db.Column(db.Integer, primary_key=True) | ||||||||||||||
| title = db.Column(db.String) | ||||||||||||||
| description = db.Column(db.String) | ||||||||||||||
| completed_at = db.Column(db.DateTime, nullable=True) | ||||||||||||||
| goal_id = db.Column(db.Integer, db.ForeignKey("goals.goal_id"), nullable=True) | ||||||||||||||
| __tablename__ = "tasks" | ||||||||||||||
|
|
||||||||||||||
| def to_json(self): | ||||||||||||||
| is_complete = self.completed_at | ||||||||||||||
| if self.completed_at == None: | ||||||||||||||
| is_complete = False | ||||||||||||||
| else: | ||||||||||||||
| is_complete = True | ||||||||||||||
|
Comment on lines
+12
to
+16
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. This can be simplified as:
Suggested change
|
||||||||||||||
| if self.goal_id != None: | ||||||||||||||
|
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. Remember,
Suggested change
|
||||||||||||||
| return { | ||||||||||||||
| "id": self.task_id, | ||||||||||||||
| "title": self.title, | ||||||||||||||
| "description": self.description, | ||||||||||||||
| "is_complete": is_complete, | ||||||||||||||
| "goal_id": self.goal_id | ||||||||||||||
| } | ||||||||||||||
| return { | ||||||||||||||
| "id": self.task_id, | ||||||||||||||
| "title": self.title, | ||||||||||||||
| "description": self.description, | ||||||||||||||
| "is_complete": is_complete | ||||||||||||||
| } | ||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,2 +1,210 @@ | ||||||
| from flask import Blueprint | ||||||
| from app import db | ||||||
| from app.models.task import Task | ||||||
| from app.models.goal import Goal | ||||||
| from flask import Blueprint, jsonify, request, make_response | ||||||
| from datetime import datetime | ||||||
| import os | ||||||
| import requests | ||||||
|
|
||||||
| tasks_bp = Blueprint("tasks", __name__, url_prefix="/tasks") | ||||||
| goals_bp = Blueprint("goals", __name__, url_prefix="/goals") | ||||||
|
|
||||||
| @goals_bp.route("/<goal_id>/tasks", methods=["POST"], strict_slashes=False) | ||||||
| def assign_tasks_to_one_goal(goal_id): | ||||||
| request_body = request.get_json() | ||||||
|
|
||||||
| goal = Goal.query.get(goal_id) | ||||||
|
|
||||||
| task_ids = request_body["task_ids"] | ||||||
|
|
||||||
| for task_id in task_ids: | ||||||
| task = Task.query.get(task_id) | ||||||
| goal.tasks.append(task) | ||||||
|
|
||||||
| db.session.commit() | ||||||
|
|
||||||
| return make_response({ | ||||||
| "id": goal.goal_id, | ||||||
| "task_ids": task_ids | ||||||
| }, 200) | ||||||
|
|
||||||
|
|
||||||
| @goals_bp.route("/<goal_id>/tasks", methods=["GET"], strict_slashes=False) | ||||||
| def get_tasks_from_goal_id(goal_id): | ||||||
| goal = Goal.query.get_or_404(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. Nice use of |
||||||
| tasks = goal.tasks | ||||||
|
|
||||||
| tasks_response = [] | ||||||
|
|
||||||
| for task in tasks: | ||||||
| tasks_response.append(task.to_json()) | ||||||
|
|
||||||
| goal_response = goal.to_json() | ||||||
| goal_response["tasks"] = tasks_response | ||||||
|
|
||||||
| return goal_response, 200 | ||||||
| 0 | ||||||
| @goals_bp.route("", methods=["POST"], strict_slashes=False) | ||||||
| def create_goal(): | ||||||
| request_body = request.get_json() | ||||||
|
|
||||||
| try: | ||||||
| new_goal = Goal(title=request_body["title"]) | ||||||
|
|
||||||
| except KeyError: | ||||||
| return make_response({ | ||||||
| "details": "Invalid data" | ||||||
| }, 400) | ||||||
|
|
||||||
| db.session.add(new_goal) | ||||||
| db.session.commit() | ||||||
|
|
||||||
| return { | ||||||
| "goal": new_goal.to_json() | ||||||
| }, 201 | ||||||
|
|
||||||
| @goals_bp.route("/<goal_id>", methods=["GET"], strict_slashes=False) | ||||||
| def get_one_goal(goal_id): | ||||||
| goal = Goal.query.get_or_404(goal_id) | ||||||
|
|
||||||
| return { | ||||||
| "goal": goal.to_json()}, 200 | ||||||
|
|
||||||
| @goals_bp.route("", methods=["GET"], strict_slashes=False) | ||||||
| def goals_index(): | ||||||
| goals = Goal.query.all() | ||||||
| goals_response = [] | ||||||
| for goal in goals: | ||||||
| goals_response.append(goal.to_json()) | ||||||
|
|
||||||
| return jsonify(goals_response), 200 | ||||||
|
|
||||||
| @goals_bp.route("/<goal_id>", methods=["PUT"], strict_slashes=False) | ||||||
| def update_goal(goal_id): | ||||||
| goal = Goal.query.get_or_404(goal_id) | ||||||
| form_data = request.get_json() | ||||||
|
|
||||||
| goal.title = form_data["title"] | ||||||
|
|
||||||
| db.session.commit() | ||||||
|
|
||||||
| return { | ||||||
| "goal": goal.to_json() | ||||||
| }, 200 | ||||||
|
|
||||||
| @goals_bp.route("/<goal_id>", methods=["DELETE"], strict_slashes=False) | ||||||
| def delete_goal(goal_id): | ||||||
| goal = Goal.query.get_or_404(goal_id) | ||||||
|
|
||||||
| db.session.delete(goal) | ||||||
| db.session.commit() | ||||||
|
|
||||||
| return make_response({ | ||||||
| "details": f'Goal {goal.goal_id} "{goal.title}" successfully deleted' | ||||||
| }) | ||||||
|
|
||||||
|
|
||||||
| @tasks_bp.route("", methods=["GET"], strict_slashes=False) | ||||||
| def tasks_index(): | ||||||
| sort_type = request.args.get("sort") | ||||||
|
|
||||||
| if sort_type == "desc": | ||||||
| tasks = Task.query.order_by(Task.title.desc()) | ||||||
| elif sort_type == "asc": | ||||||
| tasks = Task.query.order_by(Task.title.asc()) | ||||||
| else: | ||||||
| tasks = Task.query.all() | ||||||
|
|
||||||
| tasks_response = [] | ||||||
|
|
||||||
| for task in tasks: | ||||||
| tasks_response.append(task.to_json()) | ||||||
|
|
||||||
| return jsonify(tasks_response), 200 | ||||||
|
|
||||||
| @tasks_bp.route("/<task_id>", methods=["GET"], strict_slashes=False) | ||||||
| def get_one_task(task_id): | ||||||
| task = Task.query.get_or_404(task_id) | ||||||
|
|
||||||
| return { | ||||||
| "task": task.to_json()}, 200 | ||||||
|
|
||||||
| @tasks_bp.route("", methods=["POST"], strict_slashes=False) | ||||||
| def create_task(): | ||||||
| request_body = request.get_json() | ||||||
|
|
||||||
| try: | ||||||
| new_task = Task(title=request_body["title"], | ||||||
| description=request_body["description"], | ||||||
| completed_at=request_body["completed_at"]) | ||||||
|
|
||||||
| except KeyError: | ||||||
| return make_response({ | ||||||
| "details": "Invalid data" | ||||||
| }, 400) | ||||||
|
|
||||||
| db.session.add(new_task) | ||||||
| db.session.commit() | ||||||
|
|
||||||
| return { | ||||||
| "task": new_task.to_json() | ||||||
| }, 201 | ||||||
|
|
||||||
| @tasks_bp.route("/<task_id>", methods=["PUT"], strict_slashes=False) | ||||||
| def update_task(task_id): | ||||||
| task = Task.query.get_or_404(task_id) | ||||||
| form_data = request.get_json() | ||||||
|
|
||||||
| task.title = form_data["title"] | ||||||
| task.description = form_data["description"] | ||||||
| task.is_complete = form_data["completed_at"] | ||||||
|
|
||||||
| db.session.commit() | ||||||
|
|
||||||
| return { | ||||||
| "task": task.to_json() | ||||||
| }, 200 | ||||||
|
|
||||||
| @tasks_bp.route("/<task_id>", methods=["DELETE"], strict_slashes=False) | ||||||
| def delete_task(task_id): | ||||||
| task = Task.query.get_or_404(task_id) | ||||||
|
|
||||||
| db.session.delete(task) | ||||||
| db.session.commit() | ||||||
|
|
||||||
| return make_response({ | ||||||
| "details": f'Task {task.task_id} "{task.title}" successfully deleted' | ||||||
| }) | ||||||
|
|
||||||
| @tasks_bp.route("/<task_id>/mark_complete", methods=["PATCH"], strict_slashes=False) | ||||||
| def task_mark_complete(task_id): | ||||||
| task = Task.query.get_or_404(task_id) | ||||||
| current_datetime = datetime.utcnow() | ||||||
|
|
||||||
| task.completed_at = current_datetime | ||||||
|
|
||||||
| db.session.commit() | ||||||
|
|
||||||
| response = requests.get('https://slack.com/api/chat.postMessage',\ | ||||||
| params={ | ||||||
| "channel": "task-notifications", | ||||||
| "text": f"Someone just completed the task {task.title}"}, | ||||||
| headers={'Authorization': os.environ['SLACK_TOKEN']}) | ||||||
|
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. This should have been named
Suggested change
|
||||||
|
|
||||||
| return { | ||||||
| "task": task.to_json() | ||||||
| }, 200 | ||||||
|
|
||||||
|
|
||||||
| @tasks_bp.route("/<task_id>/mark_incomplete", methods=["PATCH"], strict_slashes=False) | ||||||
| def task_mark_incomplete(task_id): | ||||||
| task = Task.query.get_or_404(task_id) | ||||||
|
|
||||||
| if task.completed_at != None: | ||||||
| task.completed_at = None | ||||||
|
|
||||||
| db.session.commit() | ||||||
|
|
||||||
| return { | ||||||
| "task": task.to_json() | ||||||
| }, 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.
You didn't need to import
TaskorGoalhere since they are unused.