| @@ -56,9 +56,9 @@ def create_app(): | |||
| from .tool import tool as tool_blueprint | |||
| app.register_blueprint(tool_blueprint) | |||
| # blueprint for example parts of app | |||
| from .example import example as example_blueprint | |||
| app.register_blueprint(example_blueprint) | |||
| # blueprint for book parts of app | |||
| from .book import book as book_blueprint | |||
| app.register_blueprint(book_blueprint) | |||
| # blueprint for practice parts of app | |||
| from .practice import practice as practice_blueprint | |||
| @@ -0,0 +1,67 @@ | |||
| # @name: book.py | |||
| # @version: 0.1 | |||
| # @creation_date: 2021-11-03 | |||
| # @license: The MIT License <https://opensource.org/licenses/MIT> | |||
| # @author: Simon Bowie <ad7588@coventry.ac.uk> | |||
| # @purpose: book route for book-related functions and pages | |||
| # @acknowledgements: | |||
| # https://www.digitalocean.com/community/tutorials/how-to-make-a-web-application-using-flask-in-python-3 | |||
| from flask import Blueprint, render_template, request, flash, redirect, url_for | |||
| from flask_login import login_required, current_user | |||
| from .models import Book | |||
| from werkzeug.exceptions import abort | |||
| from . import db | |||
| book = Blueprint('book', __name__) | |||
| # function to retrieve data about a single book from the database | |||
| def get_book(book_id): | |||
| book = Book.query.filter_by(id=book_id).first() | |||
| if book is None: | |||
| abort(404) | |||
| return book | |||
| # route for displaying all books in database | |||
| @book.route('/books') | |||
| def get_books(): | |||
| books = Book.query | |||
| return render_template('books.html', books=books) | |||
| # route for displaying a single book based on the ID in the database | |||
| @book.route('/books/<int:book_id>') | |||
| def show_book(book_id): | |||
| book = get_book(book_id) | |||
| return render_template('book.html', book=book) | |||
| # route for editing a single book based on the ID in the database | |||
| @book.route('/books/<int:book_id>/edit', methods=('GET', 'POST')) | |||
| @login_required | |||
| def edit_book(book_id): | |||
| book = get_book(book_id) | |||
| if request.method == 'POST': | |||
| name = request.form['name'] | |||
| description = request.form['description'] | |||
| if not name: | |||
| flash('Name is required!') | |||
| else: | |||
| book = Book.query.get(book_id) | |||
| book.name = name | |||
| book.description = description | |||
| db.session.commit() | |||
| return redirect(url_for('book.get_books')) | |||
| return render_template('edit.html', book=book) | |||
| # route for function to delete a single book from the edit page | |||
| @book.route('/books/<int:book_id>/delete', methods=('POST',)) | |||
| @login_required | |||
| def delete_book(book_id): | |||
| book = get_book(book_id) | |||
| deletion = Book.query.get(book_id) | |||
| db.session.delete(deletion) | |||
| db.session.commit() | |||
| flash('Successfully deleted!') | |||
| return redirect(url_for('book.get_books')) | |||
| @@ -10,7 +10,7 @@ | |||
| from flask import Blueprint, render_template, request, flash, redirect, url_for | |||
| from flask_login import login_required, current_user | |||
| from .models import Tool | |||
| from .models import Example | |||
| from .models import Book | |||
| from .models import Practice | |||
| from werkzeug.exceptions import abort | |||
| from . import db | |||
| @@ -51,24 +51,24 @@ def create_resource(): | |||
| db.session.add(new_tool) | |||
| db.session.commit() | |||
| elif request.form.get('resource_type') == 'example': | |||
| elif request.form.get('resource_type') == 'book': | |||
| name = request.form.get('name') | |||
| description = request.form.get('description') | |||
| if not name: | |||
| flash('Name is required!') | |||
| else: | |||
| example = Example.query.filter_by(name=name).first() # if this returns an example, then the name already exists in database | |||
| example = Book.query.filter_by(name=name).first() # if this returns a book, then the name already exists in database | |||
| if example: # if an example is found, we want to redirect back to create page | |||
| flash('Example with same name already exists') | |||
| if example: # if a book is found, we want to redirect back to create page | |||
| flash('Book with same name already exists') | |||
| return redirect(url_for('create.create')) | |||
| # create a new example with the form data | |||
| new_example = Example(name=name, description=description) | |||
| # create a new book with the form data | |||
| new_book = Book(name=name, description=description) | |||
| # add the new example to the database | |||
| db.session.add(new_example) | |||
| # add the new book to the database | |||
| db.session.add(new_book) | |||
| db.session.commit() | |||
| elif request.form.get('resource_type') == 'practice': | |||
| @@ -1,67 +0,0 @@ | |||
| # @name: example.py | |||
| # @version: 0.1 | |||
| # @creation_date: 2021-11-03 | |||
| # @license: The MIT License <https://opensource.org/licenses/MIT> | |||
| # @author: Simon Bowie <ad7588@coventry.ac.uk> | |||
| # @purpose: example route for example-related functions and pages | |||
| # @acknowledgements: | |||
| # https://www.digitalocean.com/community/tutorials/how-to-make-a-web-application-using-flask-in-python-3 | |||
| from flask import Blueprint, render_template, request, flash, redirect, url_for | |||
| from flask_login import login_required, current_user | |||
| from .models import Example | |||
| from werkzeug.exceptions import abort | |||
| from . import db | |||
| example = Blueprint('example', __name__) | |||
| # function to retrieve data about a single example from the database | |||
| def get_example(example_id): | |||
| example = Example.query.filter_by(id=example_id).first() | |||
| if example is None: | |||
| abort(404) | |||
| return example | |||
| # route for displaying all examples in database | |||
| @example.route('/examples') | |||
| def get_examples(): | |||
| examples = Example.query | |||
| return render_template('examples.html', examples=examples) | |||
| # route for displaying a single example based on the ID in the database | |||
| @example.route('/examples/<int:example_id>') | |||
| def show_example(example_id): | |||
| example = get_example(example_id) | |||
| return render_template('example.html', example=example) | |||
| # route for editing a single example based on the ID in the database | |||
| @example.route('/examples/<int:example_id>/edit', methods=('GET', 'POST')) | |||
| @login_required | |||
| def edit_example(example_id): | |||
| example = get_example(example_id) | |||
| if request.method == 'POST': | |||
| name = request.form['name'] | |||
| description = request.form['description'] | |||
| if not name: | |||
| flash('Name is required!') | |||
| else: | |||
| example = Example.query.get(example_id) | |||
| example.name = name | |||
| example.description = description | |||
| db.session.commit() | |||
| return redirect(url_for('example.get_examples')) | |||
| return render_template('edit.html', example=example) | |||
| # route for function to delete a single example from the edit page | |||
| @example.route('/examples/<int:example_id>/delete', methods=('POST',)) | |||
| @login_required | |||
| def delete_example(example_id): | |||
| example = get_example(example_id) | |||
| deletion = Example.query.get(example_id) | |||
| db.session.delete(deletion) | |||
| db.session.commit() | |||
| flash('Successfully deleted!') | |||
| return redirect(url_for('example.get_examples')) | |||
| @@ -34,8 +34,8 @@ class Tool(db.Model): | |||
| saas = db.Column(db.Text) | |||
| dependencies = db.Column(db.Text) | |||
| # table for examples | |||
| class Example(db.Model): | |||
| # table for books | |||
| class Book(db.Model): | |||
| id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy | |||
| created = db.Column(db.DateTime, default=datetime.utcnow) | |||
| name = db.Column(db.Text) | |||
| @@ -40,7 +40,7 @@ | |||
| <div class="collapse navbar-collapse" id="navbarSupportedContent"> | |||
| <ul class="navbar-nav"> | |||
| <li class="nav-item"> | |||
| <a href="{{ url_for('example.get_examples') }}" class="nav-link"> | |||
| <a href="{{ url_for('book.get_books') }}" class="nav-link"> | |||
| Books | |||
| </a> | |||
| </li> | |||
| @@ -3,7 +3,7 @@ | |||
| {% block content %} | |||
| <div class="row"> | |||
| <div class="col-12 text-center"> | |||
| <h1>{% block title %} Examples {% endblock %}</h1> | |||
| <h1>{% block title %} Books {% endblock %}</h1> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| @@ -18,8 +18,8 @@ | |||
| <div class="col-md-4 col-sm-6 py-3"> | |||
| <div class="card"> | |||
| <div class="card-header"> | |||
| <a href="{{ url_for('example.show_example', example_id=example['id']) }}"> | |||
| <h2 class="card-title">{{ example['name'] }}</h2> | |||
| <a href="{{ url_for('book.show_book', book_id=book['id']) }}"> | |||
| <h2 class="card-title">{{ book['name'] }}</h2> | |||
| </a> | |||
| </div> | |||
| <div class="card-body"> | |||
| @@ -28,7 +28,7 @@ | |||
| </p> | |||
| <span class="badge bg-secondary">{{ example['created'].strftime("%Y-%m-%d %H:%M") }} UTC</span> | |||
| {% if current_user.is_authenticated %} | |||
| <a href="{{ url_for('example.edit_example', example_id=example['id']) }}"> | |||
| <a href="{{ url_for('book.edit_book', book_id=book['id']) }}"> | |||
| <span class="badge bg-dark">Edit</span> | |||
| </a> | |||
| {% endif %} | |||