Просмотр исходного кода

initial steps for consolidating resources into one database table

joel
Simon Bowie 2 лет назад
Родитель
Сommit
8e06695244
13 измененных файлов: 86 добавлений и 168 удалений
  1. +1
    -1
      web/app/book.py
  2. +29
    -19
      web/app/create.py
  3. +2
    -2
      web/app/main.py
  4. +10
    -108
      web/app/models.py
  5. +6
    -6
      web/app/practice.py
  6. +1
    -1
      web/app/publisher.py
  7. +1
    -1
      web/app/reference.py
  8. +1
    -1
      web/app/sensitivity.py
  9. +9
    -7
      web/app/templates/edit.html
  10. +8
    -6
      web/app/templates/tool.html
  11. +16
    -14
      web/app/tool.py
  12. +1
    -1
      web/app/typology.py
  13. +1
    -1
      web/app/workflow.py

+ 1
- 1
web/app/book.py Просмотреть файл

@@ -9,7 +9,7 @@

from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Book
from .models import Resource
from werkzeug.exceptions import abort
from . import db


+ 29
- 19
web/app/create.py Просмотреть файл

@@ -9,14 +9,8 @@

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 Practice
from .models import Sensitivity
from .models import Typology
from .models import Workflow
from .models import Publisher
from .models import Book
from .models import Reference
from .models import Resource
from .models import Relationships
from werkzeug.exceptions import abort
from . import db

@@ -28,6 +22,7 @@ create = Blueprint('create', __name__)
def create_resource():
if request.method == 'POST':
if request.form.get('resource_type') == 'tool':
type = 'tool'
name = request.form.get('tool_name')
description = request.form.get('description')
projectUrl = request.form.get('projectUrl')
@@ -38,45 +33,56 @@ def create_resource():
ingestFormats = request.form.get('ingestFormats')
outputFormats = request.form.get('outputFormats')
status = request.form.get('status')
practice_id = request.form.get('linked_practice_id')

if not name:
flash('Name is required!')
else:
tool = Tool.query.filter_by(name=name).first() # if this returns a tool, then the name already exists in database
tool = Resource.query.filter_by(type='tool').filter_by(name=name).first() # if this returns a tool, then the name already exists in database

if tool: # if a tool is found, we want to redirect back to create page
flash('Tool with same name already exists')
return redirect(url_for('create.create_resource'))

# create a new tool with the form data
new_tool = Tool(name=name, description=description, projectUrl=projectUrl, repositoryUrl=repositoryUrl, expertiseToUse=expertiseToUse, expertiseToHost=expertiseToHost, dependencies=dependencies, ingestFormats=ingestFormats, outputFormats=outputFormats, status=status, practice_id=practice_id)
new_tool = Resource(type=type, name=name, description=description, projectUrl=projectUrl, repositoryUrl=repositoryUrl, expertiseToUse=expertiseToUse, expertiseToHost=expertiseToHost, dependencies=dependencies, ingestFormats=ingestFormats, outputFormats=outputFormats, status=status)

# add the new tool to the database
db.session.add(new_tool)
db.session.commit()

if request.form.get('linked_practice_id'):
tool = Resource.query.filter_by(type='tool').filter_by(name=name).first()
first_resource_id = tool.id
second_resource_id = request.form.get('linked_practice_id')
new_relationship = Relationships(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()

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

if not name:
flash('Name is required!')
else:
practice = Practice.query.filter_by(name=name).first() # if this returns a practice, then the name already exists in database
practice = Resource.query.filter_by(type='practice').filter_by(name=name).first() # if this returns a practice, then the name already exists in database

if practice: # if a practice is found, we want to redirect back to create page
flash('Practice with same name already exists')
return redirect(url_for('create.create_resource'))

# create a new practice with the form data
new_practice = Practice(name=name, description=description)
new_practice = Resource(type=type, name=name, description=description)

# add the new practice to the database
db.session.add(new_practice)
db.session.commit()

elif request.form.get('resource_type') == 'sensitivity':
type = 'sensitivity'
name = request.form.get('sensitivity_name')
description = request.form.get('description')

@@ -90,13 +96,14 @@ def create_resource():
return redirect(url_for('create.create_resource'))

# create a new sensitivity with the form data
new_sensitivity = Sensitivity(name=name, description=description)
new_sensitivity = Resource(type=type, name=name, description=description)

# add the new sensitivity to the database
db.session.add(new_sensitivity)
db.session.commit()

elif request.form.get('resource_type') == 'typology':
type = 'typology'
name = request.form.get('typology_name')
description = request.form.get('description')

@@ -110,13 +117,14 @@ def create_resource():
return redirect(url_for('create.create_resource'))

# create a new typology with the form data
new_typology = Typology(name=name, description=description)
new_typology = Resource(type=type, name=name, description=description)

# add the new typology to the database
db.session.add(new_typology)
db.session.commit()

elif request.form.get('resource_type') == 'publisher':
type = 'publisher'
name = request.form.get('publisher_name')
description = request.form.get('description')
publisherUrl = request.form.get('publisherUrl')
@@ -131,13 +139,14 @@ def create_resource():
return redirect(url_for('create.create_resource'))

# create a new publisher with the form data
new_publisher = Publisher(name=name, description=description, publisherUrl=publisherUrl)
new_publisher = Resource(type=type, name=name, description=description, publisherUrl=publisherUrl)

# add the new publisher to the database
db.session.add(new_publisher)
db.session.commit()

elif request.form.get('resource_type') == 'book':
type = 'book'
name = request.form.get('book_name')
description = request.form.get('description')

@@ -151,13 +160,14 @@ def create_resource():
return redirect(url_for('create.create_resource'))

# create a new book with the form data
new_book = Book(name=name, description=description)
new_book = Resource(type=type, name=name, description=description)

# add the new book to the database
db.session.add(new_book)
db.session.commit()

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

if not zoteroUrl:
@@ -170,11 +180,11 @@ def create_resource():
return redirect(url_for('create.create_resource'))

# create a new reference with the form data
new_reference = Reference(zoteroUrl=zoteroUrl)
new_reference = Resource(type=type, zoteroUrl=zoteroUrl)

# add the new reference to the database
db.session.add(new_reference)
db.session.commit()

practice_dropdown = Practice.query
practice_dropdown = Resource.query.filter_by(type='practice')
return render_template('create.html', practice_dropdown=practice_dropdown)

+ 2
- 2
web/app/main.py Просмотреть файл

@@ -10,7 +10,7 @@
from flask import Blueprint, render_template
from flask_login import login_required, current_user
from . import db
from .models import Tool
from .models import Resource
from sqlalchemy.sql import func

main = Blueprint('main', __name__)
@@ -18,7 +18,7 @@ main = Blueprint('main', __name__)
# route for index page
@main.route('/')
def index():
tools = Tool.query.order_by(func.random()).limit(5).all()
tools = Resource.query.filter_by(type='tool').order_by(func.random()).limit(5).all()
return render_template('index.html', tools=tools)

# route for profile page

+ 10
- 108
web/app/models.py Просмотреть файл

@@ -20,12 +20,13 @@ class User(UserMixin, db.Model):
password = db.Column(db.String(100))
name = db.Column(db.String(1000))

# table for tools
class Tool(db.Model):
__tablename__ = 'Tool'
# table for resources
class Resource(db.Model):
__tablename__ = 'Resource'

id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
created = db.Column(db.DateTime, default=datetime.utcnow)
type = db.Column(db.Text)
name = db.Column(db.Text)
description = db.Column(db.Text)
projectUrl = db.Column(db.Text)
@@ -36,112 +37,13 @@ class Tool(db.Model):
ingestFormats = db.Column(db.Text)
outputFormats = db.Column(db.Text)
status = db.Column(db.Text)

practice_id = db.Column(db.Integer, db.ForeignKey('Practice.id'))
book_id = db.Column(db.Integer, db.ForeignKey('Book.id'))

practices = db.relationship('Practice', foreign_keys=[practice_id], backref='tool')
books = db.relationship('Book', foreign_keys=[book_id], backref='tool')

# table for practices
class Practice(db.Model):
__tablename__ = 'Practice'

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)
description = db.Column(db.Text)

