diff --git a/.gitignore b/.gitignore
index 64ae7f3..6e00996 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,25 +1,163 @@
-# If you prefer the allow list template instead of the deny list, see community template:
-# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
-#
-# Binaries for programs and plugins
-*.exe
-*.exe~
-*.dll
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
*.so
-*.dylib
-# Test binary, built with `go test -c`
-*.test
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
-# Output of the go coverage tool, specifically when used with LiteIDE
-*.out
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
-# Dependency directories (remove the comment below to include it)
-# vendor/
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
-# Go workspace file
-go.work
-go.work.sum
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
-# env file
-.env
\ No newline at end of file
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
+.pdm.toml
+.pdm-python
+.pdm-build/
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+guestbook.db
\ No newline at end of file
diff --git a/README.md b/README.md
index e8dae65..def8150 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
# guestbook
-
+A guestbook made in Python.
\ No newline at end of file
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..8588257
--- /dev/null
+++ b/app.py
@@ -0,0 +1,49 @@
+import hashlib, os
+import time
+from flask import Flask, redirect, render_template, request
+import sqlite3
+import re
+
+app = Flask(__name__)
+db = sqlite3.connect('guestbook.db', check_same_thread=False)
+cs = db.cursor()
+app.secret_key = hashlib.md5(os.urandom(32)).hexdigest()
+
+@app.template_filter('parsetime')
+def parsetime(value):
+ return time.strftime('%Y-%m-%d %H:%M', time.localtime(value))
+
+@app.route('/')
+def index():
+ statement = 'SELECT "id", "name", "website", "comment", "date", "ip" FROM "entries" ORDER BY id DESC'
+ cs.execute(statement)
+ return render_template("index.html", comments=cs.fetchall())
+
+@app.route('/submit', methods=["POST"])
+def submit():
+ errors = []
+ name = request.form.get("name")
+ website = request.form.get("website")
+ comment = request.form.get("comment")
+ if name != "":
+ if name.isalnum() != True:
+ errors.append("Your name must not contain any non-alphanumeric characters")
+ else:
+ name = "Anonymous"
+ if website !="":
+ if not re.fullmatch(r"^[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*\.[a-zA-Z]{2,3}(\.[a-zA-Z]{2,3})?$", website):
+ errors.append("Your site doesn't look valid.")
+ if comment == "":
+ errors.append("You must write something.")
+ elif len(comment) > 512:
+ errors.append("You wrote more than 512 characters")
+ if errors != []:
+ response = ""
+ for error in errors:
+ response += f"{error}
"
+ return response
+ statement = 'INSERT INTO "entries" ("name", "website", "comment", "date", "ip") VALUES (?, ?, ?, ?, ?);'
+ values = (name, website, comment, int(time.time()), str(request.remote_addr))
+ cs.execute(statement, values)
+ db.commit()
+ return redirect("/")
\ No newline at end of file
diff --git a/static/style.css b/static/style.css
new file mode 100644
index 0000000..072e489
--- /dev/null
+++ b/static/style.css
@@ -0,0 +1,46 @@
+body {
+ background-color: #110e0e;
+ max-width: 400px;
+ color: white;
+ font-family: Verdana,sans-serif;
+}
+
+form {
+ max-width: 250px;
+ margin-bottom: 12px;
+}
+
+form input{
+ width: 100%;
+ background-color: #201b1b;
+ color: white;
+ border: 2px solid #b41d1d;
+}
+form textarea {
+ width: 100%;
+ height: 100px;
+ background-color: #201b1b;
+ color: white;
+ border: 2px solid #b41d1d;
+ resize: none;
+}
+form button {
+ background-color: #ff4949;
+ color: white;
+ border: 2px solid #b41d1d;
+}
+form button:hover {
+ background-color: rgb(184, 68, 68);
+}
+.comment {
+ background-color: #201b1b;
+ color: white;
+ border: 2px solid #b41d1d;
+ padding: 8px;
+ margin-bottom: 4px;
+}
+
+a {
+ color: #ff4949;
+}
+
\ No newline at end of file
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..ea0431f
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,26 @@
+
+
+
+ {{comment[3]}} +