Skip to content

Commit

Permalink
Merge branch 'release/v17.5.10'
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-c committed May 11, 2017
2 parents 08fa042 + 27c2dc1 commit b806909
Show file tree
Hide file tree
Showing 73 changed files with 3,935 additions and 1,001 deletions.
25 changes: 16 additions & 9 deletions manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import click

import alembic.config
from flask_migrate import Migrate, MigrateCommand
from flask_migrate import Migrate

from portal.app import create_app
from portal.extensions import db
Expand All @@ -30,7 +30,13 @@
def runserver():
# Todo: figure out how to override default host in `flask run`
# http://click.pocoo.org/5/commands/#overriding-defaults
app.run(host='0.0.0.0')
app.run(
host='0.0.0.0',
threaded=True,
use_debugger=True,
use_reloader=True,
)


def _run_alembic_command(args):
"""Helper to manage working directory and run given alembic commands"""
Expand Down Expand Up @@ -73,16 +79,17 @@ def sync():
db.create_all()
stamp_db()
upgrade_db()
seed(include_interventions=True)
seed()


@click.option('--include_interventions', '-i', default=False, help='Include (overwrite) intervention data')
@click.option('--exclude_interventions', '-e', default=False,
help="Exclude (don't overwrite) intervention data")
@click.option('--keep_unmentioned', '-k', default=False, help='Keep orgs and interventions not mentioned in persistence file')
@app.cli.command(name="seed")
def seed_command(include_interventions, keep_unmentioned):
seed(include_interventions, keep_unmentioned)
def seed_command(exclude_interventions, keep_unmentioned):
seed(exclude_interventions, keep_unmentioned)

def seed(include_interventions=False, keep_unmentioned=False):
def seed(exclude_interventions=False, keep_unmentioned=False):
"""Seed database with required data"""

# Request context necessary for generating data from own HTTP APIs
Expand All @@ -98,10 +105,10 @@ def seed(include_interventions=False, keep_unmentioned=False):

# Always update interventions on development systems
if app.config["SYSTEM_TYPE"].lower() == 'development':
include_interventions = True
exclude_interventions = False

# import site export file if found
SitePersistence().import_(include_interventions, keep_unmentioned)
SitePersistence().import_(exclude_interventions, keep_unmentioned)


@app.cli.command()
Expand Down
69 changes: 69 additions & 0 deletions portal/date_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""Module for additional datetime tools/utilities"""
from datetime import date, datetime
from dateutil import parser
from flask import abort, current_app
import pytz


def as_fhir(obj):
"""For builtin types needing FHIR formatting help
Returns obj as JSON FHIR formatted string
"""
if hasattr(obj, 'as_fhir'):
return obj.as_fhir()
if isinstance(obj, datetime):
# Make SURE we only communicate unaware or UTC timezones
tz = getattr(obj, 'tzinfo', None)
if tz and tz != pytz.utc:
current_app.logger.error("Datetime export of NON-UTC timezone")
return obj.strftime("%Y-%m-%dT%H:%M:%S%z")
if isinstance(obj, date):
return obj.strftime('%Y-%m-%d')


class FHIR_datetime(object):
"""Utility class/namespace for working with FHIR datetimes"""

@staticmethod
def as_fhir(obj):
return as_fhir(obj)

@staticmethod
def parse(data, error_subject=None):
"""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
:return: UTC datetime instance from given data
"""
# 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')
try:
dt = parser.parse(data)
except ValueError:
msg = "Unable to parse {}: {}".format(error_subject, data)
current_app.logger.warn(msg)
abort(400, msg)
if dt.tzinfo:
epoch = pytz.utc.localize(epoch)
# Convert to UTC if necessary
if dt.tzinfo != pytz.utc:
dt = dt.astimezone(pytz.utc)
# As we use datetime.strftime for display, and it can't handle dates
# older than 1900, treat all such dates as an error
if dt < epoch:
raise ValueError("Dates prior to year 1900 not supported")
return dt

@staticmethod
def now():
"""Generates a FHIR compliant datetime string for current moment"""
return datetime.utcnow().isoformat()+'Z'
55 changes: 55 additions & 0 deletions portal/migrations/versions/418982ee27e2_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""empty message
Revision ID: 418982ee27e2
Revises: 0ac4b88c909f
Create Date: 2017-05-02 12:05:13.995805
"""

# revision identifiers, used by Alembic.
revision = '418982ee27e2'
down_revision = '0ac4b88c909f'

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('questionnaires',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.Text(), nullable=False),
sa.Column('document', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('questionnaire_banks',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.Text(), nullable=False),
sa.Column('organization_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('questionnaire_bank_questionnaires',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('questionnaire_bank_id', sa.Integer(), nullable=False),
sa.Column('questionnaire_id', sa.Integer(), nullable=False),
sa.Column('days_till_due', sa.Integer(), nullable=False),
sa.Column('days_till_overdue', sa.Integer(), nullable=False),
sa.Column('rank', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['questionnaire_bank_id'], ['questionnaire_banks.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['questionnaire_id'], ['questionnaires.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('questionnaire_bank_id', 'questionnaire_id', name='_questionnaire_bank_questionnaire'),
sa.UniqueConstraint('questionnaire_id', 'rank', name='_questionnaire_bank_questionnaire_rank')
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('questionnaire_bank_questionnaires')
op.drop_table('questionnaire_banks')
op.drop_table('questionnaires')
# ### end Alembic commands ###
34 changes: 34 additions & 0 deletions portal/migrations/versions/58a9d999ece9_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""empty message
Revision ID: 58a9d999ece9
Revises: 0ac4b88c909f
Create Date: 2017-04-26 12:39:32.182048
"""

# revision identifiers, used by Alembic.
revision = '58a9d999ece9'
down_revision = '0ac4b88c909f'

from alembic import op
import sqlalchemy as sa


def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('organization_locales',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('organization_id', sa.Integer(), nullable=False),
sa.Column('coding_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['coding_id'], ['codings.id'], ),
sa.ForeignKeyConstraint(['organization_id'], ['organizations.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('organization_id', 'coding_id', name='_organization_locale_coding')
)
### end Alembic commands ###


def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_table('organization_locales')
### end Alembic commands ###
22 changes: 22 additions & 0 deletions portal/migrations/versions/5d1daa0f3a14_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""empty message
Revision ID: 5d1daa0f3a14
Revises: ('58a9d999ece9', '418982ee27e2')
Create Date: 2017-05-03 16:50:12.498677
"""

# revision identifiers, used by Alembic.
revision = '5d1daa0f3a14'
down_revision = ('58a9d999ece9', '418982ee27e2')

from alembic import op
import sqlalchemy as sa


def upgrade():
pass


def downgrade():
pass
Loading

0 comments on commit b806909

Please sign in to comment.