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] Logout
- [x] Register
- [ ] User Page
- [x] User Page
- [ ] Review blog entries
- [x] Writing entries
- [ ] Editing entries

@ -45,10 +45,19 @@ def index():
@app.route("/archive")
@app.route("/archive.html")
def archive():
entries = db.get_entries()
content = con_gen.gen_arch_string()
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>")
def entry(ident):
content = con_gen.gen_stand_string(ident)
@ -103,12 +112,10 @@ def logout():
@app.route("/register", methods=["GET", "POST"])
@app.route("/register.html", methods=["GET", "POST"])
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"))
form = RegisterForm()
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)
if db_user is None:
user = User(form.username.data)

@ -33,6 +33,45 @@ def gen_arch_string():
entries = db.get_entries()
if entries is None:
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.reverse()
for entry in entries:
@ -40,6 +79,7 @@ def gen_arch_string():
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"
@ -47,18 +87,18 @@ def gen_arch_string():
content_string += "<ul>\n"
last_year = year
content_string += "<li>"
content_string += "[<a href=\"" + \
url_for("index", _anchor=str(ident)) + "\">link</a> - <a href=\"" \
+ url_for("entry", ident=str(ident)) + "\">standalone</a>] "
content_string += title + " " + rating_to_star(rating)
content_string += "<br></li>\n"
content_string += title + "<a href=\"" + \
url_for("entry", ident=str(ident)) + "\"> " + \
rating_to_star(rating)
content_string += "</a><br></li>\n"
return content_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:
string: html-formatted index string.
@ -77,12 +117,12 @@ def gen_index_string():
username = db.get_user_by_id(entry[5])[1]
reviewed = entry[6]
content_string += "<div class=\"entry\">\n"
content_string += "<h1 id=\"" + str(ident) + "\">" + title + \
" (" + year + ") " + rating_to_star(rating) + "</h1>\n"
content_string += "[<a href=\"" + url_for("entry", ident=str(ident)) + \
"\">" + "standalone" + "</a>]<br>\n"
content_string += "<small>rated " + str(rating) + " by " + username + \
" on " + str(reviewed) + "</small><br>"
content_string += "<h1 id=\"" + str(ident) + "\"><a href=\"" + \
url_for("entry", ident=str(ident)) + "\">" + title + \
" (" + year + ") " + rating_to_star(rating) + "</a></h1>\n"
content_string += "<small>rated " + str(rating) + \
"/100 by <a href=\"" + url_for("user", name=username) + "\">" \
+ username + "</a> on " + str(reviewed) + "</small><br>"
content_string += text
content_string += "<br>"
content_string += "</div>"
@ -113,10 +153,11 @@ def gen_stand_string(ident):
" (" + year + ") "
content_string += rating_to_star(rating)
content_string += "</h1>\n"
content_string += "[<a href=\"" + url_for("index", ident=str(ident)) + \
"\">" + "link" + "</a>]<br>\n"
content_string += "<small>rated " + str(rating) + " by " + \
username + " on " + str(reviewed) + "</small><br>\n"
content_string += "<small>rated " + str(rating) + \
"/100 by <a href=\"" + url_for("user", name=username) + "\">" + \
username + "</a> on <a href=\"" + \
url_for("index", _anchor=str(ident)) + "\">" + str(reviewed) + \
"</a></small><br>\n"
content_string += text + "<br>\n"
return content_string
@ -143,7 +184,7 @@ def get_rss_string():
reviewed = entry[6]
content_string += "<item>\n"
content_string += "<title>" + title + "(" + year + ") " + \
rating_to_star(rating) + "</title>\n"
rating_to_star(rating) + " by " + username + "</title>\n"
content_string += "<guid>" + \
url_for("index", _anchor=str(ident), _external=True) + \
"</guid>\n"

@ -97,6 +97,15 @@ class Database:
crs.execute(query)
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):
if self.get_user_by_name(name) is None:
return True

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

@ -2,82 +2,14 @@
:root {
--bg0: rgb(29,32,33);
--bg1: rgb(50,55,60);
--color0: rgb(220,120,0);
--error: rgb(255,0,0);
--footerbg0: rgb(29,32,33);
--footerbg0: rgb(50,55,60);
--link0: rgb(220, 120, 0);
--link1: rgb(255,255,255);
--menulink0: rgb(220, 120, 0);
--menulink1: rgb(255,255,255);
--menubg0: rgb(29,32,33);
--menubg0: rgb(50,55,60);
--text0: rgb(235,219,178);
--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 {
--bg0: rgb(255,255,255);
--bg1: rgb(192,192,192);
--color0: rgb(0,0,120);
--error: rgb(255,0,0);
--footerbg0: rgb(192,192,192);
--link0: rgb(0,0,120);
--link1: rgb(255,255,255);
@ -13,71 +13,3 @@
--text0: rgb(0,0,0);
--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 {
color: var(--link0);
text-decoration: none;
transition: var(--transtime);
}
a:hover {
color: var(--link1);
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 {
background: var(--bg0);
margin: 0;
}
@ -30,12 +45,22 @@ html {
}
footer {
background: var(--footerbg0);
color: var(--text0);
height: 100px;
padding-top: 20px;
text-align: center;
}
footer .center {
text-align: center;
.container h1,
.container h2 {
color: var(--text1);
}
.entry h1,
.entry h2 {
color: var(--text1);
margin: 5px auto 2px auto;
}
li:not(:last-child) {
@ -52,8 +77,29 @@ ul {
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 {
color: var(--text0);
min-height: 100%;
padding-bottom: 50px;
padding-left: 10%;
@ -62,10 +108,20 @@ ul {
}
.container .flash {
background-color: var(--error);
padding: 10px;
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,
.show-menu {
cursor: pointer;
@ -74,6 +130,13 @@ ul {
transition: var(--transtime);
}
.hide-menu:hover,
.show-menu:hover {
color: var(--menulink1);
}
.important {
font-size: xx-large;
padding-left: 25vw;
@ -82,27 +145,11 @@ ul {
text-align: left;
}
.important span {
font-weight: bold;
}
.logo {
height: 80px;
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 {
float: right;
font-family: monospace;
@ -111,14 +158,9 @@ ul {
line-height: 100px;
}
.main-menu a {
padding: 0 10px;
text-decoration: none;
text-transform: uppercase;
transition: 0.7s;
}
.main-menu-dropdown {
background: var(--menubg0);
color: var(--menulink0);
height: 100px;
padding: 0 20px;
}
@ -135,6 +177,11 @@ ul {
}
@media screen and (max-width:800px) {
.main-menu a {
display: block;
padding: 20px;
}
.hide-menu {
position: absolute;
right: 40px;
@ -147,6 +194,7 @@ ul {
}
.main-menu {
background: var(--menubg0);
height: 100vh;
line-height: normal;
padding: 80px 0;
@ -157,23 +205,8 @@ ul {
transition: var(--transtime);
width: 100%;
}
.main-menu a {
display: block;
padding: 20px;
}
#main-menu-check:checked ~ .main-menu {
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 %}
<div class="container">
<div class="blogarchive">
<h1>Archive</h1><br>
<div class="archive">
<h1>Archive</h1><br>
{% autoescape off %}
{{ content_string }}
{% endautoescape %}

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