mirror of
				https://github.com/tiyn/container-critique.git
				synced 2025-10-31 03:01:21 +01:00 
			
		
		
		
	src: logging and writing complete
This commit is contained in:
		
							
								
								
									
										88
									
								
								src/app.py
									
									
									
									
									
								
							
							
						
						
									
										88
									
								
								src/app.py
									
									
									
									
									
								
							| @@ -1,14 +1,21 @@ | ||||
| from flask import Flask, flash, make_response, render_template, request, redirect, abort, url_for | ||||
| from flask_login import current_user, login_user, LoginManager, logout_user | ||||
| from flask import Flask, flash, make_response, render_template, redirect, \ | ||||
|     abort, url_for | ||||
| from flask_login import current_user, login_user, LoginManager, logout_user, \ | ||||
|     login_required | ||||
| from flask_wtf import CSRFProtect | ||||
| import os | ||||
|  | ||||
| import content as con_gen | ||||
| import config | ||||
| import content as con_gen | ||||
| from database import Database, User | ||||
| from forms import LoginForm, RegisterForm, WriteForm | ||||
|  | ||||
|  | ||||
| app = Flask(__name__) | ||||
| csrf = CSRFProtect() | ||||
| app.secret_key = "123534" | ||||
| db = Database() | ||||
|  | ||||
| app.secret_key = os.urandom(32) | ||||
| csrf.init_app(app) | ||||
|  | ||||
| login = LoginManager(app) | ||||
| @@ -18,6 +25,8 @@ TITLE = config.TITLE | ||||
| STYLE = config.STYLE | ||||
| DESCRIPTION = config.DESCRIPTION | ||||
| WEBSITE = config.WEBSITE | ||||
| REGISTER = config.REGISTER | ||||
|  | ||||
|  | ||||
| @app.errorhandler(404) | ||||
| def page_not_found(e): | ||||
| @@ -38,9 +47,9 @@ def archive(): | ||||
|     return render_template("archive.html", title=TITLE, content_string=content, style=STYLE) | ||||
|  | ||||
|  | ||||
| @app.route("/entry/<path>") | ||||
| def entry(path): | ||||
|     content = con_gen.gen_stand_string(path) | ||||
| @app.route("/entry/<ident>") | ||||
| def entry(ident): | ||||
|     content = con_gen.gen_stand_string(ident) | ||||
|     if content != "": | ||||
|         return render_template("standalone.html", title=TITLE, content_string=content, style=STYLE) | ||||
|     abort(404) | ||||
| @@ -56,18 +65,14 @@ def feed(): | ||||
|     response.headers["Content-Type"] = "application/rss+xml" | ||||
|     return response | ||||
|  | ||||
|  | ||||
| @login.user_loader | ||||
| def load_user(ident): | ||||
|     ## TODO: load user from db by id | ||||
|     db_user = db.get_by_id(ident) | ||||
|     db_user = db.get_user_by_id(ident) | ||||
|     if db_user is not None: | ||||
|         return db.db_to_user(*db_user) | ||||
|     return None | ||||
|  | ||||
| from login import LoginForm, User | ||||
| from database import Database | ||||
|  | ||||
| db = Database() | ||||
|  | ||||
| @app.route("/login", methods=["GET", "POST"]) | ||||
| @app.route("/login.html", methods=["GET", "POST"]) | ||||
| @@ -76,22 +81,59 @@ def login(): | ||||
|         return redirect(url_for("index")) | ||||
|     form = LoginForm() | ||||
|     if form.validate_on_submit(): | ||||
|         db_user = db.get_by_name(form.username.data) | ||||
|         if db_user is None: | ||||
|             flash("Invalid username or password") | ||||
|             return redirect(url_for("login")) | ||||
|         user = db.db_to_user(*db_user) | ||||
|         if not user.check_password(form.password.data): | ||||
|             flash("Invalid username or password") | ||||
|             return redirect(url_for("login")) | ||||
|         login_user(user, remember=form.remember_me.data) | ||||
|         return redirect(url_for("index")) | ||||
|         db_user = db.get_user_by_name(form.username.data) | ||||
|         if db_user is not None: | ||||
|             user = db.db_to_user(*db_user) | ||||
|             if user.check_password(form.password.data): | ||||
|                 login_user(user) | ||||
|                 return redirect(url_for("index")) | ||||
|         flash("Invalid username or password.") | ||||
|         return redirect(url_for("login")) | ||||
|     return render_template("login.html", title=TITLE, form=form, style=STYLE) | ||||
|  | ||||
|  | ||||
| @app.route('/logout') | ||||
| @app.route('/logout.html') | ||||
| def logout(): | ||||
|     logout_user() | ||||
|     return redirect(url_for('index')) | ||||
|  | ||||
|  | ||||
| @app.route("/register", methods=["GET", "POST"]) | ||||
| @app.route("/register.html", methods=["GET", "POST"]) | ||||
| def register(): | ||||
|     if current_user.is_authenticated or not REGISTER: | ||||
|         return redirect(url_for("index")) | ||||
|     form = RegisterForm() | ||||
|     if form.validate_on_submit(): | ||||
|         if not REGISTER: | ||||
|             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) | ||||
|             user.set_password(form.password.data) | ||||
|             ident = db.insert_user(user) | ||||
|             if ident is not None: | ||||
|                 user.set_id(ident) | ||||
|                 login_user(user) | ||||
|                 return redirect(url_for("index")) | ||||
|         flash("An error occured during registration.") | ||||
|         return redirect(url_for("register")) | ||||
|     return render_template("register.html", title=TITLE, form=form, style=STYLE) | ||||
|  | ||||
|  | ||||
| @app.route("/write", methods=["GET", "POST"]) | ||||
| @app.route("/write.html", methods=["GET", "POST"]) | ||||
| @login_required | ||||
| def write(): | ||||
|     if not current_user.is_authenticated: | ||||
|         return redirect(url_for("index")) | ||||
|     form = WriteForm() | ||||
|     if form.validate_on_submit(): | ||||
|         db.insert_entry(form.name.data, form.date.data, form.text.data, form.rating.data, current_user.id) | ||||
|         return redirect(url_for("index")) | ||||
|     return render_template("write.html", title=TITLE, form=form, style=STYLE) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     app.run(host="0.0.0.0") | ||||
|   | ||||
| @@ -9,3 +9,6 @@ WEBSITE = "localhost:5000" | ||||
|  | ||||
| # Theme for the blog: dark, light | ||||
| STYLE = "dark" | ||||
|  | ||||
| # Allow new registrations | ||||
| REGISTER = True | ||||
|   | ||||
| @@ -1,3 +1,8 @@ | ||||
| from database import Database | ||||
|  | ||||
| db = Database() | ||||
|  | ||||
|  | ||||
| def gen_arch_string(): | ||||
|     """ | ||||
|     Creates and returns a archive string of every file in ENTRY_DIR. | ||||
| @@ -5,32 +10,100 @@ def gen_arch_string(): | ||||
|     Returns: | ||||
|     string: html-formatted archive-string | ||||
|     """ | ||||
|     return "" | ||||
|     content_string = "" | ||||
|     last_year = "" | ||||
|     entries = db.get_entries() | ||||
|     if entries is None: | ||||
|         return "" | ||||
|     entries.sort(key=lambda y: y[2]) | ||||
|     for entry in entries: | ||||
|         ident = entry[0] | ||||
|         title = entry[1] | ||||
|         year = entry[2] | ||||
|         rating = entry[4] | ||||
|         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 += "[<a href=\"" + "/index.html#" + str(ident) + \ | ||||
|             "\">link</a> - <a href=\"/entry/" + \ | ||||
|             str(ident) + "\">standalone</a>] " | ||||
|         content_string += title + \ | ||||
|             " (" + str(year) + ") - " + str(rating) + "/100<br>" | ||||
|         content_string += "</li>\n" | ||||
|  | ||||
|     return content_string | ||||
|  | ||||
|  | ||||
| def gen_index_string(): | ||||
|     """ | ||||
|     Create and returns a string including every file in the ENTRY_DIR as an index. | ||||
|     Create and returns a string including every file in the database as an index. | ||||
|  | ||||
|     Returns: | ||||
|     string: html-formatted index string | ||||
|     """ | ||||
|     return "" | ||||
|     content_string = "" | ||||
|     entries = db.get_entries() | ||||
|     if entries is None: | ||||
|         return "" | ||||
|     entries.reverse() | ||||
|     for entry in entries: | ||||
|         ident = entry[0] | ||||
|         title = entry[1] | ||||
|         year = entry[2] | ||||
|         text = entry[3] | ||||
|         rating = entry[4] | ||||
|         username = db.get_user_by_id(entry[5])[1] | ||||
|         reviewed = entry[6] | ||||
|         content_string += "<div class=\"entry\">\n" | ||||
|         content_string += "<h2 id=\"" + \ | ||||
|             str(ident) + "\">" + title + " (" + year + ") - " + \ | ||||
|             str(rating) + "/100</h2>\n" | ||||
|         content_string += "[<a href=\"" + "/entry/" + \ | ||||
|             str(ident) + "\">" + "standalone" + "</a>]<br>\n" | ||||
|         content_string += text | ||||
|         content_string += "<br>" | ||||
|         content_string += "<small>" + \ | ||||
|             str(reviewed) + " by " + username + "</small>" | ||||
|         content_string += "</div>" | ||||
|     return content_string | ||||
|  | ||||
|  | ||||
| def gen_stand_string(path_ex): | ||||
| def gen_stand_string(ident): | ||||
|     """ | ||||
|     Creates a html-string for a file. | ||||
|     If the file is markdown it will convert it. | ||||
|     This functions ensures upscaling for future formats. | ||||
|     Creates a html-string for an entry. | ||||
|  | ||||
|     Parameters: | ||||
|     path_ex: path to a file. | ||||
|     ident: ident of an entry. | ||||
|  | ||||
|     Returns: | ||||
|     string: html-formatted string string equivalent to the file | ||||
|     """ | ||||
|     return "" | ||||
|     entry = db.get_entry_by_id(ident) | ||||
|     content_string = "" | ||||
|     if entry is not None: | ||||
|         ident = entry[0] | ||||
|         title = entry[1] | ||||
|         year = entry[2] | ||||
|         text = entry[3] | ||||
|         rating = entry[4] | ||||
|         username = db.get_user_by_id(entry[5])[1] | ||||
|         reviewed = entry[6] | ||||
|         content_string += "<h1>" + title + \ | ||||
|             " (" + year + ") - " + str(rating) + "/100 </h1>\n" | ||||
|         content_string += "[" | ||||
|         content_string += "<a href=\"" + "/index.html#" + \ | ||||
|             str(ident) + "\">" + "link" + "</a>" | ||||
|         content_string += "]<br>\n" | ||||
|         content_string += "<small>" + \ | ||||
|             str(reviewed) + " by " + username + "</small>" | ||||
|         content_string += "<br>\n" | ||||
|         content_string += text | ||||
|         content_string += "<br>" | ||||
|     return content_string | ||||
|  | ||||
|  | ||||
| def get_rss_string(): | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								src/data.db
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/data.db
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								src/data/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/data/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										104
									
								
								src/database.py
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								src/database.py
									
									
									
									
									
								
							| @@ -1,14 +1,37 @@ | ||||
