basic temapltes rendered
This commit is contained in:
parent
0b86db6413
commit
e25c28b04c
@ -1,4 +1,6 @@
|
|||||||
language: python
|
language: python
|
||||||
|
python:
|
||||||
|
- "3.9"
|
||||||
arch: amd64
|
arch: amd64
|
||||||
os: linux
|
os: linux
|
||||||
dist: focal
|
dist: focal
|
||||||
|
@ -8,4 +8,6 @@ py-healthcheck
|
|||||||
sqlalchemy
|
sqlalchemy
|
||||||
flask-sqlalchemy
|
flask-sqlalchemy
|
||||||
flask-cors
|
flask-cors
|
||||||
requests
|
requests
|
||||||
|
psycopg2-binary
|
||||||
|
email_validator
|
@ -9,8 +9,8 @@ from flask_cors import CORS
|
|||||||
|
|
||||||
from utils.config import SENTRY_DSN, RELEASE_ID, RELEASEMODE, POSTGRES_DB, PORT, POSTGRES_HOSTNAME, POSTGRES_PASSWORD, \
|
from utils.config import SENTRY_DSN, RELEASE_ID, RELEASEMODE, POSTGRES_DB, PORT, POSTGRES_HOSTNAME, POSTGRES_PASSWORD, \
|
||||||
POSTGRES_USERNAME, DEBUG, SECRET_KEY, ALLOWED_ORIGINS
|
POSTGRES_USERNAME, DEBUG, SECRET_KEY, ALLOWED_ORIGINS
|
||||||
from utils import db, ma, health_database_status, security, user_datastore
|
from utils import db, health_database_status, security, user_datastore
|
||||||
from views import ItemView, LoginView, ProfileView, RegisterView, UploadView
|
from views import ItemView, ProfileView, UploadView, IndexView
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Main Flask entrypoint
|
Main Flask entrypoint
|
||||||
@ -37,10 +37,10 @@ app.config['SQLALCHEMY_DATABASE_URI'] = \
|
|||||||
f"postgresql://{POSTGRES_USERNAME}:{POSTGRES_PASSWORD}@{POSTGRES_HOSTNAME}:5432/{POSTGRES_DB}"
|
f"postgresql://{POSTGRES_USERNAME}:{POSTGRES_PASSWORD}@{POSTGRES_HOSTNAME}:5432/{POSTGRES_DB}"
|
||||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||||
app.config['SECRET_KEY'] = SECRET_KEY
|
app.config['SECRET_KEY'] = SECRET_KEY
|
||||||
|
app.config['SECURITY_REGISTERABLE'] = True
|
||||||
|
|
||||||
health = HealthCheck()
|
health = HealthCheck()
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
ma.init_app(app)
|
|
||||||
security.init_app(app, user_datastore)
|
security.init_app(app, user_datastore)
|
||||||
CORS(app, origins=ALLOWED_ORIGINS)
|
CORS(app, origins=ALLOWED_ORIGINS)
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ logger = logging.getLogger(__name__)
|
|||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
logger.addHandler(handler)
|
logger.addHandler(handler)
|
||||||
|
|
||||||
for view in [ItemView, LoginView, ProfileView, RegisterView, UploadView]:
|
for view in [ItemView, ProfileView, UploadView, IndexView]:
|
||||||
view.register(app, trailing_slash=False)
|
view.register(app, trailing_slash=False)
|
||||||
|
|
||||||
health.add_check(health_database_status)
|
health.add_check(health_database_status)
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<!-- Bootstrap CSS -->
|
<!-- Bootstrap CSS -->
|
||||||
<link rel="stylesheet" href="https://bootswatch.com/4/darkly/bootstrap.min.css">
|
<link rel="stylesheet" href="https://bootswatch.com/4/darkly/bootstrap.min.css">
|
||||||
<title>My Store Web App</title>
|
<title>UnstableVortex CAFF Store</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary mb-3">
|
<nav class="navbar navbar-expand-lg navbar-dark bg-primary mb-3">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<a class="navbar-brand" href="{{ url_for('index') }}">UnstableVortex CAFF Store</a>
|
<a class="navbar-brand" href="{{ url_for('IndexView:index') }}">UnstableVortex CAFF Store</a>
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
|
||||||
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
@ -19,16 +19,16 @@
|
|||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
<ul class="navbar-nav mr-auto">
|
<ul class="navbar-nav mr-auto">
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a class="nav-link" href="{{ url_for('index') }}">Home</a>
|
<a class="nav-link" href="{{ url_for('IndexView:index') }}">Home</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a class="nav-link" href="{{ url_for('profile') }}">Profile</a>
|
<a class="nav-link" href="{{ url_for('ProfileView:index') }}">Profile</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a class="nav-link" href="{{ url_for('login') }}">Login</a>
|
<a class="nav-link" href="{{ url_for_security('login') }}">Login</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a class="nav-link" href="{{ url_for('register') }}">Register</a>
|
<a class="nav-link" href="{{ url_for_security('login') }}">Register</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<form class="form-inline my-2 my-lg-0">
|
<form class="form-inline my-2 my-lg-0">
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
{% for image in images %}
|
{% for image in images %}
|
||||||
<div class="col-12 col-sm-6 col-md-4 px-2 mb-3">
|
<div class="col-12 col-sm-6 col-md-4 px-2 mb-3">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<a href="{{ url_for('item', id=image.id) }}">
|
<a href="{{ url_for('ItemView:index', id=image.id) }}">
|
||||||
<img src="{{image.preview}}" class="img-fluid" style="padding: 30px" alt="{{image.caption}}">
|
<img src="{{image.preview}}" class="img-fluid" style="padding: 30px" alt="{{image.name}}">
|
||||||
</a>
|
</a>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">{{image.creator}}</h5>
|
<h5 class="card-title">{{image.creator}}</h5>
|
||||||
<p class="card-text">
|
<p class="card-text">
|
||||||
{{image.caption}}
|
{{image.name}}
|
||||||
</p>
|
</p>
|
||||||
<a href="{{ url_for('download', id=image.id) }}" class="btn btn-primary" target="_blank">Download Now</a>
|
<a href="{{ url_for('download', id=image.id) }}" class="btn btn-primary" target="_blank">Download Now</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
<!-- <h5 class="card-title">Special title treatment</h5>-->
|
<!-- <h5 class="card-title">Special title treatment</h5>-->
|
||||||
<!-- <h6 class="card-subtitle text-muted">Support card subtitle</h6>-->
|
<!-- <h6 class="card-subtitle text-muted">Support card subtitle</h6>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<img src="{{image.preview}}" class="card-img" style="padding: 30px" alt="{{image.caption}}">
|
<img src="{{image.preview}}" class="card-img" style="padding: 30px" alt="{{image.name}}">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p class="card-text">{{ image.caption }}</p>
|
<p class="card-text">{{ image.name }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table table-responsive">
|
<table class="table table-responsive">
|
||||||
@ -17,10 +17,6 @@
|
|||||||
<th scope="row">Creator</th>
|
<th scope="row">Creator</th>
|
||||||
<td>{{ image.creator }}</td>
|
<td>{{ image.creator }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="table-active">
|
|
||||||
<th scope="row">Number of images</th>
|
|
||||||
<td>{{ image.num_anim }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="table-active">
|
<tr class="table-active">
|
||||||
<th scope="row">Creation date</th>
|
<th scope="row">Creation date</th>
|
||||||
<td>{{ image.creation_date }}</td>
|
<td>{{ image.creation_date }}</td>
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="jumbotron">
|
|
||||||
<h1 class="display-3">Please sign in</h1>
|
|
||||||
<br>
|
|
||||||
<form action="" method="post">
|
|
||||||
<input size="50" type="text" class="form-control" placeholder="Username" name="username" value="{{request.form.username}}"></br></br>
|
|
||||||
<input type="password" class="form-control" placeholder="Password" name="password" value="{{request.form.password}}"></br></br>
|
|
||||||
<input class="btn btn-primary" type="submit" value="Sign In"></br></br>
|
|
||||||
</form>
|
|
||||||
<p>Dont't have an account? <a class="bottom" href="{{ url_for('register') }}"> Sign Up here</a></p>
|
|
||||||
{% if error %}
|
|
||||||
<p class="error"><strong>Error:</strong> {{ error }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
@ -4,7 +4,7 @@
|
|||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
<div>
|
<div>
|
||||||
<h1>Welcome {{ user.username }}</h1>
|
<h1>Welcome {{ user.username }}</h1>
|
||||||
<a href="upload.html" class="btn btn-primary">Upload</a>
|
<a href="{{ url_for('UploadView:index') }}" class="btn btn-primary">Upload</a>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
{% if images %}
|
{% if images %}
|
||||||
@ -12,16 +12,16 @@
|
|||||||
{% for image in images %}
|
{% for image in images %}
|
||||||
<div class="col-12 col-sm-6 col-md-4 px-2 mb-3">
|
<div class="col-12 col-sm-6 col-md-4 px-2 mb-3">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<a href="{{ url_for('item', id=image.id) }}">
|
<a href="{{ url_for('ItemView:index', id=image.id) }}">
|
||||||
<img src="{{image.preview}}" class="img-fluid" style="padding: 30px" alt="{{image.caption}}">
|
<img src="{{image.preview}}" class="img-fluid" style="padding: 30px" alt="{{image.name}}">
|
||||||
</a>
|
</a>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">{{image.creator}}</h5>
|
<h5 class="card-title">{{image.creator}}</h5>
|
||||||
<p class="card-text">
|
<p class="card-text">
|
||||||
{{image.caption}}
|
{{image.caption}}
|
||||||
</p>
|
</p>
|
||||||
<a href="{{ url_for('download', id=image.id) }}" class="btn btn-primary" target="_blank">Download</a>
|
<a href="{{ url_for('ItemView:download', id=image.id) }}" class="btn btn-primary" target="_blank">Download</a>
|
||||||
<a href="{{ url_for('delete', id=image.id) }}" class="btn btn-primary" target="_blank">Delete</a>
|
<a href="{{ url_for('ItemView:delete', id=image.id) }}" class="btn btn-primary" target="_blank">Delete</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -32,6 +32,6 @@
|
|||||||
<p>No images available.</p>
|
<p>No images available.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><a href="{{ url_for('login') }}">Log in</a> to view your profile.</p>
|
<p><a href="{{ url_for_security('login') }}">Log in</a> to view your profile.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -1,18 +0,0 @@
|
|||||||
{% extends 'base.html' %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="jumbotron">
|
|
||||||
<h1 class="display-3">Please sign up</h1>
|
|
||||||
<br>
|
|
||||||
<form action="" method="post">
|
|
||||||
<input type="text" class="form-control" placeholder="Username" name="username" value="{{request.form.username}}"></br></br>
|
|
||||||
<input type="password" class="form-control" placeholder="Password" name="password" value="{{request.form.password}}"></br></br>
|
|
||||||
<input type="email" class="form-control" placeholder="Email" name="email" value="{{request.form.email}}"></br></br>
|
|
||||||
<input class="btn btn-primary" type="submit" value="Sign Up"></br></br>
|
|
||||||
</form>
|
|
||||||
<p class="bottom">Already have an account? <a class="bottom" href="{{ url_for('login') }}"> Sign In here</a></p>
|
|
||||||
{% if error %}
|
|
||||||
<p class="error"><strong>Error:</strong> {{ error }}
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
20
src/templates/security/login_user.html
Normal file
20
src/templates/security/login_user.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% from "security/_macros.html" import render_field_with_errors, render_field %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="jumbotron">
|
||||||
|
<h1 class="display-3">Please sign in</h1>
|
||||||
|
<br>
|
||||||
|
<form action="{{ url_for_security('login') }}" method="POST" name="login_user_form">
|
||||||
|
{{ login_user_form.hidden_tag() }}
|
||||||
|
{{ render_field_with_errors(login_user_form.email) }}
|
||||||
|
{{ render_field_with_errors(login_user_form.password) }}
|
||||||
|
{{ render_field_with_errors(login_user_form.remember) }}
|
||||||
|
{{ render_field(login_user_form.submit) }}
|
||||||
|
</form>
|
||||||
|
<p>Dont't have an account? <a class="bottom" href="/register"> Sign Up here</a></p>
|
||||||
|
{% if error %}
|
||||||
|
<p class="error"><strong>Error:</strong> {{ error }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
22
src/templates/security/register_user.html
Normal file
22
src/templates/security/register_user.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% from "security/_macros.html" import render_field_with_errors, render_field %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="jumbotron">
|
||||||
|
<h1 class="display-3">Please sign up</h1>
|
||||||
|
<br>
|
||||||
|
<form action="{{ url_for_security('register') }}" method="POST" name="register_user_form">
|
||||||
|
{{ register_user_form.hidden_tag() }}
|
||||||
|
{{ render_field_with_errors(register_user_form.email) }}
|
||||||
|
{{ render_field_with_errors(register_user_form.password) }}
|
||||||
|
{% if register_user_form.password_confirm %}
|
||||||
|
{{ render_field_with_errors(register_user_form.password_confirm) }}
|
||||||
|
{% endif %}
|
||||||
|
{{ render_field(register_user_form.submit) }}
|
||||||
|
</form>
|
||||||
|
<p class="bottom">Already have an account? <a class="bottom" href="/login"> Sign In here</a></p>
|
||||||
|
{% if error %}
|
||||||
|
<p class="error"><strong>Error:</strong> {{ error }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -11,6 +11,6 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p><a href="{{ url_for('login') }}">Log in</a> to upload an animation.</p>
|
<p><a href="{{ url_for_security('login') }}">Log in</a> to upload an animation.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -1,4 +1,3 @@
|
|||||||
from .db import db
|
from .db import db
|
||||||
from .marshm import ma
|
|
||||||
from .healthchecks import health_database_status
|
from .healthchecks import health_database_status
|
||||||
from .security import security, user_datastore
|
from .security import security, user_datastore
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
from .loginview import LoginView
|
|
||||||
from .profileview import ProfileView
|
from .profileview import ProfileView
|
||||||
from .registerview import RegisterView
|
|
||||||
from .uploadview import UploadView
|
from .uploadview import UploadView
|
||||||
from .itemview import ItemView
|
from .itemview import ItemView
|
||||||
|
from .indexview import IndexView
|
||||||
|
23
src/views/indexview.py
Normal file
23
src/views/indexview.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from flask import render_template
|
||||||
|
from flask_classful import FlaskView
|
||||||
|
|
||||||
|
from models import Item
|
||||||
|
|
||||||
|
"""
|
||||||
|
Index VIEW
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "@tormakris"
|
||||||
|
__copyright__ = "Copyright 2020, UnstableVortex Team"
|
||||||
|
__module_name__ = "indexview"
|
||||||
|
__version__text__ = "1"
|
||||||
|
|
||||||
|
|
||||||
|
class IndexView(FlaskView):
|
||||||
|
|
||||||
|
route_base = '/'
|
||||||
|
|
||||||
|
def index(self):
|
||||||
|
items = Item.query.all()
|
||||||
|
return render_template("index.html", images=items)
|
@ -14,5 +14,14 @@ __version__text__ = "1"
|
|||||||
|
|
||||||
class ItemView(FlaskView):
|
class ItemView(FlaskView):
|
||||||
|
|
||||||
|
route_prefix = "/item/"
|
||||||
|
route_base = '/'
|
||||||
|
|
||||||
def index(self):
|
def index(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def download(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
pass
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
from flask_classful import FlaskView
|
|
||||||
|
|
||||||
"""
|
|
||||||
Login VIEW
|
|
||||||
"""
|
|
||||||
|
|
||||||
__author__ = "@tormakris"
|
|
||||||
__copyright__ = "Copyright 2020, UnstableVortex Team"
|
|
||||||
__module_name__ = "loginview"
|
|
||||||
__version__text__ = "1"
|
|
||||||
|
|
||||||
|
|
||||||
class LoginView(FlaskView):
|
|
||||||
|
|
||||||
def index(self):
|
|
||||||
pass
|
|
@ -14,5 +14,8 @@ __version__text__ = "1"
|
|||||||
|
|
||||||
class ProfileView(FlaskView):
|
class ProfileView(FlaskView):
|
||||||
|
|
||||||
|
route_prefix = "/profile/"
|
||||||
|
route_base = '/'
|
||||||
|
|
||||||
def index(self):
|
def index(self):
|
||||||
pass
|
pass
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
from flask_classful import FlaskView
|
|
||||||
|
|
||||||
"""
|
|
||||||
Register VIEW
|
|
||||||
"""
|
|
||||||
|
|
||||||
__author__ = "@tormakris"
|
|
||||||
__copyright__ = "Copyright 2020, UnstableVortex Team"
|
|
||||||
__module_name__ = "registerview"
|
|
||||||
__version__text__ = "1"
|
|
||||||
|
|
||||||
|
|
||||||
class RegisterView(FlaskView):
|
|
||||||
|
|
||||||
def index(self):
|
|
||||||
pass
|
|
@ -14,5 +14,8 @@ __version__text__ = "1"
|
|||||||
|
|
||||||
class UploadView(FlaskView):
|
class UploadView(FlaskView):
|
||||||
|
|
||||||
|
route_prefix = "/upload/"
|
||||||
|
route_base = '/'
|
||||||
|
|
||||||
def index(self):
|
def index(self):
|
||||||
pass
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user