Browse Source

changes to database and how relationships are added

joel
Simon Bowie 2 years ago
parent
commit
325a1f74a5
12 changed files with 109 additions and 65 deletions
  1. +21
    -4
      database_functions.sh
  2. +1
    -0
      web/Dockerfile
  3. +2
    -1
      web/app/book.py
  4. +2
    -1
      web/app/create.py
  5. +4
    -0
      web/app/models.py
  6. +8
    -7
      web/app/practice.py
  7. +2
    -1
      web/app/publisher.py
  8. +53
    -0
      web/app/relationships.py
  9. +0
    -42
      web/app/resources.py
  10. +5
    -2
      web/app/templates/edit.html
  11. +3
    -0
      web/app/templates/resource.html
  12. +8
    -7
      web/app/tool.py

+ 21
- 4
database_functions.sh View File

@@ -26,7 +26,7 @@ Help()
# Display Help
echo "This script performs database functions for the ExPub Compendium"
echo
echo "Syntax: database_functions.sh [-l|h|e|i|c]"
echo "Syntax: database_functions.sh [-l|h|e|i|c|v|d]"
echo "options:"
echo "l Print the MIT License notification."
echo "h Print this Help."
@@ -34,6 +34,7 @@ Help()
echo "i Import whole database."
echo "c Export single table as tab-delimited txt."
echo "v Import tab-delimited txt file to table."
echo "d Drop table."
echo
}

@@ -58,6 +59,11 @@ Table_import()

docker exec -i $CONTAINER bash -c "mysql -u $USERNAME -p$PASSWORD $DATABASE -e 'LOAD DATA LOCAL INFILE '\''/tmp/import_file'\'' REPLACE INTO TABLE $TABLE FIELDS TERMINATED BY '\''\t'\'' LINES TERMINATED BY '\''\n'\'' IGNORE 1 ROWS;'"
}

Drop_table()
{
docker exec -i $CONTAINER bash -c "mysql -u $USERNAME -p$PASSWORD $DATABASE -e 'DROP TABLE IF EXISTS $TABLE;'"
}
############################################################
############################################################
# main program #
@@ -67,8 +73,8 @@ Table_import()
# set variables
CONTAINER=mariadb
DATABASE=toolkit
USERNAME=xxxxxxxx
PASSWORD=xxxxxxxx
USERNAME=xxxxxxxxx
PASSWORD=xxxxxxxxx
EXPORT_SQL_FILENAME=toolkit_db_
IMPORT_SQL_DIRECTORY="/Users/ad7588/Downloads"
IMPORT_SQL_FILENAME=toolkit_db.sql
@@ -82,7 +88,7 @@ if (( $# == 0 )); then
fi

# get the options
while getopts ":hleicv" flag; do
while getopts ":hleicvd" flag; do
case $flag in
l) # display License
License
@@ -119,6 +125,17 @@ while getopts ":hleicv" flag; do
Table_import
exit 1
fi;;
d) # drop table
if [ -z "$2" ]
then
echo "-d requires a table name as an argument"
echo
echo "Syntax: database_functions.sh -d [table name]"
else
TABLE=$2
Drop_table
exit 1
fi;;
\?) # Invalid option
Help
exit;;

+ 1
- 0
web/Dockerfile View File

@@ -1,5 +1,6 @@
# syntax=docker/dockerfile:1
FROM python:3.8-slim-buster
RUN apt update && apt install -y apt-transport-https ca-certificates sqlite3
WORKDIR /code
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

+ 2
- 1
web/app/book.py View File

@@ -10,6 +10,7 @@ from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Resource
from .resources import *
from .relationships import *
from werkzeug.exceptions import abort
from . import db
import os
@@ -26,7 +27,7 @@ def get_books():
@book.route('/books/<int:book_id>')
def show_book(book_id):
book = get_resource(book_id)
links = get_linked_resources(book_id)
links = get_relationships(book_id)
return render_template('resource.html', resource=book, links=links)

# route for editing a single book based on the ID in the database

+ 2
- 1
web/app/create.py View File

@@ -11,6 +11,7 @@ from flask_login import login_required, current_user
from .models import Resource
from .models import Relationship
from .resources import *
from .relationships import *
from werkzeug.exceptions import abort
from . import db
import os
@@ -54,7 +55,7 @@ def create_resource():
if request.form.getlist('linked_resources'):
for linked_resource in request.form.getlist('linked_resources'):
tool = Resource.query.filter_by(type='tool').filter_by(name=name).first()
add_linked_resource(tool.id, linked_resource)
add_relationship(tool.id, linked_resource)

elif request.form.get('resource_type') == 'practice':
type = 'practice'

+ 4
- 0
web/app/models.py View File

@@ -28,8 +28,12 @@ class Resource(db.Model):
type = db.Column(db.Text)
name = db.Column(db.Text)
description = db.Column(db.Text)
developer = db.Column(db.Text)
developerUrl = db.Column(db.Text)
projectUrl = db.Column(db.Text)
repositoryUrl = db.Column(db.Text)
license = db.Column(db.Text)
scriptingLanguage = db.Column(db.Text)
expertiseToUse = db.Column(db.Text)
expertiseToHost = db.Column(db.Text)
dependencies = db.Column(db.Text)

