diff --git a/main.py b/main.py new file mode 100644 index 0000000..45d99eb --- /dev/null +++ b/main.py @@ -0,0 +1,6 @@ +from website import create_app + +app = create_app() + +if __name__ == '__main__': + app.run(debug=True) diff --git a/website/__init__.py b/website/__init__.py new file mode 100644 index 0000000..29d88c2 --- /dev/null +++ b/website/__init__.py @@ -0,0 +1,40 @@ +from flask import Flask +from flask_sqlalchemy import SQLAlchemy +from os import path +from flask_login import LoginManager + +db = SQLAlchemy() +DB_NAME = "database.db" + + +def create_app(): + app = Flask(__name__) + app.config['SECRET_KEY'] = 'hjshjhdjah kjshkjdhjs' + app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}' + db.init_app(app) + + from .views import views + from .auth import auth + + app.register_blueprint(views, url_prefix='/') + app.register_blueprint(auth, url_prefix='/') + + from .models import User, Note + + create_database(app) + + login_manager = LoginManager() + login_manager.login_view = 'auth.login' + login_manager.init_app(app) + + @login_manager.user_loader + def load_user(id): + return User.query.get(int(id)) + + return app + + +def create_database(app): + if not path.exists('website/' + DB_NAME): + db.create_all(app=app) + print('Created Database!') diff --git a/website/auth.py b/website/auth.py new file mode 100644 index 0000000..72666d9 --- /dev/null +++ b/website/auth.py @@ -0,0 +1,66 @@ +from flask import Blueprint, render_template, request, flash, redirect, url_for +from .models import User +from werkzeug.security import generate_password_hash, check_password_hash +from . import db +from flask_login import login_user, login_required, logout_user, current_user + + +auth = Blueprint('auth', __name__) + + +@auth.route('/login', methods=['GET', 'POST']) +def login(): + if request.method == 'POST': + email = request.form.get('email') + password = request.form.get('password') + + user = User.query.filter_by(email=email).first() + if user: + if check_password_hash(user.password, password): + flash('Logged in successfully!', category='success') + login_user(user, remember=True) + return redirect(url_for('views.home')) + else: + flash('Incorrect password, try again.', category='error') + else: + flash('Email does not exist.', category='error') + + return render_template("login.html", user=current_user) + + +@auth.route('/logout') +@login_required +def logout(): + logout_user() + return redirect(url_for('auth.login')) + + +@auth.route('/sign-up', methods=['GET', 'POST']) +def sign_up(): + if request.method == 'POST': + email = request.form.get('email') + first_name = request.form.get('firstName') + password1 = request.form.get('password1') + password2 = request.form.get('password2') + + user = User.query.filter_by(email=email).first() + if user: + flash('Email already exists.', category='error') + elif len(email) < 4: + flash('Email must be greater than 3 characters.', category='error') + elif len(first_name) < 2: + flash('First name must be greater than 1 character.', category='error') + elif password1 != password2: + flash('Passwords don\'t match.', category='error') + elif len(password1) < 7: + flash('Password must be at least 7 characters.', category='error') + else: + new_user = User(email=email, first_name=first_name, password=generate_password_hash( + password1, method='sha256')) + db.session.add(new_user) + db.session.commit() + login_user(new_user, remember=True) + flash('Account created!', category='success') + return redirect(url_for('views.home')) + + return render_template("sign_up.html", user=current_user) diff --git a/website/models.py b/website/models.py new file mode 100644 index 0000000..79c17e6 --- /dev/null +++ b/website/models.py @@ -0,0 +1,18 @@ +from . import db +from flask_login import UserMixin +from sqlalchemy.sql import func + + +class Note(db.Model): + id = db.Column(db.Integer, primary_key=True) + data = db.Column(db.String(10000)) + date = db.Column(db.DateTime(timezone=True), default=func.now()) + user_id = db.Column(db.Integer, db.ForeignKey('user.id')) + + +class User(db.Model, UserMixin): + id = db.Column(db.Integer, primary_key=True) + email = db.Column(db.String(150), unique=True) + password = db.Column(db.String(150)) + first_name = db.Column(db.String(150)) + notes = db.relationship('Note') diff --git a/website/static/index.js b/website/static/index.js new file mode 100644 index 0000000..136d212 --- /dev/null +++ b/website/static/index.js @@ -0,0 +1,8 @@ +function deleteNote(noteId) { + fetch("/delete-note", { + method: "POST", + body: JSON.stringify({ noteId: noteId }), + }).then((_res) => { + window.location.href = "/"; + }); +} diff --git a/website/templates/base.html b/website/templates/base.html new file mode 100644 index 0000000..8f2613f --- /dev/null +++ b/website/templates/base.html @@ -0,0 +1,83 @@ + + + + + + + + + {% block title %}Home{% endblock %} + + + + + {% with messages = get_flashed_messages(with_categories=true) %} {% if + messages %} {% for category, message in messages %} {% if category == + 'error' %} + + {% else %} + + {% endif %} {% endfor %} {% endif %} {% endwith %} + +
{% block content %} {% endblock %}
+ + + + + + + diff --git a/website/templates/home.html b/website/templates/home.html new file mode 100644 index 0000000..0fc5c1d --- /dev/null +++ b/website/templates/home.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} {% block title %}Home{% endblock %} {% block content +%} +

Notes

+ +
+ +
+
+ +
+
+{% endblock %} diff --git a/website/templates/login.html b/website/templates/login.html new file mode 100644 index 0000000..4f67e1b --- /dev/null +++ b/website/templates/login.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} {% block title %}Login{% endblock %} {% block content +%} +
+

Login

+
+ + +
+
+ + +
+
+ +
+{% endblock %} diff --git a/website/templates/sign_up.html b/website/templates/sign_up.html new file mode 100644 index 0000000..0d401e1 --- /dev/null +++ b/website/templates/sign_up.html @@ -0,0 +1,48 @@ +{% extends "base.html" %} {% block title %}Sign Up{% endblock %} {% block +content %} +
+

Sign Up

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+{% endblock %} diff --git a/website/views.py b/website/views.py new file mode 100644 index 0000000..e3a4f16 --- /dev/null +++ b/website/views.py @@ -0,0 +1,37 @@ +from flask import Blueprint, render_template, request, flash, jsonify +from flask_login import login_required, current_user +from .models import Note +from . import db +import json + +views = Blueprint('views', __name__) + + +@views.route('/', methods=['GET', 'POST']) +@login_required +def home(): + if request.method == 'POST': + note = request.form.get('note') + + if len(note) < 1: + flash('Note is too short!', category='error') + else: + new_note = Note(data=note, user_id=current_user.id) + db.session.add(new_note) + db.session.commit() + flash('Note added!', category='success') + + return render_template("home.html", user=current_user) + + +@views.route('/delete-note', methods=['POST']) +def delete_note(): + note = json.loads(request.data) + noteId = note['noteId'] + note = Note.query.get(noteId) + if note: + if note.user_id == current_user.id: + db.session.delete(note) + db.session.commit() + + return jsonify({})