瀏覽代碼

Started recovery work. Need to upload to remote repo

control 3 年之前
當前提交
017f60fbb0

+ 41 - 0
app/__init__.py

@@ -0,0 +1,41 @@
+from flask import Flask
+from flask_sqlalchemy import SQLAlchemy
+from flask_login import LoginManager # Flask Login
+from os import path
+
+db = SQLAlchemy()
+DB_NAME = "database.db"
+
+def create_app():
+    app = Flask(__name__)
+    app.config['SECRET_KEY'] = 'Th15_iS-M1!S3cre4' # used to encrypt session cookies
+    app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
+    db.init_app(app)
+
+    # import blueprints
+    from .logic import logic 
+
+    # register blueprints
+    app.register_blueprint(logic, url_prefix  = '/') # allows the setting of prefixes for pages
+
+    # import Database models
+    from .models import User, Message
+
+    create_database(app)
+
+    login_manager = LoginManager()
+    login_manager.login_view =  'logic.login' # redirect here if not logged in
+    login_manager.init_app(app)
+
+    @login_manager.user_loader
+    # tells flask how to load a user from the db
+    def load_user(id):
+        return User.query.get(int(id)) # by default get() looks for the primary key
+
+    return app
+
+
+def create_database(app):
+    if not path.exists('app/' + DB_NAME):
+        db.create_all(app=app)
+        print('Created Database!')

二進制
app/__pycache__/__init__.cpython-39.pyc


二進制
app/__pycache__/logic.cpython-39.pyc


二進制
app/__pycache__/models.cpython-39.pyc


二進制
app/database.db


+ 136 - 0
app/logic.py

@@ -0,0 +1,136 @@
+# Site Back-End Logic
+from hmac import new
+import string, secrets
+from flask import Blueprint, render_template, request, flash, redirect, url_for
+from flask_login import login_user, login_required, logout_user, current_user
+from werkzeug.security import generate_password_hash, check_password_hash
+from .models import User, Message
+from . import db
+
+logic = Blueprint('logic', __name__)
+
+@logic.route('/', methods=['GET', 'POST'])
+@login_required
+def profile():
+    if request.method == "POST":
+        new_desc = request.form.get('description_area')
+        passwd_1 = request.form.get('passwd_1')
+        passwd_2 = request.form.get('passwd_2')
+        new_pic = request.files.get('profilepic_upload')
+
+
+        if new_desc:
+            new_desc_dbcall = User.query.filter_by(id=current_user.id).first()
+            new_desc_dbcall.description = new_desc
+            db.session.commit()
+            flash('Hooray! A new description!', category='success')
+        elif passwd_1 and passwd_2:
+            if passwd_1 == passwd_2:
+                new_passwd_dbcall = User.query.filter_by(id=current_user.id).first()
+                new_passwd_dbcall.password = generate_password_hash(passwd_2, method='sha256')
+                db.session.commit()
+                flash('Nice! Updated your password!', category='success')
+            else:
+                flash('Oh no! Your passwords must match!', category='error')
+        elif new_pic:
+            # generate random filename for uploaded file 
+            alphanumeric = string.ascii_letters + string.digits
+            ralphanum = ''.join(secrets.choice(alphanumeric) for i in range(16))
+            new_pic_dbcall = User.query.filter_by(id=current_user.id).first()
+            if '.png' in new_pic.filename:
+                new_pic.save(f'app/static/uploads/{ralphanum}.png')
+                new_pic_dbcall.profile_image = f'{ralphanum}.png'
+            elif '.jpg' in new_pic.filename or 'jpeg' in new_pic.filename:
+                new_pic.save(f'app/static/uploads/{ralphanum}.jpeg')
+                new_pic_dbcall.profile_image = f'{ralphanum}.jpeg'
+            db.session.commit()
+
+
+
+    return render_template("profile.html", user=current_user)
+
+
+@logic.route('/matchbook', methods=['GET', 'POST'])
+@login_required
+def matchbook():
+    all_users = User.query.all()
+    return render_template("matchbook.html", user=current_user, userlist=all_users)
+
+
+@logic.route('/login', methods=['GET', 'POST'])
+def login():
+    if request.method == 'POST':
+        email = request.form.get('email')
+        challenge_passwd = request.form.get('passwd_login')
+
+        user = User.query.filter_by(email=email).first()
+        if user:
+            if check_password_hash(user.password, challenge_passwd):
+                flash('Successful Login!', category='success')
+                login_user(user, remember=True)
+                return redirect(url_for('logic.profile'))
+            else:
+                flash('Unsucessful Login!', category='error')
+        else:
+            flash('Unsucessful Login!', category='error')
+    
+    return render_template("login.html", user=current_user)
+
+@logic.route('/logout')
+@login_required
+def logout():
+    logout_user()
+    return redirect(url_for('logic.login'))
+
+# Signup Route
+@logic.route('/register', methods=['GET', 'POST'])
+def register():
+    pass_list = list()
+    if request.method == 'POST':
+        email = request.form.get('email') 
+        firstname = request.form.get('firstname')
+        lastname = request.form.get('lastname')
+        age = request.form.get('age')
+        gender = request.form.get('gender')
+        passwd_1 = request.form.get('passwd_1')
+        passwd_2 = request.form.get('passwd_2')
+
+        # Basic User Input Checks
+        email_check = User.query.filter_by(email=email).first()
+        if len(email) < 1:
+            flash('Your Email must be longer than 0 characters.', category='error')
+        elif email_check:
+            flash('This Email is already taken', category='error')
+        else:
+            pass_list.append('p')
+
+        if len(firstname) < 1:
+            flash('First name must be something', category='error')
+        else:
+            pass_list.append('p')
+
+        if len(lastname) < 1:
+            flash('Last name must be something', category='error')
+        else:
+            pass_list.append('p')
+
+        if gender == 'M' or gender == 'F':
+            pass_list.append('p')
+        else:
+            flash('Gender must be either M or F!', category='error')
+
+        if len(passwd_1) < 8 or len(passwd_2) < 8:
+            flash('Your Password must be longer than or equal to 8 characters.', category='error')
+        else:
+            if passwd_1 != passwd_2:
+                flash('Your Passwords must match!', category='error')
+            else:
+                if len(pass_list) == 4:
+                    new_user = User(email=email, firstname=firstname, lastname=lastname, age=age, gender=gender, password=generate_password_hash(passwd_2, method='sha256'))
+                    db.session.add(new_user)
+                    db.session.commit()
+                    flash('Account Registration Successful!', category='success')
+                    return redirect(url_for('logic.profile'))
+                else:
+                    flash('Registration Failed', category='error')
+    return render_template("register.html", user=current_user)

+ 22 - 0
app/models.py

@@ -0,0 +1,22 @@
+# Database Models
+from . import db # that SQLAlchemy Object in __init__.py
+from flask_login import UserMixin
+from sqlalchemy.sql import func
+
+class User(db.Model, UserMixin): # User Database
+   id = db.Column(db.Integer, primary_key=True)
+   email = db.Column(db.String(150), unique=True)
+   password = db.Column(db.String(150))
+   firstname = db.Column(db.String(150))
+   lastname = db.Column(db.String(150))
+   age = db.Column(db.Integer)
+   gender = db.Column(db.String(1))
+   description = db.Column(db.String(300))
+   profile_image = db.Column(db.String(150))
+
+class Message(db.Model):
+    id = db.Column(db.Integer, primary_key=True)
+    sender = db.Column(db.Integer,) # User id
+    recipient = db.Column(db.Integer)
+    message = db.Column(db.String(10000))
+    datestamp = db.Column(db.DateTime(timezone=True), default=func.now())

二進制
app/static/uploads/TNFyxJlF6m31qG6T.png


二進制
app/static/uploads/default.png


+ 81 - 0
app/templates/base.html

@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="utf-8" />
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <link
+            rel="stylesheet"
+            href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
+            integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
+            crossorigin="anonymous"
+        />
+        <link
+            rel="stylesheet"
+            href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
+            crossorigin="anonymous"
+        />
+        <title>{% block title %}Home{% endblock %}</title>
+    </head>
+
+    <body>
+        <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar"> <!-- for mobile devices -->
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="navbar">
+                <div class="navbar-nav">
+                    {% if user.is_authenticated %} <!-- shows only if user is logged in -->
+                    <a class="nav-item nav-link" id="profile" href="/">Profile</a>
+                    <a class="nav-item nav-link" id="matchbook" href="/matchbook">Matchbook</a>
+                    <a class="nav-item nav-link" id="logout" href="/logout">Logout</a>
+                    {% else %}
+                    <a class="nav-item nav-link" id="login" href="/login">Login</a>
+                    <a class="nav-item nav-link" id="register" href="/register">Register</a>
+                    {% endif %}
+            </div>
+        </nav>
+        <!-- For Flash Errors to User -->
+        {% with messages = get_flashed_messages(with_categories=true) %}
+        {% if messages %}
+            {% for category, message in messages %}
+                {% if category == 'error' %}
+                <div class="alert alert-danger alter-dismissable fade show", role="alert">
+                    {{ message }}
+                    <button type="button" class="close" data-dismiss="alert">
+                        <span aria-hidden="true">&times;</span> <!-- fancy button styling-->
+                    </button>
+                </div>
+                {% else %}
+                <div class="alert alert-success alter-dismissable fade show", role="alert">
+                    {{ message }}
+                    <button type="button" class="close" data-dismiss="alert">
+                        <span aria-hidden="true">&times;</span> <!-- fancy button styling-->
+                    </button>
+                </div>
+                {% endif %}
+            {% endfor %}
+        {% endif %}
+        {% endwith %}
+        <div class="container">
+            {% block content %}
+            {% endblock %}
+        </div>
+
+
+        <script
+            src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
+            integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
+            crossorigin="anonymous">
+        </script>
+        <script
+            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
+            integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
+            crossorigin="anonymous">
+        </script>
+        <script
+            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
+            integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
+            crossorigin="anonymous">
+        </script>
+    </body>
+</html>

+ 27 - 0
app/templates/login.html