| from datetime import date as dt | ||||
| import os | ||||
| import sqlite3 | ||||
| from werkzeug.security import generate_password_hash, check_password_hash | ||||
|  | ||||
| from login import User | ||||
| class User(): | ||||
|  | ||||
|     def __init__(self, name, pass_hash=None): | ||||
|         self.name = name | ||||
|         self.id = 0 | ||||
|         self.is_active = True | ||||
|         self.is_authenticated = True | ||||
|         self.is_anonymous = False | ||||
|         self.pass_hash = pass_hash | ||||
|  | ||||
|     def set_password(self, password): | ||||
|         self.pass_hash = generate_password_hash(password) | ||||
|  | ||||
|     def set_id(self, ident): | ||||
|         self.id = ident | ||||
|  | ||||
|     def check_password(self, password): | ||||
|         return check_password_hash(self.pass_hash, password) | ||||
|  | ||||
|     def get_id(self): | ||||
|         return self.id | ||||
|  | ||||
|  | ||||
| class Database: | ||||
|  | ||||
|     def __init__(self): | ||||
|         self.TABLE_FILE = 'USERS' | ||||
|         self.DB_DIR = os.path.dirname(".") | ||||
|         self.USER_TABLE_FILE = 'USERS' | ||||
|         self.ENTRY_TABLE_FILE = 'ENTRIES' | ||||
|         self.DB_DIR = os.path.dirname("./data/") | ||||
|         self.setup_db() | ||||
|  | ||||
|     def connect(self): | ||||
| @@ -22,41 +45,78 @@ class Database: | ||||
|         """Creates a database with tables.""" | ||||
|         db = self.connect() | ||||
|         crs = db.cursor() | ||||
|         query = "CREATE TABLE IF NOT EXISTS " + self.TABLE_FILE + \ | ||||
|         query = "CREATE TABLE IF NOT EXISTS " + self.USER_TABLE_FILE + \ | ||||
|             "(id INTEGER PRIMARY KEY AUTOINCREMENT," + \ | ||||
|             "name CHAR(32) NOT NULL UNIQUE," + \ | ||||
|             "password CHAR(32) NOT NULL)" | ||||
|         crs.execute(query) | ||||
|         query = "CREATE TABLE IF NOT EXISTS " + self.ENTRY_TABLE_FILE + \ | ||||
|             "(id INTEGER PRIMARY KEY AUTOINCREMENT," + \ | ||||
|             "name CHAR(64) NOT NULL," + \ | ||||
|             "date CHAR(4) NOT NULL," + \ | ||||
|             "text TEXT NOT NULL," + \ | ||||
|             "rating INTEGER NOT NULL," +\ | ||||
|             "user_id INTEGER," +\ | ||||
|             "reviewed CHAR(10) NOT NULL," +\ | ||||
|             "FOREIGN KEY(user_id) REFERENCES " + self.USER_TABLE_FILE + "(id))" | ||||
|         crs.execute(query) | ||||
|         db.commit() | ||||
|  | ||||
|     def insert_user(self, name, password): | ||||
|     def insert_user(self, user): | ||||
|         """Insert a new user into the database. | ||||
|         """ | ||||
|         if self.check_name(name): | ||||
|         if self.check_user_name(user.name) and user.pass_hash is not None: | ||||
|             db = self.connect() | ||||
|             crs = db.cursor() | ||||
|             query = "INSERT INTO " + self.TABLE_FILE + "(`name`,`password`)" + \ | ||||
|             query = "INSERT INTO " + self.USER_TABLE_FILE + "(`name`,`password`)" + \ | ||||
|                     "VALUES (?, ?) ON CONFLICT DO NOTHING" | ||||
|             crs.execute(query, (name, password)) | ||||
|             crs.execute(query, (user.name, user.pass_hash)) | ||||
|             db.commit() | ||||
|             return True | ||||
|         return False | ||||
|             return crs.lastrowid | ||||
|         return None | ||||
|  | ||||
|     def check_name(self, name): | ||||
|         if self.get_by_name(name) is None: | ||||
|             return True | ||||
|         return False | ||||
|  | ||||
|     def get_by_id(self, ident): | ||||
|     def insert_entry(self, name, date, text, rating, user_id=None): | ||||
|         """Insert a new user into the database. | ||||
|         """ | ||||
|         db = self.connect() | ||||
|         crs = db.cursor() | ||||
|         query = "SELECT * FROM " + self.TABLE_FILE + " WHERE id = ?" | ||||
|         reviewed = dt.today().strftime('%Y-%m-%d') | ||||
|         query = "INSERT INTO " + self.ENTRY_TABLE_FILE + "(`name`,`date`, `text`, `rating`, `user_id`, `reviewed`)" + \ | ||||
|                 "VALUES (?, ?, ?, ?, ?, ?)" | ||||
|         crs.execute(query, (name, date, text, rating, user_id, reviewed)) | ||||
|         db.commit() | ||||
|         return crs.lastrowid | ||||
|  | ||||
|     def get_entries(self): | ||||
|         db = self.connect() | ||||
|         crs = db.cursor() | ||||
|         query = "SELECT * FROM " + self.ENTRY_TABLE_FILE | ||||
|         crs.execute(query) | ||||
|         return crs.fetchall() | ||||
|  | ||||
|     def check_user_name(self, name): | ||||
|         if self.get_user_by_name(name) is None: | ||||
|             return True | ||||
|         return False | ||||
|  | ||||
|     def get_entry_by_id(self, ident): | ||||
|         db = self.connect() | ||||
|         crs = db.cursor() | ||||
|         query = "SELECT * FROM " + self.ENTRY_TABLE_FILE + " WHERE id = ?" | ||||
|         crs.execute(query, (ident, )) | ||||
|         return crs.fetchone() | ||||
|  | ||||
|     def get_by_name(self, name): | ||||
|     def get_user_by_id(self, ident): | ||||
|         db = self.connect() | ||||
|         crs = db.cursor() | ||||
|         query = "SELECT * FROM " + self.TABLE_FILE + " WHERE name = ?" | ||||
|         query = "SELECT * FROM " + self.USER_TABLE_FILE + " WHERE id = ?" | ||||
|         crs.execute(query, (ident, )) | ||||
|         return crs.fetchone() | ||||
|  | ||||
|     def get_user_by_name(self, name): | ||||
|         db = self.connect() | ||||
|         crs = db.cursor() | ||||
|         query = "SELECT * FROM " + self.USER_TABLE_FILE + " WHERE name = ?" | ||||
|         crs.execute(query, (name, )) | ||||
|         return crs.fetchone() | ||||
|  | ||||
| @@ -64,3 +124,9 @@ class Database: | ||||
|         user = User(name, pass_hash) | ||||
|         user.set_id(ident) | ||||
|         return user | ||||
|  | ||||
|  | ||||
| #db = Database() | ||||
| #db.insert_entry("name", "2020", "text", 50, 1) | ||||
| #res = db.get_entries() | ||||
| #print(res) | ||||
|   | ||||
							
								
								
									
										26
									
								
								src/forms.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/forms.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| from datetime import date | ||||