+ 8
- 7
web/app/practice.py View File

@@ -10,6 +10,7 @@ from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Resource
from .resources import *
from .relationships import *
from werkzeug.exceptions import abort
from . import db
import os
@@ -26,7 +27,7 @@ def get_practices():
@practice.route('/practices/<int:practice_id>')
def show_practice(practice_id):
practice = get_resource(practice_id)
links = get_linked_resources(practice_id)
links = get_relationships(practice_id)
return render_template('resource.html', resource=practice, links=links)

# route for editing a single practice based on the ID in the database
@@ -35,7 +36,7 @@ def show_practice(practice_id):
def edit_practice(practice_id):
practice = get_resource(practice_id)
resource_dropdown = Resource.query
links = get_linked_resources(practice_id)
existing_relationships = get_relationships(practice_id)

if request.method == 'POST':
name = request.form['name']
@@ -53,16 +54,16 @@ def edit_practice(practice_id):
if linked_resources:
for linked_resource in linked_resources:
link = Resource.query.get(linked_resource)
if links and link not in links:
add_linked_resource(practice_id, linked_resource)
elif not links:
add_linked_resource(practice_id, linked_resource)
if existing_relationships and link not in existing_relationships:
add_relationship(practice_id, linked_resource)
elif not existing_relationships:
add_relationship(practice_id, linked_resource)
if remove_linked_resources:
for remove_linked_resource in remove_linked_resources:
delete_relationship(practice_id, remove_linked_resource)
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=links)
return render_template('edit.html', resource=practice, resource_dropdown=resource_dropdown, links=existing_relationships)

# route for function to delete a single practice from the edit page
@practice.route('/practices/<int:practice_id>/delete', methods=('POST',))

+ 2
- 1
web/app/publisher.py View File

@@ -10,6 +10,7 @@ from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Resource
from .resources import *
from .relationships import *
from werkzeug.exceptions import abort
from . import db
import os
@@ -26,7 +27,7 @@ def get_publishers():
@publisher.route('/publishers/<int:publisher_id>')
def show_publisher(publisher_id):
publisher = get_resource(publisher_id)
links = get_linked_resources(publisher_id)
links = get_relationships(publisher_id)
return render_template('resource.html', resource=publisher, links=links)

# route for editing a single publisher based on the ID in the database

+ 53
- 0
web/app/relationships.py View File

@@ -0,0 +1,53 @@
# @name: relationships.py
# @creation_date: 2022-04-11
# @license: The MIT License <https://opensource.org/licenses/MIT>
# @author: Simon Bowie <ad7588@coventry.ac.uk>
# @purpose: functions for relationships
# @acknowledgements:

from flask import Blueprint, render_template, request, flash, redirect, url_for
from .models import Resource
from .models import Relationship
from werkzeug.exceptions import abort
from . import db

# function to retrieve linked resources
def get_relationships(primary_id):
primary_relationships = Relationship.query.filter_by(first_resource_id=primary_id).all()
links = []
if primary_relationships:
links = []
for relationship in primary_relationships:
secondary_id = relationship.second_resource_id
links.extend(Resource.query.filter_by(id=secondary_id).all())
secondary_relationships = Relationship.query.filter_by(second_resource_id=primary_id).all()
if secondary_relationships:
for relationship in secondary_relationships:
primary_id = relationship.first_resource_id
links.extend(Resource.query.filter_by(id=primary_id).all())
return links
else:
secondary_relationships = Relationship.query.filter_by(second_resource_id=primary_id).all()
if secondary_relationships:
links = []
for relationship in secondary_relationships:
primary_id = relationship.first_resource_id
links.extend(Resource.query.filter_by(id=primary_id).all())
return links

# function to add a relationship to a linked resource
def add_relationship(resource_id, linked_resource_id):
first_resource_id = resource_id
second_resource_id = linked_resource_id
new_relationship = Relationship(first_resource_id=first_resource_id, second_resource_id=second_resource_id)

# add the new relationship to the database
db.session.add(new_relationship)
db.session.commit()

# function to delete a single relationship
def delete_relationship(main_id, for_deletion_id):
relation = Relationship.query.filter(((Relationship.first_resource_id == main_id) & (Relationship.second_resource_id == for_deletion_id)) | ((Relationship.first_resource_id == for_deletion_id) & (Relationship.second_resource_id == main_id))).first()
deletion = Relationship.query.get(relation.id)
db.session.delete(deletion)
db.session.commit()

+ 0
- 42
web/app/resources.py View File

@@ -8,7 +8,6 @@
from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Resource
from .models import Relationship
from werkzeug.exceptions import abort
from . import db

@@ -19,50 +18,9 @@ def get_resource(resource_id):
abort(404)
return resource

