Skip to content
Merged
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
Binary file added Projects/ThinkTank/app.db
Binary file not shown.
26 changes: 26 additions & 0 deletions Projects/ThinkTank/app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_wtf.csrf import CSRFProtect
from flask_bcrypt import Bcrypt
from flask_login import LoginManager

app = Flask(__name__)
app.config.from_object('config.Config')

csrf = CSRFProtect(app)
bcrypt = Bcrypt(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)

login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'

from app.models import User

@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))

from app import routes, models, forms
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
20 changes: 20 additions & 0 deletions Projects/ThinkTank/app/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email, EqualTo

class RegistrationForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
username = StringField('Username', validators=[DataRequired(), Length(min=2, max=64)])
password = PasswordField('Password', validators=[DataRequired(), Length(min=6)])
confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Sign Up')

class LoginForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Login')

class PageForm(FlaskForm):
title = StringField('Title', validators=[DataRequired(), Length(max=128)])
content = TextAreaField('Content', validators=[DataRequired()])
submit = SubmitField('Save')
31 changes: 31 additions & 0 deletions Projects/ThinkTank/app/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from app import db
from flask_login import UserMixin

class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), unique=True, nullable=False)
username = db.Column(db.String(64), nullable=False)
password = db.Column(db.String(60), nullable=False)
pages = db.relationship('Page', backref='author', lazy=True)

def __repr__(self):
return f"User('{self.email}')"

class Page(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(128), nullable=False)
content = db.Column(db.Text, nullable=True)
deleted = db.Column(db.Boolean, default=False, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

def __repr__(self):
return f'<Page {self.title}>'

class CalendarEvent(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(128), nullable=False)
description = db.Column(db.Text, nullable=True)
start_date = db.Column(db.Date, nullable=False)

def __repr__(self):
return f'<CalendarEvent {self.title}>'
136 changes: 136 additions & 0 deletions Projects/ThinkTank/app/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
from flask import render_template, redirect, url_for, flash, request, abort
from app import app, db, bcrypt
from app.models import Page, User, CalendarEvent
from app.forms import RegistrationForm, LoginForm, PageForm
from flask_login import login_user, current_user, logout_user, login_required

@app.route('/signup', methods=['GET', 'POST'])
def signup():
if current_user.is_authenticated:
return redirect(url_for('index'))
form = RegistrationForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user = User(email=form.email.data, username=form.username.data, password=hashed_password)
db.session.add(user)
db.session.commit()
flash('Your account has been created! You can now log in.', 'success')
return redirect(url_for('login'))
return render_template('signup.html', form=form)

@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('index'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user and bcrypt.check_password_hash(user.password, form.password.data):
login_user(user, remember=True)
flash('You have been logged in!', 'success')
return redirect(url_for('index'))
else:
flash('Login Unsuccessful. Please check email and password', 'danger')
return render_template('login.html', form=form)

@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('index'))

@app.route('/')
@login_required
def index():
pages = Page.query.filter_by(author=current_user, deleted=False).all()
trash_pages = Page.query.filter_by(author=current_user, deleted=True).all()
events = CalendarEvent.query.all()
return render_template('index.html', pages=pages, trash_pages=trash_pages, events=events)

@app.route('/page/<int:page_id>')
@login_required
def page(page_id):
page = Page.query.get_or_404(page_id)
if page.author != current_user:
abort(403)
return render_template('page.html', page=page)

@app.route('/add', methods=['GET', 'POST'])
@login_required
def add():
if request.method == 'POST':
title = request.form['title']
content = request.form['content']
date = request.form.get('date', None)
content_with_date = f"Date: {date}\n\n{content}" if date else content
new_page = Page(title=title, content=content_with_date, author=current_user)
db.session.add(new_page)
db.session.commit()
return redirect(url_for('index'))
return render_template('add.html')

@app.route('/delete/<int:page_id>', methods=['POST'])
@login_required
def delete(page_id):
page = Page.query.get_or_404(page_id)
if page.author != current_user:
abort(403)
page.deleted = True
db.session.commit()
return redirect(url_for('index'))

@app.route('/trash')
@login_required
def trash():
pages = Page.query.filter_by(author=current_user, deleted=True).all()
return render_template('trash.html', pages=pages)

@app.route('/restore/<int:page_id>', methods=['POST'])
@login_required
def restore(page_id):
page = Page.query.get_or_404(page_id)
if page.author != current_user:
abort(403)
page.deleted = False
db.session.commit()
return redirect(url_for('index'))

@app.route('/permanent_delete/<int:page_id>', methods=['POST'])
@login_required
def permanent_delete(page_id):
page = Page.query.get_or_404(page_id)
if page.author != current_user:
abort(403)
db.session.delete(page)
db.session.commit()
return redirect(url_for('index'))

@app.route('/edit/<int:page_id>', methods=['GET', 'POST'])
@login_required
def edit_page(page_id):
page = Page.query.get_or_404(page_id)
if page.author != current_user:
abort(403)
form = PageForm()
if form.validate_on_submit():
page.title = form.title.data
page.content = form.content.data
db.session.commit()
flash('Page has been updated!', 'success')
return redirect(url_for('index'))
elif request.method == 'GET':
form.title.data = page.title
form.content.data = page.content
return render_template('edit_page.html', form=form, page=page)

@app.route('/add_event', methods=['POST'])
@login_required
def add_event():
title = request.form['title']
description = request.form['description']
date = request.form['date']
new_event = CalendarEvent(title=title, description=description, start_date=date)
db.session.add(new_event)
db.session.commit()
flash('Event has been added!', 'success')
return redirect(url_for('index'))
Loading