src: added user page

master
tiyn 2 years ago
parent f4f8e3eb7f
commit ceadc87e16

@ -12,7 +12,7 @@ The blog is intended to be used to review and critique things.
- [x] Login - [x] Login
- [x] Logout - [x] Logout
- [x] Register - [x] Register
- [ ] User Page - [x] User Page
- [ ] Review blog entries - [ ] Review blog entries
- [x] Writing entries - [x] Writing entries
- [ ] Editing entries - [ ] Editing entries

@ -45,10 +45,19 @@ def index():
@app.route("/archive") @app.route("/archive")
@app.route("/archive.html") @app.route("/archive.html")
def archive(): def archive():
entries = db.get_entries()
content = con_gen.gen_arch_string() content = con_gen.gen_arch_string()
return render_template("archive.html", content_string=content) return render_template("archive.html", content_string=content)
@app.route("/user/<name>")
def user(name):
content = con_gen.gen_user_string(name)
if content != "":
return render_template("user.html", name=name, content_string=content)
abort(404)
@app.route("/entry/<ident>") @app.route("/entry/<ident>")
def entry(ident): def entry(ident):
content = con_gen.gen_stand_string(ident) content = con_gen.gen_stand_string(ident)
@ -103,12 +112,10 @@ def logout():
@app.route("/register", methods=["GET", "POST"]) @app.route("/register", methods=["GET", "POST"])
@app.route("/register.html", methods=["GET", "POST"]) @app.route("/register.html", methods=["GET", "POST"])
def register(): def register():
if current_user.is_authenticated or not REGISTER: if current_user.is_authenticated or not config.ALLOW_REGISTRATION:
return redirect(url_for("index")) return redirect(url_for("index"))
form = RegisterForm() form = RegisterForm()
if form.validate_on_submit(): if form.validate_on_submit():
if not config.ALLOW_REGISTRATION:
return redirect(url_for("index"))
db_user = db.get_user_by_name(form.username.data) db_user = db.get_user_by_name(form.username.data)
if db_user is None: if db_user is None:
user = User(form.username.data) user = User(form.username.data)