# function to retrieve linked resources
def get_linked_resources(primary_id):
primary_relationships = Relationship.query.filter_by(first_resource_id=primary_id).all()
links = []
if primary_relationships:
links = []
for relationship in primary_relationships:
secondary_id = relationship.second_resource_id
links.extend(Resource.query.filter_by(id=secondary_id).all())
secondary_relationships = Relationship.query.filter_by(second_resource_id=primary_id).all()
if secondary_relationships:
for relationship in secondary_relationships:
primary_id = relationship.first_resource_id
links.extend(Resource.query.filter_by(id=primary_id).all())
return links
else:
secondary_relationships = Relationship.query.filter_by(second_resource_id=primary_id).all()
if secondary_relationships:
links = []
for relationship in secondary_relationships:
primary_id = relationship.first_resource_id
links.extend(Resource.query.filter_by(id=primary_id).all())
return links

# function to add a relationship to a linked resource
def add_linked_resource(resource_id, linked_resource_id):
first_resource_id = resource_id
second_resource_id = linked_resource_id
new_relationship = Relationship(first_resource_id=first_resource_id, second_resource_id=second_resource_id)

# add the new relationship to the database
db.session.add(new_relationship)
db.session.commit()

# function to delete a single resource
def delete_resource(resource_id):
deletion = Resource.query.get(resource_id)
db.session.delete(deletion)
db.session.commit()
flash('Successfully deleted!')

# function to delete a single relationship
def delete_relationship(main_id, for_deletion_id):
relation = Relationship.query.filter(((Relationship.first_resource_id == main_id) & (Relationship.second_resource_id == for_deletion_id)) | ((Relationship.first_resource_id == for_deletion_id) & (Relationship.second_resource_id == main_id))).first()
deletion = Relationship.query.get(relation.id)
db.session.delete(deletion)
db.session.commit()

+ 5
- 2
web/app/templates/edit.html View File

@@ -1,6 +1,9 @@
{% extends 'base.html' %}

{% block content %}

{{linked_resources}}

<h1>{% block title %} Edit "{{ resource['name'] }}" {% endblock %}</h1>

<form method="post">
@@ -83,7 +86,7 @@
{% for resource_dropdown in resource_dropdown %}
{% if resource_dropdown['type'] != 'tool' %}
{% if links and resource_dropdown in links %}
<option value="" selected>{{ resource_dropdown['name'] }}</option>
<option value="{{ resource_dropdown['id'] }}" selected>{{ resource_dropdown['name'] }}</option>
{% else %}
<option value="{{ resource_dropdown['id'] }}">{{ resource_dropdown['name'] }}</option>
{% endif %}
@@ -101,7 +104,7 @@
{% for resource_dropdown in resource_dropdown %}
{% if resource_dropdown['type'] != 'practice' %}
{% if links and resource_dropdown in links %}
<option value="" selected>{{ resource_dropdown['name'] }}</option>
<option value="{{ resource_dropdown['id'] }}" selected>{{ resource_dropdown['name'] }}</option>
{% else %}
<option value="{{ resource_dropdown['id'] }}">{{ resource_dropdown['name'] }}</option>
{% endif %}

+ 3
- 0
web/app/templates/resource.html View File

@@ -1,6 +1,9 @@
{% extends 'base.html' %}

{% block content %}

{{linked_resources}}

<div class="row">
<div class="col">
<h1 class="text-center">{% block title %} {{ resource['name'] }} {% endblock %}</h1>

+ 8
- 7
web/app/tool.py View File

@@ -10,6 +10,7 @@ from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Resource
from .resources import *
from .relationships import *
from werkzeug.exceptions import abort
from . import db
import os
@@ -26,7 +27,7 @@ def get_tools():
@tool.route('/tools/<int:tool_id>')
def show_tool(tool_id):
tool = get_resource(tool_id)
links = get_linked_resources(tool_id)
links = get_relationships(tool_id)
return render_template('resource.html', resource=tool, links=links)

# route for editing a single tool based on the ID in the database
@@ -35,7 +36,7 @@ def show_tool(tool_id):
def edit_tool(tool_id):
tool = get_resource(tool_id)
resource_dropdown = Resource.query
links = get_linked_resources(tool_id)
existing_relationships = get_relationships(tool_id)

if request.method == 'POST':
name = request.form['name']
@@ -69,16 +70,16 @@ def edit_tool(tool_id):
if linked_resources:
for linked_resource in linked_resources:
link = Resource.query.get(linked_resource)
if links and link not in links:
add_linked_resource(tool_id, linked_resource)
elif not links:
add_linked_resource(tool_id, linked_resource)
if existing_relationships and link not in existing_relationships:
add_relationship(tool_id, linked_resource)
elif not existing_relationships:
add_relationship(tool_id, linked_resource)
if remove_linked_resources:
for remove_linked_resource in remove_linked_resources:
delete_relationship(tool_id, remove_linked_resource)
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=links)
return render_template('edit.html', resource=tool, resource_dropdown=resource_dropdown, links=existing_relationships)

# route for function to delete a single tool from the edit page
@tool.route('/tools/<int:tool_id>/delete', methods=('POST',))

Loading…
Cancel
Save