Skip to content

Commit

Permalink
Merge branch 'release/v18.3.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-c committed Mar 9, 2018
2 parents 2459c19 + fe5ac79 commit e151c2a
Show file tree
Hide file tree
Showing 93 changed files with 11,618 additions and 1,194 deletions.
2 changes: 2 additions & 0 deletions docs/source/portal_models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ Portal.Models
.. automodule:: portal.models.relationship
:members:
:undoc-members:
:exclude-members: RELATIONSHIP

.. automodule:: portal.models.role
:members:
:undoc-members:
:exclude-members: ROLE

.. automodule:: portal.models.telecom
:members:
Expand Down
1 change: 0 additions & 1 deletion portal/config/eproms/Intervention.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"entry": [
{
"card_html": "set by access strategy depending on state",
"description": "",
"display_rank": 1,
"link_label": "Begin questionnaire",
Expand Down
14 changes: 12 additions & 2 deletions portal/config/eproms/Organization.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
"url": "http://hl7.org/fhir/StructureDefinition/user-timezone"
},
{
"research_protocol": "TNGR v1",
"research_protocols": [
{"name": "TNGR v1"}
],
"url": "http://us.truenth.org/identity-codes/research-protocol"
}
],
Expand Down Expand Up @@ -431,7 +433,9 @@
"url": "http://hl7.org/fhir/StructureDefinition/user-timezone"
},
{
"research_protocol": "IRONMAN v2",
"research_protocols": [
{"name": "IRONMAN v2"}
],
"url": "http://us.truenth.org/identity-codes/research-protocol"
}
],
Expand Down Expand Up @@ -754,6 +758,12 @@
{
"timezone": "America/New_York",
"url": "http://hl7.org/fhir/StructureDefinition/user-timezone"
},
{
"research_protocols": [
{"name": "IRONMAN v2"}
],
"url": "http://us.truenth.org/identity-codes/research-protocol"
}
],
"id": 22000,
Expand Down
7 changes: 7 additions & 0 deletions portal/config/eproms/ScheduledJob.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@
"schedule": "57 * * * *",
"task": "cache_reporting_stats"
},
{
"active": true,
"name": "Service Token Watchdog",
"resourceType": "ScheduledJob",
"schedule": "30 2 * * *",
"task": "token_watchdog"
},
{
"active": false,
"args": null,
Expand Down
7 changes: 7 additions & 0 deletions portal/config/gil/ScheduledJob.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@
"schedule": "17 * * * *",
"task": "cache_assessment_status"
},
{
"active": true,
"name": "Service Token Watchdog",
"resourceType": "ScheduledJob",
"schedule": "30 2 * * *",
"task": "token_watchdog"
},
{
"active": true,
"args": null,
Expand Down
7 changes: 6 additions & 1 deletion portal/date_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,23 @@ def as_fhir(obj):
return as_fhir(obj)

@staticmethod
def parse(data, error_subject=None):
def parse(data, error_subject=None, none_safe=False):
"""Parse input string to generate a UTC datetime instance
NB - date must be more recent than year 1900 or a ValueError
will be raised.
:param data: the datetime string to parse
:param error_subject: Subject string to use in error message
:param none_safe: set true to sanely handle None values
(None in, None out). By default a 400 is raised.
:return: UTC datetime instance from given data
"""
if none_safe and data is None:
return None

# As we use datetime.strftime for display, and it can't handle dates
# older than 1900, treat all such dates as an error
epoch = datetime.strptime('1900-01-01', '%Y-%m-%d')
Expand Down
2 changes: 1 addition & 1 deletion portal/eproms/static/css/eproms.css

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions portal/eproms/static/js/resources.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var ResourcesTool = function() {
this.init = function() {
$(".tab-label").on("click", function() {
$(this).toggleClass("active");
});
$(".tab-label").trigger("click");
this.handlePrint();
};
this.handlePrint = function() {
var self = this;
$("#homeFooter").addClass("hidden-print");
self.startTime = new Date();
self.tVar = setInterval(function(){
self.endTime = new Date();
var elapsedTime = self.endTime - self.startTime;
elapsedTime /= 1000;
if (!$("#tnthNavWrapper").hasClass("no-fouc") || elapsedTime >= 3) {
$("#mainNav, #tnthNavWrapper, .watermark").each(function() {
$(this).addClass("hidden-print");
});
clearInterval(self.tVar);
}
}, 1000);
$(".work-instruction-printicon").on("click", function(e) {
e.stopPropagation();
window.print();
});
};
};

$(function() {
(new ResourcesTool()).init();
});
2 changes: 1 addition & 1 deletion portal/eproms/templates/eproms/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ <h2 class="modal-title">{{ _("TrueNTH") }}</h2>
<script src="https://cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.9.0/validator.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jasny-bootstrap/3.1.3/js/jasny-bootstrap.min.js"></script>
<!-- polyfill code for Promise -->
<script href="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.min.js"></script>
<script src="{{ url_for('static', filename='js/utility.js') }}"></script>
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
{%block table_export_filter_script %}
Expand Down
37 changes: 37 additions & 0 deletions portal/eproms/templates/eproms/resources.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{% extends "eproms/base.html" %}
{% block main %}
<h3 class="tnth-headline">{{_("Resources")}}</h3>
<article id="resourcesContentContainer">
<section class="tabs-container">
{% if video_content|length > 0 %}
<div class="tab">
<input id="tab-one" type="checkbox" name="tabs" class="tab-input">
<label for="tab-one" class="tab-label">{{_("Videos")}}</label>
<div class="tab-content">
<ul>
{% for video in video_content %}
<li class="work-instruction-item">{{video | safe}}</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
<div class="tab">
<input id="tab-two" type="checkbox" name="tabs" class="tab-input">
<label for="tab-two" class="tab-label">{{_("Work Instructions")}}</label>
<div class="tab-content">
<ul>
{% for asset in results %}
{% if 'video' not in asset['tags'] %}
<li class="work-instruction-item">
<a href="{{url_for('.work_instruction', tag=asset['tags'][1])}}" class="first-letter">{{asset['title']}}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</section>
</article>
<script src="{{url_for('.static', filename='js/resources.js')}}"></script>
{% endblock %}
15 changes: 15 additions & 0 deletions portal/eproms/templates/eproms/work_instruction.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{% extends "eproms/base.html" %}
{% block main %}
<h4 class="tnth-headline work-instruction-title">
<span>{{_("Work Instructions")}}</span>
<div class="pull-right work-instruction-icons hidden-print">
<span class="glyphicon glyphicon-print work-instruction-printicon" title="{{_('Print')}}"></span>
<a href="{{url_for('.resources')}}"><span class="glyphicon glyphicon-menu-left" title="{{_('Back to Resources')}}"></span></a>
</div>
</h4>
<div class="work-instruction-content">
<h3 class="work-instruction-content-heading first-letter">{{title | replace('-', ' ')}}</h3>
<div>{{content|safe}}</div>
</div>
<script src="{{url_for('.static', filename='js/resources.js')}}"></script>
{% endblock %}
48 changes: 46 additions & 2 deletions portal/eproms/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
from flask import (
abort,
current_app,
Expand Down Expand Up @@ -28,8 +29,9 @@
from ..models.message import EmailMessage
from ..models.organization import Organization
from ..models.role import ROLE
from ..models.user import current_user, get_user
from ..models.user import current_user, get_user_or_abort
from ..views.auth import next_after_login
from ..views.portal import get_asset, get_any_tag_data, get_all_tag_data


eproms = Blueprint(
Expand Down Expand Up @@ -240,7 +242,7 @@ def website_consent_script(patient_id):
"""
validate_origin(redirect_url)
user = current_user()
patient = get_user(patient_id)
patient = get_user_or_abort(patient_id)
org = patient.first_top_organization()
"""
NOTE, we are getting PATIENT's website consent terms here
Expand All @@ -255,3 +257,45 @@ def website_consent_script(patient_id):
terms=terms, top_organization=top_org,
entry_method=entry_method, redirect_url=redirect_url,
declaration_form=declaration_form, patient_id=patient_id)


@eproms.route('/resources', methods=['GET'])
@roles_required([ROLE.STAFF, ROLE.STAFF_ADMIN])
@oauth.require_oauth()
def resources():
user = current_user()
org = user.first_top_organization()
if not org:
abort(400, 'user must belong to an organization')
resources_data = get_any_tag_data('{} work instruction'.format(org.name.lower()))
results = json.JSONDecoder().decode(resources_data)['results']
if (len(results) > 0):
video_content = []
for asset in results:
if 'video' in asset['tags']:
video_content.append(get_asset(asset['uuid']))
return render_template('eproms/resources.html',
results=results, video_content=video_content)
else:
abort(400, 'no resources found')


@eproms.route('/resources/work-instruction/<string:tag>', methods=['GET'])
@roles_required([ROLE.STAFF, ROLE.STAFF_ADMIN])
@oauth.require_oauth()
def work_instruction(tag):
user = current_user()
org = user.first_top_organization()
if not tag:
abort(400, 'work instruction tag is required')
if not org:
abort(400, 'user must belong to an organization')
work_instruction_data = get_all_tag_data(tag, '{} work instruction'.
format(org.name.lower()))
results = json.JSONDecoder().decode(work_instruction_data)['results']
if len(results) > 0:
content = get_asset(results[0]['uuid'])
return render_template('eproms/work_instruction.html',
content=content, title=tag)
else:
abort(400, 'work instruction not found')
32 changes: 9 additions & 23 deletions portal/exercise_diet/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from flask import Blueprint, current_app, render_template, redirect, url_for

from ..models.user import current_user
from ..views.portal import get_asset, get_any_tag_data


exercise_diet = Blueprint(
Expand All @@ -12,23 +13,8 @@
url_prefix='/exercise-and-diet')


def get_asset(uuid):
url = "{LR_ORIGIN}/c/portal/truenth/asset/detailed?uuid={uuid}".format(
LR_ORIGIN=current_app.config["LR_ORIGIN"], uuid=uuid)
data = requests.get(url).content
return json.JSONDecoder().decode(data)['asset']


def get_tag_data(anyTags):
url = (
"{LR_ORIGIN}/c/portal/truenth/asset/query?anyTags={anyTags}&sort=true"
"&sortType=DESC".format(
LR_ORIGIN=current_app.config["LR_ORIGIN"], anyTags=anyTags))
return requests.get(url).content


def get_all_recipes():
recipe_data = get_tag_data(anyTags="recipe")
recipe_data = get_any_tag_data("recipe")
recipe_assets = {'vegetables': [],
'healthy_vegetable_fat': [],
'tomatoes': [],
Expand Down Expand Up @@ -56,7 +42,7 @@ def get_all_recipes():
(asset['title'], asset['uuid'],
asset['small_image'], 'recipe'))

shopping_data = get_tag_data(anyTags="shopping_tips")
shopping_data = get_any_tag_data("shopping_tips")
for asset in json.JSONDecoder().decode(shopping_data)['results']:
if 'vegetables' in asset['tags']:
recipe_assets['vegetables'].append(
Expand Down Expand Up @@ -90,7 +76,7 @@ def index():
@exercise_diet.route('/introduction')
def introduction():
assets = []
data = get_tag_data(anyTags="introduction")
data = get_any_tag_data("introduction")
for asset in json.JSONDecoder().decode(data)['results']:
assets.append(get_asset(asset['uuid']))

Expand All @@ -100,12 +86,12 @@ def introduction():

@exercise_diet.route('/diet')
def diet():
data = get_tag_data(anyTags="diet")
data = get_any_tag_data("diet")
assets = []
for asset in json.JSONDecoder().decode(data)['results']:
assets.append(get_asset(asset['uuid']))

modal_data = get_tag_data(anyTags="diet-modal")
modal_data = get_any_tag_data("diet-modal")
modals = OrderedDict()
for modal in json.JSONDecoder().decode(modal_data)['results']:
tag = modal['tags']
Expand All @@ -124,12 +110,12 @@ def portal():

@exercise_diet.route('/exercise')
def exercise():
data = get_tag_data(anyTags="exercise")
data = get_any_tag_data("exercise")
assets = []
for asset in json.JSONDecoder().decode(data)['results']:
assets.append(get_asset(asset['uuid']))

modal_data = get_tag_data(anyTags="exercise-modal")
modal_data = get_any_tag_data("exercise-modal")
modals = OrderedDict()
for modal in json.JSONDecoder().decode(modal_data)['results']:
tag = modal['tags']
Expand All @@ -143,7 +129,7 @@ def exercise():

@exercise_diet.route('/recipes')
def recipes():
data = get_tag_data(anyTags="recipe-intro")
data = get_any_tag_data("recipe-intro")
recipe_intro = get_asset(
json.JSONDecoder().decode(data)['results'][0]['uuid'])
recipe_assets = get_all_recipes()
Expand Down
2 changes: 2 additions & 0 deletions portal/factories/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from ..views.procedure import procedure_api
from ..views.portal import portal
from ..views.organization import org_api
from ..views.reporting import reporting_api
from ..views.scheduled_job import scheduled_job_api
from ..views.staff import staff
from ..views.tou import tou_api
Expand All @@ -63,6 +64,7 @@
practitioner_api,
procedure_api,
portal,
reporting_api,
scheduled_job_api,
staff,
truenth_api,
Expand Down
Loading

0 comments on commit e151c2a

Please sign in to comment.