Module Gnumed.exporters.gmTimelineExporter

Timeline exporter.

Copyright: authors

Functions

def create_fake_timeline_file(patient=None, filename=None)
Expand source code
def create_fake_timeline_file(patient=None, filename=None):
        """Used to create an 'empty' timeline file for display.

        - needed because .clear_timeline() doesn't really work
        """
        global now
        now = gmDateTime.pydt_now_here()

        if filename is None:
                timeline_fname = gmTools.get_unique_filename(prefix = 'gm-', suffix = '.timeline')
        else:
                timeline_fname = filename

        _log.debug('creating dummy timeline in [%s]', timeline_fname)
        timeline = open(timeline_fname, mode = 'wt', encoding = 'utf8', errors = 'xmlcharrefreplace')

        timeline.write(__fake_timeline_start)

        # birth
        if patient['dob'] is None:
                start = now.replace(year = now.year - 100)
                timeline.write(__xml_encounter_template % (
                        format_pydt(start),
                        format_pydt(start),
                        _('Birth') + ': ?',
                        _('Life events'),
                        _('Date of birth unknown'),
                        'False'
                ))
        else:
                start = patient['dob']
                timeline.write(__xml_encounter_template % (
                        format_pydt(patient['dob']),
                        format_pydt(patient['dob']),
                        _('Birth') + gmTools.bool2subst(patient['dob_is_estimated'], ' (%s)' % gmTools.u_almost_equal_to, ''),
                        _('Life events'),
                        '',
                        'False'
                ))

        # death
        if patient['deceased'] is None:
                end = now
        else:
                end = patient['deceased']
                timeline.write(__xml_encounter_template % (
                        format_pydt(end),
                        format_pydt(end),
                        #u'',
                        _('Death'),
                        _('Life events'),
                        '',
                        'False'
                ))

        # fake issue
        timeline.write(__fake_timeline_body_template % (
                format_pydt(start),
                format_pydt(end),
                _('Cannot display timeline.'),
                _('Cannot display timeline.')
        ))

        # display range
        if end.month == 2:
                if end.day == 29:
                        # leap years aren't consecutive
                        end = end.replace(day = 28)
        target_year = end.year + 1
        end = end.replace(year = target_year)
        timeline.write(xml_end % (
                format_pydt(start),
                format_pydt(end)
        ))

        timeline.close()
        return timeline_fname

Used to create an 'empty' timeline file for display.

  • needed because .clear_timeline() doesn't really work
