initial commit

This commit is contained in:
Alexandru 2024-09-17 20:02:37 +03:00
parent f2af86d489
commit 926da5a6cd
5 changed files with 279 additions and 20 deletions

174
.gitignore vendored
View File

@ -1,25 +1,163 @@
# If you prefer the allow list template instead of the deny list, see community template: # Byte-compiled / optimized / DLL files
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore __pycache__/
# *.py[cod]
# Binaries for programs and plugins *$py.class
*.exe
*.exe~ # C extensions
*.dll
*.so *.so
*.dylib
# Test binary, built with `go test -c` # Distribution / packaging
*.test .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 # PyInstaller
*.out # 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) # Installer logs
# vendor/ pip-log.txt
pip-delete-this-directory.txt
# Go workspace file # Unit test / coverage reports
go.work htmlcov/
go.work.sum .tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# env 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 .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

View File

@ -1,2 +1,2 @@
# guestbook # guestbook
A guestbook made in Python.

49
app.py Normal file
View File

@ -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}<br>"
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("/")

46
static/style.css Normal file
View File

@ -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;
}

26
templates/index.html Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>guestbook</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<form method="POST" action="/submit">
<input name="name" placeholder="Name (optional)">
<input name="website" placeholder="Website (optional, w/o the http(s) part)">
<textarea name="comment" placeholder="Comment (max 512 characters)"></textarea>
<button>submit</button>
</form>
<hr>
<b>Sites indexed</b>: {% for comment in comments %}<a href="http://{{comment[2]}}">{{comment[2]}}</a> {% endfor %}
<hr>
{% for comment in comments %}
<div class="comment">
<a href="http://{{comment[2]}}">{{comment[1]}}</a> <b>{{comment[4]|parsetime}}</b><br>
{{comment[3]}}
</div>
{% endfor %}
</body>
</html>