mirror of
https://github.com/Sudo-JHare/FhirPad.git
synced 2025-08-01 19:55:33 +00:00
Update routes.py
This commit is contained in:
parent
cb46f24f9e
commit
e376f8cfae
217
app/routes.py
217
app/routes.py
@ -1,22 +1,19 @@
|
|||||||
# app/routes.py
|
|
||||||
from flask import Blueprint, render_template, redirect, url_for, flash, request, send_from_directory, abort
|
from flask import Blueprint, render_template, redirect, url_for, flash, request, send_from_directory, abort
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from app import db
|
from app import db
|
||||||
from app.models import SmartApp, ApplicationType, Category, OSSupport, FHIRSupport, Speciality, PricingLicense, DesignedFor, EHRSupport
|
from app.models import FHIRApp, ApplicationType, Category, OSSupport, FHIRSupport, Speciality, PricingLicense, DesignedFor, EHRSupport
|
||||||
from app.forms import SmartAppForm, GalleryFilterForm
|
from app.forms import FHIRAppForm, GalleryFilterForm, CategoryForm
|
||||||
from sqlalchemy import or_, and_
|
from sqlalchemy import or_
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
# Setup logging
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
gallery_bp = Blueprint('gallery', __name__)
|
gallery_bp = Blueprint('gallery', __name__)
|
||||||
|
|
||||||
# Absolute path to the upload folder inside the container
|
|
||||||
UPLOAD_FOLDER = '/app/uploads/'
|
UPLOAD_FOLDER = '/app/uploads/'
|
||||||
ALLOWED_EXTENSIONS = {'jpg', 'png'}
|
ALLOWED_EXTENSIONS = {'jpg', 'png'}
|
||||||
|
|
||||||
@ -35,27 +32,31 @@ def uploaded_file(filename):
|
|||||||
|
|
||||||
@gallery_bp.route('/')
|
@gallery_bp.route('/')
|
||||||
def index():
|
def index():
|
||||||
return redirect(url_for('gallery.gallery'))
|
return redirect(url_for('gallery.landing'))
|
||||||
|
|
||||||
|
@gallery_bp.route('/landing')
|
||||||
|
def landing():
|
||||||
|
featured_apps = FHIRApp.query.order_by(FHIRApp.registration_date.desc()).limit(6).all()
|
||||||
|
categories = Category.query.all()
|
||||||
|
return render_template('landing.html', featured_apps=featured_apps, categories=categories)
|
||||||
|
|
||||||
@gallery_bp.route('/gallery', methods=['GET', 'POST'])
|
@gallery_bp.route('/gallery', methods=['GET', 'POST'])
|
||||||
def gallery():
|
def gallery():
|
||||||
form = GalleryFilterForm()
|
form = GalleryFilterForm()
|
||||||
query = SmartApp.query
|
query = FHIRApp.query
|
||||||
filter_params = {}
|
filter_params = {}
|
||||||
|
|
||||||
# Handle search
|
|
||||||
search_term = request.args.get('search', '').strip()
|
search_term = request.args.get('search', '').strip()
|
||||||
if search_term:
|
if search_term:
|
||||||
query = query.filter(
|
query = query.filter(
|
||||||
or_(
|
or_(
|
||||||
SmartApp.name.ilike(f'%{search_term}%'),
|
FHIRApp.name.ilike(f'%{search_term}%'),
|
||||||
SmartApp.description.ilike(f'%{search_term}%'),
|
FHIRApp.description.ilike(f'%{search_term}%'),
|
||||||
SmartApp.developer.ilike(f'%{search_term}%')
|
FHIRApp.developer.ilike(f'%{search_term}%')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
filter_params['search'] = search_term
|
filter_params['search'] = search_term
|
||||||
|
|
||||||
# Existing filter logic
|
|
||||||
application_type_ids = request.args.getlist('application_type', type=int)
|
application_type_ids = request.args.getlist('application_type', type=int)
|
||||||
category_ids = request.args.getlist('category', type=int)
|
category_ids = request.args.getlist('category', type=int)
|
||||||
os_support_ids = request.args.getlist('os_support', type=int)
|
os_support_ids = request.args.getlist('os_support', type=int)
|
||||||
@ -66,28 +67,28 @@ def gallery():
|
|||||||
ehr_support_ids = request.args.getlist('ehr_support', type=int)
|
ehr_support_ids = request.args.getlist('ehr_support', type=int)
|
||||||
|
|
||||||
if application_type_ids:
|
if application_type_ids:
|
||||||
query = query.filter(SmartApp.application_type_id.in_(application_type_ids))
|
query = query.filter(FHIRApp.application_type_id.in_(application_type_ids))
|
||||||
filter_params['application_type'] = application_type_ids
|
filter_params['application_type'] = application_type_ids
|
||||||
if category_ids:
|
if category_ids:
|
||||||
query = query.filter(or_(*[SmartApp.categories.contains(str(cid)) for cid in category_ids]))
|
query = query.filter(or_(*[FHIRApp.categories.contains(str(cid)) for cid in category_ids]))
|
||||||
filter_params['category'] = category_ids
|
filter_params['category'] = category_ids
|
||||||
if os_support_ids:
|
if os_support_ids:
|
||||||
query = query.filter(or_(*[SmartApp.os_support.contains(str(oid)) for oid in os_support_ids]))
|
query = query.filter(or_(*[FHIRApp.os_support.contains(str(oid)) for oid in os_support_ids]))
|
||||||
filter_params['os_support'] = os_support_ids
|
filter_params['os_support'] = os_support_ids
|
||||||
if fhir_support_ids:
|
if fhir_support_ids:
|
||||||
query = query.filter(SmartApp.fhir_compatibility_id.in_(fhir_support_ids))
|
query = query.filter(FHIRApp.fhir_compatibility_id.in_(fhir_support_ids))
|
||||||
filter_params['fhir_support'] = fhir_support_ids
|
filter_params['fhir_support'] = fhir_support_ids
|
||||||
if speciality_ids:
|
if speciality_ids:
|
||||||
query = query.filter(or_(*[SmartApp.specialties.contains(str(sid)) for sid in speciality_ids]))
|
query = query.filter(or_(*[FHIRApp.specialties.contains(str(sid)) for sid in speciality_ids]))
|
||||||
filter_params['speciality'] = speciality_ids
|
filter_params['speciality'] = speciality_ids
|
||||||
if pricing_license_ids:
|
if pricing_license_ids:
|
||||||
query = query.filter(SmartApp.licensing_pricing_id.in_(pricing_license_ids))
|
query = query.filter(FHIRApp.licensing_pricing_id.in_(pricing_license_ids))
|
||||||
filter_params['pricing_license'] = pricing_license_ids
|
filter_params['pricing_license'] = pricing_license_ids
|
||||||
if designed_for_ids:
|
if designed_for_ids:
|
||||||
query = query.filter(SmartApp.designed_for_id.in_(designed_for_ids))
|
query = query.filter(FHIRApp.designed_for_id.in_(designed_for_ids))
|
||||||
filter_params['designed_for'] = designed_for_ids
|
filter_params['designed_for'] = designed_for_ids
|
||||||
if ehr_support_ids:
|
if ehr_support_ids:
|
||||||
query = query.filter(or_(*[SmartApp.ehr_support.contains(str(eid)) for eid in ehr_support_ids]))
|
query = query.filter(or_(*[FHIRApp.ehr_support.contains(str(eid)) for eid in ehr_support_ids]))
|
||||||
filter_params['ehr_support'] = ehr_support_ids
|
filter_params['ehr_support'] = ehr_support_ids
|
||||||
|
|
||||||
apps = query.all()
|
apps = query.all()
|
||||||
@ -110,7 +111,7 @@ def gallery():
|
|||||||
|
|
||||||
@gallery_bp.route('/gallery/<int:app_id>')
|
@gallery_bp.route('/gallery/<int:app_id>')
|
||||||
def app_detail(app_id):
|
def app_detail(app_id):
|
||||||
app = SmartApp.query.get_or_404(app_id)
|
app = FHIRApp.query.get_or_404(app_id)
|
||||||
logger.debug(f"App Detail ID: {app_id}, logo_url: {app.logo_url}, app_images: {app.app_images}")
|
logger.debug(f"App Detail ID: {app_id}, logo_url: {app.logo_url}, app_images: {app.app_images}")
|
||||||
app_categories = []
|
app_categories = []
|
||||||
if app.categories:
|
if app.categories:
|
||||||
@ -144,7 +145,7 @@ def app_detail(app_id):
|
|||||||
@gallery_bp.route('/gallery/register', methods=['GET', 'POST'])
|
@gallery_bp.route('/gallery/register', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def register():
|
def register():
|
||||||
form = SmartAppForm()
|
form = FHIRAppForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
scopes = form.scopes.data
|
scopes = form.scopes.data
|
||||||
valid_scopes = all(
|
valid_scopes = all(
|
||||||
@ -153,7 +154,7 @@ def register():
|
|||||||
if scope.strip()
|
if scope.strip()
|
||||||
)
|
)
|
||||||
if not valid_scopes or not scopes.strip():
|
if not valid_scopes or not scopes.strip():
|
||||||
flash('Invalid SMART scopes. Use formats like patient/Patient.read, launch/patient.', 'danger')
|
flash('Invalid FHIR scopes. Use formats like patient/Patient.read, launch/patient.', 'danger')
|
||||||
return render_template('register.html', form=form)
|
return render_template('register.html', form=form)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -164,47 +165,6 @@ def register():
|
|||||||
flash('Error creating upload directory.', 'danger')
|
flash('Error creating upload directory.', 'danger')
|
||||||
return render_template('register.html', form=form)
|
return render_template('register.html', form=form)
|
||||||
|
|
||||||
if form.application_type_new.data:
|
|
||||||
app_type = ApplicationType(name=form.application_type_new.data)
|
|
||||||
db.session.add(app_type)
|
|
||||||
db.session.commit()
|
|
||||||
form.application_type.data = app_type.id
|
|
||||||
if form.categories_new.data:
|
|
||||||
category = Category(name=form.categories_new.data)
|
|
||||||
db.session.add(category)
|
|
||||||
db.session.commit()
|
|
||||||
form.categories.data.append(category.id)
|
|
||||||
if form.os_support_new.data:
|
|
||||||
os_support = OSSupport(name=form.os_support_new.data)
|
|
||||||
db.session.add(os_support)
|
|
||||||
db.session.commit()
|
|
||||||
form.os_support.data.append(os_support.id)
|
|
||||||
if form.fhir_compatibility_new.data:
|
|
||||||
fhir = FHIRSupport(name=form.fhir_compatibility_new.data)
|
|
||||||
db.session.add(fhir)
|
|
||||||
db.session.commit()
|
|
||||||
form.fhir_compatibility.data = fhir.id
|
|
||||||
if form.specialties_new.data:
|
|
||||||
speciality = Speciality(name=form.specialties_new.data)
|
|
||||||
db.session.add(speciality)
|
|
||||||
db.session.commit()
|
|
||||||
form.specialties.data.append(speciality.id)
|
|
||||||
if form.licensing_pricing_new.data:
|
|
||||||
pricing = PricingLicense(name=form.licensing_pricing_new.data)
|
|
||||||
db.session.add(pricing)
|
|
||||||
db.session.commit()
|
|
||||||
form.licensing_pricing.data = pricing.id
|
|
||||||
if form.designed_for_new.data:
|
|
||||||
designed = DesignedFor(name=form.designed_for_new.data)
|
|
||||||
db.session.add(designed)
|
|
||||||
db.session.commit()
|
|
||||||
form.designed_for.data = designed.id
|
|
||||||
if form.ehr_support_new.data:
|
|
||||||
ehr = EHRSupport(name=form.ehr_support_new.data)
|
|
||||||
db.session.add(ehr)
|
|
||||||
db.session.commit()
|
|
||||||
form.ehr_support.data.append(ehr.id)
|
|
||||||
|
|
||||||
logo_url = form.logo_url.data
|
logo_url = form.logo_url.data
|
||||||
if form.logo_upload.data:
|
if form.logo_upload.data:
|
||||||
file = form.logo_upload.data
|
file = form.logo_upload.data
|
||||||
@ -250,7 +210,7 @@ def register():
|
|||||||
flash('Error saving app image.', 'danger')
|
flash('Error saving app image.', 'danger')
|
||||||
return render_template('register.html', form=form)
|
return render_template('register.html', form=form)
|
||||||
|
|
||||||
app = SmartApp(
|
app = FHIRApp(
|
||||||
name=form.name.data,
|
name=form.name.data,
|
||||||
description=form.description.data,
|
description=form.description.data,
|
||||||
developer=form.developer.data,
|
developer=form.developer.data,
|
||||||
@ -287,12 +247,12 @@ def register():
|
|||||||
@gallery_bp.route('/gallery/edit/<int:app_id>', methods=['GET', 'POST'])
|
@gallery_bp.route('/gallery/edit/<int:app_id>', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def edit_app(app_id):
|
def edit_app(app_id):
|
||||||
app = SmartApp.query.get_or_404(app_id)
|
app = FHIRApp.query.get_or_404(app_id)
|
||||||
if app.user_id != current_user.id:
|
if not current_user.is_admin and app.user_id != current_user.id:
|
||||||
flash('You can only edit your own apps.', 'danger')
|
flash('You can only edit your own apps.', 'danger')
|
||||||
return redirect(url_for('gallery.app_detail', app_id=app_id))
|
return redirect(url_for('gallery.app_detail', app_id=app_id))
|
||||||
|
|
||||||
form = SmartAppForm(obj=app)
|
form = FHIRAppForm(obj=app)
|
||||||
if not form.is_submitted():
|
if not form.is_submitted():
|
||||||
if app.categories:
|
if app.categories:
|
||||||
form.categories.data = [int(cid) for cid in app.categories.split(',') if cid]
|
form.categories.data = [int(cid) for cid in app.categories.split(',') if cid]
|
||||||
@ -316,7 +276,7 @@ def edit_app(app_id):
|
|||||||
if scope.strip()
|
if scope.strip()
|
||||||
)
|
)
|
||||||
if not valid_scopes or not scopes.strip():
|
if not valid_scopes or not scopes.strip():
|
||||||
flash('Invalid SMART scopes. Use formats like patient/Patient.read, launch/patient.', 'danger')
|
flash('Invalid FHIR scopes. Use formats like patient/Patient.read, launch/patient.', 'danger')
|
||||||
return render_template('edit_app.html', form=form, app=app)
|
return render_template('edit_app.html', form=form, app=app)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -327,55 +287,6 @@ def edit_app(app_id):
|
|||||||
flash('Error creating upload directory.', 'danger')
|
flash('Error creating upload directory.', 'danger')
|
||||||
return render_template('edit_app.html', form=form, app=app)
|
return render_template('edit_app.html', form=form, app=app)
|
||||||
|
|
||||||
if form.application_type_new.data:
|
|
||||||
app_type = ApplicationType(name=form.application_type_new.data)
|
|
||||||
db.session.add(app_type)
|
|
||||||
db.session.commit()
|
|
||||||
form.application_type.data = app_type.id
|
|
||||||
if form.categories_new.data:
|
|
||||||
category = Category(name=form.categories_new.data)
|
|
||||||
db.session.add(category)
|
|
||||||
db.session.commit()
|
|
||||||
if form.categories.data is None:
|
|
||||||
form.categories.data = []
|
|
||||||
form.categories.data.append(category.id)
|
|
||||||
if form.os_support_new.data:
|
|
||||||
os_support = OSSupport(name=form.os_support_new.data)
|
|
||||||
db.session.add(os_support)
|
|
||||||
db.session.commit()
|
|
||||||
if form.os_support.data is None:
|
|
||||||
form.os_support.data = []
|
|
||||||
form.os_support.data.append(os_support.id)
|
|
||||||
if form.fhir_compatibility_new.data:
|
|
||||||
fhir = FHIRSupport(name=form.fhir_compatibility_new.data)
|
|
||||||
db.session.add(fhir)
|
|
||||||
db.session.commit()
|
|
||||||
form.fhir_compatibility.data = fhir.id
|
|
||||||
if form.specialties_new.data:
|
|
||||||
speciality = Speciality(name=form.specialties_new.data)
|
|
||||||
db.session.add(speciality)
|
|
||||||
db.session.commit()
|
|
||||||
if form.specialties.data is None:
|
|
||||||
form.specialties.data = []
|
|
||||||
form.specialties.data.append(speciality.id)
|
|
||||||
if form.licensing_pricing_new.data:
|
|
||||||
pricing = PricingLicense(name=form.licensing_pricing_new.data)
|
|
||||||
db.session.add(pricing)
|
|
||||||
db.session.commit()
|
|
||||||
form.licensing_pricing.data = pricing.id
|
|
||||||
if form.designed_for_new.data:
|
|
||||||
designed = DesignedFor(name=form.designed_for_new.data)
|
|
||||||
db.session.add(designed)
|
|
||||||
db.session.commit()
|
|
||||||
form.designed_for.data = designed.id
|
|
||||||
if form.ehr_support_new.data:
|
|
||||||
ehr = EHRSupport(name=form.ehr_support_new.data)
|
|
||||||
db.session.add(ehr)
|
|
||||||
db.session.commit()
|
|
||||||
if form.ehr_support.data is None:
|
|
||||||
form.ehr_support.data = []
|
|
||||||
form.ehr_support.data.append(ehr.id)
|
|
||||||
|
|
||||||
logo_url = form.logo_url.data
|
logo_url = form.logo_url.data
|
||||||
if form.logo_upload.data:
|
if form.logo_upload.data:
|
||||||
file = form.logo_upload.data
|
file = form.logo_upload.data
|
||||||
@ -455,8 +366,8 @@ def edit_app(app_id):
|
|||||||
@gallery_bp.route('/gallery/delete/<int:app_id>', methods=['POST'])
|
@gallery_bp.route('/gallery/delete/<int:app_id>', methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def delete_app(app_id):
|
def delete_app(app_id):
|
||||||
app = SmartApp.query.get_or_404(app_id)
|
app = FHIRApp.query.get_or_404(app_id)
|
||||||
if app.user_id != current_user.id:
|
if not current_user.is_admin and app.user_id != current_user.id:
|
||||||
flash('You can only delete your own apps.', 'danger')
|
flash('You can only delete your own apps.', 'danger')
|
||||||
return redirect(url_for('gallery.app_detail', app_id=app_id))
|
return redirect(url_for('gallery.app_detail', app_id=app_id))
|
||||||
db.session.delete(app)
|
db.session.delete(app)
|
||||||
@ -467,38 +378,42 @@ def delete_app(app_id):
|
|||||||
@gallery_bp.route('/my-listings')
|
@gallery_bp.route('/my-listings')
|
||||||
@login_required
|
@login_required
|
||||||
def my_listings():
|
def my_listings():
|
||||||
apps = SmartApp.query.filter_by(user_id=current_user.id).all()
|
apps = FHIRApp.query.filter_by(user_id=current_user.id).all()
|
||||||
return render_template('my_listings.html', apps=apps)
|
return render_template('my_listings.html', apps=apps)
|
||||||
|
|
||||||
@gallery_bp.route('/test/add')
|
@gallery_bp.route('/admin/categories', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def add_test_app():
|
def manage_categories():
|
||||||
logo_url = "https://via.placeholder.com/150"
|
if not current_user.is_admin:
|
||||||
app_images = "https://via.placeholder.com/300"
|
flash('Admin access required.', 'danger')
|
||||||
|
return redirect(url_for('gallery.landing'))
|
||||||
|
form = CategoryForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
category = Category(name=form.name.data)
|
||||||
|
db.session.add(category)
|
||||||
|
db.session.commit()
|
||||||
|
flash('Category added successfully!', 'success')
|
||||||
|
return redirect(url_for('gallery.manage_categories'))
|
||||||
|
categories = Category.query.all()
|
||||||
|
return render_template('admin_categories.html', form=form, categories=categories)
|
||||||
|
|
||||||
test_app = SmartApp(
|
@gallery_bp.route('/admin/categories/delete/<int:category_id>', methods=['POST'])
|
||||||
name="Test App",
|
@login_required
|
||||||
description="A sample SMART on FHIR app.",
|
def delete_category(category_id):
|
||||||
developer="Test Developer",
|
if not current_user.is_admin:
|
||||||
contact_email="test@example.com",
|
flash('Admin access required.', 'danger')
|
||||||
logo_url=logo_url,
|
return redirect(url_for('gallery.landing'))
|
||||||
launch_url="https://example.com/launch",
|
category = Category.query.get_or_404(category_id)
|
||||||
client_id="test-client-id",
|
db.session.delete(category)
|
||||||
scopes="patient/Patient.read,launch/patient",
|
|
||||||
website="https://example.com",
|
|
||||||
designed_for_id=DesignedFor.query.filter_by(name="Clinicians").first().id if DesignedFor.query.filter_by(name="Clinicians").first() else None,
|
|
||||||
application_type_id=ApplicationType.query.filter_by(name="SMART").first().id if ApplicationType.query.filter_by(name="SMART").first() else None,
|
|
||||||
fhir_compatibility_id=FHIRSupport.query.filter_by(name="R4").first().id if FHIRSupport.query.filter_by(name="R4").first() else None,
|
|
||||||
categories=','.join(str(c.id) for c in Category.query.filter(Category.name.in_(["Clinical", "Patient Engagement"])).all()) if Category.query.filter(Category.name.in_(["Clinical", "Patient Engagement"])).all() else None,
|
|
||||||
specialties=','.join(str(s.id) for s in Speciality.query.filter(Speciality.name.in_(["Cardiology", "General Practice"])).all()) if Speciality.query.filter(Speciality.name.in_(["Cardiology", "General Practice"])).all() else None,
|
|
||||||
licensing_pricing_id=PricingLicense.query.filter_by(name="Free").first().id if PricingLicense.query.filter_by(name="Free").first() else None,
|
|
||||||
os_support=','.join(str(o.id) for o in OSSupport.query.filter(OSSupport.name.in_(["Web", "iOS", "Android"])).all()) if OSSupport.query.filter(OSSupport.name.in_(["Web", "iOS", "Android"])).all() else None,
|
|
||||||
app_images=app_images,
|
|
||||||
ehr_support=','.join(str(e.id) for e in EHRSupport.query.filter(EHRSupport.name.in_(["Epic", "Cerner"])).all()) if EHRSupport.query.filter(EHRSupport.name.in_(["Epic", "Cerner"])).all() else None,
|
|
||||||
user_id=current_user.id
|
|
||||||
)
|
|
||||||
db.session.add(test_app)
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
logger.debug(f"Test app ID: {test_app.id}, logo_url: {test_app.logo_url}")
|
flash(f'Category "{category.name}" deleted successfully.', 'success')
|
||||||
flash('Test app added successfully!', 'success')
|
return redirect(url_for('gallery.manage_categories'))
|
||||||
return redirect(url_for('gallery.gallery'))
|
|
||||||
|
@gallery_bp.route('/admin/apps')
|
||||||
|
@login_required
|
||||||
|
def admin_apps():
|
||||||
|
if not current_user.is_admin:
|
||||||
|
flash('Admin access required.', 'danger')
|
||||||
|
return redirect(url_for('gallery.landing'))
|
||||||
|
apps = FHIRApp.query.all()
|
||||||
|
return render_template('admin_apps.html', apps=apps)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user