Skip to content

ADA C17 Sea Turtles Celina Barron Task List #119

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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion ada-project-docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ SQLALCHEMY_TEST_DATABASE_URI=postgresql+psycopg2://postgres:postgres@localhost:5

Run `$ flask db init`.

**_After you make your first model in Wave 1_**, run the other commands `migrate` and `upgrade`.
**_After you make your first model in Wave 1_**, run the other commands `migrate` with -m to add message so we know what were talking about and `upgrade`.

## Run `$ flask run` or `$ FLASK_ENV=development flask run`

Expand Down
7 changes: 7 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,11 @@ def create_app(test_config=None):

# Register Blueprints here

from .task_routes import tasks_bp
app.register_blueprint(tasks_bp)

from .goal_routes import goal_bp
app.register_blueprint(goal_bp)

return app

146 changes: 146 additions & 0 deletions app/goal_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
from urllib import response
from datetime import datetime
from typing import OrderedDict
from urllib.request import OpenerDirector
from flask import Blueprint, jsonify, request, make_response, abort
from app import db
from app.models.goal import Goal
from app.models.task import Task
from app.task_routes import validate_task

### Create a Goal:
goal_bp = Blueprint("goal_bp", __name__, url_prefix="/goals")

@goal_bp.route("", methods = ["POST"])
def create_goals():
request_body = request.get_json()
if "title" in request_body:
new_goal = Goal(
title = request_body["title"]
)
else:
return jsonify({"details":"Invalid data"}), 400


db.session.add(new_goal)
db.session.commit()
goal_response = {"goal": new_goal.to_dictionary()}
return (jsonify(goal_response), 201)


### Get Goals
@goal_bp.route("", methods = ["GET"])
def get_goals():
sort = request.args.get("sort")
#Sort by assending (is default?)
if sort == "asc":
goals =Goal.query.order_by(Goal.title)
#Sort by decending
elif sort == "desc":
goals =Goal.query.order_by(Goal.title.desc())
#No Sort
else:
goals = Goal.query.all()

goals_response = []
for goal in goals:
goals_response.append(goal.to_dictionary())
# If No Saved Goals wil stil return 200
return (jsonify(goals_response), 200)


### Get One Goal: One Saved Goal
@goal_bp.route("/<goal_id>", methods=["GET"])
def get_one_goal(goal_id):
goal = validate_goal(goal_id)
goal_response = {"goal": goal.to_dictionary()}
return (jsonify(goal_response), 200)

### Update Goal
@goal_bp.route("/<goal_id>", methods=["PUT"])
def update_goal(goal_id):
goal = validate_goal(goal_id)

request_body = request.get_json()

goal.title = request_body["title"]

db.session.commit()

goal_response = {"goal": goal.to_dictionary()}
return (jsonify(goal_response), 200)

# Goal Complete
@goal_bp.route("/<goal_id>/mark_complete", methods=["PATCH"])
def goal_complete(goal_id):
goal = validate_goal(goal_id)
goal.completed_at = datetime.utcnow()

db.session.commit()
goal_response = {"goal": goal.to_dictionary()}
return (jsonify(goal_response), 200)

# Goal Incomplete
@goal_bp.route("/<goal_id>/mark_incomplete", methods=["PATCH"])
def goal_incomplete(goal_id):
goal = validate_goal(goal_id)
goal.completed_at = None
db.session.commit()
goal_response = {"goal": goal.to_dictionary()}
return (jsonify(goal_response), 200)


# Delete Goal: Deleting a Goal
@goal_bp.route("/<goal_id>", methods=["DELETE"])
def delete_goal(goal_id):
goal = validate_goal(goal_id)

db.session.delete(goal)
db.session.commit()

response = {"details": f"Goal {goal.goal_id} \"{goal.title}\" successfully deleted"}
return (jsonify(response), 200)


# Validate there are no matching Goal: Get, Update, and Delete

def validate_goal(goal_id):
try:
goal_id = int(goal_id)
except:
abort(make_response({"message": f"Goal {goal_id} is invalid"}, 400))


goal = Goal.query.get(goal_id)

if not goal:
abort(make_response({"message": f"Goal {goal_id} not found"}, 404))
return goal


@goal_bp.route("/<goal_id>/tasks", methods=["POST"])
def post_task_ids_to_goal(goal_id):
goal = validate_goal(goal_id)

request_body = request.get_json()

for task_id in request_body["task_ids"]:
task = Task.query.get(task_id)
task.goal_id = goal_id
task.goal = goal

db.session.commit()

return jsonify({"id":goal.goal_id, "task_ids": request_body["task_ids"]}), 200

@goal_bp.route("/<goal_id>/tasks", methods=["GET"])
def get_tasks_for_goal(goal_id):
goal = validate_goal(goal_id)
task_list = [task.to_dictionary() for task in goal.tasks]

