Custom images

This commit is contained in:
2025-04-16 14:51:06 +02:00
parent 02a12fd46e
commit b8152ba6cb
10 changed files with 53 additions and 41 deletions

View File

@@ -2,12 +2,17 @@ from flask import Flask
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate from flask_migrate import Migrate
from flask_login import LoginManager # type: ignore from flask_login import LoginManager # type: ignore
import os
# App Config # App Config
app = Flask(__name__) app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///services.sqlite" app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///services.sqlite"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False # Wat is dit? app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False # Wat is dit?
app.config["SECRET_KEY"] = "bvjchsygvduycgsyugc" # Andere secret key app.config["SECRET_KEY"] = "bvjchsygvduycgsyugc" # Andere secret key
app.config["UPLOAD_FOLDER"] = r"application\static\icons"
# Ensure the upload folder exists
os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True) # type: ignore
# Object Relational Management # Object Relational Management
db = SQLAlchemy() db = SQLAlchemy()

View File

@@ -1,9 +1,17 @@
from flask_wtf import FlaskForm # type: ignore from flask_wtf import FlaskForm # type: ignore
from wtforms import StringField, SubmitField, URLField from wtforms import StringField, SubmitField, URLField
from wtforms.validators import DataRequired from wtforms.validators import DataRequired
from flask_wtf.file import FileField, FileAllowed, FileRequired # type: ignore
class ServiceForm(FlaskForm): class ServiceForm(FlaskForm):
name = StringField("Service name:", validators=[DataRequired()]) name = StringField("Service name:", validators=[DataRequired()])
url = URLField("Service URL:", validators=[DataRequired()]) url = URLField("Service URL:", validators=[DataRequired()])
image = FileField(
"Icon:",
validators=[
FileRequired(),
FileAllowed(["jpg", "jpeg", "png"], "Unsupported file format"),
],
)
submit = SubmitField("Submit") submit = SubmitField("Submit")

View File

@@ -5,10 +5,12 @@ class Service(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False) name = db.Column(db.String, nullable=False)
url = db.Column(db.String, nullable=False) url = db.Column(db.String, nullable=False)
icon = db.Column(db.String, nullable=False, default="google.png")
user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
def __init__(self, name: str, url: str, user_id: int): def __init__(self, name: str, url: str, user_id: int, icon: str):
self.name = name self.name = name
self.url = url self.url = url
self.user_id = user_id self.user_id = user_id
self.icon = icon

View File

@@ -1,22 +0,0 @@
body {
background-color: lightslategray;
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
gap: 20px;
background-color: lightslategray;
padding-top: 20px;
margin-left: 10%;
margin-right: 10%;
}
.grid-container > div {
text-align: center;
height: 100px;
padding-top: 5px;
border: 2px solid black;
border-radius: 10px;
background-color: whitesmoke;
}

View File

@@ -5,32 +5,38 @@ Add service
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<form class="form bg-body-tertiary" method="POST"> <form class="form bg-body-tertiary" method="POST" enctype="multipart/form-data">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16"> <symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/> <path
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z" />
</symbol> </symbol>
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16"> <symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/> <path
d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z" />
</symbol> </symbol>
</svg> </svg>
{% if feedback %} {% if feedback %}
{% if feedback=="Service succesfully added" %} {% if feedback=="Service succesfully added" %}
<div class="alert alert-success d-flex align-items-center" role="alert"> <div class="alert alert-success d-flex align-items-center" role="alert">
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:"><use xlink:href="#check-circle-fill"/></svg> <svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:">
<div> <use xlink:href="#check-circle-fill" />
{{feedback}} </svg>
</div> <div>
{{feedback}}
</div> </div>
{% else %} </div>
<div class="alert alert-danger d-flex align-items-center" role="alert"> {% else %}
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:"><use xlink:href="#exclamation-triangle-fill"/></svg> <div class="alert alert-danger d-flex align-items-center" role="alert">
<div> <svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:">
{{feedback}} <use xlink:href="#exclamation-triangle-fill" />
</div> </svg>
<div>
{{feedback}}
</div> </div>
{% endif %} </div>
{% endif %}
{% endif %} {% endif %}
<div> <div>
{{ form.name.label }} <br> {{ form.name() }} {{ form.name.label }} <br> {{ form.name() }}
@@ -38,6 +44,9 @@ Add service
<div> <div>
{{ form.url.label }} <br> {{ form.url() }} {{ form.url.label }} <br> {{ form.url() }}
</div> </div>
<div>
{{ form.image() }}
</div>
<div class="submit"> <div class="submit">
{{ form.submit() }} {{ form.submit() }}
</div> </div>

View File

@@ -8,8 +8,7 @@
<div class="bg-light container-xxl"> <div class="bg-light container-xxl">
<div class="row row-cols-3"> <div class="row row-cols-3">
<div class="col-sm-2" onclick="location.href='{{service.url}}';" style="cursor: pointer;"> <div class="col-sm-2" onclick="location.href='{{service.url}}';" style="cursor: pointer;">
<img class="fit-picture" <img class="fit-picture" src="{{ url_for('static', filename='icons/'+service['icon'])}}">
src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Google_%22G%22_logo.svg/2048px-Google_%22G%22_logo.svg.png">
</div> </div>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="row"> <div class="row">

View File

@@ -3,6 +3,9 @@ from flask import Blueprint, render_template, redirect, url_for
from application.dash.forms import ServiceForm from application.dash.forms import ServiceForm
from flask_login import login_required, current_user # type: ignore from flask_login import login_required, current_user # type: ignore
from application.dash.models import Service from application.dash.models import Service
import os
from application import app
from werkzeug.utils import secure_filename
dash_blueprint = Blueprint("dash", __name__, template_folder="templates") dash_blueprint = Blueprint("dash", __name__, template_folder="templates")
@@ -36,12 +39,20 @@ def service():
service_form = ServiceForm() service_form = ServiceForm()
if service_form.validate_on_submit(): # type: ignore if service_form.validate_on_submit(): # type: ignore
image = service_form.image.data
name = service_form.name.data name = service_form.name.data
url = service_form.url.data url = service_form.url.data
filename = secure_filename(image.filename)
save_path = os.path.join(
app.config["UPLOAD_FOLDER"], filename # type: ignore
)
image.save(save_path) # type: ignore
new_service = Service( new_service = Service(
name=name, # type: ignore name=name, # type: ignore
url=url, # type: ignore url=url, # type: ignore
user_id=current_user.id, user_id=current_user.id,
icon=filename, # type: ignore
) )
db.session.add(new_service) db.session.add(new_service)
db.session.commit() db.session.commit()

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
test/123123123.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB