| @@ -21,20 +21,33 @@ book = Blueprint('book', __name__) | |||
| @book.route('/books') | |||
| def get_books(): | |||
| books = Resource.query.filter_by(type='book') | |||
| return render_template('resources.html', resources=books, type='book') | |||
| for key in request.args.keys(): | |||
| if key == 'practice': | |||
| query = 'SELECT Resource.* FROM Resource LEFT JOIN Relationship ON Resource.id=Relationship.first_resource_id WHERE Relationship.second_resource_id=' + request.args.get(key) + ' AND Resource.type="book";' | |||
| books = db.engine.execute(query) | |||
| else: | |||
| kwargs = {'type': 'book', key: request.args.get(key)} | |||
| tools = Resource.query.filter_by(**kwargs) | |||
| # get filters | |||
| # practices | |||
| practices_filter = Resource.query.filter_by(type='practice').with_entities(Resource.id, Resource.name) | |||
| return render_template('resources.html', resources=books, type='book', practices_filter=practices_filter) | |||
| # 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_resource(book_id) | |||
| links = get_relationships(book_id) | |||
| return render_template('resource.html', resource=book, links=links) | |||
| relationships = get_relationships(book_id) | |||
| book_data = get_book_data(book.isbn) | |||
| return render_template('book.html', resource=book, relationships=relationships, book=book_data) | |||
| # 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_resource(book_id) | |||
| resource_dropdown = Resource.query | |||
| existing_relationships = get_relationships(book_id) | |||
| if request.method == 'POST': | |||
| if not request.form['name']: | |||
| @@ -42,11 +55,17 @@ def edit_book(book_id): | |||
| else: | |||
| book = Resource.query.get(book_id) | |||
| book.name = request.form['name'] | |||
| book.description = request.form['description'] | |||
| book.isbn = request.form['isbn'] | |||
| db.session.commit() | |||
| linked_resources = request.form.getlist('linked_resources') | |||
| remove_linked_resources = request.form.getlist('remove_linked_resources') | |||
| edit_relationships(book_id, linked_resources, remove_linked_resources, existing_relationships) | |||
| return redirect(url_for('book.get_books',_external=True,_scheme=os.environ.get('SSL_SCHEME'))) | |||
| return render_template('edit.html', resource=book) | |||
| return render_template('edit.html', resource=book, resource_dropdown=resource_dropdown, relationships=existing_relationships) | |||
| # route for function to delete a single book from the edit page | |||
| @book.route('/books/<int:book_id>/delete', methods=('POST',)) | |||
| @@ -56,7 +56,7 @@ def edit_practice(practice_id): | |||
| return redirect(url_for('practice.get_practices',_external=True,_scheme=os.environ.get('SSL_SCHEME'))) | |||
| return render_template('edit.html', resource=practice, resource_dropdown=resource_dropdown, links=existing_relationships) | |||
| return render_template('edit.html', resource=practice, resource_dropdown=resource_dropdown, relationships=existing_relationships) | |||
| # route for function to delete a single practice from the edit page | |||
| @practice.route('/practices/<int:practice_id>/delete', methods=('POST',)) | |||
| @@ -9,6 +9,7 @@ from flask import Blueprint, render_template, request, flash, redirect, url_for | |||
| from .models import Resource | |||
| from werkzeug.exceptions import abort | |||
| from . import db | |||
| from isbntools.app import * | |||
| # function to retrieve data about a single resource from the database | |||
| def get_resource(resource_id): | |||
| @@ -38,4 +39,12 @@ def get_filter_values(field): | |||
| field_filter = filter(None, field_filter) | |||
| # sort list by alphabetical order | |||
| field_filter = sorted(field_filter) | |||
| return field_filter | |||
| return field_filter | |||
| def get_book_data(isbn): | |||
| try: | |||
| book = meta(isbn) | |||
| book.update(cover(isbn)) | |||
| return book | |||
| except: | |||
| pass | |||
| @@ -0,0 +1,164 @@ | |||
| {% extends 'base.html' %} | |||
| {% block content %} | |||
| {% if book['thumbnail'] %} | |||
| <img class="img-fluid mx-auto d-block" src={{ book['thumbnail'] }} alt="cover for {{ book['Title'] }}"> | |||
| {% else %} | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <h1 class="text-center">{% block title %} {{ book['Title'] or resource['name'] }} {% endblock %}</h1> | |||
| </div> | |||
| </div> | |||
| {% endif %} | |||
| {% if current_user.is_authenticated %} | |||
| <div class="row text-center py-3"> | |||
| <a href="{{ url_for('book.edit_book', book_id=resource['id']) }}"> | |||
| <span class="badge bg-dark">Edit</span> | |||
| </a> | |||
| </div> | |||
| {% endif %} | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <table class="table table-hover"> | |||
| <tbody> | |||
| {% if book %} | |||
| <!-- fields for books from isbntools --> | |||
| {% if book['Title'] %} | |||
| <tr> | |||
| <th> | |||
| Title: | |||
| </th> | |||
| <td> | |||
| {{ book['Title'] }} | |||
| </td> | |||
| </tr> | |||
| {% endif %} | |||
| {% if book['Authors'] %} | |||
| <tr> | |||
| {% if book['Authors']|length > 1 %} | |||
| <th> | |||
| Authors: | |||
| </th> | |||
| <td> | |||
| {% for author in book['Authors'] %} | |||
| {{ author }}, | |||
| {% endfor %} | |||
| </td> | |||
| {% else %} | |||
| <th> | |||
| Author: | |||
| </th> | |||
| <td> | |||
| {% for author in book['Authors'] %} | |||
| {{ author }} | |||
| {% endfor %} | |||
| </td> | |||
| {% endif %} | |||
| </tr> | |||
| {% endif %} | |||
| {% if book['ISBN-13'] %} | |||
| <tr> | |||
| <th> | |||
| ISBN-13: | |||
| </th> | |||
| <td> | |||
| {{ book['ISBN-13'] }} | |||
| </td> | |||
| </tr> | |||
| {% endif %} | |||
| {% if book['Year'] %} | |||
| <tr> | |||
| <th> | |||
| Publication year: | |||
| </th> | |||
| <td> | |||
| {{ book['Year'] }} | |||
| </td> | |||
| </tr> | |||
| {% endif %} | |||
| {% if book['Publisher'] %} | |||
| <tr> | |||
| <th> | |||
| Publisher: | |||
| </th> | |||
| <td> | |||
| {{ book['Publisher'] }} | |||
| </td> | |||
| </tr> | |||
| {% endif %} | |||
| {% else %} | |||
| <!-- fields for books from database --> | |||
| {% if resource['name'] %} | |||
| <tr> | |||
| <th> | |||
| Title: | |||
| </th> | |||
| <td> | |||
| {{ resource['name'] }} | |||
| </td> | |||
| </tr> | |||
| {% endif %} | |||
| {% if resource['author'] %} | |||
| <tr> | |||
| <th> | |||
| Author: | |||
| </th> | |||
| <td> | |||
| {{ resource['author'] }} | |||
| </td> | |||
| </tr> | |||
| {% endif %} | |||
| {% endif %} | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| {% if relationships %} | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <h2 class="text-center">Linked resources:</h2> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| {% for relationship in relationships %} | |||
| <div class="col-md-4 col-sm-6 py-3"> | |||
| {% if relationship['type'] == 'tool' %} | |||
| <div class="card text-dark bg-tool mb-3"> | |||
| <div class="card-body"> | |||
| <a href="{{ url_for('tool.show_tool', tool_id=relationship['id']) }}"> | |||
| <h3 class="card-title text-center text-dark">{{ relationship['name'] }}</h3> | |||
| </a> | |||
| <p class="card-text"> | |||
| {{ relationship['description']|truncate(100) }} | |||
| </p> | |||
| </div> | |||
| </div> | |||
| {% elif relationship['type'] == 'practice' %} | |||
| <div class="card text-dark bg-practice mb-3"> | |||
| <div class="card-body"> | |||
| <a href="{{ url_for('practice.show_practice', practice_id=relationship['id']) }}"> | |||
| <h3 class="card-title text-center text-dark">{{ relationship['name'] }}</h3> | |||
| </a> | |||
| <p class="card-text"> | |||
| {{ relationship['description']|truncate(100) }} | |||
| </p> | |||
| </div> | |||
| </div> | |||
| {% elif relationship['type'] == 'book' %} | |||
| <div class="card text-dark bg-book mb-3"> | |||
| <div class="card-body"> | |||
| <a href="{{ url_for('book.show_book', book_id=relationship['id']) }}"> | |||
| <h3 class="card-title text-center text-dark">{{ relationship['name'] }}</h3> | |||
| </a> | |||
| <p class="card-text"> | |||
| {{ relationship['description']|truncate(100) }} | |||
| </p> | |||
| </div> | |||
| </div> | |||
| {% endif %} | |||
| </div> | |||
| {% endfor %} | |||
| </div> | |||
| {% endif %} | |||
| {% endblock %} | |||
| @@ -111,7 +111,7 @@ | |||
| <select name="linked_resources" id="linked_resources" aria-label="Linked resources" class="selectpicker" data-live-search="true" multiple> | |||
| {% for resource_dropdown in resource_dropdown %} | |||
| {% if resource_dropdown['type'] != 'tool' %} | |||
| {% if links and resource_dropdown in links %} | |||
| {% if relationships and resource_dropdown in relationships %} | |||
| <option value="{{ resource_dropdown['id'] }}" selected>{{ resource_dropdown['name'] }}</option> | |||
| {% else %} | |||
| <option value="{{ resource_dropdown['id'] }}">{{ resource_dropdown['name'] }}</option> | |||
| @@ -144,7 +144,32 @@ | |||
| <select name="linked_resources" id="linked_resources" aria-label="Linked resources" class="selectpicker" data-live-search="true" multiple> | |||
| {% for resource_dropdown in resource_dropdown %} | |||
| {% if resource_dropdown['type'] != 'practice' %} | |||
| {% if links and resource_dropdown in links %} | |||
| {% if relationships and resource_dropdown in relationships %} | |||
| <option value="{{ resource_dropdown['id'] }}" selected>{{ resource_dropdown['name'] }}</option> | |||
| {% else %} | |||
| <option value="{{ resource_dropdown['id'] }}">{{ resource_dropdown['name'] }}</option> | |||
| {% endif %} | |||
| {% endif %} | |||
| {% endfor %} | |||
| </select> | |||
| </div> | |||
| {% elif resource['type'] == 'book' %} | |||
| <div class="mb-3 mt-3"> | |||
| <label for="isbn">ISBN</label> | |||
| <input type="text" name="isbn" placeholder="ISBN" | |||
| class="form-control" | |||
| value="{{ request.form['isbn'] or resource['isbn'] }}"> | |||
| </input> | |||
| </div> | |||
| <div class="mb-3 mt-3"> | |||
| <label for="linked_practice_id">Linked resources</label> | |||
| </div> | |||
| <div class="mb-3 mt-3"> | |||
| <select name="linked_resources" id="linked_resources" aria-label="Linked resources" class="selectpicker" data-live-search="true" multiple> | |||
| {% for resource_dropdown in resource_dropdown %} | |||
| {% if resource_dropdown['type'] != 'book' %} | |||
| {% if relationships and resource_dropdown in relationships %} | |||
| <option value="{{ resource_dropdown['id'] }}" selected>{{ resource_dropdown['name'] }}</option> | |||
| {% else %} | |||
| <option value="{{ resource_dropdown['id'] }}">{{ resource_dropdown['name'] }}</option> | |||
| @@ -155,14 +180,14 @@ | |||
| </div> | |||
| {% endif %} | |||
| {% if links %} | |||
| {% if relationships %} | |||
| <div class="mb-3 mt-3"> | |||
| <label for="linked_practice_id">Remove linked resources</label> | |||
| </div> | |||
| <div class="mb-3 mt-3"> | |||
| <select name="remove_linked_resources" id="remove_linked_resources" aria-label="Remove linked resources" class="selectpicker" data-live-search="true" multiple> | |||
| {% for link in links %} | |||
| <option value="{{ link['id'] }}">{{ link['name'] }}</option> | |||
| {% for relationship in relationships %} | |||
| <option value="{{ relationship['id'] }}">{{ relationship['name'] }}</option> | |||
| {% endfor %} | |||
| </select> | |||
| </div> | |||
| @@ -188,4 +213,11 @@ | |||
| onclick="return confirm('Are you sure you want to delete this practice?')"> | |||
| </form> | |||
| {% endif %} | |||
| {% if resource['type'] == 'book' %} | |||
| <form action="{{ url_for('book.delete_book', book_id=resource['id']) }}" method="POST"> | |||
| <input type="submit" value="Delete" | |||
| class="btn btn-danger btn-sm" | |||
| onclick="return confirm('Are you sure you want to delete this book?')"> | |||
| </form> | |||
| {% endif %} | |||
| {% endblock %} | |||
| @@ -4,7 +4,7 @@ | |||
| <div class="row"> | |||
| <div class="col"> | |||
| <h1 class="text-center">{% block title %} {{ resource['name'] }} {% endblock %}</h1> | |||
| <h1 class="text-center">{% block title %} {{ resource['name'] }} {% endblock %}</h1> | |||
| </div> | |||
| </div> | |||
| {% if current_user.is_authenticated %} | |||
| @@ -20,12 +20,6 @@ | |||
| <span class="badge bg-dark">Edit</span> | |||
| </a> | |||
| </div> | |||
| {% elif resource['type'] == 'book' %} | |||
| <div class="row text-center py-3"> | |||
| <a href="{{ url_for('book.edit_book', book_id=resource['id']) }}"> | |||
| <span class="badge bg-dark">Edit</span> | |||
| </a> | |||
| </div> | |||
| {% endif %} | |||
| {% endif %} | |||
| <div class="row"> | |||
| @@ -231,17 +225,6 @@ | |||
| </p> | |||
| </div> | |||
| </div> | |||
| {% elif relationship['type'] == 'book' %} | |||
| <div class="card text-dark bg-book mb-3"> | |||
| <div class="card-body"> | |||
| <a href="{{ url_for('book.show_book', book_id=relationship['id']) }}"> | |||
| <h3 class="card-title text-center text-dark">{{ relationship['name'] }}</h3> | |||
| </a> | |||
| <p class="card-text"> | |||
| {{ relationship['description']|truncate(100) }} | |||
| </p> | |||
| </div> | |||
| </div> | |||
| {% endif %} | |||
| </div> | |||
| {% endfor %} | |||
| @@ -27,7 +27,7 @@ | |||
| <ul class="filter-items"> | |||
| {% for practice in practices_filter %} | |||
| <li {% if request.args.get('practice') == practice[0]|string %} class="fw-bold"{% endif %}> | |||
| <a href="/tools?practice={{practice[0]}}">{{ practice[1] }}</a> | |||
| <a href="/{{type + 's'}}?practice={{practice[0]}}">{{ practice[1] }}</a> | |||
| </li> | |||
| {% endfor %} | |||
| </ul> | |||
| @@ -39,7 +39,7 @@ | |||
| <ul id="filter-practice" class="collapse filter-items"> | |||
| {% for practice in practices_filter %} | |||
| <li {% if request.args.get('practice') == practice[0]|string %} class="fw-bold"{% endif %}> | |||
| <a href="/tools?practice={{practice[0]}}">{{ practice[1] }}</a> | |||
| <a href="/{{type + 's'}}?practice={{practice[0]}}">{{ practice[1] }}</a> | |||
| </li> | |||
| {% endfor %} | |||
| </ul> | |||
| @@ -55,7 +55,7 @@ | |||
| <ul class="filter-items"> | |||
| {% for language in languages_filter %} | |||
| <li {% if request.args.get('scriptingLanguage') == language %} class="fw-bold"{% endif %}> | |||
| <a href="/tools?scriptingLanguage={{language}}">{{ language }}</a> | |||
| <a href="/{{type}}?scriptingLanguage={{language}}">{{ language }}</a> | |||
| </li> | |||
| {% endfor %} | |||
| </ul> | |||
| @@ -23,7 +23,7 @@ def get_tools(): | |||
| tools = Resource.query.filter_by(type='tool') | |||
| for key in request.args.keys(): | |||
| if key == 'practice': | |||
| query = 'SELECT Resource.* FROM Resource LEFT JOIN Relationship ON Resource.id=Relationship.first_resource_id WHERE Relationship.second_resource_id=' + request.args.get(key) + ';' | |||
| query = 'SELECT Resource.* FROM Resource LEFT JOIN Relationship ON Resource.id=Relationship.first_resource_id WHERE Relationship.second_resource_id=' + request.args.get(key) + ' AND Resource.type="tool";' | |||
| tools = db.engine.execute(query) | |||
| elif key == 'scriptingLanguage': | |||
| regex = request.args.get(key) + "$|" + request.args.get(key) + "\s\/" | |||
| @@ -83,7 +83,7 @@ def edit_tool(tool_id): | |||
| return redirect(url_for('tool.get_tools',_external=True,_scheme=os.environ.get('SSL_SCHEME'))) | |||
| return render_template('edit.html', resource=tool, resource_dropdown=resource_dropdown, links=existing_relationships) | |||
| return render_template('edit.html', resource=tool, resource_dropdown=resource_dropdown, relationships=existing_relationships) | |||
| # route for function to delete a single tool from the edit page | |||
| @tool.route('/tools/<int:tool_id>/delete', methods=('POST',)) | |||
| @@ -5,3 +5,4 @@ flask-moment | |||
| gunicorn | |||
| pymysql | |||
| markdown | |||
| isbntools | |||