@@ -0,0 +1,27 @@
+{% extends "base.html" %}
+
+{% block content %}
+<h1>Login Here!</h1>
+<form method="POST">
+<div class="form-group">
+    <label for="email"></label>
+    <input 
+        type="email" 
+        class="form-control" 
+        id="email"
+        name="email"
+        placeholder="Insert Email"
+    />
+    <label for="passwd_login"></label>
+    <input 
+        type="password" 
+        class="form-control" 
+        id="passwd_login"
+        name="passwd_login"
+        placeholder="Enter Password"
+    />
+</div>
+<br />
+<button type="submit" class="btn btn-primary">Login</button>
+</form>
+{% endblock %}

+ 27 - 0
app/templates/matchbook.html

@@ -0,0 +1,27 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+
+<h1>Matchbook</h1>
+<ul class="list-group list-group-flush" id="matchbooklist">
+    {% for user in userlist %}
+    <li class="list-group-item">
+        {% if user.profile_image %}
+            <img src="static/uploads/{{ user.profile_image }}" witdh="100" height="100">
+        {% else %}
+            <img src="static/uploads/default.png" width="100" height="100">
+        {% endif %}
+        <p>{{ user.firstname }}</p>
+        <p>{{ user.lastname }}</p>
+        <p>{{ user.gender }} , {{ user.age }}</p>
+        <p>{{ user.description }}</p>
+        <form method="POST">
+            <button type="submit" class="btn btn-primary">Message</button>
+        </form>
+    </li>
+    {% endfor %}
+
+</ul>
+
+{% endblock %}

+ 40 - 0
app/templates/profile.html

@@ -0,0 +1,40 @@
+{% extends "base.html" %}
+
+{% block content %}
+<h1> Your Profile</h1>
+{% if user.profile_image %}
+    <img src="static/uploads/{{ user.profile_image }}" witdh="100" height="100">
+{% else %}
+    <img src="static/uploads/default.png" width="100" height="100">
+{% endif %}
+<form method="POST" action="" enctype="multipart/form-data">
+    <input type="file" id="profilepic_upload" name="profilepic_upload" accept="image/png, image/jpeg">
+    <button type="submit" class="btn btn-primary">Upload</button>
+</form>
+<p>{{ user.firstname }}</p>
+<p>{{ user.lastname }}</p>
+<p>{{ user.gender }} , {{ user.age }}</p>
+<form method="POST">
+    <textarea id="description_area" name="description_area" placeholder="{{ user.description }}"></textarea>
+    <button type="submit" class="btn btn-primary">Edit</button>
+</form>
+<form method="POST">
+    <label for="passwd_1"></label>
+    <input 
+        type="password" 
+        class="form-control" 
+        id="passwd_1"
+        name="passwd_1"
+        placeholder="Edit Password"
+    />
+    <label for="passwd_2"></label>
+    <input 
+        type="password" 
+        class="form-control" 
+        id="passwd_2"
+        name="passwd_2"
+        placeholder="Confirm Password"
+    />
+    <button type="submit" class="btn btn-primary">Update Password</button>
+</form>
+{% endblock %}

+ 77 - 0
app/templates/register.html

@@ -0,0 +1,77 @@
+{% extends "base.html" %}
+
+{% block content %}
+<h1> Register Here! </h1>
+<form method="POST">
+    <div class="form-group">
+        <label for="email"></label>
+        <input 
+            type="email" 
+            class="form-control" 
+            id="email"
+            name="email"
+            placeholder="Insert Email"
+        />
+        <label for="passwd_1"></label>
+        <input 
+            type="password" 
+            class="form-control" 
+            id="passwd_1"
+            name="passwd_1"
+            placeholder="Enter Password"
+        />
+        <label for="passwd_2"></label>
+        <input 
+            type="password" 
+            class="form-control" 
+            id="passwd_2"
+            name="passwd_2"
+            placeholder="Confirm Password"
+        />
+        <label for="firstname"></label>
+        <input 
+            type="text" 
+            class="form-control" 
+            id="firstname"
+            name="firstname"
+            placeholder="Insert First Name"
+        />
+        <label for="lasstname"></label>
+        <input 
+            type="text" 
+            class="form-control" 
+            id="lasstname"
+            name="lastname"
+            placeholder="Insert Last Name"
+        />
+        <label for="age"></label>
+        <input 
+            type="number" 
+            class="form-control" 
+            id="age"
+            name="age"
+            min="18"
+            max="110"
+            placeholder="Insert Your Age"
+        />
+        <label for="genderm">Male</label>
+        <input 
+            type="radio" 
+            class="form-control" 
+            id="genderm"
+            name="gender"
+            value="M"
+        />
+        <label for="genderf">Female</label>
+        <input 
+            type="radio" 
+            class="form-control" 
+            id="genderf"
+            name="gender"
+            value="F"
+        />
+    </div>
+    <br />
+    <button type="submit" class="btn btn-primary">Submit</button>
+</form>
+{% endblock %}

+ 6 - 0
main.py

@@ -0,0 +1,6 @@
+from app import create_app
+
+app = create_app()
+
+if __name__ == '__main__':
+    app.run(debug=True) ## debug=True auto re-runs websever upon change turn off for production