import from kontor-flask
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
"""
|
||||
Module kontor implements Kontor application.
|
||||
"""
|
||||
|
||||
from flask import Flask
|
||||
from flask_bootstrap import Bootstrap
|
||||
from flask_login import LoginManager
|
||||
from pymodm import connect
|
||||
|
||||
# local imports
|
||||
from config import app_config
|
||||
from .version import __version__
|
||||
|
||||
|
||||
_LOGIN_MANAGER_ = LoginManager()
|
||||
|
||||
|
||||
def get_host(config_name):
|
||||
"""
|
||||
Returns host address from configuration.
|
||||
:param config_name:
|
||||
:return: host address
|
||||
"""
|
||||
host = app_config[config_name].host
|
||||
return host
|
||||
|
||||
|
||||
def get_port(config_name):
|
||||
"""
|
||||
Returns port number from configuration.
|
||||
:param config_name:
|
||||
:return: port number
|
||||
"""
|
||||
port = app_config[config_name].port
|
||||
return port
|
||||
|
||||
|
||||
def create_app(config_name):
|
||||
"""
|
||||
Returns Flask application.
|
||||
:param config_name:
|
||||
:return: Flask application
|
||||
"""
|
||||
app = Flask(__name__, instance_relative_config=True)
|
||||
app.config.from_object(app_config[config_name])
|
||||
app.config.from_pyfile('config.py')
|
||||
|
||||
database = "mongodb://localhost:27017/{}".format(app_config[config_name].database)
|
||||
connect(database, alias="kontor")
|
||||
|
||||
Bootstrap(app)
|
||||
_LOGIN_MANAGER_.init_app(app)
|
||||
_LOGIN_MANAGER_.login_message = "You must be logged in to access this page."
|
||||
_LOGIN_MANAGER_.login_view = "auth.login"
|
||||
|
||||
from .admin.views import ADMIN as ADMIN_BLUEPRINT
|
||||
app.register_blueprint(ADMIN_BLUEPRINT, url_prefix='/admin')
|
||||
|
||||
from .auth.views import AUTH as AUTH_BLUEPRINT
|
||||
app.register_blueprint(AUTH_BLUEPRINT)
|
||||
|
||||
from .home.views import HOME as HOME_BLUEPRINT
|
||||
app.register_blueprint(HOME_BLUEPRINT)
|
||||
|
||||
from .comics.views import COMIC as COMIC_BLUEPRINT
|
||||
app.register_blueprint(COMIC_BLUEPRINT, url_prefix='/comics')
|
||||
|
||||
from .library.views import LIBRARY as LIBRARY_BLUEPRINT
|
||||
app.register_blueprint(LIBRARY_BLUEPRINT, url_prefix='/library')
|
||||
|
||||
from .tysc.views import TYSC as TYSC_BLUEPRINT
|
||||
app.register_blueprint(TYSC_BLUEPRINT, url_prefix='/tysc')
|
||||
|
||||
return app
|
||||
@@ -0,0 +1,4 @@
|
||||
"""
|
||||
Module admin implements administration functions.
|
||||
"""
|
||||
from . import views
|
||||
@@ -0,0 +1,17 @@
|
||||
"""
|
||||
Define form to edit users
|
||||
"""
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, SubmitField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
|
||||
class UserEditForm(FlaskForm):
|
||||
"""
|
||||
Form for admin to edit users
|
||||
"""
|
||||
email = StringField('Email', validators=[DataRequired()])
|
||||
username = StringField('Username', validators=[DataRequired()])
|
||||
first_name = StringField('First Name', validators=[DataRequired()])
|
||||
last_name = StringField('Last Name', validators=[DataRequired()])
|
||||
submit = SubmitField('Submit')
|
||||
@@ -0,0 +1,63 @@
|
||||
"""
|
||||
Define routing rules for managing users
|
||||
"""
|
||||
from flask import abort, Blueprint, flash, redirect, render_template, url_for
|
||||
from flask_login import current_user, login_required
|
||||
|
||||
from .forms import UserEditForm
|
||||
from ..models import User
|
||||
|
||||
ADMIN = Blueprint('admin', __name__)
|
||||
|
||||
|
||||
def check_admin():
|
||||
"""
|
||||
Prevent non-admins from accessing the page
|
||||
"""
|
||||
if not current_user.is_admin:
|
||||
abort(403)
|
||||
|
||||
|
||||
# User Views
|
||||
@ADMIN.route('/users')
|
||||
@login_required
|
||||
def list_users():
|
||||
"""
|
||||
List all users
|
||||
"""
|
||||
check_admin()
|
||||
|
||||
users = User.objects.all()
|
||||
return render_template('admin/users/users.html',
|
||||
users=users, title='Users')
|
||||
|
||||
|
||||
@ADMIN.route('/users/edit/<user_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_user(user_id):
|
||||
"""
|
||||
Edit an user.
|
||||
"""
|
||||
check_admin()
|
||||
|
||||
user = User.objects.get({'username': user_id})
|
||||
|
||||
# prevent admin from being assigned a department or role
|
||||
if user.is_admin:
|
||||
abort(403)
|
||||
|
||||
form = UserEditForm(obj=user)
|
||||
if form.validate_on_submit():
|
||||
user.email = form.email.data
|
||||
user.username = form.username.data
|
||||
user.first_name = form.first_name.data
|
||||
user.last_name = form.last_name.data
|
||||
user.save()
|
||||
flash('You have successfully edited an user.')
|
||||
|
||||
# redirect to the roles page
|
||||
return redirect(url_for('admin.list_users'))
|
||||
|
||||
return render_template('admin/users/user.html',
|
||||
user=user, form=form,
|
||||
title='Edit User')
|
||||
@@ -0,0 +1,4 @@
|
||||
"""
|
||||
Module auth implements authentication functions.
|
||||
"""
|
||||
from . import views
|
||||
@@ -0,0 +1,50 @@
|
||||
"""
|
||||
Contains forms for authentication.
|
||||
"""
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import PasswordField, StringField, SubmitField, ValidationError
|
||||
from wtforms.validators import DataRequired, Email, EqualTo
|
||||
|
||||
from ..models import User
|
||||
|
||||
|
||||
class RegistrationForm(FlaskForm):
|
||||
"""
|
||||
Form for users to create new account
|
||||
"""
|
||||
email = StringField('Email', validators=[DataRequired(), Email()])
|
||||
username = StringField('Username', validators=[DataRequired()])
|
||||
first_name = StringField('First Name', validators=[DataRequired()])
|
||||
last_name = StringField('Last Name', validators=[DataRequired()])
|
||||
password = PasswordField('Password', validators=[DataRequired(),
|
||||
EqualTo('confirm_password')
|
||||
])
|
||||
confirm_password = PasswordField('Confirm Password')
|
||||
submit = SubmitField('Register')
|
||||
|
||||
def validate_email(self, field):
|
||||
"""
|
||||
Check if email is already in use.
|
||||
:param field:
|
||||
:return:
|
||||
"""
|
||||
if User.objects.raw({'email': field.data}).count() > 0:
|
||||
raise ValidationError('Email is already in use.')
|
||||
|
||||
def validate_username(self, field):
|
||||
"""
|
||||
check if username is already in use.
|
||||
:param field:
|
||||
:return:
|
||||
"""
|
||||
if User.objects.raw({'username': field.data}).count() > 0:
|
||||
raise ValidationError('Username is already in use.')
|
||||
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
"""
|
||||
Form for users to login
|
||||
"""
|
||||
email = StringField('Email', validators=[DataRequired(), Email()])
|
||||
password = PasswordField('Password', validators=[DataRequired()])
|
||||
submit = SubmitField('Login')
|
||||
@@ -0,0 +1,79 @@
|
||||
"""
|
||||
Define routing rules for registering users and login and logout.
|
||||
"""
|
||||
from flask import Blueprint, flash, redirect, render_template, url_for
|
||||
from flask_login import login_required, login_user, logout_user
|
||||
from .forms import LoginForm, RegistrationForm
|
||||
from ..models import User
|
||||
|
||||
AUTH = Blueprint('auth', __name__)
|
||||
|
||||
|
||||
@AUTH.route('/register', methods=['GET', 'POST'])
|
||||
def register():
|
||||
"""
|
||||
Handle requests to the /register route
|
||||
Add an employee to the database through the registration form
|
||||
"""
|
||||
form = RegistrationForm()
|
||||
if form.validate_on_submit():
|
||||
user = User()
|
||||
user.email = form.email.data
|
||||
user.username = form.username.data
|
||||
user.first_name = form.first_name.data
|
||||
user.last_name = form.last_name.data
|
||||
user.password = form.password.data
|
||||
# add employee to the database
|
||||
user.save()
|
||||
flash('You have successfully registered! You may now login.')
|
||||
|
||||
# redirect to the login page
|
||||
return redirect(url_for('auth.login'))
|
||||
|
||||
# load registration template
|
||||
return render_template('auth/register.html', form=form, title='Register')
|
||||
|
||||
|
||||
@AUTH.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
"""
|
||||
Handle requests to the /login route
|
||||
Validate given email with matching password
|
||||
:return:
|
||||
"""
|
||||
form = LoginForm()
|
||||
if form.validate_on_submit():
|
||||
|
||||
# check whether employee exists in the database and whether
|
||||
# the password entered matches the password in the database
|
||||
user = User.objects.get({'email': form.email.data})
|
||||
if user is not None and user.verify_password(
|
||||
form.password.data):
|
||||
# log employee in
|
||||
login_user(user)
|
||||
|
||||
# redirect to the appropriate dashboard page
|
||||
if user.is_admin:
|
||||
return redirect(url_for('home.admin_dashboard'))
|
||||
else:
|
||||
return redirect(url_for('home.dashboard'))
|
||||
|
||||
# when login details are incorrect
|
||||
else:
|
||||
flash('Invalid email or password.')
|
||||
|
||||
# load login template
|
||||
return render_template('auth/login.html', form=form, title='Login')
|
||||
|
||||
@AUTH.route('/logout')
|
||||
@login_required
|
||||
def logout():
|
||||
"""
|
||||
Handle requests to the /logout route
|
||||
Log an employee out through the logout link
|
||||
"""
|
||||
logout_user()
|
||||
flash('You have successfully been logged out.')
|
||||
|
||||
# redirect to the login page
|
||||
return redirect(url_for('auth.login'))
|
||||
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Define routing rules for comic related information
|
||||
"""
|
||||
@@ -0,0 +1,31 @@
|
||||
"""Define form to edit publisher, artists and comics"""
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, SubmitField, BooleanField, SelectField
|
||||
from wtforms.validators import DataRequired
|
||||
from bson import ObjectId
|
||||
|
||||
|
||||
class PublisherForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a Comic publisher
|
||||
"""
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class ArtistForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a Comic publisher
|
||||
"""
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class ComicForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit Comics
|
||||
"""
|
||||
title = StringField('Title', validators=[DataRequired()])
|
||||
publisher = SelectField('Publisher', coerce=ObjectId)
|
||||
current_order = BooleanField('Current Order')
|
||||
submit = SubmitField('Submit')
|
||||
@@ -0,0 +1,51 @@
|
||||
"""This modules declares the model for Comic related information."""
|
||||
|
||||
from flask import current_app
|
||||
from pymongo.write_concern import WriteConcern
|
||||
from pymodm import MongoModel, fields
|
||||
|
||||
|
||||
class Publisher(MongoModel):
|
||||
"""Class Publisher represents a publisher of a comic."""
|
||||
name = fields.CharField()
|
||||
|
||||
def __str__(self):
|
||||
return "Publisher({})".format(self.name)
|
||||
|
||||
@property
|
||||
def comics(self):
|
||||
"""
|
||||
Return list of comics which has reference to this publisher
|
||||
:return:
|
||||
"""
|
||||
comics = Comic.objects.raw({'publisher': self.pk})
|
||||
current_app.logger.debug(comics)
|
||||
return comics
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class Artist(MongoModel):
|
||||
"""Class Artist represents a comic artist."""
|
||||
name = fields.CharField()
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class Comic(MongoModel):
|
||||
"""Class Comic represents a comic."""
|
||||
title = fields.CharField()
|
||||
publisher = fields.ReferenceField(Publisher)
|
||||
current_order = fields.BooleanField(default=False)
|
||||
completed = fields.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
@@ -0,0 +1,222 @@
|
||||
"""
|
||||
Define routing rules for comics, publisher and artists
|
||||
"""
|
||||
from flask import Blueprint, flash, redirect, render_template, url_for
|
||||
from flask_login import login_required
|
||||
from bson import ObjectId
|
||||
from pymongo.errors import PyMongoError
|
||||
from .forms import ComicForm, PublisherForm, ArtistForm
|
||||
from .models import Comic, Publisher, Artist
|
||||
|
||||
|
||||
COMIC = Blueprint('comic', __name__)
|
||||
|
||||
|
||||
@COMIC.route('/artists')
|
||||
@login_required
|
||||
def list_artists():
|
||||
"""
|
||||
List all artists
|
||||
:return:
|
||||
"""
|
||||
artists = Artist.objects.all()
|
||||
return render_template('comics/artists.html',
|
||||
artists=artists, title="Artists")
|
||||
|
||||
|
||||
@COMIC.route('/artists/edit/<artist_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_artist(artist_id):
|
||||
"""
|
||||
Edit a comic artist
|
||||
"""
|
||||
artist = Artist.objects.get({'_id': ObjectId(artist_id)})
|
||||
form = ArtistForm(obj=artist)
|
||||
if form.validate_on_submit():
|
||||
artist.name = form.name.data
|
||||
artist.save()
|
||||
flash('You have successfully edited the artist.')
|
||||
return redirect(url_for('comic.list_artists'))
|
||||
form.name.data = artist.name
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, title="Edit Artist")
|
||||
|
||||
|
||||
@COMIC.route('/artists/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_artist():
|
||||
"""
|
||||
Add a artist
|
||||
:return:
|
||||
"""
|
||||
form = ArtistForm()
|
||||
if form.validate_on_submit():
|
||||
artist = Artist()
|
||||
artist.name = form.name.data
|
||||
try:
|
||||
# add publisher to the database
|
||||
artist.save()
|
||||
flash('You have successfully added a new artist.')
|
||||
except PyMongoError:
|
||||
# in case publisher name already exists
|
||||
flash('Error: artist name already exists.')
|
||||
return redirect(url_for('comic.list_artists'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Artist")
|
||||
|
||||
|
||||
@COMIC.route('/artists/delete/<artist_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_artist(artist_id):
|
||||
"""
|
||||
Delete a comic artist
|
||||
:param artist_id:
|
||||
:return:
|
||||
"""
|
||||
artist = Artist.objects.raw({'_id': ObjectId(artist_id)})
|
||||
if artist:
|
||||
artist.delete()
|
||||
flash('You have successfully deleted the comic artist.')
|
||||
return redirect(url_for('comic.list_artists'))
|
||||
|
||||
|
||||
@COMIC.route('/publishers')
|
||||
@login_required
|
||||
def list_publishers():
|
||||
"""
|
||||
List all publishers
|
||||
:return:
|
||||
"""
|
||||
publishers = Publisher.objects.all()
|
||||
return render_template('comics/publishers.html',
|
||||
publishers=publishers, title="Publishers")
|
||||
|
||||
|
||||
@COMIC.route('/publishers/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_publisher():
|
||||
"""
|
||||
Add a publisher to the database
|
||||
:return:
|
||||
"""
|
||||
form = PublisherForm()
|
||||
if form.validate_on_submit():
|
||||
publisher = Publisher()
|
||||
publisher.name = form.name.data
|
||||
try:
|
||||
# add publisher to the database
|
||||
publisher.save()
|
||||
flash('You have successfully added a new publisher.')
|
||||
except PyMongoError:
|
||||
# in case publisher name already exists
|
||||
flash('Error: publisher name already exists.')
|
||||
return redirect(url_for('comic.list_publishers'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Publisher")
|
||||
|
||||
|
||||
@COMIC.route('/publishers/edit/<publisher_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_publisher(publisher_id):
|
||||
"""
|
||||
Edit a publisher
|
||||
"""
|
||||
publisher = Publisher.objects.get({'_id': ObjectId(publisher_id)})
|
||||
form = PublisherForm(obj=publisher)
|
||||
if form.validate_on_submit():
|
||||
publisher.name = form.name.data
|
||||
publisher.save()
|
||||
flash('You have successfully edited the publisher.')
|
||||
return redirect(url_for('comic.list_publishers'))
|
||||
form.name.data = publisher.name
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, title="Edit Publisher")
|
||||
|
||||
|
||||
@COMIC.route('/publishers/delete/<publisher_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_publisher(publisher_id):
|
||||
"""
|
||||
Delete a publisher
|
||||
:param publisher_id: ObjectId of publisher
|
||||
:return:
|
||||
"""
|
||||
publisher = Publisher.objects.raw({'_id': ObjectId(publisher_id)})
|
||||
if publisher:
|
||||
publisher.delete()
|
||||
flash('You have successfully deleted the publisher.')
|
||||
return redirect(url_for('comic.list_publishers'))
|
||||
|
||||
|
||||
@COMIC.route('/comics')
|
||||
@login_required
|
||||
def list_comics():
|
||||
"""
|
||||
List all comics
|
||||
:return:
|
||||
"""
|
||||
comics = Comic.objects.all()
|
||||
return render_template('comics/comics.html',
|
||||
comics=comics, title="Comics")
|
||||
|
||||
|
||||
@COMIC.route('/comics/edit/<comic_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_comic(comic_id):
|
||||
"""
|
||||
Edit a comic
|
||||
"""
|
||||
comic = Comic.objects.get({'_id': ObjectId(comic_id)})
|
||||
form = ComicForm(obj=comic)
|
||||
form.publisher.choices = [(p.pk, p.name) for p in Publisher.objects.all()]
|
||||
form.publisher.default = comic.publisher.pk
|
||||
form.publisher.process_data(comic.publisher.pk)
|
||||
if form.validate_on_submit():
|
||||
comic.title = form.title.data
|
||||
comic.current_order = form.current_order.data
|
||||
comic.publisher = form.publisher.data
|
||||
comic.save()
|
||||
flash('You have successfully edited the comic.')
|
||||
return redirect(url_for('comic.list_comics'))
|
||||
form.title.data = comic.title
|
||||
form.current_order.data = comic.current_order
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, title="Edit Comic")
|
||||
|
||||
|
||||
@COMIC.route('/comics/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_comic():
|
||||
"""
|
||||
Add a comic
|
||||
:return:
|
||||
"""
|
||||
form = ComicForm()
|
||||
form.publisher.choices = [(p.pk, p.name) for p in Publisher.objects.all()]
|
||||
if form.validate_on_submit():
|
||||
comic = Comic()
|
||||
comic.title = form.title.data
|
||||
comic.publisher = form.publisher.data
|
||||
try:
|
||||
comic.save()
|
||||
flash('You have successfully added a new comic.')
|
||||
except PyMongoError:
|
||||
flash('Error: comic title already exists.')
|
||||
return redirect(url_for('comic.list_comics'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Comic")
|
||||
|
||||
|
||||
@COMIC.route('/comics/delete/<comic_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_comic(comic_id):
|
||||
"""
|
||||
Delete a comic
|
||||
:param comic_id:
|
||||
:return:
|
||||
"""
|
||||
comic = Comic.objects.raw({'_id': ObjectId(comic_id)})
|
||||
if comic:
|
||||
comic.delete()
|
||||
flash('You have successfully deleted the comic.')
|
||||
return redirect(url_for('comic.list_comics'))
|
||||
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Module for the Kontor homepage.
|
||||
"""
|
||||
@@ -0,0 +1,39 @@
|
||||
"""
|
||||
Define routing rules for homepage and dashboards
|
||||
"""
|
||||
|
||||
from flask import Blueprint, render_template, abort
|
||||
from flask_login import login_required, current_user
|
||||
|
||||
HOME = Blueprint('home', __name__)
|
||||
|
||||
|
||||
@HOME.route('/')
|
||||
def homepage():
|
||||
"""
|
||||
Render the homepage template on the / route
|
||||
"""
|
||||
return render_template('home/index.html', title="Welcome")
|
||||
|
||||
|
||||
@HOME.route('/dashboard')
|
||||
@login_required
|
||||
def dashboard():
|
||||
"""
|
||||
Render the dashboard template on the /dashboard route
|
||||
"""
|
||||
return render_template('home/dashboard.html', title="Dashboard")
|
||||
|
||||
|
||||
@HOME.route('/admin/dashboard')
|
||||
@login_required
|
||||
def admin_dashboard():
|
||||
"""
|
||||
Render the admin_dashboard template on the /admin/dashboard route
|
||||
:return:
|
||||
"""
|
||||
# prevent non-admins from accessing the page
|
||||
if not current_user.is_admin:
|
||||
abort(403)
|
||||
|
||||
return render_template('home/admin_dashboard.html', title="Dashboard")
|
||||
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Define routing rules for library related information
|
||||
"""
|
||||
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
Define form to edit publisher, artists and books
|
||||
"""
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, SubmitField, SelectField, IntegerField
|
||||
from wtforms.validators import DataRequired, Optional, NumberRange
|
||||
from bson import ObjectId
|
||||
|
||||
|
||||
class PublisherForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a Comic publisher
|
||||
"""
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class AuthorForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a Comic publisher
|
||||
"""
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class BookForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit Comics
|
||||
"""
|
||||
title = StringField('Title', validators=[DataRequired()])
|
||||
author = SelectField('Author', coerce=ObjectId)
|
||||
publisher = SelectField('Publisher', coerce=ObjectId)
|
||||
isbn = StringField('ISBN', validators=[Optional()])
|
||||
year = IntegerField('Year', validators=[NumberRange(min=1970, max=2050)])
|
||||
submit = SubmitField('Submit')
|
||||
@@ -0,0 +1,55 @@
|
||||
"""
|
||||
This module declares the model for the library related information.
|
||||
"""
|
||||
from pymongo.write_concern import WriteConcern
|
||||
from pymodm import MongoModel, fields
|
||||
|
||||
|
||||
class Publisher(MongoModel):
|
||||
"""
|
||||
Class Publisher represents a publisher of a book.
|
||||
"""
|
||||
name = fields.CharField()
|
||||
|
||||
def __str__(self):
|
||||
return "Publisher({})".format(self.name)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class Author(MongoModel):
|
||||
"""
|
||||
Class Author represents an author of a book.
|
||||
"""
|
||||
name = fields.CharField()
|
||||
|
||||
def __str__(self):
|
||||
return "Author({})".format(self.name)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class Book(MongoModel):
|
||||
"""
|
||||
Class book represents a book.
|
||||
"""
|
||||
title = fields.CharField()
|
||||
author = fields.ReferenceField(Author)
|
||||
publisher = fields.ReferenceField(Publisher)
|
||||
isbn = fields.CharField(blank=True)
|
||||
year = fields.IntegerField(blank=True)
|
||||
edition = fields.CharField()
|
||||
|
||||
def __str__(self):
|
||||
return "Book({})".format(self.title)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
@@ -0,0 +1,228 @@
|
||||
"""Define routing rules for book publishers"""
|
||||
from flask import Blueprint, flash, redirect, render_template, url_for
|
||||
from flask_login import login_required
|
||||
from bson import ObjectId
|
||||
from pymongo.errors import PyMongoError
|
||||
from .forms import PublisherForm, AuthorForm, BookForm
|
||||
from .models import Publisher, Author, Book
|
||||
|
||||
|
||||
LIBRARY = Blueprint('library', __name__)
|
||||
|
||||
|
||||
@LIBRARY.route('/publishers')
|
||||
@login_required
|
||||
def list_publishers():
|
||||
"""
|
||||
List all publishers
|
||||
:return:
|
||||
"""
|
||||
publishers = Publisher.objects.all()
|
||||
return render_template('library/publishers.html',
|
||||
publishers=publishers, title="Publishers")
|
||||
|
||||
|
||||
@LIBRARY.route('/publishers/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_publisher():
|
||||
"""
|
||||
Add a publisher to the database
|
||||
:return:
|
||||
"""
|
||||
form = PublisherForm()
|
||||
if form.validate_on_submit():
|
||||
publisher = Publisher()
|
||||
publisher.name = form.name.data
|
||||
try:
|
||||
publisher.save()
|
||||
flash('You have successfully added a new publisher.')
|
||||
except PyMongoError:
|
||||
flash('Error: publisher name already exists.')
|
||||
return redirect(url_for('library.list_publishers'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Publisher")
|
||||
|
||||
|
||||
@LIBRARY.route('/publishers/edit/<publisher_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_publisher(publisher_id):
|
||||
"""
|
||||
Edit a publisher
|
||||
"""
|
||||
publisher = Publisher.objects.get({'_id': ObjectId(publisher_id)})
|
||||
form = PublisherForm(obj=publisher)
|
||||
if form.validate_on_submit():
|
||||
publisher.name = form.name.data
|
||||
publisher.save()
|
||||
flash('You have successfully edited the publisher.')
|
||||
return redirect(url_for('library.list_publishers'))
|
||||
form.name.data = publisher.name
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, publisher=publisher, title="Edit Publisher")
|
||||
|
||||
|
||||
@LIBRARY.route('/publishers/delete/<publisher_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_publisher(publisher_id):
|
||||
"""
|
||||
Delete a publisher
|
||||
:param publisher_id: ObjectId of publisher
|
||||
:return:
|
||||
"""
|
||||
publisher = Publisher.objects.raw({'_id': ObjectId(publisher_id)})
|
||||
if publisher:
|
||||
publisher.delete()
|
||||
flash('You have successfully deleted the publisher.')
|
||||
return redirect(url_for('library.list_publishers'))
|
||||
|
||||
|
||||
@LIBRARY.route('/authors')
|
||||
@login_required
|
||||
def list_authors():
|
||||
"""
|
||||
List all authors
|
||||
:return:
|
||||
"""
|
||||
authors = Author.objects.all()
|
||||
return render_template('library/authors.html',
|
||||
authors=authors, title="Authors")
|
||||
|
||||
|
||||
@LIBRARY.route('/authors/edit/<author_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_author(author_id):
|
||||
"""
|
||||
Edit a book artist
|
||||
"""
|
||||
author = Author.objects.get({'_id': ObjectId(author_id)})
|
||||
form = AuthorForm(obj=author)
|
||||
if form.validate_on_submit():
|
||||
author.name = form.name.data
|
||||
author.save()
|
||||
flash('You have successfully edited the author.')
|
||||
return redirect(url_for('library.list_authors'))
|
||||
form.name.data = author.name
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, author=author, title="Edit Author")
|
||||
|
||||
|
||||
@LIBRARY.route('/authors/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_author():
|
||||
"""
|
||||
Add a author
|
||||
:return:
|
||||
"""
|
||||
form = AuthorForm()
|
||||
if form.validate_on_submit():
|
||||
author = Author()
|
||||
author.name = form.name.data
|
||||
try:
|
||||
author.save()
|
||||
flash('You have successfully added a new author.')
|
||||
except PyMongoError:
|
||||
flash('Error: author name already exists.')
|
||||
return redirect(url_for('library.list_authors'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Author")
|
||||
|
||||
|
||||
@LIBRARY.route('/authors/delete/<author_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_author(author_id):
|
||||
"""
|
||||
Delete a author
|
||||
:param author_id:
|
||||
:return:
|
||||
"""
|
||||
author = Author.objects.raw({'_id': ObjectId(author_id)})
|
||||
if author:
|
||||
author.delete()
|
||||
flash('You have successfully deleted the author.')
|
||||
return redirect(url_for('library.list_authors'))
|
||||
|
||||
|
||||
@LIBRARY.route('/books')
|
||||
@login_required
|
||||
def list_books():
|
||||
"""
|
||||
List all comics
|
||||
:return:
|
||||
"""
|
||||
books = Book.objects.all()
|
||||
return render_template('library/books.html',
|
||||
books=books, title="Books")
|
||||
|
||||
|
||||
@LIBRARY.route('/books/edit/<book_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_book(book_id):
|
||||
"""
|
||||
Edit a book
|
||||
"""
|
||||
book = Book.objects.get({'_id': ObjectId(book_id)})
|
||||
form = BookForm(obj=book)
|
||||
form.publisher.choices = [(p.pk, p.name) for p in Publisher.objects.all()]
|
||||
if book.publisher:
|
||||
form.publisher.default = book.publisher.pk
|
||||
form.publisher.process_data(book.publisher.pk)
|
||||
form.author.choices = [(a.pk, a.name) for a in Author.objects.all()]
|
||||
if book.author:
|
||||
form.author.default = book.author.pk
|
||||
form.author.process_data(book.author.pk)
|
||||
if form.validate_on_submit():
|
||||
book.title = form.title.data
|
||||
book.publisher = form.publisher.data
|
||||
book.author = form.author.data
|
||||
if form.isbn.data:
|
||||
book.isbn = form.isbn.data
|
||||
else:
|
||||
book.isbn = None
|
||||
book.year = form.year.data
|
||||
book.save()
|
||||
flash('You have successfully edited the book.')
|
||||
return redirect(url_for('library.list_books'))
|
||||
form.title.data = book.title
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, book=book, title="Edit Book")
|
||||
|
||||
|
||||
@LIBRARY.route('/books/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_book():
|
||||
"""
|
||||
Add a book
|
||||
:return:
|
||||
"""
|
||||
form = BookForm()
|
||||
form.publisher.choices = [(p.pk, p.name) for p in Publisher.objects.all()]
|
||||
form.author.choices = [(a.pk, a.name) for a in Author.objects.all()]
|
||||
if form.validate_on_submit():
|
||||
book = Book()
|
||||
book.title = form.title.data
|
||||
book.publisher = form.publisher.data
|
||||
book.author = form.author.data
|
||||
book.year = form.year.data
|
||||
try:
|
||||
book.save()
|
||||
flash('You have successfully added a new book.')
|
||||
except PyMongoError:
|
||||
flash('Error: book title already exists.')
|
||||
return redirect(url_for('library.list_books'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Book")
|
||||
|
||||
|
||||
@LIBRARY.route('/books/delete/<book_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_book(book_id):
|
||||
"""
|
||||
Delete a book
|
||||
:param book_id:
|
||||
:return:
|
||||
"""
|
||||
book = Book.objects.raw({'_id': ObjectId(book_id)})
|
||||
if book:
|
||||
book.delete()
|
||||
flash('You have successfully deleted the book.')
|
||||
return redirect(url_for('library.list_books'))
|
||||
@@ -0,0 +1,66 @@
|
||||
"""
|
||||
This modules declares the model for Kontor users.
|
||||
"""
|
||||
from pymodm import MongoModel, fields
|
||||
from pymongo.write_concern import WriteConcern
|
||||
from flask_login import UserMixin
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
from kontor import _LOGIN_MANAGER_
|
||||
|
||||
|
||||
class User(UserMixin, MongoModel):
|
||||
"""
|
||||
This class represents an user for the Kontor application.
|
||||
"""
|
||||
email = fields.EmailField()
|
||||
username = fields.CharField(max_length=60)
|
||||
first_name = fields.CharField(max_length=60)
|
||||
last_name = fields.CharField(max_length=60)
|
||||
password_hash = fields.CharField(max_length=128)
|
||||
is_admin = fields.BooleanField(default=False)
|
||||
|
||||
@property
|
||||
def password(self):
|
||||
"""
|
||||
Prevent pasword from being accessed
|
||||
"""
|
||||
raise AttributeError('password is not a readable attribute.')
|
||||
|
||||
@password.setter
|
||||
def password(self, password):
|
||||
"""
|
||||
Set password to a hashed password
|
||||
"""
|
||||
self.password_hash = generate_password_hash(password)
|
||||
|
||||
def verify_password(self, password):
|
||||
"""
|
||||
Check if hashed password matches actual password
|
||||
"""
|
||||
return check_password_hash(self.password_hash, password)
|
||||
|
||||
def get_id(self):
|
||||
"""
|
||||
Get username as id
|
||||
:return:
|
||||
"""
|
||||
return self.username
|
||||
|
||||
def __repr__(self):
|
||||
return '<User: {}>'.format(self.username)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
# Set up user_loader
|
||||
@_LOGIN_MANAGER_.user_loader
|
||||
def load_user(user_name):
|
||||
"""
|
||||
Get list of users from database
|
||||
:param user_name:
|
||||
:return:
|
||||
"""
|
||||
return User.objects.get({'username': user_name})
|
||||
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Define routing rules for office related information
|
||||
"""
|
||||
@@ -0,0 +1,126 @@
|
||||
/* app/static/css/style.css */
|
||||
|
||||
body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body, h1, h2, h3 {
|
||||
font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
a, .navbar-default .navbar-brand, .navbar-default .navbar-nav>li>a {
|
||||
color: #aec251;
|
||||
}
|
||||
|
||||
a:hover, .navbar-default .navbar-brand:hover, .navbar-default .navbar-nav>li>a:hover {
|
||||
color: #687430;
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 50px 0;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
p.copyright {
|
||||
margin: 15px 0 0;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
width: 50%;
|
||||
margin: auto;
|
||||
color: #687430;
|
||||
background-color: #e6ecca;
|
||||
border-color: #aec251;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
border-color: #aec251;
|
||||
color: #aec251;
|
||||
}
|
||||
|
||||
.btn-default:hover {
|
||||
background-color: #aec251;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin: auto;
|
||||
width: 70%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.content-section {
|
||||
padding: 50px 0;
|
||||
border-top: 1px solid #e7e7e7;
|
||||
}
|
||||
|
||||
.footer, .push {
|
||||
clear: both;
|
||||
height: 4em;
|
||||
}
|
||||
|
||||
.intro-divider {
|
||||
width: 400px;
|
||||
border-top: 1px solid #f8f8f8;
|
||||
border-bottom: 1px solid rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.intro-header {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
text-align: center;
|
||||
color: #f8f8f8;
|
||||
background: url(../img/intro-bg.jpg) no-repeat center center;
|
||||
background-size: cover;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.intro-message {
|
||||
position: relative;
|
||||
padding-top: 20%;
|
||||
padding-bottom: 20%;
|
||||
}
|
||||
|
||||
.intro-message > h1 {
|
||||
margin: 0;
|
||||
text-shadow: 2px 2px 3px rgba(0,0,0,0.6);
|
||||
font-size: 5em;
|
||||
}
|
||||
|
||||
.intro-message > h3 {
|
||||
text-shadow: 2px 2px 3px rgba(0,0,0,0.6);
|
||||
}
|
||||
|
||||
.lead {
|
||||
font-size: 18px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.topnav {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
margin: 0 auto -4em;
|
||||
}
|
||||
|
||||
.outer {
|
||||
display: table;
|
||||
position: absolute;
|
||||
height: 70%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.middle {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.inner {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<!-- app/templates/admin/employees/employee.html -->
|
||||
|
||||
{% import "bootstrap/wtf.html" as wtf %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Edit User{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<div class="center">
|
||||
<h1> Edit User </h1>
|
||||
<br/>
|
||||
<br/>
|
||||
{{ wtf.quick_form(form) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,58 @@
|
||||
<!-- app/templates/admin/users/users.html -->
|
||||
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Users{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">Users</h1>
|
||||
{% if users %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> Name </th>
|
||||
<th width="30%"> Email </th>
|
||||
<th width="30%"> Username </th>
|
||||
<th width="15%"> Edit </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
{% if user.is_admin %}
|
||||
<tr style="background-color: #aec251; color: white;">
|
||||
<td> <i class="fa fa-key"></i> Admin </td>
|
||||
<td> N/A </td>
|
||||
<td> N/A </td>
|
||||
<td> N/A </td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td> {{ user.first_name }} {{ user.last_name }} </td>
|
||||
<td> {{ user.email }} </td>
|
||||
<td> {{ user.username }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('admin.edit_user', user_id=user.username) }}">
|
||||
<i class="fa fa-user-plus"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,18 @@
|
||||
<!-- app/templates/auth/login.html -->
|
||||
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% import "bootstrap/wtf.html" as wtf %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Login{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<div class="center">
|
||||
<h1>Login to your account</h1>
|
||||
<br/>
|
||||
{{ wtf.quick_form(form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,14 @@
|
||||
<!-- app/templates/auth/register.html -->
|
||||
|
||||
{% import "bootstrap/wtf.html" as wtf %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Register{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="center">
|
||||
<h1>Register for an account</h1>
|
||||
<br/>
|
||||
{{ wtf.quick_form(form) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,107 @@
|
||||
<!-- app/templates/base.html -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{ title }} | Kontor</title>
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
|
||||
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
|
||||
<link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet">
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.ico') }}">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-default navbar-fixed-top topnav" role="navigation">
|
||||
<div class="container topnav">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand topnav" href="{{ url_for('home.homepage') }}">Kontor</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{% if current_user.is_authenticated %}
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button">Comics <span class="caret"></span> </a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ url_for('comic.list_comics') }}">Comics</a></li>
|
||||
<li><a href="{{ url_for('comic.list_artists') }}">Artists</a></li>
|
||||
<li><a href="{{ url_for('comic.list_publishers') }}">Publishers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button">Library <span class="caret"></span> </a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ url_for('library.list_books') }}">Books</a></li>
|
||||
<li><a href="{{ url_for('library.list_authors') }}">Authors</a></li>
|
||||
<li><a href="{{ url_for('library.list_publishers') }}">Publishers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button">HomeOffice <span class="caret"></span> </a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ url_for('home.homepage') }}">HomeOffice</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button">Trading Cards <span class="caret"></span> </a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ url_for('home.homepage') }}">Trading Cards</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button">TradeYourSportsCards <span class="caret"></span> </a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ url_for('tysc.list_sports') }}">Sports</a></li>
|
||||
<li><a href="{{ url_for('tysc.list_positions') }}">Positions</a></li>
|
||||
<li><a href="{{ url_for('tysc.list_teams') }}">Teams</a></li>
|
||||
<li><a href="{{ url_for('tysc.list_players') }}">Players</a></li>
|
||||
<li><a href="{{ url_for('tysc.list_manufacturers') }}">Manufacturers</a></li>
|
||||
<li><a href="{{ url_for('tysc.list_card_sets') }}">Series</a></li>
|
||||
<li><a href="{{ url_for('tysc.list_parallel_sets') }}">Parallel Sets</a></li>
|
||||
<li><a href="{{ url_for('tysc.list_insert_sets') }}">Inserts</a></li>
|
||||
<li><a href="{{ url_for('tysc.list_cards') }}">Cards</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{% if current_user.is_admin %}
|
||||
<li><a href="{{ url_for('home.admin_dashboard') }}">Dashboard</a></li>
|
||||
<li><a href="{{ url_for('admin.list_users') }}">Users</a></li>
|
||||
{% else %}
|
||||
<li><a href="{{ url_for('home.dashboard') }}">Dashboard</a></li>
|
||||
{% endif %}
|
||||
<li><a href="{{ url_for('auth.logout') }}">{{ current_user.username }}</a></li>
|
||||
{% else %}
|
||||
<li><a href="{{ url_for('home.homepage') }}">Home</a></li>
|
||||
<li><a href="{{ url_for('auth.register') }}">Register</a></li>
|
||||
<li><a href="{{ url_for('auth.login') }}">Login</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="wrapper">
|
||||
{% block body %}
|
||||
{% endblock %}
|
||||
<div class="push"></div>
|
||||
</div>
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<p class="col-lg-12">
|
||||
<ul class="list-inline">
|
||||
<li><a href="{{ url_for('home.homepage') }}">Home</a></li>
|
||||
<li class="footer-menu-divider">⋅</li>
|
||||
<li><a href="{{ url_for('auth.register') }}">Register</a></li>
|
||||
<li class="footer-menu-divider">⋅</li>
|
||||
<li><a href="{{ url_for('auth.login') }}">Login</a></li>
|
||||
</ul>
|
||||
<p class="copyright text-muted small">Version {{ version }}. Copyright © 2017. All Rights Reserved</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,58 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Comic Artists{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">Comic Artists</h1>
|
||||
{% if artists %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> Name </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for artist in artists %}
|
||||
<tr>
|
||||
<td> {{ artist.name }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('comic.edit_artist', artist_id=artist.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('comic.delete_artist', artist_id=artist.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No artists have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('comic.add_artist') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Artist
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,66 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Comics{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">Comics</h1>
|
||||
{% if comics %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> Title </th>
|
||||
<th width="40%"> Publisher </th>
|
||||
<th width="15%"> Current Order </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for comic in comics %}
|
||||
<tr>
|
||||
<td> {{ comic.title }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('comic.edit_publisher', publisher_id=comic.publisher.pk) }}">
|
||||
{{ comic.publisher.name }}
|
||||
</a>
|
||||
</td>
|
||||
<td> {{ comic.current_order }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('comic.edit_comic', comic_id=comic.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('comic.delete_comic', comic_id=comic.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No comics have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('comic.add_comic') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Comic
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,58 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Comic Publishers{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">Comic Publishers</h1>
|
||||
{% if publishers %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> Name </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for publisher in publishers %}
|
||||
<tr>
|
||||
<td> {{ publisher.name }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('comic.edit_publisher', publisher_id=publisher.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('comic.delete_publisher', publisher_id=publisher.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No comics have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('comic.add_publisher') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Publisher
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,31 @@
|
||||
<!-- app/templates/home/admin_dashboard.html -->
|
||||
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Admin Dashboard{% endblock %}
|
||||
{% block body %}
|
||||
<div class="intro-header">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="intro-message">
|
||||
<h2>Admin Dashboard</h2>
|
||||
<hr class="intro-divider">
|
||||
<ul>
|
||||
<li><a href="{{ url_for('comic.list_comics') }}">Comics</a></li>
|
||||
<ul>
|
||||
<li><a href="{{ url_for('comic.list_publishers') }}">Publishers</a> </li>
|
||||
<li><a href="{{ url_for('comic.list_artists') }}">Artists</a> </li>
|
||||
</ul>
|
||||
<li><a href="{{ url_for('library.list_books') }}">Library</a></li>
|
||||
<ul>
|
||||
<li><a href="{{ url_for('library.list_publishers') }}">Publishers</a> </li>
|
||||
<li><a href="{{ url_for('library.list_authors') }}">Authors</a> </li>
|
||||
</ul>
|
||||
<li><a href="{{ url_for('home.homepage') }}">Office</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,20 @@
|
||||
<!-- app/templates/home/dashboard.html -->
|
||||
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Dashboard{% endblock %}
|
||||
{% block body %}
|
||||
<div class="intro-header">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="intro-message">
|
||||
<h1>The Dashboard</h1>
|
||||
<h3>We made it here!</h3>
|
||||
<hr class="intro-divider">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,20 @@
|
||||
<!-- app/templates/home/index.html -->
|
||||
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Home{% endblock %}
|
||||
{% block body %}
|
||||
<div class="intro-header">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="intro-message">
|
||||
<h1>Project Kontor</h1>
|
||||
<h3>Store everything!</h3>
|
||||
<hr class="intro-divider">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,58 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Library Authors{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">Library Authors</h1>
|
||||
{% if authors %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> Name </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for author in authors %}
|
||||
<tr>
|
||||
<td> {{ author.name }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('library.edit_author', author_id=author.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('library.delete_author', author_id=author.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No artists have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('library.add_author') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Author
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,74 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Books{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">Books</h1>
|
||||
{% if books %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> Title </th>
|
||||
<th width="25%"> Author </th>
|
||||
<th width="40%"> Publisher </th>
|
||||
<th width="5%"> ISBN </th>
|
||||
<th width="2%"> Year </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for book in books %}
|
||||
<tr>
|
||||
<td> {{ book.title }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('library.edit_author', author_id=book.author.pk) }}">
|
||||
{{ book.author.name }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('library.edit_publisher', publisher_id=book.publisher.pk) }}">
|
||||
{{ book.publisher.name }}
|
||||
</a>
|
||||
</td>
|
||||
<td> {{ book.isbn }} </td>
|
||||
<td> {{ book.year }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('library.edit_book', book_id=book.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('library.delete_book', book_id=book.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No books have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('library.add_book') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Book
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,58 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Book Publishers{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">Book Publishers</h1>
|
||||
{% if publishers %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> Name </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for publisher in publishers %}
|
||||
<tr>
|
||||
<td> {{ publisher.name }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('library.edit_publisher', publisher_id=publisher.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('library.delete_publisher', publisher_id=publisher.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No publishers have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('library.add_publisher') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Publisher
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,21 @@
|
||||
{% import "bootstrap/wtf.html" as wtf %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<div class="center">
|
||||
<h1> {{ title }} </h1>
|
||||
<br/>
|
||||
<br/>
|
||||
{{ wtf.quick_form(form) }}
|
||||
<br/>
|
||||
<hr class="intro-divider">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,58 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">{{ title }}</h1>
|
||||
{% if manufacturers %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> Name </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for manufacturer in manufacturers %}
|
||||
<tr>
|
||||
<td> {{ manufacturer.name }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.edit_manufacturer', manufacturer_id=manufacturer.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.delete_manufacturer', manufacturer_id=manufacturer.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No manufacturers have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('tysc.add_manufacturer') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Manufacturer
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,60 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">{{ title }}</h1>
|
||||
{% if players %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> First Name </th>
|
||||
<th width="15%"> Last Name </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for player in players %}
|
||||
<tr>
|
||||
<td> {{ player.first_name }} </td>
|
||||
<td> {{ player.last_name }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.edit_player', player_id=player.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.delete_player', player_id=player.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No players have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('tysc.add_player') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Player
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,62 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">{{ title }}</h1>
|
||||
{% if positions %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="25%"> Name </th>
|
||||
<th width="15%"> Description </th>
|
||||
<th width="15%"> Sport </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for position in positions %}
|
||||
<tr>
|
||||
<td> {{ position.name }} </td>
|
||||
<td> {{ position.description }} </td>
|
||||
<td> {{ position.sport.name }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.edit_position', position_id=position.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.delete_position', position_id=position.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No positions have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('tysc.add_position') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Position
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,58 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Sports{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">Sports</h1>
|
||||
{% if sports %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="15%"> Name </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for sport in sports %}
|
||||
<tr>
|
||||
<td> {{ sport.name }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.edit_sport', sport_id=sport.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.delete_sport', sport_id=sport.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No sports have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('tysc.add_sport') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Sport
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,60 @@
|
||||
{% import "bootstrap/utils.html" as utils %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Teams{% endblock %}
|
||||
{% block body %}
|
||||
<div class="content-section">
|
||||
<div class="outer">
|
||||
<div class="middle">
|
||||
<div class="inner">
|
||||
<br/>
|
||||
{{ utils.flashed_messages() }}
|
||||
<br/>
|
||||
<h1 style="text-align:center;">Teams</h1>
|
||||
{% if teams %}
|
||||
<hr class="intro-divider">
|
||||
<div class="center">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="25%"> Name </th>
|
||||
<th width="15%"> Shortname </th>
|
||||
<th width="15%"> Edit </th>
|
||||
<th width="15%"> Delete </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for team in teams %}
|
||||
<tr>
|
||||
<td> {{ team.name }} </td>
|
||||
<td> {{ team.shortname }} </td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.edit_team', team_id=team.pk) }}">
|
||||
<i class="fa fa-pencil"></i> Edit
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ url_for('tysc.delete_team', team_id=team.pk) }}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="text-align: center">
|
||||
{% else %}
|
||||
<div style="text-align: center">
|
||||
<h3> No teams have been added. </h3>
|
||||
<hr class="intro-divider">
|
||||
{% endif %}
|
||||
<a href="{{ url_for('tysc.add_team') }}" class="btn btn-default btn-lg">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add Team
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,377 @@
|
||||
"""
|
||||
Define routing rules for TradeYourSportsCards related information
|
||||
"""
|
||||
from .models import Sport, Team, Position, Player
|
||||
from .models import Manufacturer, CardSet, ParallelSet, InsertSet, Card
|
||||
|
||||
|
||||
def initialize_model():
|
||||
"""
|
||||
Initialize collections for module TradeYourSportsCards.
|
||||
"""
|
||||
initialize_sport()
|
||||
initialize_position()
|
||||
initialize_teams()
|
||||
initialize_players()
|
||||
initialize_manufacturers()
|
||||
initialize_card_sets()
|
||||
initialize_parallel_sets()
|
||||
initialize_insert_sets()
|
||||
initialize_cards()
|
||||
|
||||
|
||||
def initialize_sport():
|
||||
"""
|
||||
Initialize collection Sport with american sports.
|
||||
"""
|
||||
for sport in Sport.objects.all():
|
||||
sport.delete()
|
||||
sports = ["Baseball", "Basketball", "Football", "Hockey"]
|
||||
for sport_name in sports:
|
||||
sport = Sport()
|
||||
sport.name = sport_name
|
||||
sport.save()
|
||||
|
||||
|
||||
def initialize_position():
|
||||
"""
|
||||
Initialize collection Position with data.
|
||||
"""
|
||||
for position in Position.objects.all():
|
||||
position.delete()
|
||||
positions = {
|
||||
'Quarterback': {'short': 'QB', 'sport': 'Football'},
|
||||
'Wide Receiver': {'short': 'WR', 'sport': 'Football'},
|
||||
'Runningback': {'short': 'RB', 'sport': 'Football'},
|
||||
'Linebacker': {'short': 'LB', 'sport': 'Football'},
|
||||
'Tight End': {'short': 'TE', 'sport': 'Football'},
|
||||
'Fullback': {'short': 'FB', 'sport': 'Football'},
|
||||
'Strong Safety': {'short': 'SS', 'sport': 'Football'},
|
||||
'Defensive End': {'short': 'DE', 'sport': 'Football'},
|
||||
'Kicker': {'short': 'K', 'sport': 'Football'},
|
||||
'Punter': {'short': 'P', 'sport': 'Football'},
|
||||
'Left Guard': {'short': 'LG', 'sport': 'Football'},
|
||||
'Right Guard': {'short': 'RG', 'sport': 'Football'},
|
||||
'Offensive Tackle': {'short': 'OT', 'sport': 'Football'},
|
||||
'Defensive Back': {'short': 'DB', 'sport': 'Football'},
|
||||
'Cornerback': {'short': 'CB', 'sport': 'Football'},
|
||||
'Catcher': {'short': 'C', 'sport': 'Baseball'},
|
||||
'First Base': {'short': '1B', 'sport': 'Baseball'},
|
||||
'Second Base': {'short': '2B', 'sport': 'Baseball'},
|
||||
'Third Base': {'short': '3B', 'sport': 'Baseball'},
|
||||
'Shortstop': {'short': 'SS', 'sport': 'Baseball'},
|
||||
'Left Field': {'short': 'LF', 'sport': 'Baseball'},
|
||||
'Center Field': {'short': 'CF', 'sport': 'Baseball'},
|
||||
'Right Field': {'short': 'RF', 'sport': 'Baseball'},
|
||||
'Designated Hitter': {'short': 'DH', 'sport': 'Baseball'},
|
||||
'Pitcher': {'short': 'P', 'sport': 'Baseball'}
|
||||
}
|
||||
for key in positions:
|
||||
sport = Sport.objects.get({'name': positions.get(key)['sport']})
|
||||
position = Position()
|
||||
position.description = key
|
||||
position.name = positions.get(key)['short']
|
||||
position.sport = sport
|
||||
position.save()
|
||||
|
||||
|
||||
def initialize_teams():
|
||||
"""
|
||||
Initialize collection Team with data.
|
||||
"""
|
||||
for team in Team.objects.all():
|
||||
team.delete()
|
||||
teams = {'Buffalo Bills': {'short': 'Bills', 'sport': 'Football'},
|
||||
'Indianapolis Colts': {'short': 'Colts', 'sport': 'Football'},
|
||||
'Miami Dolphins': {'short': 'Dolphins', 'sport': 'Football'},
|
||||
'New England Patriots': {'short': 'Patriots', 'sport': 'Football'},
|
||||
'New York Jets': {'short': 'Jets', 'sport': 'Football'},
|
||||
'Baltimore Ravens': {'short': 'Ravens', 'sport': 'Football'},
|
||||
'Cincinnati Bengals': {'short': 'Bengals', 'sport': 'Football'},
|
||||
'Cleveland Browns': {'short': 'Browns', 'sport': 'Football'},
|
||||
'Jacksonville Jaguars': {'short': 'Jaguars', 'sport': 'Football'},
|
||||
'Pittsburgh Steelers': {'short': 'Steelers', 'sport': 'Football'},
|
||||
'Tennessee Titans': {'short': 'Titans', 'sport': 'Football'},
|
||||
'Denver Broncos': {'short': 'Broncos', 'sport': 'Football'},
|
||||
'Kansas City Chiefs': {'short': 'Chiefs', 'sport': 'Football'},
|
||||
'Oakland Raiders': {'short': 'Raiders', 'sport': 'Football'},
|
||||
'San Diego Chargers': {'short': 'Chargers', 'sport': 'Football'},
|
||||
'Seattle Seahawks': {'short': 'Seahawks', 'sport': 'Football'},
|
||||
'Arizona Cardinals': {'short': 'Cardinals', 'sport': 'Football'},
|
||||
'Dallas Cowboys': {'short': 'Cowboys', 'sport': 'Football'},
|
||||
'New York Giants': {'short': 'Giants', 'sport': 'Football'},
|
||||
'Philadelphia Eagles': {'short': 'Eagles', 'sport': 'Football'},
|
||||
'Washington Redskins': {'short': 'Redskins', 'sport': 'Football'},
|
||||
'Chicago Bears': {'short': 'Bears', 'sport': 'Football'},
|
||||
'Detroit Lions': {'short': 'Lions', 'sport': 'Football'},
|
||||
'Green Bay Packers': {'short': 'Packers', 'sport': 'Football'},
|
||||
'Minnesota Vikings': {'short': 'Vikings', 'sport': 'Football'},
|
||||
'Tampa Bay Buccaneers': {'short': 'Buccaneers', 'sport': 'Football'},
|
||||
'Atlanta Falcons': {'short': 'Falcons', 'sport': 'Football'},
|
||||
'Carolina Panthers': {'short': 'Panthers', 'sport': 'Football'},
|
||||
'New Orleans Saints': {'short': 'Saints', 'sport': 'Football'},
|
||||
'St.Louis Rams': {'short': 'Rams', 'sport': 'Football'},
|
||||
'San Francisco 49ers': {'short': '49ers', 'sport': 'Football'},
|
||||
'Baltimore Orioles': {'short': 'Orioles', 'sport': 'Baseball'},
|
||||
'Boston Red Sox': {'short': 'Red Sox', 'sport': 'Baseball'},
|
||||
'New York Yankees': {'short': 'Yankees', 'sport': 'Baseball'},
|
||||
'Tampa Bay Devil Rays': {'short': 'Devil Rays', 'sport': 'Baseball'},
|
||||
'Toronto Blue Jays': {'short': 'Blue Jays', 'sport': 'Baseball'},
|
||||
'Chicago White Sox': {'short': 'White Sox', 'sport': 'Baseball'},
|
||||
'Cleveland Indians': {'short': 'Indians', 'sport': 'Baseball'},
|
||||
'Detroit Tigers': {'short': 'Tigers', 'sport': 'Baseball'},
|
||||
'Kansas City Royals': {'short': 'Royals', 'sport': 'Baseball'},
|
||||
'Minnesota Twins': {'short': 'Twins', 'sport': 'Baseball'},
|
||||
'Anaheim Angels': {'short': 'Angels', 'sport': 'Baseball'},
|
||||
'Oakland Athletics': {'short': 'Athletics', 'sport': 'Baseball'},
|
||||
'Seattle Mariners': {'short': 'Mariners', 'sport': 'Baseball'},
|
||||
'Texas Rangers': {'short': 'Rangers', 'sport': 'Baseball'},
|
||||
'Atlanta Braves': {'short': 'Braves', 'sport': 'Baseball'},
|
||||
'Florida Marlins': {'short': 'Marlins', 'sport': 'Baseball'},
|
||||
'Montreal Expos': {'short': 'Expos', 'sport': 'Baseball'},
|
||||
'New York Mets': {'short': 'Mets', 'sport': 'Baseball'},
|
||||
'Philadelphia Phillies': {'short': 'Phillies', 'sport': 'Baseball'},
|
||||
'Chicago Cubs': {'short': 'Cubs', 'sport': 'Baseball'},
|
||||
'Cincinnati Reds': {'short': 'Reds', 'sport': 'Baseball'},
|
||||
'Houston Astros': {'short': 'Astros', 'sport': 'Baseball'},
|
||||
'Milwaukee Brewers': {'short': 'Brewers', 'sport': 'Baseball'},
|
||||
'Pittsburgh Pirates': {'short': 'Pirates', 'sport': 'Baseball'},
|
||||
'St.Louis Cardinals': {'short': 'Cardinals', 'sport': 'Baseball'},
|
||||
'Arizona Diamondbacks': {'short': 'Diamondbacks', 'sport': 'Baseball'},
|
||||
'Colorado Rockies': {'short': 'Rockies', 'sport': 'Baseball'},
|
||||
'Los Angeles Dodgers': {'short': 'Dodgers', 'sport': 'Baseball'},
|
||||
'San Diego Padres': {'short': 'Padres', 'sport': 'Baseball'},
|
||||
'San Francisco Giants': {'short': 'Giants', 'sport': 'Baseball'},
|
||||
'Boston Celtics': {'short': 'Celtics', 'sport': 'Basketball'},
|
||||
'Miami Heat': {'short': 'Heat', 'sport': 'Basketball'},
|
||||
'New Jersey Nets': {'short': 'Mets', 'sport': 'Basketball'},
|
||||
'New York Knicks': {'short': 'Knicks', 'sport': 'Basketball'},
|
||||
'Orlando Magic': {'short': 'Magic', 'sport': 'Basketball'},
|
||||
'Philadelphia 76ers': {'short': '76ers', 'sport': 'Basketball'},
|
||||
'Washington Wizards': {'short': 'Wizards', 'sport': 'Basketball'},
|
||||
'Atlanta Hawks': {'short': 'Hawks', 'sport': 'Basketball'},
|
||||
'Charlotte Hornets': {'short': 'Hornets', 'sport': 'Basketball'},
|
||||
'Chicago Bulls': {'short': 'Bulls', 'sport': 'Basketball'},
|
||||
'Cleveland Cavaliers': {'short': 'Cavaliers', 'sport': 'Basketball'},
|
||||
'Detroit Pistons': {'short': 'Pistons', 'sport': 'Basketball'},
|
||||
'Indiana Pacers': {'short': 'Pacers', 'sport': 'Basketball'},
|
||||
'Milwaukee Bucks': {'short': 'Bucks', 'sport': 'Basketball'},
|
||||
'Toronto Raptors': {'short': 'Raptors', 'sport': 'Basketball'},
|
||||
'Dallas Mavericks': {'short': 'Mavericks', 'sport': 'Basketball'},
|
||||
'Denver Nuggets': {'short': 'Nuggets', 'sport': 'Basketball'},
|
||||
'Houston Rockets': {'short': 'Rockets', 'sport': 'Basketball'},
|
||||
'Minnesota Timberwolves': {'short': 'Timberwolves', 'sport': 'Basketball'},
|
||||
'San Antonio Spurs': {'short': 'Spurs', 'sport': 'Basketball'},
|
||||
'Utah Jazz': {'short': 'Jazz', 'sport': 'Basketball'},
|
||||
'Vancouver Grizzlies': {'short': 'Grizzlies', 'sport': 'Basketball'},
|
||||
'Golden State Warriors': {'short': 'Warriors', 'sport': 'Basketball'},
|
||||
'Los Angeles Clippers': {'short': 'Clippers', 'sport': 'Basketball'},
|
||||
'Los Angeles Lakers': {'short': 'Lakers', 'sport': 'Basketball'},
|
||||
'Phoenix Suns': {'short': 'Suns', 'sport': 'Basketball'},
|
||||
'Portland Trail Blazers': {'short': 'Blazers', 'sport': 'Basketball'},
|
||||
'Sacramento Kings': {'short': 'Kings', 'sport': 'Basketball'},
|
||||
'Seattle SuperSonics': {'short': 'SuperSonics', 'sport': 'Basketball'},
|
||||
'Boston Bruins': {'short': 'Bruins', 'sport': 'Hockey'},
|
||||
'Buffalo Sabres': {'short': 'Sabres', 'sport': 'Hockey'},
|
||||
'Montreal Canadiens': {'short': 'Canadiens', 'sport': 'Hockey'},
|
||||
'Ottawa Senators': {'short': 'Senators', 'sport': 'Hockey'},
|
||||
'Toronto Maple Leafs': {'short': 'Maple Leafs', 'sport': 'Hockey'},
|
||||
'New Jersey Devils': {'short': 'Devils', 'sport': 'Hockey'},
|
||||
'New York Islander': {'short': 'Islander', 'sport': 'Hockey'},
|
||||
'New York Rangers': {'short': 'Rangers', 'sport': 'Hockey'},
|
||||
'Philadelphia Flyers': {'short': 'Flyers', 'sport': 'Hockey'},
|
||||
'Pittsburgh Penguins': {'short': 'Penguins', 'sport': 'Hockey'},
|
||||
'Atlanta Trashers': {'short': 'Trashers', 'sport': 'Hockey'},
|
||||
'Carolina Hurricanes': {'short': 'Hurricanes', 'sport': 'Hockey'},
|
||||
'Florida Panthers': {'short': 'Panthers', 'sport': 'Hockey'},
|
||||
'Tampa Bay Lightnings': {'short': 'Lightnings', 'sport': 'Hockey'},
|
||||
'Washington Capitals': {'short': 'Capitals', 'sport': 'Hockey'},
|
||||
'Chicago Blackhawks': {'short': 'Blackhawks', 'sport': 'Hockey'},
|
||||
'Columbo Blue Jackets': {'short': 'Blue Jackets', 'sport': 'Hockey'},
|
||||
'Detroit Red Wings': {'short': 'Red Wings', 'sport': 'Hockey'},
|
||||
'Nashville Predators': {'short': 'Predators', 'sport': 'Hockey'},
|
||||
'St.Louis Blues': {'short': 'Blues', 'sport': 'Hockey'},
|
||||
'Calgary Flames': {'short': 'Flames', 'sport': 'Hockey'},
|
||||
'Colorado Avalanche': {'short': 'Avalanche', 'sport': 'Hockey'},
|
||||
'Edmonton Oilers': {'short': 'Oilers', 'sport': 'Hockey'},
|
||||
'Minnesota Wild': {'short': 'Wild', 'sport': 'Hockey'},
|
||||
'Vancouver Canucks': {'short': 'Canucks', 'sport': 'Hockey'},
|
||||
'Anaheim Mighty Ducks': {'short': 'Mighty Ducks', 'sport': 'Hockey'},
|
||||
'Dallas Stars': {'short': 'Stars', 'sport': 'Hockey'},
|
||||
'Los Angeles Kings': {'short': 'Kings', 'sport': 'Hockey'},
|
||||
'Phoenix Coyotes': {'short': 'Coyotes', 'sport': 'Hockey'},
|
||||
'San Jose Sharks': {'short': 'Sharks', 'sport': 'Hockey'},
|
||||
'Houston Texans': {'short': 'Texans', 'sport': 'Football'},
|
||||
'Houston Oilers': {'short': 'Oilers', 'sport': 'Football'}
|
||||
}
|
||||
for key in teams:
|
||||
sport = Sport.objects.get({'name': teams.get(key)['sport']})
|
||||
team = Team()
|
||||
team.name = key
|
||||
team.shortname = teams.get(key)['short']
|
||||
team.sport = sport
|
||||
team.save()
|
||||
|
||||
|
||||
def initialize_players():
|
||||
"""
|
||||
Initialize collection Manufacturer with data.
|
||||
"""
|
||||
for player in Player.objects.all():
|
||||
player.delete()
|
||||
players = ['Pathon, Jerome', 'Bruschi, Tedy', 'Couch, Tim', 'Shea, Aaron',
|
||||
'Lewis, Jamal', 'Lewis, Jermaine', 'Banks, Tony', 'Fuamatu-Ma\'Afala, Chris',
|
||||
'Bettis, Jerome', 'Stewart, Kordell', 'Moon, Warren', 'Lockett, Kevin',
|
||||
'Gannon, Rich', 'Jett, James', 'Strong, Mack', 'Huard, Brock',
|
||||
'Watters, Ricky', 'Aikman, Troy', 'LaFleur, David', 'Brazzell, Chris',
|
||||
'Dayne, Ron', 'Brown, Na', 'Small, Torrance', 'Lewis, Chad', 'Murrell, Adrian',
|
||||
'Smith, Maurice', 'Chandler, Chris', 'Kanell, Danny', 'Williams, Ricky',
|
||||
'Garcia, Jeff', 'Streets, Tai', 'Garner, Charlie', 'Rice, Jerry',
|
||||
'Owens, Terrell', 'Bruce, Isaac', 'Canidate, Trung']
|
||||
for player_name in players:
|
||||
player = Player()
|
||||
(last_name, first_name) = player_name.split(',')
|
||||
player.last_name = last_name.strip()
|
||||
player.first_name = first_name.strip()
|
||||
player.save()
|
||||
|
||||
|
||||
def initialize_manufacturers():
|
||||
"""
|
||||
Initialize collection Manufacturer with data.
|
||||
"""
|
||||
for manufacturer in Manufacturer.objects.all():
|
||||
manufacturer.delete()
|
||||
manufacturers = ['Pacific', 'Fleer', 'Bowman', 'Topps', 'Donruss',
|
||||
'Score', 'Flair', 'Upper Deck']
|
||||
for manufacturer_name in manufacturers:
|
||||
manufacturer = Manufacturer()
|
||||
manufacturer.name = manufacturer_name
|
||||
manufacturer.save()
|
||||
|
||||
|
||||
def initialize_card_sets():
|
||||
"""
|
||||
Initialize collection CardSet with data.
|
||||
"""
|
||||
for card_set in CardSet.objects.all():
|
||||
card_set.delete()
|
||||
card_sets = {'Pacific': 'Pacific',
|
||||
'Fleer': 'Fleer',
|
||||
'Bowman': 'Bowman',
|
||||
'Leaf': 'Topps',
|
||||
'Ultra': 'Fleer',
|
||||
'Mystique': 'Fleer',
|
||||
'Finest Hour': 'Pacific',
|
||||
'SP': 'Upper Deck',
|
||||
'SPx': 'Upper Deck',
|
||||
'SP Authentic': 'Upper Deck',
|
||||
'Black Diamond': 'Upper Deck'
|
||||
}
|
||||
for set_name in card_sets:
|
||||
card_set = CardSet()
|
||||
card_set.name = set_name
|
||||
card_set.manufacturer = Manufacturer.objects.get({'name': card_sets.get(set_name)})
|
||||
card_set.save()
|
||||
|
||||
|
||||
def initialize_parallel_sets():
|
||||
"""
|
||||
Initialize collection ParallelSet with data.
|
||||
"""
|
||||
for parallel_set in ParallelSet.objects.all():
|
||||
parallel_set.delete()
|
||||
parallel_sets = {'Mystique Gold': 'Fleer',
|
||||
'Pacific Copper': 'Pacific',
|
||||
'Pacific Gold': 'Pacific'
|
||||
}
|
||||
for key in parallel_sets:
|
||||
manufacturer = Manufacturer.objects.get({'name': parallel_sets.get(key)})
|
||||
parallel_set = ParallelSet()
|
||||
parallel_set.name = key
|
||||
parallel_set.manufacturer = manufacturer
|
||||
parallel_set.save()
|
||||
|
||||
|
||||
def initialize_insert_sets():
|
||||
"""
|
||||
Initialize collection InsertSet with data.
|
||||
"""
|
||||
for insert_set in InsertSet.objects.all():
|
||||
insert_set.delete()
|
||||
manufacturer = Manufacturer.objects.get({'name': 'Fleer'})
|
||||
insert_set = InsertSet()
|
||||
insert_set.name = 'Mystique Big Buzz'
|
||||
insert_set.manufacturer = manufacturer
|
||||
insert_set.save()
|
||||
|
||||
|
||||
def initialize_cards():
|
||||
"""
|
||||
Initialize collection Card with data.
|
||||
"""
|
||||
for card in Card.objects.all():
|
||||
card.delete()
|
||||
players = ['Pathon, Jerome', 'Bruschi, Tedy', 'Couch, Tim', 'Shea, Aaron',
|
||||
'Lewis, Jamal', 'Lewis, Jermaine', 'Banks, Tony', 'Fuamatu-Ma\'Afala, Chris',
|
||||
'Bettis, Jerome', 'Stewart, Kordell', 'Moon, Warren', 'Lockett, Kevin',
|
||||
'Gannon, Rich', 'Jett, James', 'Strong, Mack', 'Huard, Brock',
|
||||
'Watters, Ricky', 'Aikman, Troy', 'LaFleur, David', 'Brazzell, Chris',
|
||||
'Dayne, Ron', 'Brown, Na', 'Small, Torrance', 'Lewis, Chad', 'Murrell, Adrian',
|
||||
'Smith, Maurice', 'Chandler, Chris', 'Kanell, Danny', 'Williams, Ricky',
|
||||
'Garcia, Jeff', 'Streets, Tai', 'Garner, Charlie', 'Rice, Jerry',
|
||||
'Owens, Terrell', 'Bruce, Isaac', 'Canidate, Trung']
|
||||
cards = [
|
||||
[0, 'Indianapolis Colts', 'Pacific', 'Pacific', None, None, False, 2001, 185],
|
||||
[1, 'Indianapolis Colts', 'Pacific', 'Pacific', None, None, False, 2001, 250],
|
||||
[2, 'Cleveland Browns', 'Pacific', 'Pacific', None, None, False, 2001, 103],
|
||||
[3, 'Cleveland Browns', 'Pacific', 'Pacific', None, None, False, 2001, 112],
|
||||
[4, 'Baltimore Ravens', 'Pacific', 'Pacific', None, None, False, 2001, 37],
|
||||
[5, 'Baltimore Ravens', 'Pacific', 'Pacific', None, None, False, 2001, 38],
|
||||
[6, 'Baltimore Ravens', 'Pacific', 'Pacific', None, None, False, 2001, 31],
|
||||
[7, 'Pittsburgh Steelers', 'Pacific', 'Pacific', None, None, False, 2001, 338],
|
||||
[8, 'Pittsburgh Steelers', 'Pacific', 'Pacific', None, None, False, 2001, 335],
|
||||
[9, 'Pittsburgh Steelers', 'Pacific', 'Pacific', None, None, False, 2001, 345],
|
||||
[10, 'Kansas City Chiefs', 'Pacific', 'Pacific', None, None, False, 2001, 213],
|
||||
[11, 'Kansas City Chiefs', 'Pacific', 'Pacific', None, None, False, 2001, 212],
|
||||
[12, 'Oakland Raiders', 'Pacific', 'Pacific', None, None, False, 2001, 311],
|
||||
[13, 'Oakland Raiders', 'Pacific', 'Pacific', None, None, False, 2001, 312],
|
||||
[14, 'Seattle Seahawks', 'Pacific', 'Pacific', None, None, False, 2001, 403],
|
||||
[15, 'Seattle Seahawks', 'Pacific', 'Pacific', None, None, False, 2001, 397],
|
||||
[16, 'Seattle Seahawks', 'Pacific', 'Pacific', None, None, False, 2001, 404],
|
||||
[17, 'Dallas Cowboys', 'Pacific', 'Pacific', None, None, False, 2001, 116],
|
||||
[18, 'Dallas Cowboys', 'Pacific', 'Pacific', None, None, False, 2001, 122],
|
||||
[19, 'Dallas Cowboys', 'Pacific', 'Pacific', None, None, False, 2001, 117],
|
||||
[20, 'New York Giants', 'Pacific', 'Pacific', None, None, False, 2001, 281],
|
||||
[21, 'New York Giants', 'Pacific', 'Pacific', None, None, False, 2001, 321],
|
||||
[22, 'Philadelphia Eagles', 'Pacific', 'Pacific', None, None, False, 2001, 331],
|
||||
[23, 'Philadelphia Eagles', 'Pacific', 'Pacific', None, None, False, 2001, 324],
|
||||
[24, 'Washington Redskins', 'Pacific', 'Pacific', None, None, False, 2001, 445],
|
||||
[25, 'Atlanta Falcons', 'Pacific', 'Pacific', None, None, False, 2001, 28],
|
||||
[26, 'Atlanta Falcons', 'Pacific', 'Pacific', None, None, False, 2001, 17],
|
||||
[27, 'Atlanta Falcons', 'Pacific', 'Pacific', None, None, False, 2001, 23],
|
||||
[28, 'New Orleans Saints', 'Pacific', 'Pacific', None, None, False, 2001, 273],
|
||||
[29, 'San Francisco 49ers', 'Pacific', 'Pacific', None, None, False, 2001, 380],
|
||||
[30, 'San Francisco 49ers', 'Pacific', 'Pacific', None, None, False, 2001, 390],
|
||||
[31, 'San Francisco 49ers', 'Pacific', 'Pacific', None, None, False, 2001, 381],
|
||||
[32, 'San Francisco 49ers', 'Pacific', 'Pacific', None, None, False, 2001, 387],
|
||||
[33, 'San Francisco 49ers', 'Pacific', 'Pacific', None, None, False, 2001, 386],
|
||||
[34, 'St.Louis Rams', 'Pacific', 'Pacific', None, None, False, 2001, 349],
|
||||
[35, 'St.Louis Rams', 'Pacific', 'Pacific', None, None, False, 2001, 350],
|
||||
]
|
||||
for card_data in cards:
|
||||
card = Card()
|
||||
player_name = players[card_data[0]]
|
||||
(last_name, first_name) = player_name.split(',')
|
||||
card.player = Player.objects.get(
|
||||
{'last_name': last_name.strip(), 'first_name': first_name.strip()}
|
||||
)
|
||||
card.team = Team.objects.get({'name': card_data[1]})
|
||||
card.manufacturer = Manufacturer.objects.get({'name': card_data[2]})
|
||||
card.card_set = CardSet.objects.get({'name': card_data[3]})
|
||||
card.parallel_set = card_data[4]
|
||||
card.insert_set = card_data[5]
|
||||
card.rookie = card_data[6]
|
||||
card.year = card_data[7]
|
||||
card.number = card_data[8]
|
||||
card.save()
|
||||
@@ -0,0 +1,76 @@
|
||||
"""
|
||||
Define form to edit sport, teams, player, manufacturers and card types
|
||||
"""
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, SubmitField, SelectField, IntegerField, BooleanField
|
||||
from wtforms.validators import DataRequired, Optional, NumberRange
|
||||
from bson import ObjectId
|
||||
|
||||
|
||||
class SportForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a Sport
|
||||
"""
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class TeamForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a team
|
||||
"""
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
shortname = StringField('Shortname', validators=[DataRequired()])
|
||||
sport = SelectField('Sport', coerce=ObjectId)
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class PlayerForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a player.
|
||||
"""
|
||||
first_name = StringField('First name', validators=[DataRequired()])
|
||||
last_name = StringField('Last name', validators=[DataRequired()])
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class PositionForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit field positions for sports
|
||||
"""
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
description = StringField('Description', validators=[DataRequired()])
|
||||
sport = SelectField('Sport', coerce=ObjectId)
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class ManufacturerForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a card manufacturer.
|
||||
"""
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class CardSetForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a regular card set
|
||||
"""
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
manufacturer = SelectField('Manufacturer', coerce=ObjectId)
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
class CardForm(FlaskForm):
|
||||
"""
|
||||
Form to add and edit a trading card
|
||||
"""
|
||||
player = SelectField('Player', coerce=ObjectId)
|
||||
team = SelectField('Team', coerce=ObjectId)
|
||||
manufacturer = SelectField('Manufacturer', coerce=ObjectId)
|
||||
card_set = SelectField('Card Set', coerce=ObjectId)
|
||||
parallel_set = SelectField('Parallel Set', coerce=ObjectId, validators=[Optional()])
|
||||
insert_set = SelectField('Inserts', coerce=ObjectId, validators=[Optional()])
|
||||
rookie = BooleanField('Rookie', validators=[DataRequired()])
|
||||
year = IntegerField('Year', validators=[NumberRange(min=1956, max=2020)])
|
||||
number = IntegerField('Number', validators=[DataRequired()])
|
||||
@@ -0,0 +1,155 @@
|
||||
"""This modules declares the model for TradingCards related information."""
|
||||
from pymongo.write_concern import WriteConcern
|
||||
from pymodm import MongoModel, fields
|
||||
|
||||
|
||||
class Sport(MongoModel):
|
||||
"""Class Sport represents a sport."""
|
||||
name = fields.CharField()
|
||||
|
||||
def __str__(self):
|
||||
"""Returns printable version of Sport object."""
|
||||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
"""Returns printable version of Sport object."""
|
||||
return "Sport({})".format(self.name)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class Position(MongoModel):
|
||||
"""Class Position represents the position of a player for a sport."""
|
||||
name = fields.CharField(max_length=4)
|
||||
description = fields.CharField(max_length=30)
|
||||
sport = fields.ReferenceField(Sport)
|
||||
|
||||
def __str__(self):
|
||||
"""Returns printable version of Position object."""
|
||||
return "{0}({1})".format(self.name, self.description)
|
||||
|
||||
def __repr__(self):
|
||||
"""Returns printable version of Position object."""
|
||||
return "Position({0}, {1})".format(self.name, self.description)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class Team(MongoModel):
|
||||
"""Class Team represents a team for a sport."""
|
||||
name = fields.CharField(max_length=60)
|
||||
shortname = fields.CharField(max_length=30)
|
||||
sport = fields.ReferenceField(Sport, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
"""Returns printable version of Team object."""
|
||||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
"""Returns printable version of Team object."""
|
||||
return "Team({0}{1})".format(self.name, self.shortname)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class Player(MongoModel):
|
||||
"""
|
||||
Class Player represents a player.
|
||||
"""
|
||||
first_name = fields.CharField(max_length=60)
|
||||
last_name = fields.CharField(max_length=60)
|
||||
|
||||
def __str__(self):
|
||||
"""Returns printable version of Team object."""
|
||||
return "{0} {1}".format(self.first_name, self.last_name)
|
||||
|
||||
def __repr__(self):
|
||||
"""Returns printable version of Team object."""
|
||||
return "Player({0} {1})".format(self.first_name, self.last_name)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class Manufacturer(MongoModel):
|
||||
"""
|
||||
Class Manufacturer represents a manufacturer of trading cards.
|
||||
"""
|
||||
name = fields.CharField()
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class CardSet(MongoModel):
|
||||
"""
|
||||
Class CardSet represents the regular card set.
|
||||
"""
|
||||
name = fields.CharField()
|
||||
manufacturer = fields.ReferenceField(Manufacturer)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class ParallelSet(MongoModel):
|
||||
"""
|
||||
Class CardSet represents the parallel card set.
|
||||
"""
|
||||
name = fields.CharField()
|
||||
manufacturer = fields.ReferenceField(Manufacturer)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class InsertSet(MongoModel):
|
||||
"""
|
||||
Class CardSet represents the inserts card set.
|
||||
"""
|
||||
name = fields.CharField()
|
||||
manufacturer = fields.ReferenceField(Manufacturer)
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
|
||||
|
||||
class Card(MongoModel):
|
||||
"""
|
||||
Class CardSet represents the regular card set.
|
||||
"""
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
# Nine is reasonable in this case.
|
||||
player = fields.ReferenceField(Player)
|
||||
team = fields.ReferenceField(Team)
|
||||
manufacturer = fields.ReferenceField(Manufacturer)
|
||||
card_set = fields.ReferenceField(CardSet, blank=True)
|
||||
parallel_set = fields.ReferenceField(ParallelSet, blank=True)
|
||||
insert_set = fields.ReferenceField(InsertSet, blank=True)
|
||||
rookie = fields.BooleanField(default=False)
|
||||
year = fields.IntegerField(min_value=1956, max_value=2020)
|
||||
number = fields.IntegerField()
|
||||
|
||||
class Meta:
|
||||
"""Sets the connection and connections details."""
|
||||
connection_alias = 'kontor'
|
||||
write_concern = WriteConcern(j=True)
|
||||
@@ -0,0 +1,405 @@
|
||||
"""
|
||||
Define BLueprint and Views for TradeYourSportsCards
|
||||
"""
|
||||
from flask import Blueprint, url_for, render_template, redirect, flash
|
||||
from flask_login import login_required
|
||||
from bson import ObjectId
|
||||
from pymongo.errors import PyMongoError
|
||||
from .forms import SportForm, TeamForm, PlayerForm, PositionForm
|
||||
from .forms import ManufacturerForm
|
||||
from .models import Sport, Team, Player, Position
|
||||
from .models import Manufacturer, CardSet, ParallelSet, InsertSet, Card
|
||||
|
||||
|
||||
TYSC = Blueprint('tysc', __name__)
|
||||
|
||||
|
||||
@TYSC.route('/sport')
|
||||
@login_required
|
||||
def list_sports():
|
||||
"""
|
||||
List sports.
|
||||
:return:
|
||||
"""
|
||||
sports = Sport.objects.all()
|
||||
return render_template('tysc/sports.html', sports=sports, title="Sports")
|
||||
|
||||
|
||||
@TYSC.route('/sport/edit/<sport_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_sport(sport_id):
|
||||
"""
|
||||
Edit a sport
|
||||
"""
|
||||
sport = Sport.objects.get({'_id': ObjectId(sport_id)})
|
||||
form = SportForm(obj=sport)
|
||||
if form.validate_on_submit():
|
||||
sport.name = form.name.data
|
||||
sport.save()
|
||||
flash('You have successfully edited the sport.')
|
||||
return redirect(url_for('tysc.list_sports'))
|
||||
form.name.data = sport.name
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, sport=sport, title="Edit Sport")
|
||||
|
||||
|
||||
@TYSC.route('/sport/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_sport():
|
||||
"""
|
||||
Add a sport
|
||||
:return:
|
||||
"""
|
||||
form = SportForm()
|
||||
if form.validate_on_submit():
|
||||
sport = Sport()
|
||||
sport.name = form.name.data
|
||||
try:
|
||||
sport.save()
|
||||
flash('You have successfully added a new sport.')
|
||||
except PyMongoError:
|
||||
flash('Error: sport name already exists.')
|
||||
return redirect(url_for('tysc.list_sports'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Sport")
|
||||
|
||||
|
||||
@TYSC.route('/sport/delete/<sport_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_sport(sport_id):
|
||||
"""
|
||||
Delete a sport
|
||||
:param sport_id:
|
||||
:return:
|
||||
"""
|
||||
sport = Sport.objects.raw({'_id': ObjectId(sport_id)})
|
||||
if sport:
|
||||
sport.delete()
|
||||
flash('You have successfully deleted the sport.')
|
||||
return redirect(url_for('tysc.list_sports'))
|
||||
|
||||
|
||||
@TYSC.route('/team')
|
||||
@login_required
|
||||
def list_teams():
|
||||
"""
|
||||
List teams.
|
||||
:return:
|
||||
"""
|
||||
teams = Team.objects.all()
|
||||
return render_template('tysc/teams.html', teams=teams, title="Teams")
|
||||
|
||||
|
||||
@TYSC.route('/team/edit/<team_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_team(team_id):
|
||||
"""
|
||||
Edit a team
|
||||
"""
|
||||
team = Team.objects.get({'_id': ObjectId(team_id)})
|
||||
form = TeamForm(obj=team)
|
||||
form.sport.choices = [(s.pk, s.name) for s in Sport.objects.all()]
|
||||
if team.sport:
|
||||
form.sport.default = team.sport.pk
|
||||
form.sport.process_data(team.sport.pk)
|
||||
if form.validate_on_submit():
|
||||
team.name = form.name.data
|
||||
team.shortname = form.shortname.data
|
||||
team.sport = form.sport.data
|
||||
team.save()
|
||||
flash('You have successfully edited the team.')
|
||||
return redirect(url_for('tysc.list_teams'))
|
||||
form.name.data = team.name
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, team=team, title="Edit Team")
|
||||
|
||||
|
||||
@TYSC.route('/team/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_team():
|
||||
"""
|
||||
Add a team
|
||||
:return:
|
||||
"""
|
||||
form = TeamForm()
|
||||
form.sport.choices = [(s.pk, s.name) for s in Sport.objects.all()]
|
||||
if form.validate_on_submit():
|
||||
team = Team()
|
||||
team.name = form.name.data
|
||||
team.shortname = form.shortname.data
|
||||
team.sport = form.sport.data
|
||||
try:
|
||||
team.save()
|
||||
flash('You have successfully added a new team.')
|
||||
except PyMongoError:
|
||||
flash('Error: team name already exists.')
|
||||
return redirect(url_for('tysc.list_teams'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Team")
|
||||
|
||||
|
||||
@TYSC.route('/team/delete/<team_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_team(team_id):
|
||||
"""
|
||||
Delete a team
|
||||
:param team_id:
|
||||
:return:
|
||||
"""
|
||||
team = Team.objects.raw({'_id': ObjectId(team_id)})
|
||||
if team:
|
||||
team.delete()
|
||||
return redirect(url_for('tysc.list_teams'))
|
||||
|
||||
|
||||
@TYSC.route('/position')
|
||||
@login_required
|
||||
def list_positions():
|
||||
"""
|
||||
List positions.
|
||||
:return:
|
||||
"""
|
||||
positions = Position.objects.all()
|
||||
return render_template('tysc/positions.html', positions=positions, title="Positions")
|
||||
|
||||
|
||||
@TYSC.route('/position/edit/<position_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_position(position_id):
|
||||
"""
|
||||
Edit a position
|
||||
"""
|
||||
position = Position.objects.get({'_id': ObjectId(position_id)})
|
||||
form = PositionForm(obj=position)
|
||||
form.sport.choices = [(s.pk, s.name) for s in Sport.objects.all()]
|
||||
if position.sport:
|
||||
form.sport.default = position.sport.pk
|
||||
form.sport.process_data(position.sport.pk)
|
||||
if form.validate_on_submit():
|
||||
position.name = form.name.data
|
||||
position.description = form.description.data
|
||||
position.sport = form.sport.data
|
||||
position.save()
|
||||
flash('You have successfully edited the position.')
|
||||
return redirect(url_for('tysc.list_positions'))
|
||||
form.name.data = position.name
|
||||
form.description.data = position.description
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, position=position, title="Edit position")
|
||||
|
||||
|
||||
@TYSC.route('/position/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_position():
|
||||
"""
|
||||
Add a position
|
||||
:return:
|
||||
"""
|
||||
form = PositionForm()
|
||||
form.sport.choices = [(s.pk, s.name) for s in Sport.objects.all()]
|
||||
if form.validate_on_submit():
|
||||
position = Position()
|
||||
position.name = form.name.data
|
||||
position.description = form.description.data
|
||||
position.sport = form.sport.data
|
||||
try:
|
||||
position.save()
|
||||
flash('You have successfully added a new position.')
|
||||
except PyMongoError:
|
||||
flash('Error: team position already exists.')
|
||||
return redirect(url_for('tysc.list_positions'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Position")
|
||||
|
||||
|
||||
@TYSC.route('/position/delete/<position_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_position(position_id):
|
||||
"""
|
||||
Delete a position
|
||||
:param position_id:
|
||||
:return:
|
||||
"""
|
||||
position = Position.objects.raw({'_id': ObjectId(position_id)})
|
||||
if position:
|
||||
position.delete()
|
||||
return redirect(url_for('tysc.list_positions'))
|
||||
|
||||
|
||||
@TYSC.route('/player')
|
||||
@login_required
|
||||
def list_players():
|
||||
"""
|
||||
List players.
|
||||
:return:
|
||||
"""
|
||||
players = Player.objects.all()
|
||||
return render_template('tysc/players.html', players=players, title="Players")
|
||||
|
||||
|
||||
@TYSC.route('/player/edit/<player_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_player(player_id):
|
||||
"""
|
||||
Edit a player
|
||||
"""
|
||||
player = Player.objects.get({'_id': ObjectId(player_id)})
|
||||
form = PlayerForm(obj=player)
|
||||
if form.validate_on_submit():
|
||||
player.first_name = form.first_name.data
|
||||
player.last_name = form.last_name.data
|
||||
player.save()
|
||||
flash('You have successfully edited the player.')
|
||||
return redirect(url_for('tysc.list_players'))
|
||||
form.first_name.data = player.first_name
|
||||
form.last_name.data = player.last_name
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, player=player, title="Edit player")
|
||||
|
||||
|
||||
@TYSC.route('/player/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_player():
|
||||
"""
|
||||
Add a player
|
||||
:return:
|
||||
"""
|
||||
form = PlayerForm()
|
||||
if form.validate_on_submit():
|
||||
player = Player()
|
||||
player.first_name = form.first_name.data
|
||||
player.last_name = form.last_name.data
|
||||
try:
|
||||
player.save()
|
||||
flash('You have successfully added a new player.')
|
||||
except PyMongoError:
|
||||
flash('Error: player name already exists.')
|
||||
return redirect(url_for('tysc.list_players'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add player")
|
||||
|
||||
|
||||
@TYSC.route('/player/delete/<player_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_player(player_id):
|
||||
"""
|
||||
Delete a player
|
||||
:param player_id:
|
||||
:return:
|
||||
"""
|
||||
player = Player.objects.raw({'_id': ObjectId(player_id)})
|
||||
if player:
|
||||
player.delete()
|
||||
return redirect(url_for('tysc.list_players'))
|
||||
|
||||
|
||||
@TYSC.route('/manufacturer')
|
||||
@login_required
|
||||
def list_manufacturers():
|
||||
"""
|
||||
List manufacturers.
|
||||
:return:
|
||||
"""
|
||||
manufacturers = Manufacturer.objects.all()
|
||||
return render_template('tysc/manufacturers.html',
|
||||
manufacturers=manufacturers,
|
||||
title="Manufacturers")
|
||||
|
||||
|
||||
@TYSC.route('/manufacturer/edit/<manufacturer_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_manufacturer(manufacturer_id):
|
||||
"""
|
||||
Edit a manufacturer
|
||||
"""
|
||||
manufacturer = Manufacturer.objects.get({'_id': ObjectId(manufacturer_id)})
|
||||
form = ManufacturerForm(obj=manufacturer)
|
||||
if form.validate_on_submit():
|
||||
manufacturer.name = form.name.data
|
||||
manufacturer.save()
|
||||
flash('You have successfully edited the manufacturer.')
|
||||
return redirect(url_for('tysc.list_manufacturers'))
|
||||
form.name.data = manufacturer.name
|
||||
return render_template('simpleform.html', action="Edit",
|
||||
form=form, manufacturer=manufacturer, title="Edit Manufacturer")
|
||||
|
||||
|
||||
@TYSC.route('/manufacturer/add', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_manufacturer():
|
||||
"""
|
||||
Add a manufacturer
|
||||
:return:
|
||||
"""
|
||||
form = ManufacturerForm()
|
||||
if form.validate_on_submit():
|
||||
manufacturer = Manufacturer()
|
||||
manufacturer.name = form.name.data
|
||||
try:
|
||||
manufacturer.save()
|
||||
flash('You have successfully added a new manufacturer.')
|
||||
except PyMongoError:
|
||||
flash('Error: manufacturer name already exists.')
|
||||
return redirect(url_for('tysc.list_manufacturers'))
|
||||
return render_template('simpleform.html', action="Add",
|
||||
form=form, title="Add Manufacturer")
|
||||
|
||||
|
||||
@TYSC.route('/manufacturer/delete/<manufacturer_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_manufacturer(manufacturer_id):
|
||||
"""
|
||||
Delete a manufacturer
|
||||
:param manufacturer_id:
|
||||
:return:
|
||||
"""
|
||||
manufacturer = Manufacturer.objects.raw({'_id': ObjectId(manufacturer_id)})
|
||||
if manufacturer:
|
||||
manufacturer.delete()
|
||||
flash('You have successfully deleted the manufacturer.')
|
||||
return redirect(url_for('tysc.list_manufacturers'))
|
||||
|
||||
|
||||
@TYSC.route('/cardsets')
|
||||
@login_required
|
||||
def list_card_sets():
|
||||
"""
|
||||
List card sets.
|
||||
:return:
|
||||
"""
|
||||
card_sets = CardSet.objects.all()
|
||||
return render_template('tysc/cardsets.html', card_sets=card_sets, title="Card Sets")
|
||||
|
||||
|
||||
@TYSC.route('/parallelsets')
|
||||
@login_required
|
||||
def list_parallel_sets():
|
||||
"""
|
||||
List card sets.
|
||||
:return:
|
||||
"""
|
||||
parallel_sets = ParallelSet.objects.all()
|
||||
return render_template('tysc/parallelsets.html',
|
||||
parallel_sets=parallel_sets, title="Parallel Sets")
|
||||
|
||||
|
||||
@TYSC.route('/insertsets')
|
||||
@login_required
|
||||
def list_insert_sets():
|
||||
"""
|
||||
List card sets.
|
||||
:return:
|
||||
"""
|
||||
insert_sets = InsertSet.objects.all()
|
||||
return render_template('tysc/insertsets.html', insert_sets=insert_sets, title="Inserts")
|
||||
|
||||
|
||||
@TYSC.route('/cards')
|
||||
@login_required
|
||||
def list_cards():
|
||||
"""
|
||||
List card sets.
|
||||
:return:
|
||||
"""
|
||||
cards = Card.objects.all()
|
||||
return render_template('tysc/cards.html', cards=cards, title="Cards")
|
||||
@@ -0,0 +1,2 @@
|
||||
"""This module declares the version of the Kontor application."""
|
||||
__version__ = '0.0.7'
|
||||
Reference in New Issue
Block a user