@ -33,6 +33,45 @@ def gen_arch_string():
entries = db.get_entries() entries = db.get_entries()
if entries is None: if entries is None:
return "" return ""
entries.sort(key=lambda y: y[1])
entries.reverse()
entries.sort(key=lambda y: y[2])
entries.reverse()
for entry in entries:
ident = entry[0]
title = entry[1]
year = entry[2]
rating = entry[4]
username = db.get_user_by_id(entry[5])[1]
if year != last_year:
if last_year != "":
content_string += "</ul>\n"
content_string += "<h2>" + year + "</h2>\n"
content_string += "<ul>\n"
last_year = year
content_string += "<li>"
content_string += title + "<a href=\"" + \
url_for("entry", ident=str(ident)) + "\"> " + \
rating_to_star(rating) + " by " + username
content_string += "</a><br></li>\n"
return content_string
def gen_user_string(name):
"""
Creates and returns a archive string of every file in ENTRY_DIR.
Returns:
string: html-formatted archive-string.
"""
content_string = ""
last_year = ""
entries = db.get_entries_by_name(name)
if entries is None:
return ""
entries.sort(key=lambda y: y[1])
entries.reverse()
entries.sort(key=lambda y: y[2]) entries.sort(key=lambda y: y[2])
entries.reverse() entries.reverse()
for entry in entries: for entry in entries:
@ -40,6 +79,7 @@ def gen_arch_string():
title = entry[1] title = entry[1]
year = entry[2] year = entry[2]
rating = entry[4] rating = entry[4]
username = db.get_user_by_id(entry[5])[1]
if year != last_year: if year != last_year:
if last_year != "": if last_year != "":
content_string += "</ul>\n" content_string += "</ul>\n"
@ -47,18 +87,18 @@ def gen_arch_string():
content_string += "<ul>\n" content_string += "<ul>\n"
last_year = year last_year = year
content_string += "<li>" content_string += "<li>"
content_string += "[<a href=\"" + \ content_string += title + "<a href=\"" + \
url_for("index", _anchor=str(ident)) + "\">link</a> - <a href=\"" \ url_for("entry", ident=str(ident)) + "\"> " + \
+ url_for("entry", ident=str(ident)) + "\">standalone</a>] " rating_to_star(rating)
content_string += title + " " + rating_to_star(rating) content_string += "</a><br></li>\n"
content_string += "<br></li>\n"
return content_string return content_string
def gen_index_string(): def gen_index_string():
""" """
Create and returns a string including every file in the database as an index. Create and returns a string including every file in the database as an
index.
Returns: Returns:
string: html-formatted index string. string: html-formatted index string.
@ -77,12 +117,12 @@ def gen_index_string():
username = db.get_user_by_id(entry[5])[1] username = db.get_user_by_id(entry[5])[1]
reviewed = entry[6] reviewed = entry[6]
content_string += "<div class=\"entry\">\n" content_string += "<div class=\"entry\">\n"
content_string += "<h1 id=\"" + str(ident) + "\">" + title + \ content_string += "<h1 id=\"" + str(ident) + "\"><a href=\"" + \
" (" + year + ") " + rating_to_star(rating) + "</h1>\n" url_for("entry", ident=str(ident)) + "\">" + title + \
content_string += "[<a href=\"" + url_for("entry", ident=str(ident)) + \ " (" + year + ") " + rating_to_star(rating) + "</a></h1>\n"
"\">" + "standalone" + "</a>]<br>\n" content_string += "<small>rated " + str(rating) + \
content_string += "<small>rated " + str(rating) + " by " + username + \ "/100 by <a href=\"" + url_for("user", name=username) + "\">" \
" on " + str(reviewed) + "</small><br>" + username + "</a> on " + str(reviewed) + "</small><br>"
content_string += text content_string += text
content_string += "<br>" content_string += "<br>"
content_string += "</div>" content_string += "</div>"
@ -113,10 +153,11 @@ def gen_stand_string(ident):
" (" + year + ") " " (" + year + ") "
content_string += rating_to_star(rating) content_string += rating_to_star(rating)
content_string += "</h1>\n" content_string += "</h1>\n"
content_string += "[<a href=\"" + url_for("index", ident=str(ident)) + \ content_string += "<small>rated " + str(rating) + \
"\">" + "link" + "</a>]<br>\n" "/100 by <a href=\"" + url_for("user", name=username) + "\">" + \
content_string += "<small>rated " + str(rating) + " by " + \ username + "</a> on <a href=\"" + \
username + " on " + str(reviewed) + "</small><br>\n" url_for("index", _anchor=str(ident)) + "\">" + str(reviewed) + \
"</a></small><br>\n"
content_string += text + "<br>\n" content_string += text + "<br>\n"
return content_string return content_string
@ -143,7 +184,7 @@ def get_rss_string():
reviewed = entry[6] reviewed = entry[6]
content_string += "<item>\n" content_string += "<item>\n"
content_string += "<title>" + title + "(" + year + ") " + \ content_string += "<title>" + title + "(" + year + ") " + \
rating_to_star(rating) + "</title>\n" rating_to_star(rating) + " by " + username + "</title>\n"
content_string += "<guid>" + \ content_string += "<guid>" + \
url_for("index", _anchor=str(ident), _external=True) + \ url_for("index", _anchor=str(ident), _external=True) + \
"</guid>\n" "</guid>\n"

@ -97,6 +97,15 @@ class Database:
crs.execute(query) crs.execute(query)
return crs.fetchall() return crs.fetchall()
def get_entries_by_name(self, name):
db = self.connect()
crs = db.cursor()
query = "SELECT * FROM " + self.ENTRY_TABLE_FILE + \
" WHERE user_id = (SELECT id FROM " + self.USER_TABLE_FILE + \
" WHERE name = ?)"
crs.execute(query, (name, ))
return crs.fetchall()
def check_user_name(self, name): def check_user_name(self, name):
if self.get_user_by_name(name) is None: if self.get_user_by_name(name) is None:
return True return True