def create_timeline_file(patient=None,
filename=None,
include_documents=False,
include_vaccinations=False,
include_encounters=False)
Expand source code
def create_timeline_file(patient=None, filename=None, include_documents=False, include_vaccinations=False, include_encounters=False):

        emr = patient.emr
        global now
        now = gmDateTime.pydt_now_here()

        if filename is None:
                timeline_fname = gmTools.get_unique_filename(prefix = 'gm-', suffix = '.timeline')      # .timeline required ...
        else:
                timeline_fname = filename
        _log.debug('exporting EMR as timeline into [%s]', timeline_fname)
        timeline = open(timeline_fname, mode = 'wt', encoding = 'utf8', errors = 'xmlcharrefreplace')

        if patient['dob'] is None:
                lifespan_start = format_pydt(now.replace(year = now.year - 100))
        else:
                lifespan_start = format_pydt(patient['dob'])

        if patient['deceased'] is None:
                life_ends2day = 'True'
                lifespan_end = format_pydt(now)
        else:
                life_ends2day = 'False'
                lifespan_end = format_pydt(patient['deceased'])

        earliest_care_date = emr.earliest_care_date
        most_recent_care_date = emr.most_recent_care_date
        if most_recent_care_date is None:
                most_recent_care_date = lifespan_end
                care_ends2day = life_ends2day
        else:
                most_recent_care_date = format_pydt(most_recent_care_date)
                care_ends2day = 'False'

        timeline.write(xml_start % (
                # era: life span of patient
                _('Lifespan'),
                lifespan_start,
                lifespan_end,
                life_ends2day,
                ERA_NAME_CARE_PERIOD,
                format_pydt(earliest_care_date),
                most_recent_care_date,
                care_ends2day,
                # categories
                _('Health issues'),
                _('Episodes'),
                _('Encounters'),
                _('Hospital stays'),
                _('Procedures'),
                _('Documents'),
                _('Vaccinations'),
                _('Substances'),
                _('Life events')
        ))
        # birth
        if patient['dob'] is None:
                start = now.replace(year = now.year - 100)
                timeline.write(__xml_encounter_template % (
                        format_pydt(start),
                        format_pydt(start),
                        '?',
                        _('Life events'),
                        _('Date of birth unknown'),
                        'True'
                ))
        else:
                start = patient['dob']
                timeline.write(__xml_encounter_template % (
                        format_pydt(patient['dob']),
                        format_pydt(patient['dob']),
                        '*',
                        _('Life events'),
                        _('Birth: %s') % patient.get_formatted_dob(format = '%Y %b %d %H:%M', honor_estimation = True),
                        'True'
                ))

        # start of care
        timeline.write(__xml_encounter_template % (
                format_pydt(earliest_care_date),
                format_pydt(earliest_care_date),
                gmTools.u_heavy_greek_cross,
                _('Life events'),
                _('Start of Care: %s\n(the earliest recorded event of care in this praxis)') % format_pydt(earliest_care_date, format = '%Y %b %d'),
                'True'
        ))

        # containers must be defined before their
        # subevents, so put health issues first
        timeline.write('\n              <!-- ========================================\n Health issues\n======================================== -->')
        for issue in emr.health_issues:
                timeline.write(__format_health_issue_as_timeline_xml(issue, patient, emr))

        timeline.write('\n              <!-- ========================================\n Episodes\n======================================== -->')
        for epi in emr.get_episodes(order_by = 'pk_health_issue'):
                timeline.write(__format_episode_as_timeline_xml(epi, patient))

        if include_encounters:
                timeline.write(u'\n<!--\n========================================\n Encounters\n======================================== -->')
                for enc in emr.get_encounters(skip_empty = True):
                        timeline.write(__format_encounter_as_timeline_xml(enc, patient))

        timeline.write('\n<!--\n========================================\n Hospital stays\n======================================== -->')
        for stay in emr.hospital_stays:
                timeline.write(__format_hospital_stay_as_timeline_xml(stay))

        timeline.write('\n<!--\n========================================\n Procedures\n======================================== -->')
        for proc in emr.performed_procedures:
                timeline.write(__format_procedure_as_timeline_xml(proc))

        if include_vaccinations:
                timeline.write(u'\n<!--\n========================================\n Vaccinations\n======================================== -->')
                for vacc in emr.vaccinations:
                        timeline.write(__format_vaccination_as_timeline_xml(vacc))

        timeline.write('\n<!--\n========================================\n Substance intakes\n======================================== -->')
        for intake in emr.get_current_medications(include_inactive = True):
                timeline.write(__format_intake_as_timeline_xml(intake))

        if include_documents:
                timeline.write(u'\n<!--\n========================================\n Documents\n======================================== -->')
                for doc in patient.document_folder.documents:
                        timeline.write(__format_document_as_timeline_xml(doc))

        # allergies ?
        # - unclear where and how to place
        # test results ?
        # - too many events, at most "day sample drawn"

        # death
        if patient['deceased'] is None:
                end = now
        else:
                end = patient['deceased']
                death_ago = gmDateTime.format_apparent_age_medically (
                        age = gmDateTime.calculate_apparent_age(start = end, end = now)
                )
                timeline.write(__xml_encounter_template % (
                        format_pydt(end),
                        format_pydt(end),
                        gmTools.u_dagger,
                        _('Life events'),
                        _('Death: %s\n(%s ago at age %s)') % (
                                format_pydt(end, format = '%Y %b %d %H:%M'),
                                death_ago,
                                patient.get_medical_age()
                        ),
                        'True'
                ))

        # display range
        if end.month == 2:
                if end.day == 29:
                        # leap years aren't consecutive
                        end = end.replace(day = 28)
        target_year = end.year + 1
        end = end.replace(year = target_year)
        timeline.write(xml_end % (
                format_pydt(start),
                format_pydt(end)
        ))

        timeline.close()
        return timeline_fname
def format_pydt(pydt, format='%Y-%m-%d %H:%M:%S')
Expand source code
def format_pydt(pydt, format = '%Y-%m-%d %H:%M:%S'):
        return pydt.strftime(format = format)