| from flask_wtf import FlaskForm | ||||
| from wtforms import StringField, PasswordField, SubmitField, TextAreaField | ||||
| from wtforms.fields.html5 import IntegerField | ||||
| from wtforms.validators import DataRequired, EqualTo, InputRequired, NumberRange | ||||
|  | ||||
|  | ||||
| class LoginForm(FlaskForm): | ||||
|     username = StringField("Username", validators=[DataRequired()]) | ||||
|     password = PasswordField("Password", validators=[DataRequired()]) | ||||
|     submit = SubmitField("Sign In") | ||||
|  | ||||
|  | ||||
| class RegisterForm(FlaskForm): | ||||
|     username = StringField("Username", validators=[DataRequired()]) | ||||
|     password = PasswordField("Password", validators=[DataRequired()]) | ||||
|     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.")]) | ||||
|     text = TextAreaField("Text", validators=[DataRequired()]) | ||||
|     rating = IntegerField("Rating", default=50, validators=[InputRequired(), NumberRange(min=0, max=100, message="Number has to be between 0 and 100.")]) | ||||
|     submit = SubmitField("Publish") | ||||
							
								
								
									
										34
									
								
								src/login.py
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								src/login.py
									
									
									
									
									
								
							| @@ -1,34 +0,0 @@ | ||||