goal_dict = goal.to_dictionary()
goal_dict["tasks"] = task_list

return jsonify(goal_dict)


13 changes: 13 additions & 0 deletions app/models/goal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,16 @@

class Goal(db.Model):
goal_id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String, nullable=False)
tasks = db.relationship("Task", back_populates="goals", lazy = True)

def to_dictionary(self):
goal_dict = {
"id": self.goal_id,
"title": self.title
}

if self.tasks:
goal_dict["tasks"] = [task.task_id for task in self.tasks]

return goal_dict
20 changes: 20 additions & 0 deletions app/models/task.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
from email.policy import default
from app import db


class Task(db.Model):
task_id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String, nullable=False)
description = db.Column(db.String, nullable=False)
completed_at = db.Column(db.DateTime, nullable=True, default=None)
goal_id = db.Column(db.Integer, db.ForeignKey('goal.goal_id'), nullable = True)
goals = db.relationship("Goal", back_populates="tasks")

def to_dictionary(self):
return dict(
id=self.task_id,
title=self.title,
description=self.description,
is_complete=self.is_complete()
)

def is_complete(self):
if not self.completed_at:
return False
else:
return True
1 change: 0 additions & 1 deletion app/routes.py

This file was deleted.

137 changes: 137 additions & 0 deletions app/task_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
from datetime import datetime
from typing import OrderedDict
from urllib.request import OpenerDirector
from flask import Blueprint, jsonify, request, make_response, abort
from app import db
from app.models.task import Task

### Create a Task:
tasks_bp = Blueprint("tasks_bp", __name__, url_prefix="/tasks")

@tasks_bp.route("", methods = ["POST"])
def create_tasks():
request_body = request.get_json()
if "title" in request_body and "description" in request_body and "completed_at" in request_body:
new_task = Task(
title = request_body["title"],
description = request_body["description"],
completed_at = request_body["completed_at"]
)
elif "title" in request_body and "description" in request_body:
new_task = Task(
title = request_body["title"],
description = request_body["description"],
# completed_at = request_body["completed_at"]
)
else:
return jsonify({"details":"Invalid data"}), 400

db.session.add(new_task)
db.session.commit()
task_response = {"task": new_task.to_dictionary()}
return (jsonify(task_response), 201)


### Get Tasks
@tasks_bp.route("", methods = ["GET"])
def get_tasks():
sort = request.args.get("sort")
#Sort by assending (is default?)
if sort == "asc":
tasks =Task.query.order_by(Task.title)
#Sort by decending
elif sort == "desc":
tasks =Task.query.order_by(Task.title.desc())
#No Sort
else:
tasks = Task.query.all()

tasks_response = []
for task in tasks:
tasks_response.append(task.to_dictionary())
# If No Saved Tasks wil stil return 200
return (jsonify(tasks_response), 200)


### Get One Task: One Saved Task
@tasks_bp.route("/<task_id>", methods=["GET"])
def get_one_task(task_id):
task = validate_task(task_id)
task_response = {"task": task.to_dictionary()}
return (jsonify(task_response), 200)


### Update Task
@tasks_bp.route("/<task_id>", methods=["PUT"])
def update_task(task_id):
task = validate_task(task_id)

request_body = request.get_json()

task.title = request_body["title"]
task.description = request_body["description"]

db.session.commit()

task_response = {"task": task.to_dictionary()}
return (jsonify(task_response), 200)

# Task Complete
@tasks_bp.route("/<task_id>/mark_complete", methods=["PATCH"])
def task_complete(task_id):
task = validate_task(task_id)
task.completed_at = datetime.utcnow()

db.session.commit()
task_response = {"task": task.to_dictionary()}
return (jsonify(task_response), 200)

# Task Incomplete
@tasks_bp.route("/<task_id>/mark_incomplete", methods=["PATCH"])
def task_incomplete(task_id):
task = validate_task(task_id)
task.completed_at = None
db.session.commit()
task_response = {"task": task.to_dictionary()}
return (jsonify(task_response), 200)


# Delete Task: Deleting a Task
@tasks_bp.route("/<task_id>", methods=["DELETE"])
def delete_task(task_id):
task = validate_task(task_id)

db.session.delete(task)
db.session.commit()

response = {"details": f"Task {task.task_id} \"{task.title}\" successfully deleted"}
return (jsonify(response), 200)


# Validate there are no matching Task: Get, Update, and Delete

def validate_task(task_id):
try:
task_id = int(task_id)
except:
abort(make_response({"message": f"Task {task_id} is invalid"}, 400))


task = Task.query.get(task_id)

if not task:
abort(make_response({"message": f"Task {task_id} not found"}, 404))
return task













1 change: 1 addition & 0 deletions migrations/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
Loading