tool_id = db.Column(db.Integer, db.ForeignKey('Tool.id'))
typology_id = db.Column(db.Integer, db.ForeignKey('Typology.id'))
book_id = db.Column(db.Integer, db.ForeignKey('Book.id'))
reference_id = db.Column(db.Integer, db.ForeignKey('Reference.id'))

tools = db.relationship('Tool', foreign_keys=[tool_id], backref='practice')
typologies = db.relationship('Typology', foreign_keys=[typology_id], backref='practice')
books = db.relationship('Book', foreign_keys=[book_id], backref='practice')
references = db.relationship('Reference', foreign_keys=[reference_id], backref='practice')

# table for sensitivities
class Sensitivity(db.Model):
__tablename__ = 'Sensitivity'

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)
description = db.Column(db.Text)

practice_id = db.Column(db.Integer, db.ForeignKey('Practice.id'))
typology_id = db.Column(db.Integer, db.ForeignKey('Typology.id'))
reference_id = db.Column(db.Integer, db.ForeignKey('Reference.id'))

practices = db.relationship('Practice', foreign_keys=[practice_id], backref='sensitivity')
typologies = db.relationship('Typology', foreign_keys=[typology_id], backref='sensitivity')
references = db.relationship('Reference', foreign_keys=[reference_id], backref='sensitivity')

# table for typologies
class Typology(db.Model):
__tablename__ = 'Typology'

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)
description = db.Column(db.Text)

tool_id = db.Column(db.Integer, db.ForeignKey('Tool.id'))
book_id = db.Column(db.Integer, db.ForeignKey('Book.id'))
practice_id = db.Column(db.Integer, db.ForeignKey('Practice.id'))
reference_id = db.Column(db.Integer, db.ForeignKey('Reference.id'))

tools = db.relationship('Tool', foreign_keys=[tool_id], backref='typology')
books = db.relationship('Book', foreign_keys=[book_id], backref='typology_books')
practices = db.relationship('Practice', foreign_keys=[practice_id], backref='typology')
references = db.relationship('Reference', foreign_keys=[reference_id], backref='typology')

# table for workflows
class Workflow(db.Model):
__tablename__ = 'Workflow'

id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
created = db.Column(db.DateTime, default=datetime.utcnow)

# table for publishers
class Publisher(db.Model):
__tablename__ = 'Publisher'

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)
description = db.Column(db.Text)
publisherUrl = db.Column(db.Text)
zoteroUrl = db.Column(db.Text)

book_id = db.Column(db.Integer, db.ForeignKey('Book.id'))

books = db.relationship('Book', foreign_keys=[book_id], backref='publisher')

# table for books
class Book(db.Model):
__tablename__ = 'Book'

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)
description = db.Column(db.Text)

tool_id = db.Column(db.Integer, db.ForeignKey('Tool.id'))
typology_id = db.Column(db.Integer, db.ForeignKey('Typology.id'))
practice_id = db.Column(db.Integer, db.ForeignKey('Practice.id'))
workflow_id = db.Column(db.Integer, db.ForeignKey('Workflow.id'))

tools = db.relationship('Tool', foreign_keys=[tool_id], backref='book')
typology = db.relationship('Typology', foreign_keys=[typology_id], backref='book')
practices = db.relationship('Practice', foreign_keys=[practice_id], backref='book')
workflow = db.relationship('Workflow', foreign_keys=[workflow_id], backref='book')

# table for references
class Reference(db.Model):
__tablename__ = 'Reference'
# table for relationships
class Relationships(db.Model):
__tablename__ = 'Relationships'

