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
15 changes: 10 additions & 5 deletions .replit
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
entrypoint = "wsgi.py"
modules = ["python-3.10:v18-20230807-322e88b"]

modules = ["python-3.10", "nix"]

hidden = [".pythonlibs"]
run = "flask run --host=0.0.0.0 --port=8080 --reload"

[nix]
channel = "stable-23_05"
channel = "stable-24_05"

[deployment]
run = ["python3", "wsgi.py"]
deploymentTarget = "cloudrun"
run = ["sh", "-c", "flask run --host=0.0.0.0 --port=8080 --reload"]
deploymentTarget = "cloudrun"

[[ports]]
localPort = 8080
externalPort = 80
6 changes: 5 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from flask import Flask
from flask import Flask, render_template

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.app_context().push()

@app.route('/')
def home():
return "Hello World!"
Binary file modified instance/project.db
Binary file not shown.
68 changes: 68 additions & 0 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class User(db.Model):
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(120), nullable=False)

todos = db.relationship('Todo', backref='user', lazy=True, cascade="all, delete-orphan")

def __init__(self, username, email, password):
self.username = username
self.email = email
Expand All @@ -24,3 +26,69 @@ def set_password(self, password):

def __repr__(self):
return f'<User {self.id} {self.username} - {self.email}>'

# Add method to User model in models.py
def add_todo_category(self, todo_id, category_text):
# Fetch the todo by id
todo = Todo.query.filter_by(id=todo_id, user_id=self.id).first()
# Make sure the todo exists and belongs to the current user
if not todo:
return False

# Check if category already exists for current user
category = Category.query.filter_by(text=category_text, user_id=self.id).first()
if not category:
# Create new category
category = Category(user_id=self.id, text=category_text)
db.session.add(category)
db.session.commit()

# Associate todo with the category if not already associated
if category not in todo.categories:
todo.categories.append(category)
db.session.add(todo)
db.session.commit()

return True

class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) #set userid as a foreign key to user.id
text = db.Column(db.String(255), nullable=False)
done = db.Column(db.Boolean, default=False)

def toggle(self):
self.done = not self.done
db.session.add(self)
db.session.commit()

def __init__(self, text):
self.text = text

def __repr__(self):

return f'<Todo: {self.id} | {self.user.username} | {self.text} | { "done" if self.done else "not done" }>'

class TodoCategory(db.Model):
__tablename__ ='todo_category'
id = db.Column(db.Integer, primary_key=True)
todo_id = db.Column(db.Integer, db.ForeignKey('todo.id'), nullable=False)
category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False)
last_modified = db.Column(db.DateTime, default=func.now(), onupdate=func.now())

def __repr__(self):
return f'<TodoCategory last modified {self.last_modified.strftime("%Y/%m/%d, %H:%M:%S")}>'

class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
text = db.Column(db.String(255), nullable=False)
user = db.relationship('User', backref=db.backref('categories', lazy='joined'))
todos = db.relationship('Todo', secondary='todo_category', backref=db.backref('categories', lazy=True))

def __init__(self, user_id, text):
self.user_id = user_id
self.text = text

def __repr__(self):
return f'<Category user:{self.user.username} - {self.text}>'
121 changes: 119 additions & 2 deletions wsgi.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import click, sys
from models import db, User
from models import db, User,Todo
from app import app
from sqlalchemy.exc import IntegrityError

Expand All @@ -10,5 +10,122 @@ def initialize():
db.init_app(app)
db.create_all()
bob = User('bob', 'bob@mail.com', 'bobpass')
bob.todos.append(Todo('wash car'))
print(bob)
print('database intialized')
print('database intialized')
db.session.add(bob)
db.session.commit()
print(bob)

@app.cli.command("get-user", help="Retrieves a User")
@click.argument('username', default='bob')
def get_user(username):
bob = User.query.filter_by(username=username).first() #.first just prints the first row
if not bob:
print(f'{username} not found!')
return
print(bob)

@app.cli.command('get-users')
def get_users():
# gets all objects of a model
users = User.query.all()
print(users)

@app.cli.command("change-email")
@click.argument('username', default='bob')
@click.argument('email', default='bob@mail.com')
def change_email(username, email):
bob = User.query.filter_by(username=username).first()
if not bob:
print(f'{username} not found!')
return
bob.email = email
db.session.add(bob)
db.session.commit()
print(bob)


@app.cli.command('create-user')
@click.argument('username', default='rick')
@click.argument('email', default='rick@mail.com')
@click.argument('password', default='rickpass')
def create_user(username, email, password):
newuser = User(username, email, password)
try:
db.session.add(newuser)
db.session.commit()
except IntegrityError as e:
#let's the database undo any previous steps of a transaction
db.session.rollback()
# print(e.orig) #optionally print the error raised by the database
print("Username or email already taken!") #give the user a useful message
else:
print(newuser) # print the newly created user

@app.cli.command('delete-user')
@click.argument('username', default='bob')
def delete_user(username):
bob = User.query.filter_by(username=username).first()
if not bob:
print(f'{username} not found!')
return
db.session.delete(bob)
db.session.commit()
print(f'{username} deleted')

@app.cli.command('get-todos')
@click.argument('username', default='bob')
def get_user_todos(username):
bob = User.query.filter_by(username=username).first()
if not bob:
print(f'{username} not found!')
return
print(bob.todos)

@app.cli.command('add-todo')
@click.argument('username', default='bob')
@click.argument('text', default='wash car')
def add_task(username, text):
bob = User.query.filter_by(username=username).first()
if not bob:
print(f'{username} not found!')
return
new_todo = Todo(text)
bob.todos.append(new_todo)
db.session.add(bob)
db.session.commit()

@click.argument('todo_id', default=1)
@click.argument('username', default='bob')
@app.cli.command('toggle-todo')
def toggle_todo_command(todo_id, username):
user = User.query.filter_by(username=username).first()
if not user:
print(f'{username} not found!')
return

todo = Todo.query.filter_by(id=todo_id, user_id=user.id).first()
if not todo:
print(f'{username} has no todo id {todo_id}')

todo.toggle()
print(f'{todo.text} is {"done" if todo.done else "not done"}!')

@click.argument('category', default='chores')
@click.argument('username', default='bob')
@click.argument('todo_id', default=1)
@app.cli.command('add-category', help="Adds a category to a todo")
def add_todo_category_command(category, todo_id, username,):
user = User.query.filter_by(username=username).first()
if not user:
print(f'user {username} not found!')
return

res = user.add_todo_category(todo_id, category)
if not res:
print(f'{username} has no todo id {todo_id}')
return

todo = Todo.query.get(todo_id)
print(todo)