@ -4,27 +4,33 @@ from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField from wtforms import StringField, PasswordField, SubmitField
from wtforms.fields.html5 import IntegerField from wtforms.fields.html5 import IntegerField
from wtforms.validators import DataRequired, EqualTo, InputRequired, \ from wtforms.validators import DataRequired, EqualTo, InputRequired, \
NumberRange, ValidationError NumberRange, ValidationError, Length
class LoginForm(FlaskForm): class LoginForm(FlaskForm):
username = StringField("Username", validators=[DataRequired()]) username = StringField("Username", validators=[DataRequired(),
password = PasswordField("Password", validators=[DataRequired()]) Length(min=4, max=32)])
password = PasswordField("Password", validators=[DataRequired(),
Length(min=4, max=32)])
submit = SubmitField("Sign In") submit = SubmitField("Sign In")
class RegisterForm(FlaskForm): class RegisterForm(FlaskForm):
username = StringField("Username", validators=[DataRequired()]) username = StringField("Username", validators=[DataRequired(),
password = PasswordField("Password", validators=[DataRequired()]) Length(min=4, max=32)])
password = PasswordField("Password", validators=[DataRequired(),
Length(min=4, max=32)])
password2 = PasswordField( password2 = PasswordField(
"Repeat Password", validators=[DataRequired(), EqualTo("password")]) "Repeat Password", validators=[DataRequired(), EqualTo("password")])
submit = SubmitField("Register") submit = SubmitField("Register")
class WriteForm(FlaskForm): class WriteForm(FlaskForm):
name = StringField("Name", validators=[DataRequired()]) name = StringField("Name", validators=[DataRequired(),
date = IntegerField("Release Year", default=date.today().year, validators=[DataRequired( Length(min=2, max=64)])
), NumberRange(min=0, max=date.today().year, message="Year has to be valid.")]) date = IntegerField("Release Year", default=date.today().year, validators=[
DataRequired(), NumberRange(min=0, max=date.today().year,
message="Year has to be valid.")])
text = CKEditorField("Text", validators=[DataRequired()]) text = CKEditorField("Text", validators=[DataRequired()])
rating = IntegerField("Rating", default=50, validators=[InputRequired( rating = IntegerField("Rating", default=50, validators=[InputRequired(
), NumberRange(min=0, max=100, message="Number has to be between 0 and 100.")]) ), NumberRange(min=0, max=100, message="Number has to be between 0 and 100.")])

@ -2,82 +2,14 @@
:root { :root {
--bg0: rgb(29,32,33); --bg0: rgb(29,32,33);
--bg1: rgb(50,55,60);
--color0: rgb(220,120,0); --color0: rgb(220,120,0);
--error: rgb(255,0,0); --footerbg0: rgb(50,55,60);
--footerbg0: rgb(29,32,33);
--link0: rgb(220, 120, 0); --link0: rgb(220, 120, 0);
--link1: rgb(255,255,255); --link1: rgb(255,255,255);
--menulink0: rgb(220, 120, 0); --menulink0: rgb(220, 120, 0);
--menulink1: rgb(255,255,255); --menulink1: rgb(255,255,255);
--menubg0: rgb(29,32,33); --menubg0: rgb(50,55,60);
--text0: rgb(235,219,178); --text0: rgb(235,219,178);
--text1: rgb(220, 120, 0); --text1: rgb(220, 120, 0);
} }
a {
color: var(--link0);
transition: var(--transtime);
}
a:hover {
color: var(--link1);
}
body {
background: var(--bg0);
}
footer {
background: var(--footerbg0);
color: var(--text0);
}
span {
color: var(--text1);
}
.container {
color: var(--text0);
}
.container h1,
.container h2 {
color: var(--text1);
}
.container .flash {
background-color: var(--error);
}
.hide-menu:hover,
.main-menu a:hover,
.show-menu:hover {
color: var(--menulink1);
}
.main-menu a {
color: var(--menulink0);
}
.main-menu-dropdown {
background: var(--menubg0);
color: var(--menulink0);
}
@media screen and (max-width:800px) {
.main-menu {
background: var(--menubg0);
}
}
.entry {
background: var(--bg0);
border-left: 10px solid var(--color0);
color: var(--text0);
}
.entry h1,
.entry h2 {
color: var(--text1);
}