id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
created = db.Column(db.DateTime, default=datetime.utcnow)
zoteroUrl = db.Column(db.Text)
first_resource_id = db.Column(db.Integer)
second_resource_id = db.Column(db.Integer)

+ 6
- 6
web/app/practice.py Просмотреть файл

@@ -9,7 +9,7 @@

from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Practice
from .models import Resource
from werkzeug.exceptions import abort
from . import db

@@ -17,7 +17,7 @@ practice = Blueprint('practice', __name__)

# function to retrieve data about a single practice from the database
def get_practice(practice_id):
practice = Practice.query.filter_by(id=practice_id).first()
practice = Resource.query.filter_by(id=practice_id).first()
if practice is None:
abort(404)
return practice
@@ -25,7 +25,7 @@ def get_practice(practice_id):
# route for displaying all practices in database
@practice.route('/practices')
def get_practices():
practices = Practice.query
practices = Resource.query.filter_by(type='practice')
return render_template('practices.html', practices=practices)

# route for displaying a single practice based on the ID in the database
@@ -47,20 +47,20 @@ def edit_practice(practice_id):
if not name:
flash('Name is required!')
else:
practice = Practice.query.get(practice_id)
practice = Resource.query.get(practice_id)
practice.name = name
practice.description = description
db.session.commit()
return redirect(url_for('practice.get_practices'))

return render_template('edit.html', practice=practice)
return render_template('edit.html', resource=practice)

# route for function to delete a single practice from the edit page
@practice.route('/practices/<int:practice_id>/delete', methods=('POST',))
@login_required
def delete_practice(practice_id):
practice = get_practice(practice_id)
deletion = Practice.query.get(practice_id)
deletion = Resource.query.get(practice_id)
db.session.delete(deletion)
db.session.commit()
flash('Successfully deleted!')

+ 1
- 1
web/app/publisher.py Просмотреть файл

@@ -9,7 +9,7 @@

from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Publisher
from .models import Resource
from werkzeug.exceptions import abort
from . import db


+ 1
- 1
web/app/reference.py Просмотреть файл

@@ -9,7 +9,7 @@

from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Reference
from .models import Resource
from werkzeug.exceptions import abort
from . import db


+ 1
- 1
web/app/sensitivity.py Просмотреть файл

@@ -9,7 +9,7 @@

from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Sensitivity
from .models import Resource
from werkzeug.exceptions import abort
from . import db


+ 9
- 7
web/app/templates/edit.html Просмотреть файл

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

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

<form method="post">
<div class="mb-3 mt-3">
<label for="name">Name</label>
<input type="text" name="name" placeholder="Tool name"
<input type="text" name="name" placeholder="Name"
class="form-control"
value="{{ request.form['name'] or tool['name'] }}">
value="{{ request.form['name'] or resource['name'] }}">
</input>
</div>

<div class="mb-3 mt-3">
<label for="description">Description</label>
<textarea name="description" placeholder="Tool description"
class="form-control">{{ request.form['description'] or tool['description'] }}</textarea>
<textarea name="description" placeholder="Description"
class="form-control">{{ request.form['description'] or resource['description'] }}</textarea>
</div>
<div class="mb-3 mt-3">
<button type="submit" class="btn btn-primary">Submit</button>
@@ -23,9 +23,11 @@
</form>
<hr>

<form action="{{ url_for('tool.delete_tool', tool_id=tool['id']) }}" method="POST">
<input type="submit" value="Delete Tool"
{% if resource['type'] == 'tool' %}
<form action="{{ url_for('tool.delete_tool', tool_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 tool?')">
</form>
{% endif %}
{% endblock %}

+ 8
- 6
web/app/templates/tool.html Просмотреть файл

