flask site buildout #2

Merged
finn merged 25 commits from mgtut1 into master 2024-08-05 08:41:03 +00:00
10 changed files with 66 additions and 2 deletions
Showing only changes of commit cdebe081c3 - Show all commits

View File

@ -16,6 +16,7 @@ pip install flask-sqlalchemy
pip install flask-migrate
pip install flask-login
pip install email-validator
pip install pydenticon
...
pip freeze > requirements.txt
```

View File

@ -1,9 +1,12 @@
import os
from datetime import datetime, timezone
from typing import Optional
import sqlalchemy as sa
import sqlalchemy.orm as so
from app import db, login
from werkzeug.security import generate_password_hash, check_password_hash
import pydenticon, hashlib, base64
from app import db, login
from flask_login import UserMixin
class User(UserMixin, db.Model):
@ -17,6 +20,33 @@ class User(UserMixin, db.Model):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
def gen_avatar(self, write_png=True):
foreground = [ "rgb(45,79,255)",
"rgb(254,180,44)",
"rgb(226,121,234)",
"rgb(30,179,253)",
"rgb(232,77,65)",
"rgb(49,203,115)",
"rgb(141,69,170)" ]
background = "rgb(22,22,22)"
digest = hashlib.md5(self.email.lower().encode('utf-8')).hexdigest()
basedir = os.path.abspath(os.path.dirname(__file__))
pngloc = os.path.join(basedir, 'usercontent', 'identicon', str(digest) + '.png')
icongen = pydenticon.Generator(5, 5, digest=hashlib.md5, foreground=foreground, background=background)
pngicon = icongen.generate(self.email, 120, 120, padding=(10, 10, 10, 10), inverted=False, output_format="png")
if write_png:
pngfile = open(pngloc, "wb")
pngfile.write(pngicon)
pngfile.close()
else:
return str(base64.b64encode(pngicon))[2:-1]
def avatar(self):
digest = hashlib.md5(self.email.lower().encode('utf-8')).hexdigest()
basedir = os.path.abspath(os.path.dirname(__file__))
pngloc = os.path.join(basedir, 'usercontent', 'identicon', digest + '.png')
return pngloc
def __repr__(self):
return '<User {}>'.format(self.username)

View File

@ -57,8 +57,17 @@ def register():
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
user.gen_avatar()
flash('User has been created.')
return redirect(url_for('login'))
return render_template('register.html', title='Register', form=form)
@app.route('/user/<username>')
@login_required
def user(username):
user = db.first_or_404(sa.select(User).where(User.username == username))
posts = [
{'author': user, 'body': 'Test1'},
{'author': user, 'body': 'Test2?'}
]
return render_template('user.html', user=user, posts=posts)

View File

@ -0,0 +1,6 @@
<table>
<tr valign="top">
<td><img width="60" height=="60" src="data:image/png;base64,{{ user.gen_avatar(write_png=False) }}"></td>
<td>{{ post.author.username }} says:<br>{{ post.body }}</td>
</tr>
</table>

View File

@ -15,6 +15,7 @@
{% if current_user.is_anonymous %}
<a href="{{ url_for('login') }}">login</a>
{% else %}
<a href="{{ url_for('user', username=current_user.username) }}">Profile</a>
<a href="{{ url_for('logout') }}">logout</a>
{% endif %}

View File

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block content %}
<table>
<tr valign="top">
<td><img src="data:image/png;base64,{{ user.gen_avatar(write_png=False) }}"></td>
<td><h1>User: {{ user.username }}</h1></td>
</tr>
</table>
<hr>
{% for post in posts %}
{% include '_post.html' %}
{% endfor %}
{% endblock %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

View File

@ -14,6 +14,8 @@ itsdangerous==2.2.0
Jinja2==3.1.4
Mako==1.3.5
MarkupSafe==2.1.5
pillow==10.4.0
pydenticon==0.3.1
python-dotenv==1.0.1
SQLAlchemy==2.0.31
typing_extensions==4.12.2