| from flask_wtf import FlaskForm | ||||
| from wtforms import StringField, PasswordField, SubmitField, BooleanField | ||||
| from wtforms.validators import DataRequired | ||||
|  | ||||
| from werkzeug.security import generate_password_hash, check_password_hash | ||||
|  | ||||
|  | ||||
| class User(): | ||||
|  | ||||
|     def __init__(self, name, pass_hash=None): | ||||
|         self.name = name | ||||
|         self.id = 0 | ||||
|         self.is_active = True | ||||
|         self.is_authenticated = True | ||||
|         self.is_anonymous = False | ||||
|         self.pass_hash = pass_hash | ||||
|  | ||||
|     def set_password(self, password): | ||||
|         self.pass_hash = generate_password_hash(password) | ||||
|  | ||||
|     def set_id(self, ident): | ||||
|         self.id = ident | ||||
|  | ||||
|     def check_password(self, password): | ||||
|         return check_password_hash(self.pass_hash, password) | ||||
|  | ||||
|     def get_id(self): | ||||
|         return self.id | ||||
|  | ||||
| class LoginForm(FlaskForm): | ||||
|     username = StringField("Username", validators=[DataRequired()]) | ||||
|     password = PasswordField("Password", validators=[DataRequired()]) | ||||
|     remember_me = BooleanField("Remember Me") | ||||
|     submit = SubmitField("Sign In") | ||||
| @@ -1,5 +1,6 @@ | ||||
| Flask==2.1.2 | ||||
| Flask_Login==0.6.2 | ||||
| Flask_WTF==0.14.3 | ||||
| Werkzeug==2.1.2 | ||||
| Werkzeug==2.0.0 | ||||
| WTForms==2.2.1 | ||||
| jinja2==3.0.3 | ||||
|   | ||||
| @@ -15,7 +15,6 @@ | ||||
|                 {{ form.password.label }}<br> | ||||
|                 {{ form.password(size=32) }} | ||||
|             </p> | ||||
|             <p>{{ form.remember_me() }} {{ form.remember_me.label }}</p> | ||||
|             <p>{{ form.submit() }}</p> | ||||
|             {% for mesg in get_flashed_messages() %} | ||||
|             <p>{{ mesg }}</p> | ||||
|   | ||||
							
								
								
									
										38
									
								
								src/templates/register.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/templates/register.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| {% extends "template.html" %} | ||||