@ -2,8 +2,8 @@
:root { :root {
--bg0: rgb(255,255,255); --bg0: rgb(255,255,255);
--bg1: rgb(192,192,192);
--color0: rgb(0,0,120); --color0: rgb(0,0,120);
--error: rgb(255,0,0);
--footerbg0: rgb(192,192,192); --footerbg0: rgb(192,192,192);
--link0: rgb(0,0,120); --link0: rgb(0,0,120);
--link1: rgb(255,255,255); --link1: rgb(255,255,255);
@ -13,71 +13,3 @@
--text0: rgb(0,0,0); --text0: rgb(0,0,0);
--text1: rgb(0,0,120); --text1: rgb(0,0,120);
} }
a {
color: var(--link0);
transition: var(--transtime);
}
a:hover {
color: var(--link1);
}
body {
background: var(--bg0);
}
footer {
background: var(--footerbg0);
color: var(--text0);
}
span {
color: var(--text1);
}
.container {
color: var(--text0);
}
.container h1,
.container h2 {
color: var(--text1);
}
.container .flash {
background-color: var(--error);
}
.hide-menu:hover,
.main-menu a:hover,
.show-menu:hover {
color: var(--menulink1);
}
.main-menu a {
color: var(--menulink0);
}
.main-menu-dropdown {
background: var(--menubg0);
color: var(--menulink0);
}
@media screen and (max-width:800px) {
.main-menu {
background: var(--menubg0);
}
}
.entry {
background: var(--bg0);
border-left: 10px solid var(--color0);
color: var(--text0);
}
.entry h1,
.entry h2 {
color: var(--text1);
}