@@ -101,25 +101,27 @@
</table>
</div>
</div>
{% if resources %}
<div class="row">
<div class="col">
<h2 class="text-center">Linked practices:</h2>
<h2 class="text-center">Linked resources:</h2>
</div>
</div>
<div class="row">
{% for resource in resources %}
<div class="col-md-4 col-sm-6 py-3">
<div class="card text-dark bg-warning mb-3">
<div class="card-body">
<a href="{{ url_for('practice.show_practice', practice_id=practice['id']) }}">
<h3 class="card-title text-center text-dark">{{ practice['name'] }}</h3>
<a href="{{ url_for('practice.show_practice', practice_id=resource['id']) }}">
<h3 class="card-title text-center text-dark">{{ resource['name'] }}</h3>
</a>
<p class="card-text">
{{ practice['description']|truncate(100) }}
{{ resource['description']|truncate(100) }}
</p>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
{% endblock %}

+ 16
- 14
web/app/tool.py Просмотреть файл

@@ -9,8 +9,8 @@

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 Practice
from .models import Resource
from .models import Relationships
from werkzeug.exceptions import abort
from . import db

@@ -18,28 +18,31 @@ tool = Blueprint('tool', __name__)

# function to retrieve data about a single tool from the database
def get_tool(tool_id):
tool = Tool.query.filter_by(id=tool_id).first()
tool = Resource.query.filter_by(id=tool_id).first()
if tool is None:
abort(404)
return tool

# function to retrieve linked practices
def get_practice(practice_id):
practice = Practice.query.filter_by(id=practice_id).first()
return practice
# function to retrieve linked resources
def get_linked_resources(tool_id):
relationships = Relationships.query.filter_by(first_resource_id=tool_id).first()
if relationships:
resource_id = relationships.second_resource_id
resources = Resource.query.filter_by(id=resource_id).all()
return resources

# route for displaying all tools in database
@tool.route('/tools')
def get_tools():
tools = Tool.query
tools = Resource.query.filter_by(type='tool')
return render_template('tools.html', tools=tools)

# route for displaying a single tool based on the ID in the database
@tool.route('/tools/<int:tool_id>')
def show_tool(tool_id):
tool = get_tool(tool_id)
practice = get_practice(tool.practice_id)
return render_template('tool.html', tool=tool, practice=practice)
resources = get_linked_resources(tool_id)
return render_template('tool.html', tool=tool, resources=resources)

# route for editing a single tool based on the ID in the database
@tool.route('/tools/<int:tool_id>/edit', methods=('GET', 'POST'))
@@ -54,7 +57,7 @@ def edit_tool(tool_id):
if not name:
flash('Name is required!')
else:
tool = Tool.query.get(tool_id)
tool = Resource.query.get(tool_id)
tool.name = name
tool.description = description
tool.projectUrl = project_url
@@ -65,18 +68,17 @@ def edit_tool(tool_id):
tool.ingestFormats = ingest
tool.outputFormats = output
tool.status = status
tool.practice_id = practice_id
db.session.commit()
return redirect(url_for('tool.get_tools'))

return render_template('edit.html', tool=tool)
return render_template('edit.html', resource=tool)

# route for function to delete a single tool from the edit page
@tool.route('/tools/<int:tool_id>/delete', methods=('POST',))
@login_required
def delete_tool(tool_id):
tool = get_tool(tool_id)
deletion = Tool.query.get(tool_id)
deletion = Resource.query.get(tool_id)
db.session.delete(deletion)
db.session.commit()
flash('Successfully deleted!')

+ 1
- 1
web/app/typology.py Просмотреть файл

@@ -9,7 +9,7 @@

from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Typology
from .models import Resource
from werkzeug.exceptions import abort
from . import db


+ 1
- 1
web/app/workflow.py Просмотреть файл

@@ -9,7 +9,7 @@

from flask import Blueprint, render_template, request, flash, redirect, url_for
from flask_login import login_required, current_user
from .models import Workflow
from .models import Resource
from werkzeug.exceptions import abort
from . import db


Загрузка…
Отмена
Сохранить