|  | ||||
| {% block content %} | ||||
|  | ||||
| <div class="container"> | ||||
|     <div class="logging"> | ||||
|         <h1>Register</h1> | ||||
|         <form action="" method="post" novalidate> | ||||
|             {{ form.hidden_tag() }} | ||||
|             <p> | ||||
|                 {{ form.username.label }}<br> | ||||
|                 {{ form.username(size=32) }} | ||||
|                 {% for error in form.username.errors %} | ||||
|                 <span style="color: red;">[{{ error }}]</span> | ||||
|                 {% endfor %} | ||||
|             </p> | ||||
|             <p> | ||||
|                 {{ form.password.label }}<br> | ||||
|                 {{ form.password(size=32) }} | ||||
|                 {% for error in form.password.errors %} | ||||
|                 <span style="color: red;">[{{ error }}]</span> | ||||
|                 {% endfor %} | ||||
|             </p> | ||||
|             <p> | ||||
|                 {{ form.password2.label }}<br> | ||||
|                 {{ form.password2(size=32) }} | ||||
|                 {% for error in form.password2.errors %} | ||||
|                 <span style="color: red;">[{{ error }}]</span> | ||||
|                 {% endfor %} | ||||
|             </p> | ||||
|             <p>{{ form.submit() }}</p> | ||||
|             {% for mesg in get_flashed_messages() %} | ||||
|             <p>{{ mesg }}</p> | ||||
|             {% endfor %} | ||||
|         </form> | ||||
|     </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
| @@ -16,11 +16,6 @@ | ||||
|             <a href="{{ url_for('index') }}">Blog</a> | ||||
|             <a href="{{ url_for('archive') }}">Archive</a> | ||||
|             <label for="main-menu-check" class="hide-menu">X</label> | ||||
|             {% if current_user.is_anonymous %} | ||||
|             <a href="{{ url_for('login') }}">Login</a> | ||||
|             {% else %} | ||||
|             <a href="{{ url_for('logout') }}">Logout</a> | ||||
|             {% endif %} | ||||
|         </div> | ||||
|     </div> | ||||
|     <!-- Menu --> | ||||
| @@ -30,7 +25,15 @@ | ||||
|     <!-- Content --> | ||||
|     <footer> | ||||
|         <div class="center"> | ||||
|             Made with <a href="https://github.com/tiyn/container-critique">Container Critique </a>. | ||||
|             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> | ||||
|     </footer> | ||||
| </body> | ||||
|   | ||||
							
								
								
									
										45
									
								
								src/templates/write.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/templates/write.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| {% extends "template.html" %} | ||||
