diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..e50103f Binary files /dev/null and b/.DS_Store differ diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..ac21435 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/forum/.DS_Store b/forum/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/forum/.DS_Store differ diff --git a/forum/app.py b/forum/app.py index 4d8a828..0ae7641 100644 --- a/forum/app.py +++ b/forum/app.py @@ -6,8 +6,8 @@ from . import create_app app = create_app() -app.config['SITE_NAME'] = 'Schooner' -app.config['SITE_DESCRIPTION'] = 'a schooner forum' +app.config['SITE_NAME'] = 'Something, Anything, that is not that' +app.config['SITE_DESCRIPTION'] = 'a forum for Data to learn from' app.config['FLASK_DEBUG'] = 1 def init_site(): diff --git a/forum/models.py b/forum/models.py index 8add9ae..6a6ccff 100644 --- a/forum/models.py +++ b/forum/models.py @@ -86,6 +86,8 @@ class Comment(db.Model): postdate = db.Column(db.DateTime) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) post_id = db.Column(db.Integer, db.ForeignKey("post.id")) + replies = db.relationship('Reply', backref='comment', cascade='all, delete-orphan') + lastcheck = None savedresponce = None @@ -115,6 +117,46 @@ def get_time_string(self): self.savedresponce = "Just a moment ago!" return self.savedresponce +class Reply(db.Model): + id = db.Column(db.Integer, primary_key=True) + content = db.Column(db.Text) + postdate = db.Column(db.DateTime) + user_id = db.Column(db.Integer, db.ForeignKey('user.id')) + comment_id = db.Column(db.Integer, db.ForeignKey("comment.id")) + + user = db.relationship('User', backref='replies') + + + lastcheck = None + savedresponce = None + def __init__(self, content, postdate, user_id, comment_id): + self.content = content + self.postdate = postdate + self.user_id = user_id + self.comment_id = comment_id + def get_time_string(self): + #this only needs to be calculated every so often, not for every request + #this can be a rudamentary chache + now = datetime.datetime.now() + if self.lastcheck is None or (now - self.lastcheck).total_seconds() > 30: + self.lastcheck = now + else: + return self.savedresponce + + diff = now - self.postdate + seconds = diff.total_seconds() + if seconds / (60 * 60 * 24 * 30) > 1: + self.savedresponce = " " + str(int(seconds / (60 * 60 * 24 * 30))) + " months ago" + elif seconds / (60 * 60 * 24) > 1: + self.savedresponce = " " + str(int(seconds / (60* 60 * 24))) + " days ago" + elif seconds / (60 * 60) > 1: + self.savedresponce = " " + str(int(seconds / (60 * 60))) + " hours ago" + elif seconds / (60) > 1: + self.savedresponce = " " + str(int(seconds / 60)) + " minutes ago" + else: + self.savedresponce = "Just a moment ago!" + return self.savedresponce + def error(errormessage): return "" + errormessage + "" diff --git a/forum/routes.py b/forum/routes.py index 75993e5..46db246 100644 --- a/forum/routes.py +++ b/forum/routes.py @@ -1,10 +1,11 @@ -from flask import render_template, request, redirect, url_for +from flask import render_template, request, redirect, url_for, flash from flask_login import current_user, login_user, logout_user from flask_login.utils import login_required import datetime from flask import Blueprint, render_template, request, redirect, url_for -from forum.models import User, Post, Comment, Subforum, valid_content, valid_title, db, generateLinkPath, error +from forum.models import User, Post, Comment, Subforum, valid_content, valid_title, db, generateLinkPath, error, Reply from forum.user import username_taken, email_taken, valid_username +from werkzeug.security import generate_password_hash, check_password_hash ## # This file needs to be broken up into several, to make the project easier to work on. @@ -117,6 +118,17 @@ def comment(): db.session.commit() return redirect("/viewpost?post=" + str(post_id)) +@login_required +@rt.route('/action_reply/comment/', methods=['POST']) #attempt to mimic comment as a reply +def action_reply(comment_id): + comment = Comment.query.get_or_404(comment_id) + content = request.form['content'] + postdate = datetime.datetime.now() + reply = Reply(content=content, postdate=postdate, user_id=current_user.id, comment_id=comment_id) + db.session.add(reply) + db.session.commit() + return redirect(url_for('routes.viewpost', post=comment.post_id)) + @login_required @rt.route('/action_post', methods=['POST']) def action_post(): @@ -145,3 +157,42 @@ def action_post(): db.session.commit() return redirect("/viewpost?post=" + str(post.id)) +@login_required +@rt.route('/user') +def user(): + user_id = request.args.get('user_id') + + if user_id: + user = User.query.get_or_404(user_id) + posts = Post.query.filter(Post.user_id == user.id).all() + comments = Comment.query.filter(Comment.user_id == user.id).all() + replies = Reply.query.filter(Reply.user_id == user.id).all() + return render_template('user.html', user=user, posts=posts, comments= comments, replies= replies) + elif current_user.is_authenticated: + return redirect(url_for('routes.user', user_id=current_user.id)) + else: + return redirect ('/loginform') + +@login_required +@rt.route('/change_password', methods=['POST', 'GET']) +def change_password(): + if request.method == 'POST': + old_password = request.form['old_password'] + new_password = request.form['new_password'] + confirm_password = request.form['confirm_password'] + + if not check_password_hash(current_user.password_hash, old_password): + flash('Old password does not match records.', 'danger') + return redirect(url_for('routes.change_password')) + + if new_password != confirm_password: + flash('New and confirm do not match.', 'warning') + return redirect(url_for('routes.change_password')) + + current_user.password_hash = generate_password_hash(new_password) + db.session.commit() + + flash('Password has been updated', 'success') + return redirect(url_for('routes.change_password')) + + return render_template('change_password.html') \ No newline at end of file diff --git a/forum/static/style.css b/forum/static/style.css index 2dd2e2e..f6259d5 100644 --- a/forum/static/style.css +++ b/forum/static/style.css @@ -13,10 +13,10 @@ } .header{ - border: 1px solid black; + border: 5px solid black; overflow: hidden; vertical-align: middle; - padding: 0.5%; + padding: 3.5%; margin-bottom: none; } .content{ diff --git a/forum/templates/.DS_Store b/forum/templates/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/forum/templates/.DS_Store differ diff --git a/forum/templates/change_password.html b/forum/templates/change_password.html new file mode 100644 index 0000000..c69253f --- /dev/null +++ b/forum/templates/change_password.html @@ -0,0 +1,28 @@ +{% extends 'layout.html' %} +{% block body %} +{{ path|safe }} + +
+