@ -9,15 +9,30 @@
} }
a { a {
color: var(--link0);
text-decoration: none; text-decoration: none;
transition: var(--transtime); transition: var(--transtime);
} }
a:hover { a:hover {
color: var(--link1);
cursor: pointer; cursor: pointer;
} }
.main-menu a {
color: var(--menulink0);
padding: 0 10px;
text-decoration: none;
text-transform: uppercase;
transition: 0.7s;
}
.main-menu a:hover {
color: var(--menulink1);
}
body { body {
background: var(--bg0);
margin: 0; margin: 0;
} }
@ -30,12 +45,22 @@ html {
} }
footer { footer {
background: var(--footerbg0);
color: var(--text0);
height: 100px; height: 100px;
padding-top: 20px; padding-top: 20px;
text-align: center;
} }
footer .center { .container h1,
text-align: center; .container h2 {
color: var(--text1);
}
.entry h1,
.entry h2 {
color: var(--text1);
margin: 5px auto 2px auto;
} }
li:not(:last-child) { li:not(:last-child) {
@ -52,8 +77,29 @@ ul {
padding-left: 20; padding-left: 20;
} }
span {
color: var(--text1);
}
.main-menu-dropdown span {
float: left;
font-family: monospace;
font-size: 30px;
font-weight: bold;
line-height: 100px;
padding: 0 10px;
text-decoration: none;
text-transform: uppercase;
transition: 0.7s;
}
.important span {
font-weight: bold;
}
.container { .container {
color: var(--text0);
min-height: 100%; min-height: 100%;
padding-bottom: 50px; padding-bottom: 50px;
padding-left: 10%; padding-left: 10%;
@ -62,10 +108,20 @@ ul {
} }
.container .flash { .container .flash {
background-color: var(--error);
padding: 10px; padding: 10px;
width: 400px; width: 400px;
} }
.entry {
background: var(--bg1);
border-left: 10px solid var(--color0);
border-radius: 0 10px 30px 0;
color: var(--text0);
margin-bottom: 20px;
padding: 10px;
}
.hide-menu, .hide-menu,
.show-menu { .show-menu {
cursor: pointer; cursor: pointer;
@ -74,6 +130,13 @@ ul {
transition: var(--transtime); transition: var(--transtime);
} }
.hide-menu:hover,
.show-menu:hover {
color: var(--menulink1);
}
.important { .important {
font-size: xx-large; font-size: xx-large;
padding-left: 25vw; padding-left: 25vw;
@ -82,27 +145,11 @@ ul {
text-align: left; text-align: left;
} }
.important span {
font-weight: bold;
}
.logo { .logo {
height: 80px; height: 80px;
padding-top: 10px; padding-top: 10px;
} }
.main-menu-dropdown span {
float: left;
font-family: monospace;
font-size: 30px;
font-weight: bold;
line-height: 100px;
padding: 0 10px;
text-decoration: none;
text-transform: uppercase;
transition: 0.7s;
}
.main-menu { .main-menu {
float: right; float: right;
font-family: monospace; font-family: monospace;
@ -111,14 +158,9 @@ ul {
line-height: 100px; line-height: 100px;
} }
.main-menu a {
padding: 0 10px;
text-decoration: none;
text-transform: uppercase;
transition: 0.7s;
}
.main-menu-dropdown { .main-menu-dropdown {
background: var(--menubg0);
color: var(--menulink0);
height: 100px; height: 100px;
padding: 0 20px; padding: 0 20px;
} }
@ -135,6 +177,11 @@ ul {
} }
@media screen and (max-width:800px) { @media screen and (max-width:800px) {
.main-menu a {
display: block;
padding: 20px;
}
.hide-menu { .hide-menu {
position: absolute; position: absolute;
right: 40px; right: 40px;
@ -147,6 +194,7 @@ ul {
} }
.main-menu { .main-menu {
background: var(--menubg0);
height: 100vh; height: 100vh;
line-height: normal; line-height: normal;
padding: 80px 0; padding: 80px 0;
@ -157,23 +205,8 @@ ul {
transition: var(--transtime); transition: var(--transtime);
width: 100%; width: 100%;
} }
.main-menu a {
display: block;
padding: 20px;
}
#main-menu-check:checked ~ .main-menu { #main-menu-check:checked ~ .main-menu {
right: 0; right: 0;
} }
} }
.entry {
border-radius: 0 10px 30px 0;
margin-bottom: 20px;
padding: 10px;
}
.entry h1,
.entry h2 {
margin: 5px auto 2px auto;
}

@ -2,8 +2,8 @@
{% block content %} {% block content %}
<div class="container"> <div class="container">
<div class="blogarchive"> <div class="archive">
<h1>Archive</h1><br> <h1>Archive</h1><br>
{% autoescape off %} {% autoescape off %}
{{ content_string }} {{ content_string }}
{% endautoescape %} {% endautoescape %}

@ -30,18 +30,16 @@
{% endblock %} {% endblock %}
<!-- Content --> <!-- Content -->
<footer> <footer>
<div class="center"> Made with <a href="https://github.com/tiyn/container-critique">Container Critique </a>.<br>
Made with <a href="https://github.com/tiyn/container-critique">Container Critique </a>.<br> {% if current_user.is_anonymous %}
{% if current_user.is_anonymous %} <a href="{{ url_for('login') }}">Login</a>
<a href="{{ url_for('login') }}">Login</a> -
- <a href="{{ url_for('register') }}">Register</a>
<a href="{{ url_for('register') }}">Register</a> {% else %}
{% else %} <a href="{{ url_for('logout') }}">Logout</a>
<a href="{{ url_for('logout') }}">Logout</a> -
- <a href="{{ url_for('write') }}">Write entry</a>
<a href="{{ url_for('write') }}">Write entry</a> {% endif %}
{% endif %}
</div>
</footer> </footer>
</body> </body>
</html> </html>

@ -0,0 +1,12 @@
{% extends "template.html" %}
{% block content %}
<div class="container">
<div class="archive">
<h1>User: {{ User }}</h1><br>
{% autoescape off %}
{{ content_string }}
{% endautoescape %}
</div>
</div>
{% endblock %}
Loading…
Cancel
Save