| @@ -20,30 +20,35 @@ book = Blueprint('book', __name__) | |||
| @book.route('/books') | |||
| def get_books(): | |||
| view = request.args.get('view') | |||
| type = 'book' | |||
| books = Resource.query.filter_by(type=type).all() | |||
| resource_type = 'book' | |||
| books_query = Resource.query.filter_by(type=resource_type) | |||
| for key in request.args.keys(): | |||
| if key != 'view': | |||
| if key == 'practice': | |||
| books = Resource.query.join(Relationship, Relationship.first_resource_id == Resource.id, isouter=True).filter(Resource.type==type, Relationship.second_resource_id==request.args.get(key)).all() | |||
| also_books = Resource.query.join(Relationship, Relationship.second_resource_id == Resource.id, isouter=True).filter(Resource.type==type, Relationship.first_resource_id==request.args.get(key)).all() | |||
| books = books + also_books | |||
| else: | |||
| kwargs = {'type': type, key: request.args.get(key)} | |||
| books = Resource.query.filter_by(**kwargs).all() | |||
| books_1 = books_query.join(Relationship, Relationship.first_resource_id == Resource.id, isouter=True).filter(Relationship.second_resource_id==request.args.get(key)) | |||
| books_2 = books_query.join(Relationship, Relationship.second_resource_id == Resource.id, isouter=True).filter(Relationship.first_resource_id==request.args.get(key)) | |||
| books_query = books_1.union(books_2) | |||
| if key != 'practice': | |||
| kwargs = {key: request.args.get(key)} | |||
| books_query = books_query.filter_by(**kwargs) | |||
| # finalise the query | |||
| books = books_query.all() | |||
| # get number of books | |||
| count = len(books) | |||
| if view != 'list': | |||
| # append relationships to each book | |||
| append_relationships_multiple(books) | |||
| # get filters | |||
| append_relationships_multiple(books) | |||
| else: | |||
| # reorder books by book name | |||
| books = sorted(books, key=lambda d: d.__dict__['name']) | |||
| # get values for filters | |||
| # practices | |||
| practices_filter = Resource.query.filter_by(type='practice').with_entities(Resource.id, Resource.name) | |||
| practices_filter = Resource.query.filter_by(type='practice').with_entities(Resource.id, Resource.name).all() | |||
| # year | |||
| year_filter = get_filter_values('year', type) | |||
| year_filter = get_filter_values('year', resource_type) | |||
| # typology | |||
| typology_filter = get_filter_values('typology', type) | |||
| return render_template('resources.html', resources=books, type=type, practices_filter=practices_filter, year_filter=year_filter, typology_filter=typology_filter, count=count, view=view) | |||
| typology_filter = get_filter_values('typology', resource_type) | |||
| return render_template('resources.html', resources=books, type=resource_type, practices_filter=practices_filter, year_filter=year_filter, typology_filter=typology_filter, count=count, view=view) | |||
| # route for displaying a single book based on the ID in the database | |||
| @book.route('/books/<int:book_id>') | |||
| @@ -20,19 +20,18 @@ main = Blueprint('main', __name__) | |||
| @main.route('/') | |||
| def index(): | |||
| view = request.args.get('view') | |||
| tools = Resource.query.filter_by(type='tool').order_by(func.random()).limit(6).all() | |||
| if view != 'list': | |||
| # append relationships to each tool | |||
| append_relationships_multiple(tools) | |||
| books = Resource.query.filter_by(type='book').order_by(func.random()).limit(6).all() | |||
| if view != 'list': | |||
| # append relationships to each book | |||
| append_relationships_multiple(books) | |||
| # curated list of resources to display on homepage | |||
| tool_ids = ['4','10', '34', '27'] | |||
| practice_ids = ['53', '59', '65', '56'] | |||
| book_ids = ['94', '72', '105', '67'] | |||
| # concatenate lists of resources | |||
| resource_ids = tool_ids + practice_ids + book_ids | |||
| # get data for curated resources | |||
| curated = get_curated_resources(resource_ids) | |||
| with open('content/home.md', 'r') as f: | |||
| text = f.read() | |||
| text = markdown.markdown(text) | |||
| book_showcase = get_full_resource('69') | |||
| return render_template('index.html', text=text, tools=tools, books=books, book=book_showcase, view=view) | |||
| return render_template('index.html', text=text, resources=curated, view=view) | |||
| # route for profile page | |||
| @main.route('/profile') | |||
| @@ -13,6 +13,7 @@ from .resources import * | |||
| from .relationships import * | |||
| from . import db | |||
| import os | |||
| import markdown | |||
| practice = Blueprint('practice', __name__) | |||
| @@ -26,13 +27,20 @@ def get_practices(): | |||
| if view != 'list': | |||
| # append relationships to each practice | |||
| append_relationships_multiple(practices) | |||
| else: | |||
| # reorder practices by practice name | |||
| practices = sorted(practices, key=lambda d: d.__dict__['name']) | |||
| return render_template('resources.html', resources=practices, type='practice', count=count, view=view) | |||
| # route for displaying a single practice based on the ID in the database | |||
| @practice.route('/practices/<int:practice_id>') | |||
| def show_practice(practice_id): | |||
| practice = get_full_resource(practice_id) | |||
| practice.references = replace_urls(practice.references) | |||
| # render Markdown as HTML | |||
| practice.longDescription = markdown.markdown(practice.longDescription) | |||
| practice.experimental = markdown.markdown(practice.experimental) | |||
| practice.considerations = markdown.markdown(practice.considerations) | |||
| practice.references = markdown.markdown(practice.references) | |||
| return render_template('resource.html', resource=practice) | |||
| # route for editing a single practice based on the ID in the database | |||
| @@ -15,6 +15,7 @@ from .relationships import * | |||
| from isbntools.app import * | |||
| import requests | |||
| import re | |||
| from sqlalchemy.sql import func | |||
| # function to retrieve data about a single resource from the database | |||
| def get_resource(resource_id): | |||
| @@ -33,6 +34,13 @@ def get_full_resource(resource_id): | |||
| resource.__dict__.update(book_data) | |||
| return resource | |||
| # function to retrieve data about a curated list of resources | |||
| def get_curated_resources(resource_ids): | |||
| resources = Resource.query.filter(Resource.id.in_(resource_ids)).order_by(func.random()).all() | |||
| # append relationships to each resource | |||
| append_relationships_multiple(resources) | |||
| return resources | |||
| # function to delete a single resource | |||
| def delete_resource(resource_id): | |||
| deletion = Resource.query.get(resource_id) | |||
| @@ -62,51 +70,19 @@ def get_book_data(isbn): | |||
| book = meta(isbn) | |||
| description = {'desc': desc(isbn)} | |||
| book.update(description) | |||
| # get highest-resolution book cover possible | |||
| openl_url = 'https://covers.openlibrary.org/b/isbn/' + book['ISBN-13'] + '-L.jpg?default=false' | |||
| request = requests.get(openl_url) | |||
| if request.status_code != 200: | |||
| book.update(cover(isbn)) | |||
| else: | |||
| book_cover = {'thumbnail': openl_url} | |||
| book.update(book_cover) | |||
| #book = get_book_cover(book) | |||
| return book | |||
| except: | |||
| pass | |||
| # function to get full metadata for a book and combine into one object | |||
| # TO BE DELETED | |||
| def get_book(resource_id): | |||
| book = get_resource(resource_id) | |||
| book_data = get_book_data(book.isbn) | |||
| book.__dict__.update(book_data) | |||
| return book | |||
| # function to replace embedded URL strings with href links | |||
| def replace_urls(input): | |||
| # Compile a regular expression to match URLs. | |||
| # This regular expression is not exhaustive and may not match all possible URLs. | |||
| # It is intended to be a starting point and can be refined and expanded as needed. | |||
| url_regex = re.compile(r'((?:https?:(?:/{1,3}|[a-z0-9%])|[a-z0-9.\-]+[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)/)(?:[^\s()<>{}\[\]]+|\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\))+(?:\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\)|[^\s`!()\[\]{};:\'\".,<>?«»“”‘’])|(?:(?<!@)[a-z0-9]+(?:[.\-][a-z0-9]+)*[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\b/?(?!@)))') | |||
| # Find all URLs in the input string using the regular expression. | |||
| # This will return a list of Match objects, each of which represents a single URL in the string. | |||
| matches = url_regex.finditer(input) | |||
| # Iterate over the list of matches and replace each URL with an HTML link. | |||
| for match in matches: | |||
| # Get the full URL from the Match object. | |||
| url = match.group(0) | |||
| # Create the HTML link by wrapping the URL in an <a> tag. | |||
| # If the URL does not include a protocol (e.g. "http://" or "https://"), | |||
| # then add "http://" as the default protocol. | |||
| if not url.startswith('http'): | |||
| link = f'<a href="http://{url}">{url}</a>' | |||
| else: | |||
| link = f'<a href="{url}">{url}</a>' | |||
| # Replace the URL in the original string with the HTML link. | |||
| input = input.replace(url, link) | |||
| return input | |||
| # function to get book cover data | |||
| def get_book_cover(book): | |||
| # get highest-resolution book cover possible | |||
| openl_url = 'https://covers.openlibrary.org/b/isbn/' + book['ISBN-13'] + '-L.jpg?default=false' | |||
| request = requests.get(openl_url) | |||
| if request.status_code != 200: | |||
| book.update(cover(isbn)) | |||
| else: | |||
| book_cover = {'thumbnail': openl_url} | |||
| book.update(book_cover) | |||
| return book | |||
| @@ -224,8 +224,8 @@ | |||
| > | |||
| {% if (resource['type'] == 'book') %} | |||
| <img class="w-20 h-20 object-contain float-right m-4 grayscale rotate-[15deg]" src="https://dummyimage.com/4:5x70" alt="cover for {{ resource['name'] }}"> | |||
| {% if (resource.type == 'book') and (resource.references) %} | |||
| <img class="w-20 h-20 object-contain float-right m-4 grayscale rotate-[15deg]" src="{{resource.references}}" alt="cover for {{ resource.name }}"> | |||
| {% endif %} | |||
| <h2 class="{{ resource['type'] }} {% if size==1 %} big-title {% else %} small-title {% endif %} mb-2">{{ resource['name'] }}</h2> | |||
| @@ -262,7 +262,7 @@ | |||
| <!DOCTYPE html> | |||
| <html> | |||
| <html lang="en-gb"> | |||
| <head> | |||
| {{ moment.include_moment() }} | |||
| @@ -7,13 +7,13 @@ | |||
| <div class="left"> | |||
| <div class="mb-2">Book</div> | |||
| <div class="border-r-2 border-black pr-8"> | |||
| {% if resource['thumbnail'] %} | |||
| {% if resource.references %} | |||
| <div class="float-right"> | |||
| <img class="w-40 h-40 object-contain m-16 rotate-[15deg]" src={{ resource['thumbnail'] }} alt="cover for {{ resource['Title'] }}"> | |||
| <img class="w-40 h-40 object-contain m-16 rotate-[15deg]" src={{ resource.references }} alt="cover for {{ resource['Title'] }}"> | |||
| </div> | |||
| {% endif %} | |||
| <h2 class="book huge-title mb-2 max-w-[30rem]">{% block title %} {{ resource['Title'] or resource['name'] }} {% endblock %}</h2> | |||
| <h2 class="book huge-title mb-2 max-w-[30rem]">{% block title %} {{ resource.name }} {% endblock %}</h2> | |||
| {% if resource['Year'] %} | |||
| {{ resource['Year'] }} | |||
| @@ -6,40 +6,20 @@ | |||
| <div class="border-b-2 border-black grid gap-8 lg:grid-cols-[52rem,30rem] content-start"> | |||
| <div class="mx-2 lg:ml-[13rem] text my-8 meta max-w-[30rem]"> | |||
| {{ text|safe }} | |||
| <br/> | |||
| <a href="{{ url_for(request.endpoint, view='list') }}">LIST VIEW</a> | |||
| </div> | |||
| </div> | |||
| {{ view_switch() }} | |||
| {% if view == 'list' %} | |||
| {% for tool in tools %} | |||
| {{ resource_list(tool, loop, false) }} | |||
| {% endfor %} | |||
| {% else %} | |||
| {% for tool in tools %} | |||
| {{ resource_with_related(tool, loop, false) }} | |||
| {% endfor %} | |||
| {% endif %} | |||
| {% if view == 'list' %} | |||
| {% for book in books %} | |||
| {{ resource_list(book, loop, false) }} | |||
| {% endfor %} | |||
| {% for resource in resources %} | |||
| {{ resource_list(resource, loop, false) }} | |||
| {% endfor %} | |||
| {% else %} | |||
| {% for book in books %} | |||
| {{ resource_with_related(book, loop, false) }} | |||
| {% endfor %} | |||
| {% for resource in resources %} | |||
| {{ resource_with_related(resource, loop, false) }} | |||
| {% endfor %} | |||
| {% endif %} | |||
| </div> | |||
| {% endblock %} | |||
| {% endblock %} | |||
| @@ -18,117 +18,92 @@ | |||
| </div> | |||
| </div> --> | |||
| {% macro filter_dropdown(id, filter, plural='') %} | |||
| <select name="{{ id }}" hx-trigger="change"> | |||
| <option value="all" {% if request.args.get(id, '' ) == '' %} selected {% endif %} | |||
| hx-get="{{ request.base_url }}?{% for key in request.args %}{% if key != id %}&{{ key }}={{ request.args.get(key) }}{% endif %}{% endfor %}" | |||
| hx-push-url="true"> | |||
| {% if plural != '' %} | |||
| All {{ plural }} | |||
| {% else %} | |||
| All {{ id }}s | |||
| {% endif%} | |||
| </option> | |||
| {% for thing in filter %} | |||
| <option value="{{ thing[0] }}" {% if request.args.get(id)==thing[0]|string %} selected {% endif %} | |||
| hx-get="{{ request.base_url }}?{{ id }}={{ thing[0] }}{% for key in request.args %}{% if key != id %}&{{ key }}={{ request.args.get(key) }}{% endif %}{% endfor %}" | |||
| hx-push-url="true"> | |||
| {{ thing[1] }} | |||
| </option> | |||
| {% endfor %} | |||
| </select> | |||
| {% endmacro%} | |||
| {% macro filter_dropdown_nokey(id, filter, plural='') %} | |||
| <select name="{{ id }}" hx-trigger="change"> | |||
| <option value="all" {% if request.args.get(id, '' ) == '' %} selected {% endif %} | |||
| hx-get="{{ request.base_url }}?{% for key in request.args %}{% if key != id %}&{{ key }}={{ request.args.get(key) }}{% endif %}{% endfor %}" | |||
| hx-push-url="true"> | |||
| {% if plural != '' %} | |||
| All {{ plural }} | |||
| {% else %} | |||
| All {{ id }}s | |||
| {% endif%} | |||
| </option> | |||
| {% for thing in filter %} | |||
| <option value="{{ thing }}" {% if request.args.get(id)==thing|string %} selected {% endif %} | |||
| hx-get="{{ request.base_url }}?{{ id }}={{ thing }}{% for key in request.args %}{% if key != id %}&{{ key }}={{ request.args.get(key) }}{% endif %}{% endfor %}" | |||
| hx-push-url="true"> | |||
| {{ thing }} | |||
| </option> | |||
| {% endfor %} | |||
| </select> | |||
| {% endmacro%} | |||
| <div class="border-b-2 border-black grid lg:grid-cols-[52rem,30rem] content-start"> | |||
| <div class="mx-2 lg:ml-[13rem] text my-8 meta lg:max-w-[30rem]"> | |||
| Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ultricies egestas felis at dignissim. Morbi ut bibendum | |||
| nisl. Integer ac sollicitudin risus. Vivamus et est est. Ut vitae lacus nec justo tincidunt interdum. Fusce sapien odio, | |||
| commodo nec est et, interdum varius risus. Curabitur vehicula consequat auctor. | |||
| <br/><br/> | |||
| <a href="{{ url_for(request.endpoint, view='list') }}">As list</a> <a href="{{ url_for(request.endpoint, view='') }}">With related</a> | |||
| </div> | |||
| </div> | |||
| <script> | |||
| function filter() { | |||
| return { | |||
| expandFilters: false, | |||
| init() { | |||
| // console.log(this.showRelated) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <div class="" x-data="filter()"> | |||
| <div id="resources" :class="expandFilters?'expanded':''"> | |||
| <div class="std-margin grid lg:grid-cols-4 sticky top-14"> | |||
| <div class="hidden lg:block cursor-pointer" @click="expandFilters = !expandFilters">Show/hide filters</div> | |||
| <div class="" > | |||
| <div id="resources" > | |||
| {{ view_switch() }} | |||
| <div class="flex gap-8"> | |||
| {% if practices_filter %} | |||
| <div class=""> | |||
| <div class="filter-header">Practices</div> | |||
| <div class="filter-options my-4" x-show="expandFilters"> | |||
| {% for practice in practices_filter %} | |||
| <div {% if request.args.get('practice')==practice[0]|string %} class="active" {% endif %}> | |||
| <a href="{{ url_for(request.endpoint, practice=practice[0]) }}" hx-target="#resources" hx-select="#resources">{{ practice[1] }}</a> | |||
| </div> | |||
| {% endfor %} | |||
| </div> | |||
| </div> | |||
| {{ filter_dropdown('practice', practices_filter) }} | |||
| {% endif %} | |||
| {% if year_filter %} | |||
| <div class=""> | |||
| <div class="filter-header">Year</div> | |||
| <div class="filter-options my-4" x-show="expandFilters"> | |||
| {% for year in year_filter %} | |||
| <div {% if request.args.get('year')==year %} class="active" {% endif %}> | |||
| <a href="{{ url_for(request.endpoint, year=year) }}" hx-target="#resources" hx-select="#resources">{{ year }}</a> | |||
| </div> | |||
| {% endfor %} | |||
| </div> | |||
| </div> | |||
| {{ filter_dropdown_nokey('year', year_filter) }} | |||
| {% endif %} | |||
| {% if typology_filter %} | |||
| <div class=""> | |||
| <div class="filter-header">Typology category</div> | |||
| <div class="filter-options my-4" x-show="expandFilters"> | |||
| {% for typology in typology_filter %} | |||
| <div {% if request.args.get('typology')==typology %} class="active" {% endif %}> | |||
| <a href="{{ url_for(request.endpoint, typology=typology) }}" hx-target="#resources" hx-select="#resources">{{ typology }}</a> | |||
| </div> | |||
| {% endfor %} | |||
| </div> | |||
| </div> | |||
| {{ filter_dropdown_nokey('typology', typology_filter, 'typologies') }} | |||
| {% endif %} | |||
| {% if languages_filter %} | |||
| <div class="" > | |||
| <div class="filter-header">Scripting languages</div> | |||
| <div class="filter-options my-4" x-show="expandFilters"> | |||
| {% for language in languages_filter %} | |||
| <div {% if request.args.get('scriptingLanguage')==language %} class="active" {% endif %}> | |||
| <a href="{{ url_for(request.endpoint, scriptingLanguage=language) }}" hx-target="#resources" hx-select="#resources">{{ language }}</a> | |||
| </div> | |||
| {% endfor %} | |||
| </div> | |||
| </div> | |||
| {{ filter_dropdown_nokey('scriptingLanguage', languages_filter, 'scripting languages') }} | |||
| {% endif %} | |||
| {% if licenses_filter %} | |||
| <div class="" > | |||
| <div class="filter-header">License</div> | |||
| <div class="filter-options my-4" x-show="expandFilters"> | |||
| {% for license in licenses_filter %} | |||
| <div {% if request.args.get('license')==license %} class="active" {% endif %}> | |||
| <a href="{{ url_for(request.endpoint, license=license) }}" hx-target="#resources" hx-select="#resources">{{ license }}</a> | |||
| </div> | |||
| {% endfor %} | |||
| </div> | |||
| </div> | |||
| {{ filter_dropdown_nokey('license', licenses_filter) }} | |||
| {% endif %} | |||
| {% if status_filter %} | |||
| <div class="" > | |||
| <div class="filter-header">Status</div> | |||
| <div class="filter-options my-4" x-show="expandFilters"> | |||
| {% for status in status_filter %} | |||
| <div {% if request.args.get('status')==status %} class="active" {% endif %}> | |||
| <a href="{{ url_for(request.endpoint, status=status) }}" hx-target="#resources" hx-select="#resources">{{ status }}</a> | |||
| </div> | |||
| {% endfor %} | |||
| </div> | |||
| </div> | |||
| {{ filter_dropdown_nokey('status', status_filter, 'statuses') }} | |||
| {% endif %} | |||
| </div> | |||
| </div> | |||
| <div> | |||
| {% if view == 'list' %} | |||
| {% for resource in resources %} | |||
| {{ resource_list(resource, loop) }} | |||
| {% endfor %} | |||
| {% else %} | |||
| {% for resource in resources %} | |||
| {{ resource_with_related(resource, loop) }} | |||
| {% endfor %} | |||
| {% endif %} | |||
| </div> | |||
| <div> | |||
| {% if view == 'list' %} | |||
| {% for resource in resources %} | |||
| {{ resource_list(resource, loop) }} | |||
| {% endfor %} | |||
| {% else %} | |||
| {% for resource in resources %} | |||
| {{ resource_with_related(resource, loop) }} | |||
| {% endfor %} | |||
| {% endif %} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -20,36 +20,40 @@ tool = Blueprint('tool', __name__) | |||
| @tool.route('/tools') | |||
| def get_tools(): | |||
| view = request.args.get('view') | |||
| type = 'tool' | |||
| tools = Resource.query.filter_by(type=type).all() | |||
| resource_type = 'tool' | |||
| tools_query = Resource.query.filter_by(type=resource_type) | |||
| for key in request.args.keys(): | |||
| if key != 'view': | |||
| if key == 'practice': | |||
| tools = Resource.query.join(Relationship, Relationship.first_resource_id == Resource.id, isouter=True).filter(Resource.type==type, Relationship.second_resource_id==request.args.get(key)).all() | |||
| also_tools = Resource.query.join(Relationship, Relationship.second_resource_id == Resource.id, isouter=True).filter(Resource.type==type, Relationship.first_resource_id==request.args.get(key)).all() | |||
| tools = tools + also_tools | |||
| elif key == 'scriptingLanguage': | |||
| tools_1 = tools_query.join(Relationship, Relationship.first_resource_id == Resource.id, isouter=True).filter(Relationship.second_resource_id==request.args.get(key)) | |||
| tools_2 = tools_query.join(Relationship, Relationship.second_resource_id == Resource.id, isouter=True).filter(Relationship.first_resource_id==request.args.get(key)) | |||
| tools_query = tools_1.union(tools_2) | |||
| if key == 'scriptingLanguage': | |||
| regex = request.args.get(key) + "$|" + request.args.get(key) + "\s\/" | |||
| tools = Resource.query.filter_by(type=type).filter(Resource.scriptingLanguage.regexp_match(regex)).all() | |||
| else: | |||
| kwargs = {'type': type, key: request.args.get(key)} | |||
| tools = Resource.query.filter_by(**kwargs).all() | |||
| tools_query = tools_query.filter(Resource.scriptingLanguage.regexp_match(regex)) | |||
| if key != 'practice' and key != 'scriptingLanguage': | |||
| kwargs = {key: request.args.get(key)} | |||
| tools_query = tools_query.filter_by(**kwargs) | |||
| # finalise the query | |||
| tools = tools_query.all() | |||
| # get number of tools | |||
| count = len(tools) | |||
| if view != 'list': | |||
| # append relationships to each tool | |||
| append_relationships_multiple(tools) | |||
| # get filters | |||
| else: | |||
| # reorder tools by tools name | |||
| tools = sorted(tools, key=lambda d: d.__dict__['name']) | |||
| # get values for filters | |||
| # practices | |||
| practices_filter = Resource.query.filter_by(type='practice').with_entities(Resource.id, Resource.name) | |||
| #FOR LATER: SELECT Resource.name, second.name FROM Resource LEFT JOIN Relationship ON Resource.id=Relationship.first_resource_id LEFT JOIN Resource second ON Relationship.second_resource_id=second.id; | |||
| practices_filter = Resource.query.filter_by(type='practice').with_entities(Resource.id, Resource.name).all() | |||
| # license | |||
| licenses_filter = get_filter_values('license', type) | |||
| licenses_filter = get_filter_values('license', resource_type) | |||
| # language | |||
| languages_filter = get_filter_values('scriptingLanguage', type) | |||
| languages_filter = get_filter_values('scriptingLanguage', resource_type) | |||
| # status | |||
| status_filter = get_filter_values('status', type) | |||
| return render_template('resources.html', resources=tools, type=type, practices_filter=practices_filter, licenses_filter=licenses_filter, languages_filter=languages_filter, status_filter=status_filter, count=count, view=view) | |||
| status_filter = get_filter_values('status', resource_type) | |||
| return render_template('resources.html', resources=tools, type=resource_type, practices_filter=practices_filter, licenses_filter=licenses_filter, languages_filter=languages_filter, status_filter=status_filter, count=count, view=view) | |||
| # route for displaying a single tool based on the ID in the database | |||
| @tool.route('/tools/<int:tool_id>') | |||