|  | ||||
| {% block content %} | ||||
|  | ||||
| <div class="container"> | ||||
|     <div class="writing"> | ||||
|         <h1>Sign In</h1> | ||||
|         <form action="" method="post" novalidate> | ||||
|             {{ form.hidden_tag() }} | ||||
|             <p> | ||||
|                 {{ form.name.label }}<br> | ||||
|                 {{ form.name(size=64) }} | ||||
|                 {% for error in form.name.errors %} | ||||
|                 <span style="color: red;">[{{ error }}]</span> | ||||
|                 {% endfor %} | ||||
|             </p> | ||||
|             <p> | ||||
|                 {{ form.date.label }}<br> | ||||
|                 {{ form.date }} | ||||
|                 {% for error in form.date.errors %} | ||||
|                 <span style="color: red;">[{{ error }}]</span> | ||||
|                 {% endfor %} | ||||
|             </p> | ||||
|             <p> | ||||
|                 {{ form.text.label }}<br> | ||||
|                 {{ form.text }} | ||||
|                 {% for error in form.text.errors %} | ||||
|                 <span style="color: red;">[{{ error }}]</span> | ||||
|                 {% endfor %} | ||||
|             </p> | ||||
|             <p> | ||||
|                 {{ form.rating.label }}<br> | ||||
|                 {{ form.rating }} | ||||
|                 {% for error in form.rating.errors %} | ||||
|                 <span style="color: red;">[{{ error }}]</span> | ||||
|                 {% endfor %} | ||||
|             </p> | ||||
|             <p>{{ form.submit() }}</p> | ||||
|             {% for mesg in get_flashed_messages() %} | ||||
|             <p>{{ mesg }}</p> | ||||
|             {% endfor %} | ||||
|         </form> | ||||
|     </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
		Reference in New Issue
	
	Block a user