Change Password

+ + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} +
+ {% for category, message in messages %} +
+ {{ message }} +
+ {% endfor %} +
+ {% endif %} + {% endwith %} + +
+
+
+
+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/forum/templates/createpost.html b/forum/templates/createpost.html index 85947a6..63235ab 100644 --- a/forum/templates/createpost.html +++ b/forum/templates/createpost.html @@ -11,11 +11,12 @@
-
+ +
-
+
- +
{% endblock %} \ No newline at end of file diff --git a/forum/templates/header.html b/forum/templates/header.html index 9403a0d..1db16bb 100644 --- a/forum/templates/header.html +++ b/forum/templates/header.html @@ -1,8 +1,27 @@ -{{ config.SITE_NAME }}{% if config.SITE_DESCRIPTION %} - {% endif %} {{ config.SITE_DESCRIPTION }} -
+ +
\ No newline at end of file + + +{% if current_user.is_authenticated %} +
+ Profile + Change Password +
+{% endif %} \ No newline at end of file diff --git a/forum/templates/layout.html b/forum/templates/layout.html index a2a5e14..3c359fa 100644 --- a/forum/templates/layout.html +++ b/forum/templates/layout.html @@ -1,30 +1,58 @@ - - - {{ config.SITE_NAME }} + + + + + + Bootstrap + + + {{ config.SITE_NAME }} + -
-
- {% include 'header.html' %} -
- {% if errors %} -
- {% for error in errors %} -

- {{ error }} -

- - {% endfor %} -
+ + + + + + +
+
+
Your Logo
+
+ +
+
{% include 'header.html' %}
+
+ + +
+ {% if errors %} +
+ {% for error in errors %} +

+ {{ error }} +

+ + {% endfor %} + +
{% endif %} -
- {% block body %}{% endblock %} -
+
+
+
+
{% block body %}{% endblock %}
+
+
+ + + + diff --git a/forum/templates/user.html b/forum/templates/user.html new file mode 100644 index 0000000..f5bab63 --- /dev/null +++ b/forum/templates/user.html @@ -0,0 +1,52 @@ +{% extends 'layout.html' %} +{% block body %} +{{ path|safe }} + + {% if current_user.is_authenticated %} +

Welcome, {{ user.username }}

+

These are your posts:

+ {% if posts %} + + {% else %} +

You have no posts at this time.

+ {% endif %} +

These are your comments:

+ {% if comments %} + + {% else %} +

You have no comments at this time.

+ {% endif %} + +

These are your replies:

+ {% if replies %} + + {% else %} +

You have no replies at this time.

+ {% endif %} + + {% else %} + Click here to login or register! + {% endif %} + +{% endblock %} \ No newline at end of file diff --git a/forum/templates/viewpost.html b/forum/templates/viewpost.html index 3f489ca..7e7180d 100644 --- a/forum/templates/viewpost.html +++ b/forum/templates/viewpost.html @@ -1,7 +1,6 @@ {% extends 'layout.html' %} {% block body %} {{ path|safe}} -
{{post.title}} @@ -20,16 +19,13 @@
-
- +
+
- - - {% if current_user.is_authenticated %} - + {% else %} Login or register to make a comment @@ -38,10 +34,10 @@ {%if comments%}
{% for comment in comments %} - +
- ({{ comment.user.username }}) - + ({{ comment.user.username }}) -
{{ comment.content }} @@ -50,24 +46,56 @@
{{ comment.get_time_string() }}
+ + {% if current_user.is_authenticated %} +
+ + +
+ {% endif %} + + {% if comment.replies %} +
+ {% for reply in comment.replies %} +
+
+ ({{ reply.user.username }}) - +
+
+ {{ reply.content }} +
+
+ {{ reply.get_time_string() }} +
+
+ {% endfor %} +
+ {% endif %} +

{% endfor %}
{% endif %} +